diff options
author | 2020-06-02 21:34:49 -0700 | |
---|---|---|
committer | 2020-07-10 15:49:48 -0700 | |
commit | 0783e99d457c9d9a3ede400bdb355ba35e828de6 (patch) | |
tree | 7796db4b8f617c73befbb2d76c79e516ee56fd93 | |
parent | 8dcf124c0894e90b932ff5501892dacc37f36fad (diff) |
AIDL-ize InputManager IInputFlinger interface.
Use AIDL interface to define the IInputFlinger interface and replace
the manual interface.
Bug:155425003
Test: atest libgui_test, atest libinput_test.
Change-Id: Ibad036b8ceb3a3f5c6d58f8de4ea8c79379d29b5
32 files changed, 915 insertions, 489 deletions
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h deleted file mode 100644 index d23e3b7767..0000000000 --- a/include/input/IInputFlinger.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef _LIBINPUT_IINPUT_FLINGER_H -#define _LIBINPUT_IINPUT_FLINGER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <binder/IInterface.h> - -#include <input/InputWindow.h> -#include <input/ISetInputWindowsListener.h> - -namespace android { - -/* - * This class defines the Binder IPC interface for accessing various - * InputFlinger features. - */ -class IInputFlinger : public IInterface { -public: - DECLARE_META_INTERFACE(InputFlinger) - - virtual void setInputWindows(const std::vector<InputWindowInfo>& inputHandles, - const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0; - virtual void registerInputChannel(const sp<InputChannel>& channel) = 0; - virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0; -}; - - -/** - * Binder implementation. - */ -class BnInputFlinger : public BnInterface<IInputFlinger> { -public: - enum { - SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, - REGISTER_INPUT_CHANNEL_TRANSACTION, - UNREGISTER_INPUT_CHANNEL_TRANSACTION - }; - - virtual status_t onTransact(uint32_t code, const Parcel& data, - Parcel* reply, uint32_t flags = 0); -}; - -} // namespace android - -#endif // _LIBINPUT_IINPUT_FLINGER_H diff --git a/include/input/ISetInputWindowsListener.h b/include/input/ISetInputWindowsListener.h deleted file mode 100644 index 15d31b25c1..0000000000 --- a/include/input/ISetInputWindowsListener.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2019 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 - -#include <binder/IInterface.h> -#include <binder/Parcel.h> - -namespace android { - -class ISetInputWindowsListener : public IInterface { -public: - DECLARE_META_INTERFACE(SetInputWindowsListener) - virtual void onSetInputWindowsFinished() = 0; -}; - -class BnSetInputWindowsListener: public BnInterface<ISetInputWindowsListener> { -public: - enum SetInputWindowsTag : uint32_t { - ON_SET_INPUT_WINDOWS_FINISHED - }; - - virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0) override; -}; - -}; // namespace android diff --git a/include/input/InputApplication.h b/include/input/InputApplication.h index ccffeb1327..b6b935329b 100644 --- a/include/input/InputApplication.h +++ b/include/input/InputApplication.h @@ -21,6 +21,7 @@ #include <binder/IBinder.h> #include <binder/Parcel.h> +#include <binder/Parcelable.h> #include <input/Input.h> #include <utils/RefBase.h> @@ -31,15 +32,17 @@ namespace android { /* * Describes the properties of an application that can receive input. */ -struct InputApplicationInfo { +struct InputApplicationInfo : public Parcelable { sp<IBinder> token; std::string name; std::chrono::nanoseconds dispatchingTimeout; - status_t write(Parcel& output) const; - static InputApplicationInfo read(const Parcel& from); -}; + InputApplicationInfo() = default; + + status_t readFromParcel(const android::Parcel* parcel) override; + status_t writeToParcel(android::Parcel* parcel) const override; +}; /* * Handle for an application that can receive input. @@ -76,6 +79,7 @@ public: * Returns true on success, or false if the handle is no longer valid. */ virtual bool updateInfo() = 0; + protected: InputApplicationHandle(); virtual ~InputApplicationHandle(); diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 7ca9031f77..0219cf7c2a 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -34,7 +34,9 @@ #include <android-base/chrono_utils.h> #include <binder/IBinder.h> +#include <binder/Parcelable.h> #include <input/Input.h> +#include <sys/stat.h> #include <utils/BitSet.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -174,6 +176,18 @@ struct InputMessage { void getSanitizedCopy(InputMessage* msg) const; }; +struct InputChannelInfo : public Parcelable { + std::string mName; + android::base::unique_fd mFd; + sp<IBinder> mToken; + + InputChannelInfo() = default; + InputChannelInfo(const std::string& name, android::base::unique_fd fd, sp<IBinder> token) + : mName(name), mFd(std::move(fd)), mToken(token){}; + status_t readFromParcel(const android::Parcel* parcel) override; + status_t writeToParcel(android::Parcel* parcel) const override; +}; + /* * An input channel consists of a local unix domain socket used to send and receive * input messages across processes. Each channel has a descriptive name for debugging purposes. @@ -183,10 +197,10 @@ struct InputMessage { * The input channel is closed when all references to it are released. */ class InputChannel : public RefBase { -protected: +public: + InputChannel(); virtual ~InputChannel(); -public: static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); @@ -200,8 +214,10 @@ public: static status_t openInputChannelPair(const std::string& name, sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel); - inline std::string getName() const { return mName; } - inline int getFd() const { return mFd.get(); } + inline std::string getName() const { return mInfo.mName; } + inline int getFd() const { return mInfo.mFd.get(); } + inline sp<IBinder> getToken() const { return mInfo.mToken; } + inline InputChannelInfo& getInfo() { return mInfo; } /* Send a message to the other endpoint. * @@ -231,8 +247,9 @@ public: /* Return a new object that has a duplicate of this channel's fd. */ sp<InputChannel> dup() const; - status_t write(Parcel& out) const; - static sp<InputChannel> read(const Parcel& from); + status_t readFromParcel(const android::Parcel* parcel); + + status_t writeToParcel(android::Parcel* parcel) const; /** * The connection token is used to identify the input connection, i.e. @@ -248,12 +265,23 @@ public: */ sp<IBinder> getConnectionToken() const; + bool operator==(const InputChannel& inputChannel) const { + struct stat lhsInfo, rhsInfo; + if (fstat(mInfo.mFd.get(), &lhsInfo) != 0) { + return false; + } + if (fstat(inputChannel.getFd(), &rhsInfo) != 0) { + return false; + } + // If file descriptors are pointing to same inode they are duplicated fds. + return inputChannel.getName() == getName() && + inputChannel.getConnectionToken() == mInfo.mToken && + lhsInfo.st_ino == rhsInfo.st_ino; + } + private: InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); - std::string mName; - android::base::unique_fd mFd; - - sp<IBinder> mToken; + InputChannelInfo mInfo; }; /* @@ -325,7 +353,6 @@ public: status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); private: - sp<InputChannel> mChannel; }; diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index f8c759c85d..582e73d858 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -17,6 +17,8 @@ #ifndef _UI_INPUT_WINDOW_H #define _UI_INPUT_WINDOW_H +#include <binder/Parcel.h> +#include <binder/Parcelable.h> #include <input/Input.h> #include <input/InputTransport.h> #include <ui/Rect.h> @@ -27,14 +29,12 @@ #include "InputApplication.h" namespace android { -class Parcel; /* * Describes the properties of a window that can receive input. */ -struct InputWindowInfo { +struct InputWindowInfo : public Parcelable { InputWindowInfo() = default; - InputWindowInfo(const Parcel& from); // Window flags from WindowManager.LayoutParams enum : uint32_t { @@ -195,9 +195,11 @@ struct InputWindowInfo { bool overlaps(const InputWindowInfo* other) const; - status_t write(Parcel& output) const; + bool operator==(const InputWindowInfo& inputChannel) const; - static InputWindowInfo read(const Parcel& from); + status_t writeToParcel(android::Parcel* parcel) const override; + + status_t readFromParcel(const android::Parcel* parcel) override; }; std::string inputWindowFlagsToString(uint32_t flags); @@ -210,22 +212,19 @@ std::string inputWindowFlagsToString(uint32_t flags); */ class InputWindowHandle : public RefBase { public: + explicit InputWindowHandle(); + InputWindowHandle(const InputWindowHandle& other); + InputWindowHandle(const InputWindowInfo& other); - inline const InputWindowInfo* getInfo() const { - return &mInfo; - } + inline const InputWindowInfo* getInfo() const { return &mInfo; } sp<IBinder> getToken() const; int32_t getId() const { return mInfo.id; } - sp<IBinder> getApplicationToken() { - return mInfo.applicationInfo.token; - } + sp<IBinder> getApplicationToken() { return mInfo.applicationInfo.token; } - inline std::string getName() const { - return !mInfo.name.empty() ? mInfo.name : "<invalid>"; - } + inline std::string getName() const { return !mInfo.name.empty() ? mInfo.name : "<invalid>"; } inline std::chrono::nanoseconds getDispatchingTimeout( std::chrono::nanoseconds defaultValue) const { @@ -235,13 +234,14 @@ public: /** * 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() = 0; + virtual bool updateInfo() { return false; } /** * Updates from another input window handle. @@ -254,8 +254,11 @@ public: */ void releaseChannel(); + // Not override since this class is not derrived from Parcelable. + status_t readFromParcel(const android::Parcel* parcel); + status_t writeToParcel(android::Parcel* parcel) const; + protected: - explicit InputWindowHandle(); virtual ~InputWindowHandle(); InputWindowInfo mInfo; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e43446ac8c..1030b82f14 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -55,7 +55,7 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(color.g); output.writeFloat(color.b); #ifndef NO_INPUT - inputInfo.write(output); + inputHandle->writeToParcel(&output); #endif output.write(transparentRegion); output.writeUint32(transform); @@ -152,7 +152,7 @@ status_t layer_state_t::read(const Parcel& input) color.b = input.readFloat(); #ifndef NO_INPUT - inputInfo = InputWindowInfo::read(input); + inputHandle->readFromParcel(&input); #endif input.read(transparentRegion); @@ -404,7 +404,7 @@ void layer_state_t::merge(const layer_state_t& other) { #ifndef NO_INPUT if (other.what & eInputInfoChanged) { what |= eInputInfoChanged; - inputInfo = other.inputInfo; + inputHandle = new InputWindowHandle(*other.inputHandle); } #endif diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 16b46df4f6..d797a3547a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1359,7 +1359,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput mStatus = BAD_INDEX; return *this; } - s->inputInfo = info; + s->inputHandle = new InputWindowHandle(info); s->what |= layer_state_t::eInputInfoChanged; return *this; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index e60f6777ae..00ae220906 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -201,7 +201,7 @@ struct layer_state_t { mat4 colorTransform; #ifndef NO_INPUT - InputWindowInfo inputInfo; + sp<InputWindowHandle> inputHandle = new InputWindowHandle(); #endif client_cache_t cachedBuffer; diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 32c7fc2588..152f7ad56c 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -36,15 +36,16 @@ #include <gui/SurfaceComposerClient.h> #include <gui/SurfaceControl.h> -#include <input/InputWindow.h> -#include <input/IInputFlinger.h> -#include <input/InputTransport.h> +#include <android/os/IInputFlinger.h> #include <input/Input.h> +#include <input/InputTransport.h> +#include <input/InputWindow.h> #include <ui/DisplayConfig.h> #include <ui/Rect.h> #include <ui/Region.h> +using android::os::IInputFlinger; namespace android { namespace test { @@ -71,7 +72,7 @@ public: InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel); mInputFlinger = getInputFlinger(); - mInputFlinger->registerInputChannel(mServerChannel); + mInputFlinger->registerInputChannel(mServerChannel->getInfo()); populateInputInfo(width, height); @@ -153,9 +154,7 @@ public: EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS); } - ~InputSurface() { - mInputFlinger->unregisterInputChannel(mServerChannel); - } + ~InputSurface() { mInputFlinger->unregisterInputChannel(mServerChannel->getInfo()); } void doTransaction(std::function<void(SurfaceComposerClient::Transaction&, const sp<SurfaceControl>&)> transactionBody) { diff --git a/libs/input/Android.bp b/libs/input/Android.bp index 7037680935..ade9c25c53 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -46,14 +46,14 @@ cc_library { target: { android: { srcs: [ - "IInputFlinger.cpp", "InputApplication.cpp", "InputTransport.cpp", "InputWindow.cpp", - "ISetInputWindowsListener.cpp", "LatencyStatistics.cpp", "VelocityControl.cpp", "VelocityTracker.cpp", + "android/os/IInputFlinger.aidl", + "android/os/ISetInputWindowsListener.aidl", ], shared_libs: [ @@ -72,6 +72,11 @@ cc_library { }, }, }, + + aidl: { + local_include_dirs: ["."], + export_aidl_headers: true + }, } subdirs = ["tests"] diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp deleted file mode 100644 index 8ec51653a8..0000000000 --- a/libs/input/IInputFlinger.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2013 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 <stdint.h> -#include <sys/types.h> - -#include <binder/Parcel.h> -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> - -#include <input/IInputFlinger.h> - -namespace android { - -class BpInputFlinger : public BpInterface<IInputFlinger> { -public: - explicit BpInputFlinger(const sp<IBinder>& impl) : - BpInterface<IInputFlinger>(impl) { } - - virtual void setInputWindows(const std::vector<InputWindowInfo>& inputInfo, - const sp<ISetInputWindowsListener>& setInputWindowsListener) { - Parcel data, reply; - data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); - - data.writeUint32(static_cast<uint32_t>(inputInfo.size())); - for (const auto& info : inputInfo) { - info.write(data); - } - data.writeStrongBinder(IInterface::asBinder(setInputWindowsListener)); - - remote()->transact(BnInputFlinger::SET_INPUT_WINDOWS_TRANSACTION, data, &reply, - IBinder::FLAG_ONEWAY); - } - - virtual void registerInputChannel(const sp<InputChannel>& channel) { - Parcel data, reply; - data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); - channel->write(data); - remote()->transact(BnInputFlinger::REGISTER_INPUT_CHANNEL_TRANSACTION, data, &reply); - } - - virtual void unregisterInputChannel(const sp<InputChannel>& channel) { - Parcel data, reply; - data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); - channel->write(data); - remote()->transact(BnInputFlinger::UNREGISTER_INPUT_CHANNEL_TRANSACTION, data, &reply); - } -}; - -IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger"); - -status_t BnInputFlinger::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - switch(code) { - case SET_INPUT_WINDOWS_TRANSACTION: { - CHECK_INTERFACE(IInputFlinger, data, reply); - size_t count = data.readUint32(); - if (count > data.dataSize()) { - return BAD_VALUE; - } - std::vector<InputWindowInfo> handles; - for (size_t i = 0; i < count; i++) { - handles.push_back(InputWindowInfo::read(data)); - } - const sp<ISetInputWindowsListener> setInputWindowsListener = - ISetInputWindowsListener::asInterface(data.readStrongBinder()); - setInputWindows(handles, setInputWindowsListener); - break; - } - case REGISTER_INPUT_CHANNEL_TRANSACTION: { - CHECK_INTERFACE(IInputFlinger, data, reply); - sp<InputChannel> channel = InputChannel::read(data); - registerInputChannel(channel); - break; - } - case UNREGISTER_INPUT_CHANNEL_TRANSACTION: { - CHECK_INTERFACE(IInputFlinger, data, reply); - sp<InputChannel> channel = InputChannel::read(data); - unregisterInputChannel(channel); - break; - } - default: - return BBinder::onTransact(code, data, reply, flags); - } - return NO_ERROR; -} - -}; diff --git a/libs/input/ISetInputWindowsListener.cpp b/libs/input/ISetInputWindowsListener.cpp deleted file mode 100644 index a0330da89e..0000000000 --- a/libs/input/ISetInputWindowsListener.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2019 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 <input/ISetInputWindowsListener.h> - -namespace android { - -class BpSetInputWindowsListener : public BpInterface<ISetInputWindowsListener> { -public: - explicit BpSetInputWindowsListener(const sp<IBinder>& impl) - : BpInterface<ISetInputWindowsListener>(impl) { - } - - virtual ~BpSetInputWindowsListener() = default; - - virtual void onSetInputWindowsFinished() { - Parcel data, reply; - data.writeInterfaceToken(ISetInputWindowsListener::getInterfaceDescriptor()); - remote()->transact(BnSetInputWindowsListener::ON_SET_INPUT_WINDOWS_FINISHED, data, &reply, - IBinder::FLAG_ONEWAY); - } -}; - -IMPLEMENT_META_INTERFACE(SetInputWindowsListener, "android.input.ISetInputWindowsListener"); - -status_t BnSetInputWindowsListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags) { - switch(code) { - case ON_SET_INPUT_WINDOWS_FINISHED: { - CHECK_INTERFACE(ISetInputWindowsListener, data, reply); - onSetInputWindowsFinished(); - return NO_ERROR; - } - default: { - return BBinder::onTransact(code, data, reply, flags); - } - } -} - -} // namespace android diff --git a/libs/input/InputApplication.cpp b/libs/input/InputApplication.cpp index c745c24c66..41721a7344 100644 --- a/libs/input/InputApplication.cpp +++ b/libs/input/InputApplication.cpp @@ -22,29 +22,34 @@ namespace android { -// --- InputApplicationHandle --- - -InputApplicationHandle::InputApplicationHandle() { -} - -InputApplicationHandle::~InputApplicationHandle() { +status_t InputApplicationInfo::readFromParcel(const android::Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + token = parcel->readStrongBinder(); + dispatchingTimeout = decltype(dispatchingTimeout)(parcel->readInt64()); + status_t status = parcel->readUtf8FromUtf16(&name); + + return status; } -InputApplicationInfo InputApplicationInfo::read(const Parcel& from) { - InputApplicationInfo ret; - ret.token = from.readStrongBinder(); - ret.name = from.readString8().c_str(); - ret.dispatchingTimeout = decltype(ret.dispatchingTimeout)(from.readInt64()); +status_t InputApplicationInfo::writeToParcel(android::Parcel* parcel) const { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + status_t status = parcel->writeStrongBinder(token) + ?: parcel->writeInt64(dispatchingTimeout.count()) + ?: parcel->writeUtf8AsUtf16(name) ; - return ret; + return status; } -status_t InputApplicationInfo::write(Parcel& output) const { - output.writeStrongBinder(token); - output.writeString8(String8(name.c_str())); - output.writeInt64(dispatchingTimeout.count()); +// --- InputApplicationHandle --- - return OK; -} +InputApplicationHandle::InputApplicationHandle() {} + +InputApplicationHandle::~InputApplicationHandle() {} } // namespace android diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 11af23e1a2..c6043ac203 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -246,6 +246,28 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const { } } +// --- InputChannelInfo --- + +status_t InputChannelInfo::writeToParcel(android::Parcel* parcel) const { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + status_t status = parcel->writeStrongBinder(mToken) + ?: parcel->writeUtf8AsUtf16(mName) ?: parcel->writeUniqueFileDescriptor(mFd); + return status; +} + +status_t InputChannelInfo::readFromParcel(const android::Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + mToken = parcel->readStrongBinder(); + status_t status = parcel->readUtf8FromUtf16(&mName) ?: parcel->readUniqueFileDescriptor(&mFd); + return status; +} + // --- InputChannel --- sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd, @@ -260,15 +282,17 @@ sp<InputChannel> InputChannel::create(const std::string& name, android::base::un } InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token) - : mName(name), mFd(std::move(fd)), mToken(token) { + : mInfo(name, std::move(fd), token) { if (DEBUG_CHANNEL_LIFECYCLE) { - ALOGD("Input channel constructed: name='%s', fd=%d", mName.c_str(), mFd.get()); + ALOGD("Input channel constructed: name='%s', fd=%d", mInfo.mName.c_str(), mInfo.mFd.get()); } } +InputChannel::InputChannel() {} + InputChannel::~InputChannel() { if (DEBUG_CHANNEL_LIFECYCLE) { - ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get()); + ALOGD("Input channel destroyed: name='%s', fd=%d", getName().c_str(), getFd()); } } @@ -308,7 +332,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) { msg->getSanitizedCopy(&cleanMsg); ssize_t nWrite; do { - nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); + nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); } while (nWrite == -1 && errno == EINTR); if (nWrite < 0) { @@ -343,7 +367,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) { status_t InputChannel::receiveMessage(InputMessage* msg) { ssize_t nRead; do { - nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT); + nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT); } while (nRead == -1 && errno == EINTR); if (nRead < 0) { @@ -383,7 +407,7 @@ status_t InputChannel::receiveMessage(InputMessage* msg) { sp<InputChannel> InputChannel::dup() const { android::base::unique_fd newFd(::dup(getFd())); if (!newFd.ok()) { - ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), mName.c_str(), + ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), getName().c_str(), strerror(errno)); const bool hitFdLimit = errno == EMFILE || errno == ENFILE; // If this process is out of file descriptors, then throwing that might end up exploding @@ -394,38 +418,19 @@ sp<InputChannel> InputChannel::dup() const { getName().c_str()); return nullptr; } - return InputChannel::create(mName, std::move(newFd), mToken); + return InputChannel::create(getName(), std::move(newFd), getConnectionToken()); } -status_t InputChannel::write(Parcel& out) const { - status_t s = out.writeCString(getName().c_str()); - if (s != OK) { - return s; - } - - s = out.writeStrongBinder(mToken); - if (s != OK) { - return s; - } - - s = out.writeUniqueFileDescriptor(mFd); - return s; +status_t InputChannel::writeToParcel(android::Parcel* parcel) const { + return mInfo.writeToParcel(parcel); } -sp<InputChannel> InputChannel::read(const Parcel& from) { - std::string name = from.readCString(); - sp<IBinder> token = from.readStrongBinder(); - android::base::unique_fd rawFd; - status_t fdResult = from.readUniqueFileDescriptor(&rawFd); - if (fdResult != OK) { - return nullptr; - } - - return InputChannel::create(name, std::move(rawFd), token); +status_t InputChannel::readFromParcel(const android::Parcel* parcel) { + return mInfo.readFromParcel(parcel); } sp<IBinder> InputChannel::getConnectionToken() const { - return mToken; + return mInfo.mToken; } // --- InputPublisher --- diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp index 3700e8f0f8..ae9b3f0994 100644 --- a/libs/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp @@ -24,9 +24,6 @@ #include <log/log.h> -#include <ui/Rect.h> -#include <ui/Region.h> - namespace android { const char* inputWindowFlagToString(uint32_t flag) { @@ -164,96 +161,130 @@ bool InputWindowInfo::overlaps(const InputWindowInfo* other) const { && frameTop < other->frameBottom && frameBottom > other->frameTop; } -status_t InputWindowInfo::write(Parcel& output) const { +bool InputWindowInfo::operator==(const InputWindowInfo& info) const { + return info.token == token && info.id == id && info.name == name && + info.layoutParamsFlags == layoutParamsFlags && + info.layoutParamsType == layoutParamsType && + info.dispatchingTimeout == dispatchingTimeout && info.frameLeft == frameLeft && + info.frameTop == frameTop && info.frameRight == frameRight && + info.frameBottom == frameBottom && info.surfaceInset == surfaceInset && + info.globalScaleFactor == globalScaleFactor && info.windowXScale == windowXScale && + info.windowYScale == windowYScale && + info.touchableRegion.hasSameRects(touchableRegion) && info.visible == visible && + info.canReceiveKeys == canReceiveKeys && info.trustedOverlay == trustedOverlay && + info.hasFocus == hasFocus && info.hasWallpaper == hasWallpaper && + info.paused == paused && info.ownerPid == ownerPid && info.ownerUid == ownerUid && + info.inputFeatures == inputFeatures && info.displayId == displayId && + info.portalToDisplayId == portalToDisplayId && + info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop && + info.applicationInfo.name == applicationInfo.name && + info.applicationInfo.token == applicationInfo.token && + info.applicationInfo.dispatchingTimeout == applicationInfo.dispatchingTimeout; +} + +status_t InputWindowInfo::writeToParcel(android::Parcel* parcel) const { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } if (name.empty()) { - output.writeInt32(0); + parcel->writeInt32(0); return OK; } - output.writeInt32(1); - status_t s = output.writeStrongBinder(token); - if (s != OK) return s; + parcel->writeInt32(1); - output.writeInt32(id); - output.writeString8(String8(name.c_str())); - output.writeInt32(layoutParamsFlags); - output.writeInt32(layoutParamsType); - output.writeInt64(dispatchingTimeout.count()); - output.writeInt32(frameLeft); - output.writeInt32(frameTop); - output.writeInt32(frameRight); - output.writeInt32(frameBottom); - output.writeInt32(surfaceInset); - output.writeFloat(globalScaleFactor); - output.writeFloat(windowXScale); - output.writeFloat(windowYScale); - output.writeBool(visible); - output.writeBool(canReceiveKeys); - output.writeBool(hasFocus); - output.writeBool(hasWallpaper); - output.writeBool(paused); - output.writeBool(trustedOverlay); - output.writeInt32(ownerPid); - output.writeInt32(ownerUid); - output.writeInt32(inputFeatures); - output.writeInt32(displayId); - output.writeInt32(portalToDisplayId); - applicationInfo.write(output); - output.write(touchableRegion); - output.writeBool(replaceTouchableRegionWithCrop); - output.writeStrongBinder(touchableRegionCropHandle.promote()); - return OK; -} + status_t status = parcel->writeStrongBinder(token) ?: + parcel->writeInt64(dispatchingTimeout.count()) ?: + parcel->writeInt32(id) ?: + parcel->writeUtf8AsUtf16(name) ?: + parcel->writeInt32(layoutParamsFlags) ?: + parcel->writeInt32(layoutParamsType) ?: + parcel->writeInt32(frameLeft) ?: + parcel->writeInt32(frameTop) ?: + parcel->writeInt32(frameRight) ?: + parcel->writeInt32(frameBottom) ?: + parcel->writeInt32(surfaceInset) ?: + parcel->writeFloat(globalScaleFactor) ?: + parcel->writeFloat(windowXScale) ?: + parcel->writeFloat(windowYScale) ?: + parcel->writeBool(visible) ?: + parcel->writeBool(canReceiveKeys) ?: + parcel->writeBool(hasFocus) ?: + parcel->writeBool(hasWallpaper) ?: + parcel->writeBool(paused) ?: + parcel->writeBool(trustedOverlay) ?: + parcel->writeInt32(ownerPid) ?: + parcel->writeInt32(ownerUid) ?: + parcel->writeInt32(inputFeatures) ?: + parcel->writeInt32(displayId) ?: + parcel->writeInt32(portalToDisplayId) ?: + applicationInfo.writeToParcel(parcel) ?: + parcel->write(touchableRegion) ?: + parcel->writeBool(replaceTouchableRegionWithCrop) ?: + parcel->writeStrongBinder(touchableRegionCropHandle.promote()); -InputWindowInfo InputWindowInfo::read(const Parcel& from) { - InputWindowInfo ret; + return status; +} - if (from.readInt32() == 0) { - return ret; +status_t InputWindowInfo::readFromParcel(const android::Parcel* parcel) { + if (parcel == nullptr) { + ALOGE("%s: Null parcel", __func__); + return BAD_VALUE; + } + if (parcel->readInt32() == 0) { + return OK; } - ret.token = from.readStrongBinder(); - ret.id = from.readInt32(); - ret.name = from.readString8().c_str(); - ret.layoutParamsFlags = from.readInt32(); - ret.layoutParamsType = from.readInt32(); - ret.dispatchingTimeout = decltype(ret.dispatchingTimeout)(from.readInt64()); - ret.frameLeft = from.readInt32(); - ret.frameTop = from.readInt32(); - ret.frameRight = from.readInt32(); - ret.frameBottom = from.readInt32(); - ret.surfaceInset = from.readInt32(); - ret.globalScaleFactor = from.readFloat(); - ret.windowXScale = from.readFloat(); - ret.windowYScale = from.readFloat(); - ret.visible = from.readBool(); - ret.canReceiveKeys = from.readBool(); - ret.hasFocus = from.readBool(); - ret.hasWallpaper = from.readBool(); - ret.paused = from.readBool(); - ret.trustedOverlay = from.readBool(); - ret.ownerPid = from.readInt32(); - ret.ownerUid = from.readInt32(); - ret.inputFeatures = from.readInt32(); - ret.displayId = from.readInt32(); - ret.portalToDisplayId = from.readInt32(); - ret.applicationInfo = InputApplicationInfo::read(from); - from.read(ret.touchableRegion); - ret.replaceTouchableRegionWithCrop = from.readBool(); - ret.touchableRegionCropHandle = from.readStrongBinder(); + token = parcel->readStrongBinder(); + dispatchingTimeout = decltype(dispatchingTimeout)(parcel->readInt64()); + status_t status = parcel->readInt32(&id) ?: + parcel->readUtf8FromUtf16(&name) ?: + parcel->readInt32(&layoutParamsFlags) ?: + parcel->readInt32(&layoutParamsType) ?: + parcel->readInt32(&frameLeft) ?: + parcel->readInt32(&frameTop) ?: + parcel->readInt32(&frameRight) ?: + parcel->readInt32(&frameBottom) ?: + parcel->readInt32(&surfaceInset) ?: + parcel->readFloat(&globalScaleFactor) ?: + parcel->readFloat(&windowXScale) ?: + parcel->readFloat(&windowYScale) ?: + parcel->readBool(&visible) ?: + parcel->readBool(&canReceiveKeys) ?: + parcel->readBool(&hasFocus) ?: + parcel->readBool(&hasWallpaper) ?: + parcel->readBool(&paused) ?: + parcel->readBool(&trustedOverlay) ?: + parcel->readInt32(&ownerPid) ?: + parcel->readInt32(&ownerUid) ?: + parcel->readInt32(&inputFeatures) ?: + parcel->readInt32(&displayId) ?: + parcel->readInt32(&portalToDisplayId) ?: + applicationInfo.readFromParcel(parcel) ?: + parcel->read(touchableRegion) ?: + parcel->readBool(&replaceTouchableRegionWithCrop); - return ret; -} + touchableRegionCropHandle = parcel->readStrongBinder(); -InputWindowInfo::InputWindowInfo(const Parcel& from) { - *this = read(from); + return status; } // --- InputWindowHandle --- -InputWindowHandle::InputWindowHandle() { +InputWindowHandle::InputWindowHandle() {} + +InputWindowHandle::~InputWindowHandle() {} + +InputWindowHandle::InputWindowHandle(const InputWindowHandle& other) : mInfo(other.mInfo) {} + +InputWindowHandle::InputWindowHandle(const InputWindowInfo& other) : mInfo(other) {} + +status_t InputWindowHandle::writeToParcel(android::Parcel* parcel) const { + return mInfo.writeToParcel(parcel); } -InputWindowHandle::~InputWindowHandle() { +status_t InputWindowHandle::readFromParcel(const android::Parcel* parcel) { + return mInfo.readFromParcel(parcel); } void InputWindowHandle::releaseChannel() { diff --git a/libs/input/android/InputChannelInfo.aidl b/libs/input/android/InputChannelInfo.aidl new file mode 100644 index 0000000000..2e83b966f1 --- /dev/null +++ b/libs/input/android/InputChannelInfo.aidl @@ -0,0 +1,20 @@ +/* //device/java/android/android/view/InputChannel.aidl +** +** Copyright 2020, 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. +*/ + +package android; + +parcelable InputChannelInfo cpp_header "input/InputTransport.h"; diff --git a/libs/input/android/InputWindowInfo.aidl b/libs/input/android/InputWindowInfo.aidl new file mode 100644 index 0000000000..eeaf400227 --- /dev/null +++ b/libs/input/android/InputWindowInfo.aidl @@ -0,0 +1,20 @@ +/* //device/java/android/android/view/InputChannel.aidl +** +** Copyright 2020, 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. +*/ + +package android; + +parcelable InputWindowInfo cpp_header "input/InputWindow.h"; diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl new file mode 100644 index 0000000000..8ff9dae47e --- /dev/null +++ b/libs/input/android/os/IInputFlinger.aidl @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2020, 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. + */ + +package android.os; + +import android.InputChannelInfo; +import android.InputWindowInfo; +import android.os.ISetInputWindowsListener; + +/** @hide */ +interface IInputFlinger +{ + void setInputWindows(in InputWindowInfo[] inputHandles, + in @nullable ISetInputWindowsListener setInputWindowsListener); + void registerInputChannel(in InputChannelInfo info); + void unregisterInputChannel(in InputChannelInfo info); +} diff --git a/libs/input/android/os/ISetInputWindowsListener.aidl b/libs/input/android/os/ISetInputWindowsListener.aidl new file mode 100644 index 0000000000..bb58fb671b --- /dev/null +++ b/libs/input/android/os/ISetInputWindowsListener.aidl @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2020, 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. + */ + +package android.os; + +/** @hide */ +oneway interface ISetInputWindowsListener +{ + void onSetInputWindowsFinished(); +} diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp index ada275d014..7f4bd6eac2 100644 --- a/libs/input/tests/InputChannel_test.cpp +++ b/libs/input/tests/InputChannel_test.cpp @@ -23,6 +23,7 @@ #include <errno.h> #include <binder/Binder.h> +#include <binder/Parcel.h> #include <gtest/gtest.h> #include <input/InputTransport.h> #include <utils/StopWatch.h> @@ -197,5 +198,36 @@ TEST_F(InputChannelTest, SendAndReceive_MotionClassification) { } } +TEST_F(InputChannelTest, InputChannelParcelAndUnparcel) { + sp<InputChannel> serverChannel, clientChannel; + + status_t result = + InputChannel::openInputChannelPair("channel parceling", serverChannel, clientChannel); + + ASSERT_EQ(OK, result) << "should have successfully opened a channel pair"; + + InputChannel chan; + Parcel parcel; + ASSERT_EQ(OK, serverChannel->writeToParcel(&parcel)); + parcel.setDataPosition(0); + chan.readFromParcel(&parcel); + + EXPECT_EQ(chan == *serverChannel, true) + << "inputchannel should be equal after parceling and unparceling.\n" + << "name " << chan.getName() << " name " << serverChannel->getName(); +} + +TEST_F(InputChannelTest, DuplicateChannelAndAssertEqual) { + sp<InputChannel> serverChannel, clientChannel; + + status_t result = + InputChannel::openInputChannelPair("channel dup", serverChannel, clientChannel); + + ASSERT_EQ(OK, result) << "should have successfully opened a channel pair"; + + sp<InputChannel> dupChan = serverChannel->dup(); + + EXPECT_EQ(*serverChannel == *dupChan, true) << "inputchannel should be equal after duplication"; +} } // namespace android diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp index 87505323c3..cdea922bd2 100644 --- a/libs/input/tests/InputWindow_test.cpp +++ b/libs/input/tests/InputWindow_test.cpp @@ -28,13 +28,13 @@ namespace android { namespace test { TEST(InputWindowInfo, ParcellingWithoutToken) { - InputWindowInfo i; + InputWindowInfo i, i2; i.token = nullptr; Parcel p; - ASSERT_EQ(OK, i.write(p)); + ASSERT_EQ(OK, i.writeToParcel(&p)); p.setDataPosition(0); - InputWindowInfo i2 = InputWindowInfo::read(p); + i2.readFromParcel(&p); ASSERT_TRUE(i2.token == nullptr); } @@ -69,10 +69,10 @@ TEST(InputWindowInfo, Parcelling) { i.touchableRegionCropHandle = touchableRegionCropHandle; Parcel p; - i.write(p); - + i.writeToParcel(&p); p.setDataPosition(0); - InputWindowInfo i2 = InputWindowInfo::read(p); + InputWindowInfo i2; + i2.readFromParcel(&p); ASSERT_EQ(i.token, i2.token); ASSERT_EQ(i.id, i2.id); ASSERT_EQ(i.name, i2.name); diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp index f2a0014da4..c5f60ade96 100644 --- a/services/inputflinger/InputManager.cpp +++ b/services/inputflinger/InputManager.cpp @@ -93,16 +93,15 @@ sp<InputDispatcherInterface> InputManager::getDispatcher() { class BinderWindowHandle : public InputWindowHandle { public: - BinderWindowHandle(const InputWindowInfo& info) { - mInfo = info; - } + BinderWindowHandle(const InputWindowInfo& info) { mInfo = info; } bool updateInfo() override { return true; } }; -void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos, +binder::Status InputManager::setInputWindows( + const std::vector<InputWindowInfo>& infos, const sp<ISetInputWindowsListener>& setInputWindowsListener) { std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay; @@ -116,22 +115,38 @@ void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos, if (setInputWindowsListener) { setInputWindowsListener->onSetInputWindowsFinished(); } + return binder::Status::ok(); } // Used by tests only. -void InputManager::registerInputChannel(const sp<InputChannel>& channel) { +binder::Status InputManager::registerInputChannel(const InputChannelInfo& info) { IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); if (uid != AID_SHELL && uid != AID_ROOT) { ALOGE("Invalid attempt to register input channel over IPC" "from non shell/root entity (PID: %d)", ipc->getCallingPid()); - return; + return binder::Status::ok(); } + android::base::unique_fd newFd(::dup(info.mFd)); + sp<InputChannel> channel = InputChannel::create(info.mName, std::move(newFd), info.mToken); mDispatcher->registerInputChannel(channel); + return binder::Status::ok(); } -void InputManager::unregisterInputChannel(const sp<InputChannel>& channel) { +binder::Status InputManager::unregisterInputChannel(const InputChannelInfo& info) { + android::base::unique_fd newFd(::dup(info.mFd)); + sp<InputChannel> channel = InputChannel::create(info.mName, std::move(newFd), info.mToken); mDispatcher->unregisterInputChannel(channel); + return binder::Status::ok(); +} + +status_t InputManager::dump(int fd, const Vector<String16>& args) { + std::string dump; + + dump += " InputFlinger dump\n"; + + ::write(fd, dump.c_str(), dump.size()); + return NO_ERROR; } } // namespace android diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h index 41d9478147..4993b54b5c 100644 --- a/services/inputflinger/InputManager.h +++ b/services/inputflinger/InputManager.h @@ -26,18 +26,23 @@ #include <InputDispatcherInterface.h> #include <InputDispatcherPolicyInterface.h> -#include <input/ISetInputWindowsListener.h> +#include <android/os/ISetInputWindowsListener.h> #include <input/Input.h> #include <input/InputTransport.h> -#include <input/IInputFlinger.h> +#include <android/os/BnInputFlinger.h> +#include <android/os/IInputFlinger.h> #include <utils/Errors.h> -#include <utils/Vector.h> -#include <utils/Timers.h> #include <utils/RefBase.h> +#include <utils/Timers.h> +#include <utils/Vector.h> + +using android::os::BnInputFlinger; +using android::os::ISetInputWindowsListener; namespace android { class InputChannel; +class InputDispatcherThread; /* * The input manager is the core of the system event processing. @@ -98,11 +103,13 @@ public: sp<InputClassifierInterface> getClassifier() override; sp<InputDispatcherInterface> getDispatcher() override; - void setInputWindows(const std::vector<InputWindowInfo>& handles, - const sp<ISetInputWindowsListener>& setInputWindowsListener) override; + status_t dump(int fd, const Vector<String16>& args) override; + binder::Status setInputWindows( + const std::vector<InputWindowInfo>& handles, + const sp<ISetInputWindowsListener>& setInputWindowsListener) override; - void registerInputChannel(const sp<InputChannel>& channel) override; - void unregisterInputChannel(const sp<InputChannel>& channel) override; + binder::Status registerInputChannel(const InputChannelInfo& info) override; + binder::Status unregisterInputChannel(const InputChannelInfo& info) override; private: sp<InputReaderInterface> mReader; diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h index 9b002f437c..f25131c7c7 100644 --- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h +++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h @@ -18,15 +18,14 @@ #define _UI_INPUT_INPUTDISPATCHER_INPUTDISPATCHERINTERFACE_H #include <InputListener.h> -#include <input/ISetInputWindowsListener.h> +#include <android/os/ISetInputWindowsListener.h> +#include <input/InputApplication.h> +#include <input/InputTransport.h> +#include <input/InputWindow.h> #include <unordered_map> namespace android { -class InputApplicationHandle; -class InputChannel; -class InputWindowHandle; - /* * Constants used to report the outcome of input event injection. */ diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h index 21255dd0d6..c886bee263 100644 --- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h +++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h @@ -21,11 +21,11 @@ #include <binder/IBinder.h> #include <input/Input.h> +#include <input/InputApplication.h> #include <utils/RefBase.h> namespace android { -class InputApplicationHandle; /* * Input dispatcher policy interface. diff --git a/services/inputflinger/host/Android.bp b/services/inputflinger/host/Android.bp index b56f356dfd..2643c228ff 100644 --- a/services/inputflinger/host/Android.bp +++ b/services/inputflinger/host/Android.bp @@ -59,7 +59,8 @@ cc_binary { shared_libs: [ "libbinder", "libinputflingerhost", - "libutils" + "libutils", + "libinput" ], static_libs: [ "libarect", diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h index 973b4f92fa..9364a2a767 100644 --- a/services/inputflinger/host/InputFlinger.h +++ b/services/inputflinger/host/InputFlinger.h @@ -22,13 +22,17 @@ #include "InputHost.h" +#include <android/os/BnInputFlinger.h> +#include <android/os/ISetInputWindowsListener.h> +#include <binder/Binder.h> #include <cutils/compiler.h> -#include <input/IInputFlinger.h> -#include <input/ISetInputWindowsListener.h> -#include <utils/String8.h> #include <utils/String16.h> +#include <utils/String8.h> #include <utils/StrongPointer.h> +using android::os::BnInputFlinger; +using android::os::ISetInputWindowsListener; + namespace android { class InputFlinger : public BnInputFlinger { @@ -40,10 +44,12 @@ public: InputFlinger() ANDROID_API; virtual status_t dump(int fd, const Vector<String16>& args); - void setInputWindows(const std::vector<InputWindowInfo>&, - const sp<ISetInputWindowsListener>&) {} - void registerInputChannel(const sp<InputChannel>&) {} - void unregisterInputChannel(const sp<InputChannel>&) {} + binder::Status setInputWindows(const std::vector<InputWindowInfo>&, + const sp<ISetInputWindowsListener>&) { + return binder::Status::ok(); + } + binder::Status registerInputChannel(const InputChannelInfo&) { return binder::Status::ok(); } + binder::Status unregisterInputChannel(const InputChannelInfo&) { return binder::Status::ok(); } private: virtual ~InputFlinger(); diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index a0d2f4f172..eae09633af 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -35,7 +35,14 @@ cc_test { "InputClassifierConverter_test.cpp", "InputDispatcher_test.cpp", "InputReader_test.cpp", + "InputFlingerService_test.cpp", "UinputDevice.cpp", + "IInputFlingerQuery.aidl" ], + aidl: { + include_dirs: [ + "frameworks/native/libs/input", + ], + }, require_root: true, } diff --git a/services/inputflinger/tests/IInputFlingerQuery.aidl b/services/inputflinger/tests/IInputFlingerQuery.aidl new file mode 100644 index 0000000000..1edc08965f --- /dev/null +++ b/services/inputflinger/tests/IInputFlingerQuery.aidl @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2020, 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. + */ + +import android.InputChannelInfo; +import android.InputWindowInfo; +import android.os.ISetInputWindowsListener; + +/** @hide */ +interface IInputFlingerQuery +{ + /* Test interfaces */ + void getInputWindows(out InputWindowInfo[] inputHandles); + void getInputChannels(out InputChannelInfo[] infos); +} diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp new file mode 100644 index 0000000000..fd3f5627b7 --- /dev/null +++ b/services/inputflinger/tests/InputFlingerService_test.cpp @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2020 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 <BnInputFlingerQuery.h> +#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> +#include <binder/IServiceManager.h> +#include <binder/Parcel.h> +#include <binder/ProcessState.h> + +#include <input/Input.h> +#include <input/InputTransport.h> +#include <input/InputWindow.h> + +#include <gtest/gtest.h> +#include <inttypes.h> +#include <linux/uinput.h> +#include <log/log.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <chrono> +#include <thread> +#include <unordered_map> + +#define TAG "InputFlingerServiceTest" + +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 constexpr int32_t TestInfoId = 1; +static const std::string TestInfoName = "InputFlingerServiceTestInputWindowInfo"; +static constexpr int32_t TestInfoLayoutParamsFlags = 0xABCD; +static constexpr int32_t TestInfoLayoutParamsType = 39; +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 TestInfoCanReceiveKeys = false; +static constexpr bool TestInfoTrustedOverlay = true; +static constexpr bool TestInfoHasFocus = 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 int32_t TestInfoInputFeatures = 29; +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: + void SetUp() override; + void TearDown() override; + +protected: + void InitializeInputFlinger(); + void setInputWindowsByInfos(std::vector<InputWindowInfo>& infos); + + void setInputWindowsFinished(); + void verifyInputWindowInfo(const InputWindowInfo& info) const; + InputWindowInfo& getInfo() const { return const_cast<InputWindowInfo&>(mInfo); } + + sp<IInputFlinger> mService; + sp<IInputFlingerQuery> mQuery; + +private: + sp<SetInputWindowsListener> mSetInputWindowsListener; + sp<InputChannel> mServerChannel, mClientChannel; + InputWindowInfo 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: + virtual ~TestInputManager(){}; + +public: + TestInputManager(){}; + void checkFdFlags(const android::base::unique_fd& fd); + + binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles); + binder::Status getInputChannels(std::vector<::android::InputChannelInfo>* infos); + + status_t dump(int fd, const Vector<String16>& args) override; + + binder::Status setInputWindows( + const std::vector<InputWindowInfo>& handles, + const sp<ISetInputWindowsListener>& setInputWindowsListener) override; + + binder::Status registerInputChannel(const InputChannelInfo& channel) override; + binder::Status unregisterInputChannel(const InputChannelInfo& channel) override; + +private: + mutable Mutex mLock; + std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mHandlesPerDisplay; + std::vector<sp<InputChannel>> mInputChannels; +}; + +class TestInputQuery : public BnInputFlingerQuery { +public: + TestInputQuery(sp<android::TestInputManager> manager) : mManager(manager){}; + binder::Status getInputWindows(std::vector<::android::InputWindowInfo>* inputHandles) override; + binder::Status getInputChannels(std::vector<::android::InputChannelInfo>* infos) override; + +private: + sp<android::TestInputManager> mManager; +}; + +binder::Status TestInputQuery::getInputWindows( + std::vector<::android::InputWindowInfo>* inputHandles) { + return mManager->getInputWindows(inputHandles); +} + +binder::Status TestInputQuery::getInputChannels(std::vector<::android::InputChannelInfo>* infos) { + return mManager->getInputChannels(infos); +} + +binder::Status SetInputWindowsListener::onSetInputWindowsFinished() { + if (mCbFunc != nullptr) { + mCbFunc(); + } + return binder::Status::ok(); +} + +binder::Status TestInputManager::setInputWindows( + const std::vector<InputWindowInfo>& infos, + const sp<ISetInputWindowsListener>& setInputWindowsListener) { + AutoMutex _l(mLock); + + for (const auto& info : infos) { + mHandlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>()); + mHandlesPerDisplay[info.displayId].push_back(new InputWindowHandle(info)); + } + if (setInputWindowsListener) { + setInputWindowsListener->onSetInputWindowsFinished(); + } + return binder::Status::ok(); +} + +void TestInputManager::checkFdFlags(const android::base::unique_fd& fd) { + const int result = fcntl(fd, F_GETFL); + EXPECT_NE(result, -1); + EXPECT_EQ(result & O_NONBLOCK, O_NONBLOCK); +} + +binder::Status TestInputManager::registerInputChannel(const InputChannelInfo& info) { + AutoMutex _l(mLock); + // check Fd flags + checkFdFlags(info.mFd); + + android::base::unique_fd newFd(::dup(info.mFd)); + sp<InputChannel> channel = InputChannel::create(info.mName, std::move(newFd), info.mToken); + mInputChannels.push_back(channel); + + return binder::Status::ok(); +} + +binder::Status TestInputManager::unregisterInputChannel(const InputChannelInfo& info) { + AutoMutex _l(mLock); + // check Fd flags + checkFdFlags(info.mFd); + android::base::unique_fd newFd(::dup(info.mFd)); + sp<InputChannel> channel = InputChannel::create(info.mName, std::move(newFd), info.mToken); + + auto it = std::find_if(mInputChannels.begin(), mInputChannels.end(), + [&](sp<InputChannel>& it) { return *it == *channel; }); + if (it != mInputChannels.end()) { + mInputChannels.erase(it); + } + + return binder::Status::ok(); +} + +status_t TestInputManager::dump(int fd, const Vector<String16>& args) { + std::string dump; + + dump += " InputFlinger dump\n"; + + ::write(fd, dump.c_str(), dump.size()); + return NO_ERROR; +} + +binder::Status TestInputManager::getInputWindows( + std::vector<::android::InputWindowInfo>* 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::InputChannelInfo>* infos) { + infos->clear(); + for (auto& channel : mInputChannels) { + auto chanDup = channel->dup(); + infos->push_back(std::move(chanDup->getInfo())); + } + return binder::Status::ok(); +} + +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.layoutParamsFlags = TestInfoLayoutParamsFlags; + mInfo.layoutParamsType = TestInfoLayoutParamsType; + mInfo.dispatchingTimeout = TestInfoDispatchingTimeout; + mInfo.frameLeft = TestInfoFrameLeft; + mInfo.frameTop = TestInfoFrameTop; + mInfo.frameRight = TestInfoFrameRight; + mInfo.frameBottom = TestInfoFrameBottom; + mInfo.surfaceInset = TestInfoSurfaceInset; + mInfo.globalScaleFactor = TestInfoGlobalScaleFactor; + mInfo.windowXScale = TestInfoWindowXScale; + mInfo.windowYScale = TestInfoWindowYScale; + mInfo.touchableRegion = TestInfoTouchableRegion; + mInfo.visible = TestInfoVisible; + mInfo.canReceiveKeys = TestInfoCanReceiveKeys; + mInfo.trustedOverlay = TestInfoTrustedOverlay; + mInfo.hasFocus = TestInfoHasFocus; + 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.dispatchingTimeout = TestAppInfoDispatchingTimeout; + + InitializeInputFlinger(); +} + +void InputFlingerServiceTest::TearDown() {} + +void InputFlingerServiceTest::verifyInputWindowInfo(const InputWindowInfo& info) const { + EXPECT_EQ(mInfo, info); +} + +void InputFlingerServiceTest::InitializeInputFlinger() { + sp<IBinder> input(defaultServiceManager()->waitForService(kTestServiceName)); + ASSERT_TRUE(input != nullptr); + mService = interface_cast<IInputFlinger>(input); + + input = defaultServiceManager()->waitForService(kQueryServiceName); + ASSERT_TRUE(input != nullptr); + mQuery = interface_cast<IInputFlingerQuery>(input); +} + +void InputFlingerServiceTest::setInputWindowsByInfos(std::vector<InputWindowInfo>& 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); + // Verify input windows from service + std::vector<::android::InputWindowInfo> inputHandles; + mQuery->getInputWindows(&inputHandles); + for (auto& inputInfo : inputHandles) { + verifyInputWindowInfo(inputInfo); + } +} + +/** + * Test InputFlinger service interface SetInputWindows + */ +TEST_F(InputFlingerServiceTest, InputWindow_SetInputWindows) { + std::vector<InputWindowInfo> infos = {getInfo()}; + setInputWindowsByInfos(infos); +} + +/** + * Test InputFlinger service interface registerInputChannel + */ +TEST_F(InputFlingerServiceTest, InputWindow_RegisterInputChannel) { + sp<InputChannel> serverChannel, clientChannel; + + InputChannel::openInputChannelPair("testchannels", serverChannel, clientChannel); + mService->registerInputChannel(serverChannel->getInfo()); + + std::vector<::android::InputChannelInfo> infos(2); + mQuery->getInputChannels(&infos); + EXPECT_EQ(infos.size(), 1UL); + + auto& info = infos[0]; + android::base::unique_fd newFd(::dup(info.mFd)); + sp<InputChannel> channel = InputChannel::create(info.mName, std::move(newFd), info.mToken); + EXPECT_EQ(*channel, *serverChannel); + + mService->unregisterInputChannel(serverChannel->getInfo()); + mQuery->getInputChannels(&infos); + EXPECT_EQ(infos.size(), 0UL); +} + +/** + * Test InputFlinger service interface registerInputChannel with invalid cases + */ +TEST_F(InputFlingerServiceTest, InputWindow_RegisterInputChannelInvalid) { + sp<InputChannel> serverChannel, clientChannel; + InputChannel::openInputChannelPair("testchannels", serverChannel, clientChannel); + + std::vector<::android::InputChannelInfo> infos(2); + mQuery->getInputChannels(&infos); + EXPECT_EQ(infos.size(), 0UL); + + mService->registerInputChannel(InputChannelInfo()); + mService->unregisterInputChannel(clientChannel->getInfo()); + + mService->registerInputChannel(serverChannel->getInfo()); + mService->registerInputChannel(clientChannel->getInfo()); + mQuery->getInputChannels(&infos); + EXPECT_EQ(infos.size(), 2UL); + + mService->unregisterInputChannel(clientChannel->getInfo()); + mService->unregisterInputChannel(serverChannel->getInfo()); + mQuery->getInputChannels(&infos); + EXPECT_EQ(infos.size(), 0UL); +} + +} // namespace android + +int main(int argc, char** argv) { + pid_t forkPid = fork(); + + if (forkPid == 0) { + // Server process + android::sp<android::TestInputManager> manager = new android::TestInputManager(); + android::sp<android::TestInputQuery> query = new android::TestInputQuery(manager); + + android::defaultServiceManager()->addService(android::kTestServiceName, manager, + false /*allowIsolated*/); + android::defaultServiceManager()->addService(android::kQueryServiceName, query, + false /*allowIsolated*/); + android::ProcessState::self()->startThreadPool(); + android::IPCThreadState::self()->joinThreadPool(); + } else { + android::ProcessState::self()->startThreadPool(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); + } + return 0; +} diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e5e3f48732..aa7b90348a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -30,6 +30,8 @@ #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> #include <binder/PermissionCache.h> @@ -58,7 +60,6 @@ #include <gui/LayerState.h> #include <gui/Surface.h> #include <hidl/ServiceManagement.h> -#include <input/IInputFlinger.h> #include <layerproto/LayerProtoParser.h> #include <log/log.h> #include <private/android_filesystem_config.h> @@ -256,6 +257,21 @@ private: } // 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"); @@ -321,7 +337,9 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mEventQueue(mFactory.createMessageQueue()), mCompositionEngine(mFactory.createCompositionEngine()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), - mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) {} + mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) { + mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); }); +} SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) { ALOGI("SurfaceFlinger is starting"); @@ -623,7 +641,7 @@ void SurfaceFlinger::bootFinished() if (input == nullptr) { ALOGE("Failed to link to input service"); } else { - mInputFlinger = interface_cast<IInputFlinger>(input); + mInputFlinger = interface_cast<os::IInputFlinger>(input); } readPersistentProperties(); @@ -2892,19 +2910,19 @@ void SurfaceFlinger::updateInputFlinger() { } void SurfaceFlinger::updateInputWindowInfo() { - std::vector<InputWindowInfo> inputHandles; + std::vector<InputWindowInfo> inputInfos; mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (layer->needsInputInfo()) { // When calculating the screen bounds we ignore the transparent region since it may // result in an unwanted offset. - inputHandles.push_back(layer->fillInputInfo()); + inputInfos.push_back(layer->fillInputInfo()); } }); - mInputFlinger->setInputWindows(inputHandles, - mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener - : nullptr); + mInputFlinger->setInputWindows(inputInfos, + mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener + : nullptr); } void SurfaceFlinger::commitInputWindowCommands() { @@ -3807,7 +3825,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( } if (what & layer_state_t::eInputInfoChanged) { if (privileged) { - layer->setInputInfo(s.inputInfo); + layer->setInputInfo(*s.inputHandle->getInfo()); flags |= eTraversalNeeded; } else { ALOGE("Attempt to update InputWindowInfo without permission ACCESS_SURFACE_FLINGER"); @@ -6059,10 +6077,6 @@ status_t SurfaceFlinger::getDesiredDisplayConfigSpecs(const sp<IBinder>& display } } -void SurfaceFlinger::SetInputWindowsListener::onSetInputWindowsFinished() { - mFlinger->setInputWindowsFinished(); -} - wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) { Mutex::Autolock _l(mStateLock); return fromHandleLocked(handle); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d8ea5016e8..7ab0729f35 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -33,7 +33,6 @@ #include <gui/ITransactionCompletedListener.h> #include <gui/LayerState.h> #include <gui/OccupancyTracker.h> -#include <input/ISetInputWindowsListener.h> #include <layerproto/LayerProtoHeader.h> #include <math/mat4.h> #include <renderengine/LayerSettings.h> @@ -89,8 +88,8 @@ namespace android { class Client; class EventThread; class HWComposer; +struct SetInputWindowsListener; class IGraphicBufferProducer; -class IInputFlinger; class Layer; class MessageBase; class RefreshRateOverlay; @@ -99,6 +98,10 @@ class RenderArea; class TimeStats; class FrameTracer; +namespace os { + class IInputFlinger; +} + namespace compositionengine { class DisplaySurface; class OutputLayer; @@ -336,6 +339,7 @@ public: // If set, disables reusing client composition buffers. This can be set by // debug.sf.disable_client_composition_cache bool mDisableClientCompositionCache = false; + void setInputWindowsFinished(); private: friend class BufferLayer; @@ -606,7 +610,6 @@ private: void updateInputFlinger(); void updateInputWindowInfo(); void commitInputWindowCommands() REQUIRES(mStateLock); - void setInputWindowsFinished(); void updateCursorAsync(); void initScheduler(DisplayId primaryDisplayId); @@ -1254,21 +1257,12 @@ private: const float mInternalDisplayDensity; const float mEmulatedDisplayDensity; - sp<IInputFlinger> mInputFlinger; + sp<os::IInputFlinger> mInputFlinger; InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock); // Should only be accessed by the main thread. InputWindowCommands mInputWindowCommands; - struct SetInputWindowsListener : BnSetInputWindowsListener { - explicit SetInputWindowsListener(sp<SurfaceFlinger> flinger) - : mFlinger(std::move(flinger)) {} - - void onSetInputWindowsFinished() override; - - const sp<SurfaceFlinger> mFlinger; - }; - - const sp<SetInputWindowsListener> mSetInputWindowsListener = new SetInputWindowsListener(this); + sp<SetInputWindowsListener> mSetInputWindowsListener; bool mPendingSyncInputWindows GUARDED_BY(mStateLock) = false; Hwc2::impl::PowerAdvisor mPowerAdvisor; |