blob: 9fe395d397cd1522e0dcbefd702cc32c1cb3c7e9 [file] [log] [blame]
/*
* Copyright 2024 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 "InputTracerInterface.h"
#include <android-base/thread_annotations.h>
#include <gui/WindowInfo.h>
#include <memory>
#include <mutex>
#include <thread>
#include <unordered_set>
#include <vector>
#include "../Entry.h"
#include "InputTracingBackendInterface.h"
namespace android::inputdispatcher::trace::impl {
/**
* The tracer implementation for InputDispatcher.
*
* InputTracer is thread-safe, so it can be called from any thread. Upon construction, InputTracer
* will start its own thread that it uses for write events into the tracing backend. That is the
* one and only thread that will interact with the tracing backend, since the Perfetto backend
* uses thread-local storage.
*
* See the documentation in InputTracerInterface for the API surface.
*/
class InputTracer : public InputTracerInterface {
public:
explicit InputTracer(std::unique_ptr<InputTracingBackendInterface>);
~InputTracer() override;
InputTracer(const InputTracer&) = delete;
InputTracer& operator=(const InputTracer&) = delete;
std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) override;
void dispatchToTargetHint(const EventTrackerInterface&, const InputTarget&) override;
void eventProcessingComplete(const EventTrackerInterface&) override;
void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface*) override;
private:
std::mutex mLock;
std::thread mTracerThread;
bool mThreadExit GUARDED_BY(mLock){false};
std::condition_variable mThreadWakeCondition;
std::unique_ptr<InputTracingBackendInterface> mBackend;
// The state of a tracked event.
struct EventState {
const TracedEvent event;
// TODO(b/210460522): Add additional args for tracking event sensitivity and
// dispatch target UIDs.
};
std::vector<const EventState> mTraceQueue GUARDED_BY(mLock);
using WindowDispatchArgs = InputTracingBackendInterface::WindowDispatchArgs;
std::vector<const WindowDispatchArgs> mDispatchTraceQueue GUARDED_BY(mLock);
// Provides thread-safe access to the state from an event tracker cookie.
std::optional<EventState>& getState(const EventTrackerInterface&) REQUIRES(mLock);
// Implementation of the event tracker cookie.
class EventTrackerImpl : public EventTrackerInterface {
public:
explicit EventTrackerImpl(InputTracer&, TracedEvent&& entry);
virtual ~EventTrackerImpl() override;
private:
InputTracer& mTracer;
// This event tracker cookie will only hold the state as long as it has not been written
// to the trace. The state is released when the event is written to the trace.
mutable std::optional<EventState> mLockedState;
// Only allow InputTracer access to the locked state through getTrackerState() to ensure
// that the InputTracer lock is held when this is accessed.
friend std::optional<EventState>& InputTracer::getState(const EventTrackerInterface&);
};
void threadLoop();
void writeEventsToBackend(const std::vector<const EventState>& events,
const std::vector<const WindowDispatchArgs>& dispatchEvents);
};
} // namespace android::inputdispatcher::trace::impl