summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceInterceptor.h
blob: 673f9e789df946b9af9509c3918ef9c93ebe210a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Copyright 2016 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 ANDROID_SURFACEINTERCEPTOR_H
#define ANDROID_SURFACEINTERCEPTOR_H

#include <frameworks/native/cmds/surfacereplayer/proto/src/trace.pb.h>

#include <mutex>

#include <binder/IBinder.h>

#include <gui/LayerState.h>

#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/StrongPointer.h>
#include <utils/Vector.h>

#include "DisplayDevice.h"

namespace android {

class BufferItem;
class Layer;
class SurfaceFlinger;
struct ComposerState;
struct DisplayDeviceState;
struct DisplayState;
struct layer_state_t;
using Transaction = surfaceflinger::Transaction;
using Trace = surfaceflinger::Trace;
using Rectangle = surfaceflinger::Rectangle;
using SurfaceChange = surfaceflinger::SurfaceChange;
using Increment = surfaceflinger::Increment;
using DisplayChange = surfaceflinger::DisplayChange;

constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/transaction_trace.pb";

class SurfaceInterceptor : public IBinder::DeathRecipient {
public:
    virtual ~SurfaceInterceptor();

    // Both vectors are used to capture the current state of SF as the initial snapshot in the trace
    virtual void enable(const SortedVector<sp<Layer>>& layers,
                        const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays) = 0;
    virtual void disable() = 0;
    virtual bool isEnabled() = 0;

    virtual void addTransactionTraceListener(
            const sp<gui::ITransactionTraceListener>& listener) = 0;
    virtual void binderDied(const wp<IBinder>& who) = 0;

    // Intercept display and surface transactions
    virtual void saveTransaction(
            const Vector<ComposerState>& stateUpdates,
            const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays,
            const Vector<DisplayState>& changedDisplays, uint32_t flags, int originPid,
            int originUid, uint64_t transactionId) = 0;

    // Intercept surface data
    virtual void saveSurfaceCreation(const sp<const Layer>& layer) = 0;
    virtual void saveSurfaceDeletion(const sp<const Layer>& layer) = 0;
    virtual void saveBufferUpdate(int32_t layerId, uint32_t width, uint32_t height,
                                  uint64_t frameNumber) = 0;

    // Intercept display data
    virtual void saveDisplayCreation(const DisplayDeviceState& info) = 0;
    virtual void saveDisplayDeletion(int32_t sequenceId) = 0;
    virtual void savePowerModeUpdate(int32_t sequenceId, int32_t mode) = 0;
    virtual void saveVSyncEvent(nsecs_t timestamp) = 0;
};

namespace impl {

/*
 * SurfaceInterceptor intercepts and stores incoming streams of window
 * properties on SurfaceFlinger.
 */
class SurfaceInterceptor final : public android::SurfaceInterceptor {
public:
    SurfaceInterceptor() = default;
    ~SurfaceInterceptor() override = default;

    // Both vectors are used to capture the current state of SF as the initial snapshot in the trace
    void enable(const SortedVector<sp<Layer>>& layers,
                const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays) override;
    void disable() override;
    bool isEnabled() override;

    void addTransactionTraceListener(const sp<gui::ITransactionTraceListener>& listener) override;
    void binderDied(const wp<IBinder>& who) override;

    // Intercept display and surface transactions
    void saveTransaction(const Vector<ComposerState>& stateUpdates,
                         const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays,
                         const Vector<DisplayState>& changedDisplays, uint32_t flags, int originPid,
                         int originUid, uint64_t transactionId) override;

    // Intercept surface data
    void saveSurfaceCreation(const sp<const Layer>& layer) override;
    void saveSurfaceDeletion(const sp<const Layer>& layer) override;
    void saveBufferUpdate(int32_t layerId, uint32_t width, uint32_t height,
                          uint64_t frameNumber) override;

    // Intercept display data
    void saveDisplayCreation(const DisplayDeviceState& info) override;
    void saveDisplayDeletion(int32_t sequenceId) override;
    void savePowerModeUpdate(int32_t sequenceId, int32_t mode) override;
    void saveVSyncEvent(nsecs_t timestamp) override;

private:
    // The creation increments of Surfaces and Displays do not contain enough information to capture
    // the initial state of each object, so a transaction with all of the missing properties is
    // performed at the initial snapshot for each display and surface.
    void saveExistingDisplaysLocked(
            const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays);
    void saveExistingSurfacesLocked(const SortedVector<sp<Layer>>& layers);
    void addInitialSurfaceStateLocked(Increment* increment, const sp<const Layer>& layer);
    void addInitialDisplayStateLocked(Increment* increment, const DisplayDeviceState& display);

    status_t writeProtoFileLocked();
    const sp<const Layer> getLayer(const wp<const IBinder>& weakHandle) const;
    int32_t getLayerId(const sp<const Layer>& layer) const;
    int32_t getLayerIdFromWeakRef(const wp<const Layer>& layer) const;
    int32_t getLayerIdFromHandle(const sp<const IBinder>& weakHandle) const;

    Increment* createTraceIncrementLocked();
    void addSurfaceCreationLocked(Increment* increment, const sp<const Layer>& layer);
    void addSurfaceDeletionLocked(Increment* increment, const sp<const Layer>& layer);
    void addBufferUpdateLocked(Increment* increment, int32_t layerId, uint32_t width,
            uint32_t height, uint64_t frameNumber);
    void addVSyncUpdateLocked(Increment* increment, nsecs_t timestamp);
    void addDisplayCreationLocked(Increment* increment, const DisplayDeviceState& info);
    void addDisplayDeletionLocked(Increment* increment, int32_t sequenceId);
    void addPowerModeUpdateLocked(Increment* increment, int32_t sequenceId, int32_t mode);

    // Add surface transactions to the trace
    SurfaceChange* createSurfaceChangeLocked(Transaction* transaction, int32_t layerId);
    void setProtoRectLocked(Rectangle* protoRect, const Rect& rect);
    void addPositionLocked(Transaction* transaction, int32_t layerId, float x, float y);
    void addDepthLocked(Transaction* transaction, int32_t layerId, uint32_t z);
    void addSizeLocked(Transaction* transaction, int32_t layerId, uint32_t w, uint32_t h);
    void addAlphaLocked(Transaction* transaction, int32_t layerId, float alpha);
    void addMatrixLocked(Transaction* transaction, int32_t layerId,
            const layer_state_t::matrix22_t& matrix);
    void addTransparentRegionLocked(Transaction* transaction, int32_t layerId,
            const Region& transRegion);
    void addFlagsLocked(Transaction* transaction, int32_t layerId, uint8_t flags, uint8_t mask);
    void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack);
    void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
    void addCornerRadiusLocked(Transaction* transaction, int32_t layerId, float cornerRadius);
    void addBackgroundBlurRadiusLocked(Transaction* transaction, int32_t layerId,
                                       int32_t backgroundBlurRadius);
    void addBlurRegionsLocked(Transaction* transaction, int32_t layerId,
                              const std::vector<BlurRegion>& effectRegions);
    void addSurfaceChangesLocked(Transaction* transaction, const layer_state_t& state);
    void addTransactionLocked(Increment* increment, const Vector<ComposerState>& stateUpdates,
                              const DefaultKeyedVector<wp<IBinder>, DisplayDeviceState>& displays,
                              const Vector<DisplayState>& changedDisplays,
                              uint32_t transactionFlags, int originPid, int originUid,
                              uint64_t transactionId);
    void addReparentLocked(Transaction* transaction, int32_t layerId, int32_t parentId);
    void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId,
                                 int z);
    void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius);
    void addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, bool isTrustedOverlay);

    // Add display transactions to the trace
    DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId);
    void addDisplaySurfaceLocked(Transaction* transaction, int32_t sequenceId,
            const sp<const IGraphicBufferProducer>& surface);
    void addDisplayLayerStackLocked(Transaction* transaction, int32_t sequenceId,
            uint32_t layerStack);
    void addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w,
            uint32_t h);
    void addDisplayProjectionLocked(Transaction* transaction, int32_t sequenceId,
            int32_t orientation, const Rect& viewport, const Rect& frame);
    void addDisplayChangesLocked(Transaction* transaction,
            const DisplayState& state, int32_t sequenceId);

    // Add transaction origin to trace
    void setTransactionOriginLocked(Transaction* transaction, int32_t pid, int32_t uid);

    bool mEnabled {false};
    std::string mOutputFileName {DEFAULT_FILENAME};
    std::mutex mTraceMutex {};
    Trace mTrace {};
    std::mutex mListenersMutex;
    std::map<wp<IBinder>, sp<gui::ITransactionTraceListener>> mTraceToggledListeners
            GUARDED_BY(mListenersMutex);
};

} // namespace impl

} // namespace android

#endif // ANDROID_SURFACEINTERCEPTOR_H