blob: 61fa7b84fbad25291281822f8ac949f18b9dbcf1 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#pragma once
#include "android/base/async/SubscriberList.h"
#include "android/base/Compiler.h"
#include "android/skin/qt/qt-std-hash.h"
#include <QEvent>
#include <QObject>
#include <list>
#include <memory>
#include <unordered_set>
// Use this class to "spy" on events received by other objects.
// This class is not thread-safe. All subscribers should be on
// the UI thread.
class EventCapturer : public QObject {
Q_OBJECT
public:
using Callback = std::function<void(const QObject*, const QEvent*)>;
using ObjectPredicate = std::function<bool(const QObject*)>;
using EventTypeSet = std::unordered_set<QEvent::Type>;
using SubscriberToken = android::base::SubscriptionToken;
private:
struct SubscriberInfo {
// What types of events the subscriber wants.
EventTypeSet event_types;
// What objects the subscriber wants to monitor.
std::unordered_set<QObject*> objects;
// Callback provided by the subscriber.
Callback callback;
SubscriberInfo(EventTypeSet e,
std::unordered_set<QObject*> o,
Callback c)
: event_types(e), objects(o), callback(c) {}
};
public:
EventCapturer() = default;
virtual ~EventCapturer() = default;
// Ensures that |callback| is invoked for every event that meets
// the following requirements:
// 1. The event is triggered for an object that is part
// of |root|'s hierarchy.
// 2. |child_filter| was true for that object at the moment
// |subscribeToEvents| was called.
// 3. The event's type is one of those listed in |event_types|.
// This method returns a non-copyable, movable, opaque token.
// When that token is destroyed (i.e. by going out of scope),
// events will no longer be delivered to the subscriber.
SubscriberToken subscribeToEvents(
QObject* root,
const ObjectPredicate& child_filter,
const EventTypeSet& event_types,
const Callback& callback);
private:
// Intercepts the events from monitored objects.
bool eventFilter(QObject* target, QEvent* event) override;
// Information about all the subscribers.
android::base::SubscriberList<SubscriberInfo> mSubscribers;
DISALLOW_COPY_AND_ASSIGN(EventCapturer);
};