diff options
31 files changed, 552 insertions, 120 deletions
| diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h index 4365a3c4e3..d23e3b7767 100644 --- a/include/input/IInputFlinger.h +++ b/include/input/IInputFlinger.h @@ -37,7 +37,6 @@ public:      virtual void setInputWindows(const std::vector<InputWindowInfo>& inputHandles,              const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0; -    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;      virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;      virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;  }; @@ -51,8 +50,7 @@ public:      enum {          SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,          REGISTER_INPUT_CHANNEL_TRANSACTION, -        UNREGISTER_INPUT_CHANNEL_TRANSACTION, -        TRANSFER_TOUCH_FOCUS +        UNREGISTER_INPUT_CHANNEL_TRANSACTION      };      virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 9be06cdd19..da6a8cb9fa 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -2543,11 +2543,13 @@ status_t Parcel::continueWrite(size_t desired)              if (objectsSize == 0) {                  free(mObjects);                  mObjects = nullptr; +                mObjectsCapacity = 0;              } else {                  binder_size_t* objects =                      (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));                  if (objects) {                      mObjects = objects; +                    mObjectsCapacity = objectsSize;                  }              }              mObjectsSize = objectsSize; diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp index a772e57ef6..875059cede 100644 --- a/libs/dumputils/dump_utils.cpp +++ b/libs/dumputils/dump_utils.cpp @@ -70,6 +70,9 @@ static const char* hal_interfaces_to_dump[] {          "android.hardware.sensors@1.0::ISensors",          "android.hardware.thermal@2.0::IThermal",          "android.hardware.vr@1.0::IVr", +        "android.hardware.automotive.audiocontrol@1.0::IAudioControl", +        "android.hardware.automotive.vehicle@2.0::IVehicle", +        "android.hardware.automotive.evs@1.0::IEvsCamera",          NULL,  }; diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 528bfb194e..3a7cb44450 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -166,7 +166,9 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,                          mCore->mFreeBuffers.push_back(front->mSlot);                      } -                    listener = mCore->mConnectedProducerListener; +                    if (mCore->mBufferReleasedCbEnabled) { +                        listener = mCore->mConnectedProducerListener; +                    }                      ++numDroppedBuffers;                  } @@ -457,7 +459,9 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,              mCore->mFreeBuffers.push_back(slot);          } -        listener = mCore->mConnectedProducerListener; +        if (mCore->mBufferReleasedCbEnabled) { +            listener = mCore->mConnectedProducerListener; +        }          BQ_LOGV("releaseBuffer: releasing slot %d", slot);          mCore->mDequeueCondition.notify_all(); @@ -668,7 +672,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount(          BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);          mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;          VALIDATE_CONSISTENCY(); -        if (delta < 0) { +        if (delta < 0 && mCore->mBufferReleasedCbEnabled) {              listener = mCore->mConsumerListener;          }      } diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index e0e3431ca5..0264bd24a6 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -65,6 +65,7 @@ BufferQueueCore::BufferQueueCore() :      mConnectedApi(NO_CONNECTED_API),      mLinkedToDeath(),      mConnectedProducerListener(), +    mBufferReleasedCbEnabled(false),      mSlots(),      mQueue(),      mFreeSlots(), @@ -260,6 +261,12 @@ void BufferQueueCore::freeAllBuffersLocked() {  }  void BufferQueueCore::discardFreeBuffersLocked() { +    // Notify producer about the discarded buffers. +    if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) { +        std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end()); +        mConnectedProducerListener->onBuffersDiscarded(freeBuffers); +    } +      for (int s : mFreeBuffers) {          mFreeSlots.insert(s);          clearBufferSlotLocked(s); diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 3efb1b6acb..4f8eb6b5e8 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1221,9 +1221,8 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,                      }                      mCore->mLinkedToDeath = listener;                  } -                if (listener->needsReleaseNotify()) { -                    mCore->mConnectedProducerListener = listener; -                } +                mCore->mConnectedProducerListener = listener; +                mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify();              }              break;          default: diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp index 936063a5bd..808e3369f1 100644 --- a/libs/gui/IProducerListener.cpp +++ b/libs/gui/IProducerListener.cpp @@ -24,6 +24,7 @@ namespace android {  enum {      ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,      NEEDS_RELEASE_NOTIFY, +    ON_BUFFERS_DISCARDED,  };  class BpProducerListener : public BpInterface<IProducerListener> @@ -56,6 +57,13 @@ public:          }          return result;      } + +    virtual void onBuffersDiscarded(const std::vector<int>& discardedSlots) { +        Parcel data, reply; +        data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); +        data.writeInt32Vector(discardedSlots); +        remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY); +    }  };  // Out-of-line virtual method definition to trigger vtable emission in this @@ -76,6 +84,10 @@ public:      virtual bool needsReleaseNotify() override {          return mBase->needsReleaseNotify();      } + +    virtual void onBuffersDiscarded(const std::vector<int32_t>& discardedSlots) override { +        return mBase->onBuffersDiscarded(discardedSlots); +    }  };  IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener, @@ -92,6 +104,17 @@ status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,              CHECK_INTERFACE(IProducerListener, data, reply);              reply->writeBool(needsReleaseNotify());              return NO_ERROR; +        case ON_BUFFERS_DISCARDED: { +            CHECK_INTERFACE(IProducerListener, data, reply); +            std::vector<int32_t> discardedSlots; +            status_t result = data.readInt32Vector(&discardedSlots); +            if (result != NO_ERROR) { +                ALOGE("ON_BUFFERS_DISCARDED failed to read discardedSlots: %d", result); +                return result; +            } +            onBuffersDiscarded(discardedSlots); +            return NO_ERROR; +        }      }      return BBinder::onTransact(code, data, reply, flags);  } @@ -104,4 +127,7 @@ bool BnProducerListener::needsReleaseNotify() {      return true;  } +void BnProducerListener::onBuffersDiscarded(const std::vector<int32_t>& /*discardedSlots*/) { +} +  } // namespace android diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 9fe5de82d1..b822319d22 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -35,6 +35,7 @@  #include <ui/DisplayStatInfo.h>  #include <ui/Fence.h> +#include <ui/GraphicBuffer.h>  #include <ui/HdrCapabilities.h>  #include <ui/Region.h> @@ -1287,6 +1288,14 @@ int Surface::connect(int api, const sp<IProducerListener>& listener) {  }  int Surface::connect( +        int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) { +    if (sListener != nullptr) { +        mListenerProxy = new ProducerListenerProxy(this, sListener); +    } +    return connect(api, mListenerProxy, reportBufferRemoval); +} + +int Surface::connect(          int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {      ATRACE_CALL();      ALOGV("Surface::connect"); @@ -1684,6 +1693,28 @@ void Surface::freeAllBuffers() {      }  } +status_t Surface::getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots, +        std::vector<sp<GraphicBuffer>>* outBuffers) { +    ALOGV("Surface::getAndFlushBuffersFromSlots"); +    for (int32_t i : slots) { +        if (i < 0 || i >= NUM_BUFFER_SLOTS) { +            ALOGE("%s: Invalid slotIndex: %d", __FUNCTION__, i); +            return BAD_VALUE; +        } +    } + +    Mutex::Autolock lock(mMutex); +    for (int32_t i : slots) { +        if (mSlots[i].buffer == nullptr) { +            ALOGW("%s: Discarded slot %d doesn't contain buffer!", __FUNCTION__, i); +            continue; +        } +        outBuffers->push_back(mSlots[i].buffer); +        mSlots[i].buffer = nullptr; +    } +    return OK; +} +  void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {      ATRACE_CALL();      ALOGV("Surface::setSurfaceDamage"); @@ -1951,4 +1982,22 @@ status_t Surface::attachAndQueueBufferWithDataspace(Surface* surface, sp<Graphic      return err;  } +void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_t>& slots) { +    ATRACE_CALL(); +    sp<Surface> parent = mParent.promote(); +    if (parent == nullptr) { +        return; +    } + +    std::vector<sp<GraphicBuffer>> discardedBufs; +    status_t res = parent->getAndFlushBuffersFromSlots(slots, &discardedBufs); +    if (res != OK) { +        ALOGE("%s: Failed to get buffers from slots: %s(%d)", __FUNCTION__, +                strerror(-res), res); +        return; +    } + +    mSurfaceListener->onBuffersDiscarded(discardedBufs); +} +  }; // namespace android diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h index 690a85f395..17617bce13 100644 --- a/libs/gui/include/gui/BufferQueueCore.h +++ b/libs/gui/include/gui/BufferQueueCore.h @@ -189,8 +189,12 @@ private:      sp<IProducerListener> mLinkedToDeath;      // mConnectedProducerListener is used to handle the onBufferReleased -    // notification. +    // and onBuffersDiscarded notification.      sp<IProducerListener> mConnectedProducerListener; +    // mBufferReleasedCbEnabled is used to indicate whether onBufferReleased() +    // callback is registered by the listener. When set to false, +    // mConnectedProducerListener will not trigger onBufferReleased() callback. +    bool mBufferReleasedCbEnabled;      // mSlots is an array of buffer slots that must be mirrored on the producer      // side. This allows buffer ownership to be transferred between the producer diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h index a13d8e4945..32a3690ff2 100644 --- a/libs/gui/include/gui/IProducerListener.h +++ b/libs/gui/include/gui/IProducerListener.h @@ -17,6 +17,8 @@  #ifndef ANDROID_GUI_IPRODUCERLISTENER_H  #define ANDROID_GUI_IPRODUCERLISTENER_H +#include <vector> +  #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>  #include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>  #include <binder/IInterface.h> @@ -44,6 +46,9 @@ public:      // multiple threads.      virtual void onBufferReleased() = 0; // Asynchronous      virtual bool needsReleaseNotify() = 0; +    // onBuffersFreed is called from IGraphicBufferConsumer::discardFreeBuffers +    // to notify the producer that certain free buffers are discarded by the consumer. +    virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) = 0; // Asynchronous  };  class IProducerListener : public ProducerListener, public IInterface @@ -65,6 +70,7 @@ public:      virtual status_t onTransact(uint32_t code, const Parcel& data,              Parcel* reply, uint32_t flags = 0);      virtual bool needsReleaseNotify(); +    virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);  };  class DummyProducerListener : public BnProducerListener diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 5c6a1ee383..a5641b07e5 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -20,6 +20,7 @@  #include <gui/BufferQueueDefs.h>  #include <gui/HdrMetadata.h>  #include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h>  #include <ui/ANativeObjectBase.h>  #include <ui/GraphicTypes.h> @@ -35,6 +36,21 @@ namespace android {  class ISurfaceComposer; +/* This is the same as ProducerListener except that onBuffersDiscarded is + * called with a vector of graphic buffers instead of buffer slots. + */ +class SurfaceListener : public virtual RefBase +{ +public: +    SurfaceListener() = default; +    virtual ~SurfaceListener() = default; + +    virtual void onBufferReleased() = 0; +    virtual bool needsReleaseNotify() = 0; + +    virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) = 0; +}; +  /*   * An implementation of ANativeWindow that feeds graphics buffers into a   * BufferQueue. @@ -283,6 +299,10 @@ public:              sp<Fence>* outFence);      virtual int attachBuffer(ANativeWindowBuffer*); +    virtual int connect( +            int api, bool reportBufferRemoval, +            const sp<SurfaceListener>& sListener); +      // When client connects to Surface with reportBufferRemoval set to true, any buffers removed      // from this Surface will be collected and returned here. Once this method returns, these      // buffers will no longer be referenced by this Surface unless they are attached to this @@ -299,6 +319,26 @@ protected:      enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS };      enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; +    class ProducerListenerProxy : public BnProducerListener { +    public: +        ProducerListenerProxy(wp<Surface> parent, sp<SurfaceListener> listener) +               : mParent(parent), mSurfaceListener(listener) {} +        virtual ~ProducerListenerProxy() {} + +        virtual void onBufferReleased() { +            mSurfaceListener->onBufferReleased(); +        } + +        virtual bool needsReleaseNotify() { +            return mSurfaceListener->needsReleaseNotify(); +        } + +        virtual void onBuffersDiscarded(const std::vector<int32_t>& slots); +    private: +        wp<Surface> mParent; +        sp<SurfaceListener> mSurfaceListener; +    }; +      void querySupportedTimestampsLocked() const;      void freeAllBuffers(); @@ -466,6 +506,10 @@ protected:      bool mReportRemovedBuffers = false;      std::vector<sp<GraphicBuffer>> mRemovedBuffers; + +    sp<IProducerListener> mListenerProxy; +    status_t getAndFlushBuffersFromSlots(const std::vector<int32_t>& slots, +            std::vector<sp<GraphicBuffer>>* outBuffers);  };  } // namespace android diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 119e888edb..406f21faf6 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -998,12 +998,31 @@ TEST_F(BufferQueueTest, TestOccupancyHistory) {      ASSERT_EQ(true, thirdSegment.usedThirdBuffer);  } +struct BufferDiscardedListener : public BnProducerListener { +public: +    BufferDiscardedListener() = default; +    virtual ~BufferDiscardedListener() = default; + +    virtual void onBufferReleased() {} +    virtual bool needsReleaseNotify() { return false; } +    virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) { +        mDiscardedSlots.insert(mDiscardedSlots.end(), slots.begin(), slots.end()); +    } + +    const std::vector<int32_t>& getDiscardedSlots() const { return mDiscardedSlots; } +private: +    // No need to use lock given the test triggers the listener in the same +    // thread context. +    std::vector<int32_t> mDiscardedSlots; +}; +  TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {      createBufferQueue();      sp<DummyConsumer> dc(new DummyConsumer);      ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));      IGraphicBufferProducer::QueueBufferOutput output; -    ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, +    sp<BufferDiscardedListener> pl(new BufferDiscardedListener); +    ASSERT_EQ(OK, mProducer->connect(pl,              NATIVE_WINDOW_API_CPU, false, &output));      int slot = BufferQueue::INVALID_BUFFER_SLOT; @@ -1044,12 +1063,19 @@ TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {      ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));      ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,                      EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE)); +    int releasedSlot = item.mSlot; +      // Acquire 1 buffer, leaving 1 filled buffer in queue      ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));      // Now discard the free buffers      ASSERT_EQ(OK, mConsumer->discardFreeBuffers()); +    // Check onBuffersDiscarded is called with correct slots +    auto buffersDiscarded = pl->getDiscardedSlots(); +    ASSERT_EQ(buffersDiscarded.size(), 1); +    ASSERT_EQ(buffersDiscarded[0], releasedSlot); +      // Check no free buffers in dump      String8 dumpString;      mConsumer->dumpState(String8{}, &dumpString); diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 386f731d23..03b9cd75db 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -133,27 +133,6 @@ public:          EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());      } -    void expectMotionEvent(int motionEventType, int x, int y) { -        InputEvent *ev = consumeEvent(); -        ASSERT_NE(ev, nullptr); -        ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION); -        MotionEvent *mev = static_cast<MotionEvent *>(ev); -        EXPECT_EQ(motionEventType, mev->getAction()); -        EXPECT_EQ(x, mev->getX(0)); -        EXPECT_EQ(y, mev->getY(0)); -    } - -    void expectNoMotionEvent(int motionEventType) { -        InputEvent *ev = consumeEvent(); -        if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) { -            // Didn't find an event or a motion event so assume action didn't occur. -            return; -        } - -        MotionEvent *mev = static_cast<MotionEvent *>(ev); -        EXPECT_NE(motionEventType, mev->getAction()); -    } -      ~InputSurface() {          mInputFlinger->unregisterInputChannel(mServerChannel);      } @@ -278,15 +257,6 @@ void injectTap(int x, int y) {      }  } -void injectMotionEvent(std::string event, int x, int y) { -    char *buf1, *buf2; -    asprintf(&buf1, "%d", x); -    asprintf(&buf2, "%d", y); -    if (fork() == 0) { -        execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL); -    } -} -  TEST_F(InputSurfacesTest, can_receive_input) {      std::unique_ptr<InputSurface> surface = makeSurface(100, 100);      surface->showAt(100, 100); @@ -435,9 +405,11 @@ TEST_F(InputSurfacesTest, input_ignores_transparent_region) {      surface->expectTap(1, 1);  } -// Ensure we send the input to the right surface when the surface visibility changes due to the -// first buffer being submitted. ref: b/120839715 -TEST_F(InputSurfacesTest, input_respects_buffer_layer_buffer) { +// TODO(b/139494112) update tests once we define expected behavior +// Ensure we still send input to the surface regardless of surface visibility changes due to the +// first buffer being submitted or alpha changes. +// Original bug ref: b/120839715 +TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {      std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);      std::unique_ptr<InputSurface> bufferSurface =              InputSurface::makeBufferInputSurface(mComposerClient, 100, 100); @@ -446,14 +418,14 @@ TEST_F(InputSurfacesTest, input_respects_buffer_layer_buffer) {      bufferSurface->showAt(10, 10);      injectTap(11, 11); -    bgSurface->expectTap(1, 1); +    bufferSurface->expectTap(1, 1);      postBuffer(bufferSurface->mSurfaceControl);      injectTap(11, 11);      bufferSurface->expectTap(1, 1);  } -TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) { +TEST_F(InputSurfacesTest, input_ignores_buffer_layer_alpha) {      std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);      std::unique_ptr<InputSurface> bufferSurface =              InputSurface::makeBufferInputSurface(mComposerClient, 100, 100); @@ -468,10 +440,10 @@ TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {      bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });      injectTap(11, 11); -    bgSurface->expectTap(1, 1); +    bufferSurface->expectTap(1, 1);  } -TEST_F(InputSurfacesTest, input_respects_color_layer_alpha) { +TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {      std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);      std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100); @@ -484,7 +456,7 @@ TEST_F(InputSurfacesTest, input_respects_color_layer_alpha) {      fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });      injectTap(11, 11); -    bgSurface->expectTap(1, 1); +    fgSurface->expectTap(1, 1);  }  TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) { @@ -504,26 +476,6 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {      bgSurface->expectTap(1, 1);  } -TEST_F(InputSurfacesTest, transfer_touch_focus) { -    std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100); - -    fromSurface->showAt(10, 10); -    injectMotionEvent("DOWN", 11, 11); -    fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1); - -    std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100); -    toSurface->showAt(10, 10); - -    sp<IBinder> fromToken = fromSurface->mServerChannel->getToken(); -    sp<IBinder> toToken = toSurface->mServerChannel->getToken(); -    SurfaceComposerClient::Transaction t; -    t.transferTouchFocus(fromToken, toToken).apply(true); - -    injectMotionEvent("UP", 11, 11); -    toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1); -    fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP); -} -  TEST_F(InputSurfacesTest, input_respects_outscreen) {      std::unique_ptr<InputSurface> surface = makeSurface(100, 100);      surface->showAt(-1, -1); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index d3708586f5..a8516872fd 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -57,6 +57,37 @@ class FakeProducerFrameEventHistory;  static constexpr uint64_t NO_FRAME_INDEX = std::numeric_limits<uint64_t>::max(); +class DummySurfaceListener : public SurfaceListener { +public: +    DummySurfaceListener(bool enableReleasedCb = false) : +            mEnableReleaseCb(enableReleasedCb), +            mBuffersReleased(0) {} +    virtual ~DummySurfaceListener() = default; + +    virtual void onBufferReleased() { +        mBuffersReleased++; +    } +    virtual bool needsReleaseNotify() { +        return mEnableReleaseCb; +    } +    virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) { +        mDiscardedBuffers.insert(mDiscardedBuffers.end(), buffers.begin(), buffers.end()); +    } + +    int getReleaseNotifyCount() const { +        return mBuffersReleased; +    } +    const std::vector<sp<GraphicBuffer>>& getDiscardedBuffers() const { +        return mDiscardedBuffers; +    } +private: +    // No need to use lock given the test triggers the listener in the same +    // thread context. +    bool mEnableReleaseCb; +    int32_t mBuffersReleased; +    std::vector<sp<GraphicBuffer>> mDiscardedBuffers; +}; +  class SurfaceTest : public ::testing::Test {  protected:      SurfaceTest() { @@ -88,6 +119,86 @@ protected:          mComposerClient->dispose();      } +    void testSurfaceListener(bool hasSurfaceListener, bool enableReleasedCb, +            int32_t extraDiscardedBuffers) { +        sp<IGraphicBufferProducer> producer; +        sp<IGraphicBufferConsumer> consumer; +        BufferQueue::createBufferQueue(&producer, &consumer); + +        sp<DummyConsumer> dummyConsumer(new DummyConsumer); +        consumer->consumerConnect(dummyConsumer, false); +        consumer->setConsumerName(String8("TestConsumer")); + +        sp<Surface> surface = new Surface(producer); +        sp<ANativeWindow> window(surface); +        sp<DummySurfaceListener> listener; +        if (hasSurfaceListener) { +            listener = new DummySurfaceListener(enableReleasedCb); +        } +        ASSERT_EQ(OK, surface->connect( +                NATIVE_WINDOW_API_CPU, +                /*reportBufferRemoval*/true, +                /*listener*/listener)); +        const int BUFFER_COUNT = 4 + extraDiscardedBuffers; +        ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(window.get(), BUFFER_COUNT)); + +        ANativeWindowBuffer* buffers[BUFFER_COUNT]; +        // Dequeue first to allocate a number of buffers +        for (int i = 0; i < BUFFER_COUNT; i++) { +            ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffers[i])); +        } +        for (int i = 0; i < BUFFER_COUNT; i++) { +            ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffers[i], -1)); +        } + +        ANativeWindowBuffer* buffer; +        // Fill BUFFER_COUNT-1 buffers +        for (int i = 0; i < BUFFER_COUNT-1; i++) { +            ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffer)); +            ASSERT_EQ(NO_ERROR, window->queueBuffer(window.get(), buffer, -1)); +        } + +        // Dequeue 1 buffer +        ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(window.get(), &buffer)); + +        // Acquire and free 1+extraDiscardedBuffers buffer, check onBufferReleased is called. +        std::vector<BufferItem> releasedItems; +        releasedItems.resize(1+extraDiscardedBuffers); +        for (int i = 0; i < releasedItems.size(); i++) { +            ASSERT_EQ(NO_ERROR, consumer->acquireBuffer(&releasedItems[i], 0)); +            ASSERT_EQ(NO_ERROR, consumer->releaseBuffer(releasedItems[i].mSlot, +                    releasedItems[i].mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, +                    Fence::NO_FENCE)); +        } +        int32_t expectedReleaseCb = (enableReleasedCb ? releasedItems.size() : 0); +        if (hasSurfaceListener) { +            ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount()); +        } + +        // Acquire 1 buffer, leaving 1+extraDiscardedBuffers filled buffer in queue +        BufferItem item; +        ASSERT_EQ(NO_ERROR, consumer->acquireBuffer(&item, 0)); + +        // Discard free buffers +        ASSERT_EQ(NO_ERROR, consumer->discardFreeBuffers()); + +        if (hasSurfaceListener) { +            ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount()); + +            // Check onBufferDiscarded is called with correct buffer +            auto discardedBuffers = listener->getDiscardedBuffers(); +            ASSERT_EQ(discardedBuffers.size(), releasedItems.size()); +            for (int i = 0; i < releasedItems.size(); i++) { +                ASSERT_EQ(discardedBuffers[i], releasedItems[i].mGraphicBuffer); +            } + +            ASSERT_EQ(expectedReleaseCb, listener->getReleaseNotifyCount()); +        } + +        // Disconnect the surface +        ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU)); +    } +      sp<Surface> mSurface;      sp<SurfaceComposerClient> mComposerClient;      sp<SurfaceControl> mSurfaceControl; @@ -480,6 +591,21 @@ TEST_F(SurfaceTest, GetAndFlushRemovedBuffers) {      ASSERT_LE(removedBuffers.size(), 1u);  } +TEST_F(SurfaceTest, SurfaceListenerTest) { +    // Test discarding 1 free buffers with no listener +    testSurfaceListener(/*hasListener*/false, /*enableReleaseCb*/false, /*extraDiscardedBuffers*/0); +    // Test discarding 2 free buffers with no listener +    testSurfaceListener(/*hasListener*/false, /*enableReleaseCb*/false, /*extraDiscardedBuffers*/1); +    // Test discarding 1 free buffers with a listener, disabling onBufferReleased +    testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/false, /*extraDiscardedBuffers*/0); +    // Test discarding 2 free buffers with a listener, disabling onBufferReleased +    testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/false, /*extraDiscardedBuffers*/1); +    // Test discarding 1 free buffers with a listener, enabling onBufferReleased +    testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/true, /*extraDiscardedBuffers*/0); +    // Test discarding 3 free buffers with a listener, enabling onBufferReleased +    testSurfaceListener(/*hasListener*/true, /*enableReleasedCb*/true, /*extraDiscardedBuffers*/2); +} +  TEST_F(SurfaceTest, TestGetLastDequeueStartTime) {      sp<ANativeWindow> anw(mSurface);      ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU)); diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp index d6a73bfd27..de3a23d76e 100644 --- a/libs/input/IInputFlinger.cpp +++ b/libs/input/IInputFlinger.cpp @@ -45,16 +45,6 @@ public:                  IBinder::FLAG_ONEWAY);      } -    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) { -        Parcel data, reply; -        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); - -        data.writeStrongBinder(fromToken); -        data.writeStrongBinder(toToken); -        remote()->transact(BnInputFlinger::TRANSFER_TOUCH_FOCUS, data, &reply, -                IBinder::FLAG_ONEWAY); -    } -      virtual void registerInputChannel(const sp<InputChannel>& channel) {          Parcel data, reply;          data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); @@ -104,13 +94,6 @@ status_t BnInputFlinger::onTransact(          unregisterInputChannel(channel);          break;      } -    case TRANSFER_TOUCH_FOCUS: { -        CHECK_INTERFACE(IInputFlinger, data, reply); -        sp<IBinder> fromToken = data.readStrongBinder(); -        sp<IBinder> toToken = data.readStrongBinder(); -        transferTouchFocus(fromToken, toToken); -        break; -    }      default:          return BBinder::onTransact(code, data, reply, flags);      } diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 5f1c71ec4f..b54ce0fcf7 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -132,6 +132,17 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,      status_t error =              mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle); +    size_t bufSize; + +    // if stride has no meaning or is too large, +    // approximate size with the input width instead +    if ((*stride) != 0 && +        std::numeric_limits<size_t>::max() / height / (*stride) < static_cast<size_t>(bpp)) { +        bufSize = static_cast<size_t>(width) * height * bpp; +    } else { +        bufSize = static_cast<size_t>((*stride)) * height * bpp; +    } +      if (error == NO_ERROR) {          Mutex::Autolock _l(sLock);          KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); @@ -142,7 +153,7 @@ status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,          rec.format = format;          rec.layerCount = layerCount;          rec.usage = usage; -        rec.size = static_cast<size_t>(height * (*stride) * bpp); +        rec.size = bufSize;          rec.requestorName = std::move(requestorName);          list.add(*handle, rec); diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h index faec97855a..06357270f5 100644 --- a/libs/ui/include/ui/GraphicBufferAllocator.h +++ b/libs/ui/include/ui/GraphicBufferAllocator.h @@ -54,7 +54,7 @@ public:      void dump(std::string& res) const;      static void dumpToSystemLog(); -private: +protected:      struct alloc_rec_t {          uint32_t width;          uint32_t height; diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp index 99434b7273..0a07a48bd1 100644 --- a/libs/ui/tests/Android.bp +++ b/libs/ui/tests/Android.bp @@ -29,6 +29,26 @@ cc_test {  }  cc_test { +    name: "GraphicBufferAllocator_test", +    header_libs: [ +        "libdvr_headers", +        "libnativewindow_headers", +    ], +    static_libs: [ +        "libgmock", +    ], +    shared_libs: [ +        "liblog", +	"libui", +    ], +    srcs: [ +        "GraphicBufferAllocator_test.cpp", +        "mock/MockGrallocAllocator.cpp", +    ], +    cflags: ["-Wall", "-Werror"], +} + +cc_test {      name: "GraphicBuffer_test",      header_libs: [          "libdvr_headers", diff --git a/libs/ui/tests/GraphicBufferAllocator_test.cpp b/libs/ui/tests/GraphicBufferAllocator_test.cpp new file mode 100644 index 0000000000..efca083e6e --- /dev/null +++ b/libs/ui/tests/GraphicBufferAllocator_test.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 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. + */ + +#define LOG_TAG "GraphicBufferAllocatorTest" + +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferAllocator.h> +#include <ui/PixelFormat.h> + +#include <gtest/gtest.h> + +#include "mock/MockGrallocAllocator.h" + +#include <algorithm> +#include <limits> + +namespace android { + +namespace { + +constexpr uint32_t kTestWidth = 1024; +constexpr uint32_t kTestHeight = 1; +constexpr uint32_t kTestLayerCount = 1; +constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN; + +} // namespace + +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SetArgPointee; + +class TestableGraphicBufferAllocator : public GraphicBufferAllocator { +public: +    TestableGraphicBufferAllocator() { +        mAllocator = std::make_unique<const mock::MockGrallocAllocator>(); +    } +    void setUpAllocateExpectations(status_t err, uint32_t stride) { +        std::cout << "Setting expected stride to " << stride << std::endl; +        EXPECT_CALL(*(reinterpret_cast<const mock::MockGrallocAllocator*>(mAllocator.get())), +                    allocate) +                .WillOnce(DoAll(SetArgPointee<6>(stride), Return(err))); +    } +    std::unique_ptr<const GrallocAllocator>& getAllocator() { return mAllocator; } +}; + +class GraphicBufferAllocatorTest : public testing::Test { +public: +    GraphicBufferAllocatorTest() : mAllocator() {} +    const TestableGraphicBufferAllocator& getAllocator() { return mAllocator; } + +protected: +    TestableGraphicBufferAllocator mAllocator; +}; + +TEST_F(GraphicBufferAllocatorTest, AllocateNoError) { +    mAllocator.setUpAllocateExpectations(NO_ERROR, kTestWidth); +    android::PixelFormat format = PIXEL_FORMAT_RGBA_8888; +    uint32_t stride = 0; +    buffer_handle_t handle; +    status_t err = mAllocator.allocate(kTestWidth, kTestHeight, format, kTestLayerCount, kTestUsage, +                                       &handle, &stride, 0, "GraphicBufferAllocatorTest"); +    ASSERT_EQ(NO_ERROR, err); +    ASSERT_EQ(kTestWidth, stride); +} + +TEST_F(GraphicBufferAllocatorTest, AllocateZeroStride) { +    android::PixelFormat format = PIXEL_FORMAT_RGBA_8888; +    uint32_t expectedStride = 0; + +    mAllocator.setUpAllocateExpectations(NO_ERROR, expectedStride); +    uint32_t stride = 0; +    buffer_handle_t handle; +    // a divide by zero would cause a crash +    status_t err = mAllocator.allocate(kTestWidth, kTestHeight, format, kTestLayerCount, kTestUsage, +                                       &handle, &stride, 0, "GraphicBufferAllocatorTest"); +    ASSERT_EQ(NO_ERROR, err); +    ASSERT_EQ(expectedStride, stride); +} + +TEST_F(GraphicBufferAllocatorTest, AllocateLargeStride) { +    uint32_t height = std::numeric_limits<uint32_t>::max(); +    uint32_t bpp = 4; +    android::PixelFormat format = PIXEL_FORMAT_RGBA_8888; + +    if (std::numeric_limits<size_t>::max() / height / bpp >= std::numeric_limits<uint32_t>::max()) { +        std::cout << "stride cannot cause overflow" << std::endl; +        GTEST_SUCCEED() << "stride cannot cause overflow"; +        return; +    } +    uint32_t width = std::numeric_limits<size_t>::max() / height / bpp; + +    uint32_t expectedStride = std::numeric_limits<uint32_t>::max(); + +    mAllocator.setUpAllocateExpectations(NO_ERROR, expectedStride); +    uint32_t stride = 0; +    buffer_handle_t handle; +    // an overflow would cause a crash +    status_t err = mAllocator.allocate(width, height, format, kTestLayerCount, kTestUsage, &handle, +                                       &stride, 0, "GraphicBufferAllocatorTest"); +    ASSERT_EQ(NO_ERROR, err); +    ASSERT_EQ(expectedStride, stride); +} +} // namespace android diff --git a/libs/ui/tests/mock/MockGrallocAllocator.cpp b/libs/ui/tests/mock/MockGrallocAllocator.cpp new file mode 100644 index 0000000000..d71e25fc08 --- /dev/null +++ b/libs/ui/tests/mock/MockGrallocAllocator.cpp @@ -0,0 +1,27 @@ +/* + * 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 "MockGrallocAllocator.h" + +namespace android { + +namespace mock { + +MockGrallocAllocator::MockGrallocAllocator() = default; +MockGrallocAllocator::~MockGrallocAllocator() = default; + +} // namespace mock +} // namespace android diff --git a/libs/ui/tests/mock/MockGrallocAllocator.h b/libs/ui/tests/mock/MockGrallocAllocator.h new file mode 100644 index 0000000000..22c80a4638 --- /dev/null +++ b/libs/ui/tests/mock/MockGrallocAllocator.h @@ -0,0 +1,44 @@ +/* + * 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 <gmock/gmock.h> + +#include <ui/Gralloc.h> + +namespace android { + +class GraphicBuffer; + +namespace mock { + +class MockGrallocAllocator : public GrallocAllocator { +public: +    MockGrallocAllocator(); +    ~MockGrallocAllocator() override; + +    MOCK_METHOD(bool, isLoaded, (), (const, override)); +    MOCK_METHOD(std::string, dumpDebugInfo, (), (const, override)); +    MOCK_METHOD(status_t, allocate, +                (uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, +                 uint64_t usage, uint32_t bufferCount, uint32_t* outStride, +                 buffer_handle_t* outBufferHandles), +                (const, override)); +}; + +} // namespace mock +} // namespace android diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp index 6a7f2797f4..ef1a2247e9 100644 --- a/services/inputflinger/InputClassifier.cpp +++ b/services/inputflinger/InputClassifier.cpp @@ -82,7 +82,7 @@ static bool isTouchEvent(const NotifyMotionArgs& args) {  // Check if the "deep touch" feature is on.  static bool deepPressEnabled() {      std::string flag_value = server_configurable_flags::GetServerConfigurableFlag( -            INPUT_NATIVE_BOOT, DEEP_PRESS_ENABLED, "false"); +            INPUT_NATIVE_BOOT, DEEP_PRESS_ENABLED, "true");      std::transform(flag_value.begin(), flag_value.end(), flag_value.begin(), ::tolower);      if (flag_value == "1" || flag_value == "true") {          ALOGI("Deep press feature enabled."); diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp index 359325faed..7d3067242a 100644 --- a/services/inputflinger/InputManager.cpp +++ b/services/inputflinger/InputManager.cpp @@ -119,10 +119,6 @@ void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos,      }  } -void InputManager::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) { -    mDispatcher->transferTouchFocus(fromToken, toToken); -} -  // Used by tests only.  void InputManager::registerInputChannel(const sp<InputChannel>& channel) {      IPCThreadState* ipc = IPCThreadState::self(); diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h index f3da324ba4..40f66d82f4 100644 --- a/services/inputflinger/InputManager.h +++ b/services/inputflinger/InputManager.h @@ -96,7 +96,6 @@ public:      virtual void setInputWindows(const std::vector<InputWindowInfo>& handles,              const sp<ISetInputWindowsListener>& setInputWindowsListener); -    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);      virtual void registerInputChannel(const sp<InputChannel>& channel);      virtual void unregisterInputChannel(const sp<InputChannel>& channel); diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp index 8d05640b38..a4d9e4edc2 100644 --- a/services/inputflinger/dispatcher/Entry.cpp +++ b/services/inputflinger/dispatcher/Entry.cpp @@ -18,10 +18,12 @@  #include "Connection.h" +#include <android-base/properties.h>  #include <android-base/stringprintf.h>  #include <cutils/atomic.h>  #include <inttypes.h> +using android::base::GetBoolProperty;  using android::base::StringPrintf;  namespace android::inputdispatcher { @@ -133,7 +135,11 @@ KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, ui  KeyEntry::~KeyEntry() {}  void KeyEntry::appendDescription(std::string& msg) const { -    msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, " +    msg += StringPrintf("KeyEvent"); +    if (!GetBoolProperty("ro.debuggable", false)) { +        return; +    } +    msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "                          "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "                          "repeatCount=%d), policyFlags=0x%08x",                          deviceId, source, displayId, keyActionToString(action).c_str(), flags, @@ -186,7 +192,11 @@ MotionEntry::MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t device  MotionEntry::~MotionEntry() {}  void MotionEntry::appendDescription(std::string& msg) const { -    msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 +    msg += StringPrintf("MotionEvent"); +    if (!GetBoolProperty("ro.debuggable", false)) { +        return; +    } +    msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32                          ", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "                          "buttonState=0x%08x, "                          "classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, " diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h index d8b352cbc6..973b4f92fa 100644 --- a/services/inputflinger/host/InputFlinger.h +++ b/services/inputflinger/host/InputFlinger.h @@ -42,7 +42,6 @@ public:      virtual status_t dump(int fd, const Vector<String16>& args);      void setInputWindows(const std::vector<InputWindowInfo>&,              const sp<ISetInputWindowsListener>&) {} -    void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}      void registerInputChannel(const sp<InputChannel>&) {}      void unregisterInputChannel(const sp<InputChannel>&) {} diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index 7927fa95b6..e33bedbfce 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -35,11 +35,7 @@ bool ContainerLayer::isVisible() const {      return false;  } -bool ContainerLayer::canReceiveInput() const { -    return !isHiddenByPolicy(); -}  void ContainerLayer::setPerFrameData(const sp<const DisplayDevice>&, const ui::Transform&,                                       const Rect&, int32_t, const ui::Dataspace) {} -  } // namespace android diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index 7222a3e15a..e6dbfcce4e 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -31,8 +31,6 @@ public:      const char* getTypeId() const override { return "ContainerLayer"; }      bool isVisible() const override; -    bool canReceiveInput() const override; -      void setPerFrameData(const sp<const DisplayDevice>& display, const ui::Transform& transform,                           const Rect& viewport, int32_t supportedPerFrameMetadata,                           const ui::Dataspace targetDataspace) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index dda15e9e1e..3e6ddedf48 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2106,7 +2106,7 @@ std::shared_ptr<compositionengine::Layer> Layer::getCompositionLayer() const {  }  bool Layer::canReceiveInput() const { -    return isVisible(); +    return !isHiddenByPolicy();  }  compositionengine::OutputLayer* Layer::findOutputLayerForDisplay( diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 60b3a11754..7047710e85 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3029,7 +3029,7 @@ void SurfaceFlinger::updateInputFlinger() {          setInputWindowsFinished();      } -    executeInputWindowCommands(); +    mInputWindowCommands.clear();  }  void SurfaceFlinger::updateInputWindowInfo() { @@ -3053,19 +3053,6 @@ void SurfaceFlinger::commitInputWindowCommands() {      mPendingInputWindowCommands.clear();  } -void SurfaceFlinger::executeInputWindowCommands() { -    for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) { -        if (transferTouchFocusCommand.fromToken != nullptr && -            transferTouchFocusCommand.toToken != nullptr && -            transferTouchFocusCommand.fromToken != transferTouchFocusCommand.toToken) { -            mInputFlinger->transferTouchFocus(transferTouchFocusCommand.fromToken, -                                              transferTouchFocusCommand.toToken); -        } -    } - -    mInputWindowCommands.clear(); -} -  void SurfaceFlinger::updateCursorAsync()  {      for (const auto& [token, display] : mDisplays) { @@ -6236,7 +6223,7 @@ status_t SurfaceFlinger::setAllowedDisplayConfigs(const sp<IBinder>& displayToke          return NO_ERROR;      } -    postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS { +    postMessageSync(new LambdaMessage([&]() {          const auto display = getDisplayDeviceLocked(displayToken);          if (!display) {              ALOGE("Attempt to set allowed display configs for invalid display token %p", @@ -6244,6 +6231,7 @@ status_t SurfaceFlinger::setAllowedDisplayConfigs(const sp<IBinder>& displayToke          } else if (display->isVirtual()) {              ALOGW("Attempt to set allowed display configs for virtual display");          } else { +            Mutex::Autolock lock(mStateLock);              setAllowedDisplayConfigsInternal(display, allowedConfigs);          }      })); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 49bb574147..8e4203aed5 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -554,7 +554,6 @@ private:      void updateInputFlinger();      void updateInputWindowInfo();      void commitInputWindowCommands() REQUIRES(mStateLock); -    void executeInputWindowCommands();      void setInputWindowsFinished();      void updateCursorAsync(); |