Merge "Revert "Enable input window rotation flag"" into sc-v2-dev
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/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index d9024fa..70f2ae7 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -166,9 +166,10 @@
mTransformHint = mSurfaceControl->getTransformHint();
mBufferItemConsumer->setTransformHint(mTransformHint);
SurfaceComposerClient::Transaction()
- .setFlags(surface, layer_state_t::eEnableBackpressure,
- layer_state_t::eEnableBackpressure)
- .apply();
+ .setFlags(surface, layer_state_t::eEnableBackpressure,
+ layer_state_t::eEnableBackpressure)
+ .setApplyToken(mApplyToken)
+ .apply();
mNumAcquired = 0;
mNumFrameAvailable = 0;
BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
@@ -190,7 +191,7 @@
}
void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
- int32_t format) {
+ int32_t format, SurfaceComposerClient::Transaction* outTransaction) {
std::unique_lock _lock{mMutex};
if (mFormat != format) {
mFormat = format;
@@ -227,15 +228,18 @@
// We only need to update the scale if we've received at least one buffer. The reason
// for this is the scale is calculated based on the requested size and buffer size.
// If there's no buffer, the scale will always be 1.
+ SurfaceComposerClient::Transaction* destFrameTransaction =
+ (outTransaction) ? outTransaction : &t;
if (mSurfaceControl != nullptr && mLastBufferInfo.hasBuffer) {
- t.setDestinationFrame(mSurfaceControl,
- Rect(0, 0, newSize.getWidth(), newSize.getHeight()));
+ destFrameTransaction->setDestinationFrame(mSurfaceControl,
+ Rect(0, 0, newSize.getWidth(),
+ newSize.getHeight()));
}
applyTransaction = true;
}
}
if (applyTransaction) {
- t.apply();
+ t.setApplyToken(mApplyToken).apply();
}
}
@@ -453,6 +457,9 @@
incStrong((void*)transactionCallbackThunk);
Rect crop = computeCrop(bufferItem);
+ const bool updateDestinationFrame =
+ bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE ||
+ !mLastBufferInfo.hasBuffer;
mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(),
bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform,
bufferItem.mScalingMode, crop);
@@ -470,7 +477,9 @@
t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this));
mSurfaceControlsWithPendingCallback.push(mSurfaceControl);
- t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight()));
+ if (updateDestinationFrame) {
+ t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight()));
+ }
t->setBufferCrop(mSurfaceControl, crop);
t->setTransform(mSurfaceControl, bufferItem.mTransform);
t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
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/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 0d6a673..ea9b1c6 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -96,7 +96,8 @@
void setTransactionCompleteCallback(uint64_t frameNumber,
std::function<void(int64_t)>&& transactionCompleteCallback);
- void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format);
+ void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format,
+ SurfaceComposerClient::Transaction* outTransaction = nullptr);
void flushShadowQueue() {}
status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index b0c631a..7af1f0e 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -242,18 +242,6 @@
}
/**
- * Requests that the state of this object be updated to reflect
- * the most current available information about the application.
- * As this class is created as RefBase object, no pure virtual function is allowed.
- *
- * This method should only be called from within the input dispatcher's
- * critical section.
- *
- * Returns true on success, or false if the handle is no longer valid.
- */
- virtual bool updateInfo() { return false; }
-
- /**
* Updates from another input window handle.
*/
void updateFrom(const sp<WindowInfoHandle> handle);
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/Android.bp b/services/inputflinger/Android.bp
index 24d186c..73e5749 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -96,6 +96,7 @@
"libinputflinger_base",
"libinputreporter",
"libinputreader",
+ "libgui",
],
static_libs: [
"libinputdispatcher",
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index e81dcfe..7b3658d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -114,33 +114,6 @@
return mDispatcher;
}
-class BinderWindowHandle : public WindowInfoHandle {
-public:
- BinderWindowHandle(const WindowInfo& info) { mInfo = info; }
-
- bool updateInfo() override {
- return true;
- }
-};
-
-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 BinderWindowHandle(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/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index f77c029..5e9facf 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -185,10 +185,11 @@
const sp<InputDispatcher>& dispatcher, const std::string name)
: FakeInputReceiver(dispatcher, name), mFrame(Rect(0, 0, WIDTH, HEIGHT)) {
inputApplicationHandle->updateInfo();
+ updateInfo();
mInfo.applicationInfo = *inputApplicationHandle->getInfo();
}
- virtual bool updateInfo() override {
+ void updateInfo() {
mInfo.token = mClientChannel->getConnectionToken();
mInfo.name = "FakeWindowHandle";
mInfo.type = WindowInfo::Type::APPLICATION;
@@ -207,8 +208,6 @@
mInfo.ownerPid = INJECTOR_PID;
mInfo.ownerUid = INJECTOR_UID;
mInfo.displayId = ADISPLAY_ID_DEFAULT;
-
- return true;
}
protected:
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index 7c7a16b..171f2b5 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -64,6 +64,7 @@
"libstatspull",
"libstatssocket",
"libui",
+ "libgui",
"libutils",
"lib-platform-compat-native-api",
"server_configurable_flags",
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9f4108d..d32d6f4 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -55,6 +55,7 @@
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
#include <com/android/internal/compat/IPlatformCompatNative.h>
+#include <gui/SurfaceComposerClient.h>
#include <input/InputDevice.h>
#include <log/log.h>
#include <log/log_event_list.h>
@@ -559,6 +560,10 @@
}
}
+void InputDispatcher::onFirstRef() {
+ SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
+}
+
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;
@@ -4436,11 +4441,6 @@
std::vector<sp<WindowInfoHandle>> newHandles;
for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
- if (!handle->updateInfo()) {
- // handle no longer valid
- continue;
- }
-
const WindowInfo* info = handle->getInfo();
if ((getInputChannelLocked(handle->getToken()) == nullptr &&
info->portalToDisplayId == ADISPLAY_ID_NONE)) {
@@ -6240,4 +6240,16 @@
mLooper->wake();
}
+void InputDispatcher::onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) {
+ // The listener sends the windows as a flattened array. Separate the windows by display for
+ // more convenient parsing.
+ std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
+
+ for (const auto& info : windowInfos) {
+ handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
+ handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
+ }
+ setInputWindows(handlesPerDisplay);
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 87dd6ee..2436e73 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -58,6 +58,7 @@
#include <InputListener.h>
#include <InputReporterInterface.h>
+#include <gui/WindowInfosListener.h>
namespace android::inputdispatcher {
@@ -80,7 +81,7 @@
*
* A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
*/
-class InputDispatcher : public android::InputDispatcherInterface {
+class InputDispatcher : public android::InputDispatcherInterface, public gui::WindowInfosListener {
protected:
~InputDispatcher() override;
@@ -142,6 +143,8 @@
void displayRemoved(int32_t displayId) override;
+ void onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) override;
+
private:
enum class DropReason {
NOT_DROPPED,
@@ -659,6 +662,8 @@
sp<InputReporterInterface> mReporter;
sp<com::android::internal::compat::IPlatformCompatNative> mCompatService;
+
+ void onFirstRef() override;
};
} // namespace android::inputdispatcher
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/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 8c0edca..662be80 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -41,7 +41,6 @@
mInfo.focusable = focusable;
}
- bool updateInfo() { return true; }
void setFocusable(bool focusable) { mInfo.focusable = focusable; }
void setVisible(bool visible) { mInfo.visible = visible; }
};
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/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index a568220..f884a4b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -937,8 +937,6 @@
mInfo.displayId = displayId;
}
- virtual bool updateInfo() { return true; }
-
void setFocusable(bool focusable) { mInfo.focusable = focusable; }
void setVisible(bool visible) { mInfo.visible = visible; }
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/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 5d6f8c7..c233bf0 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -915,7 +915,7 @@
if (activationIndex < 0) {
return false;
}
- return mActivationCount.valueAt(activationIndex).numActiveClients() > 0;
+ return mActivationCount.valueAt(activationIndex).isActive;
}
void SensorDevice::onMicSensorAccessChanged(void* ident, int handle, nsecs_t samplingPeriodNs) {
diff --git a/services/sensorservice/SensorInterface.cpp b/services/sensorservice/SensorInterface.cpp
index 560834f..c285c00 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -92,14 +92,16 @@
}
status_t ProximitySensor::activate(void* ident, bool enabled) {
- bool wasActive = mActive;
+ bool lastState = mSensorDevice.isSensorActive(mSensor.getHandle());
+
status_t status = HardwareSensor::activate(ident, enabled);
if (status != NO_ERROR) {
return status;
}
- mActive = enabled;
- if (wasActive != enabled) {
- mSensorService.onProximityActiveLocked(enabled);
+
+ bool currentState = mSensorDevice.isSensorActive(mSensor.getHandle());
+ if (currentState != lastState) {
+ mSensorService.onProximityActiveLocked(currentState);
}
return NO_ERROR;
}
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index ea181c9..4e9f7bf 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -119,7 +119,6 @@
void didEnableAllSensors() override;
private:
SensorService& mSensorService;
- bool mActive;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 032ff9a..6253036 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -890,7 +890,11 @@
mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
mBufferInfo.mFence = s.acquireFence;
mBufferInfo.mTransform = s.bufferTransform;
+ auto lastDataspace = mBufferInfo.mDataspace;
mBufferInfo.mDataspace = translateDataspace(s.dataspace);
+ if (lastDataspace != mBufferInfo.mDataspace) {
+ mFlinger->mSomeDataspaceChanged = true;
+ }
mBufferInfo.mCrop = computeBufferCrop(s);
mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0192f6c..3616240 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) {
@@ -1628,6 +1610,9 @@
hdrInfoReporter = sp<HdrLayerInfoReporter>::make();
}
hdrInfoReporter->addListener(listener);
+
+
+ mAddingHDRLayerInfoListener = true;
return OK;
}
@@ -2131,6 +2116,8 @@
mTracing.notify("bufferLatched");
}
}
+
+ mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
mVisibleRegionsDirty = false;
if (mCompositionEngine->needsAnotherUpdate()) {
@@ -2275,6 +2262,7 @@
std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>>
hdrInfoListeners;
+ bool haveNewListeners = false;
{
Mutex::Autolock lock(mStateLock);
if (mFpsReporter) {
@@ -2292,37 +2280,45 @@
}
}
}
+ haveNewListeners = mAddingHDRLayerInfoListener; // grab this with state lock
+ mAddingHDRLayerInfoListener = false;
}
- for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
- HdrLayerInfoReporter::HdrLayerInfo info;
- int32_t maxArea = 0;
- mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
- const auto layerFe = layer->getCompositionEngineLayerFE();
- if (layer->isVisible() && compositionDisplay->belongsInOutput(layerFe)) {
- const Dataspace transfer =
+ if (haveNewListeners || mSomeDataspaceChanged || mVisibleRegionsWereDirtyThisFrame) {
+ for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
+ HdrLayerInfoReporter::HdrLayerInfo info;
+ int32_t maxArea = 0;
+ mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
+ const auto layerFe = layer->getCompositionEngineLayerFE();
+ if (layer->isVisible() && compositionDisplay->belongsInOutput(layerFe)) {
+ const Dataspace transfer =
static_cast<Dataspace>(layer->getDataSpace() & Dataspace::TRANSFER_MASK);
- const bool isHdr = (transfer == Dataspace::TRANSFER_ST2084 ||
- transfer == Dataspace::TRANSFER_HLG);
+ const bool isHdr = (transfer == Dataspace::TRANSFER_ST2084 ||
+ transfer == Dataspace::TRANSFER_HLG);
- if (isHdr) {
- const auto* outputLayer = compositionDisplay->getOutputLayerForLayer(layerFe);
- if (outputLayer) {
- info.numberOfHdrLayers++;
- const auto displayFrame = outputLayer->getState().displayFrame;
- const int32_t area = displayFrame.width() * displayFrame.height();
- if (area > maxArea) {
- maxArea = area;
- info.maxW = displayFrame.width();
- info.maxH = displayFrame.height();
+ if (isHdr) {
+ const auto* outputLayer =
+ compositionDisplay->getOutputLayerForLayer(layerFe);
+ if (outputLayer) {
+ info.numberOfHdrLayers++;
+ const auto displayFrame = outputLayer->getState().displayFrame;
+ const int32_t area = displayFrame.width() * displayFrame.height();
+ if (area > maxArea) {
+ maxArea = area;
+ info.maxW = displayFrame.width();
+ info.maxH = displayFrame.height();
+ }
}
}
}
- }
- });
- listener->dispatchHdrLayerInfo(info);
+ });
+ listener->dispatchHdrLayerInfo(info);
+ }
}
+ mSomeDataspaceChanged = false;
+ mVisibleRegionsWereDirtyThisFrame = false;
+
mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence);
mTransactionCallbackInvoker.sendCallbacks();
@@ -2468,7 +2464,6 @@
handleTransactionLocked(transactionFlags);
mDebugInTransaction = 0;
- invalidateHwcGeometry();
// here the transaction has been committed
}
@@ -3045,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) {
@@ -3064,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;
@@ -3074,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() {
@@ -6431,7 +6424,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 022ca12..c428c37 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;
@@ -334,7 +333,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
@@ -822,7 +821,7 @@
void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
void updateInputFlinger();
- void updateInputWindowInfo();
+ void notifyWindowInfos();
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
@@ -1264,11 +1263,19 @@
State mDrawingState{LayerVector::StateSet::Drawing};
bool mVisibleRegionsDirty = false;
+ // VisibleRegions dirty is already cleared by postComp, but we need to track it to prevent
+ // extra work in the HDR layer info listener.
+ bool mVisibleRegionsWereDirtyThisFrame = false;
+ // Used to ensure we omit a callback when HDR layer info listener is newly added but the
+ // scene hasn't changed
+ bool mAddingHDRLayerInfoListener = false;
+
// Set during transaction application stage to track if the input info or children
// for a layer has changed.
// TODO: Also move visibleRegions over to a boolean system.
bool mInputInfoChanged = false;
bool mSomeChildrenChanged;
+ bool mSomeDataspaceChanged = false;
bool mForceTransactionDisplayChange = false;
bool mGeometryInvalid = false;
@@ -1440,8 +1447,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