~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/WebInspectorUI/UserInterface/Controllers/TabActivityDiagnosticEventRecorder.js

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2019 Apple Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
WI.TabActivityDiagnosticEventRecorder = class TabActivityDiagnosticEventRecorder extends WI.DiagnosticEventRecorder
 
27
{
 
28
    constructor(controller)
 
29
    {
 
30
        super("TabActivity", controller);
 
31
 
 
32
        this._inspectorHasFocus = true;
 
33
        this._lastUserInteractionTimestamp = undefined;
 
34
 
 
35
        this._eventSamplingTimerIdentifier = undefined;
 
36
        this._initialDelayBeforeSamplingTimerIdentifier = undefined;
 
37
    }
 
38
 
 
39
    // Static
 
40
 
 
41
    // In milliseconds.
 
42
    static get eventSamplingInterval() { return 60 * 1000; }
 
43
    static get initialDelayBeforeSamplingInterval() { return 10 * 1000; }
 
44
 
 
45
    // Protected
 
46
 
 
47
    setup()
 
48
    {
 
49
        const options = {
 
50
            capture: true,
 
51
        };
 
52
        window.addEventListener("focus", this, options);
 
53
        window.addEventListener("blur", this, options);
 
54
        window.addEventListener("keydown", this, options);
 
55
        window.addEventListener("mousedown", this, options);
 
56
 
 
57
        // If it's been less than 10 seconds since the frontend loaded, wait a bit.
 
58
        if (performance.now() - WI.frontendCompletedLoadTimestamp < TabActivityDiagnosticEventRecorder.initialDelayBeforeSamplingInterval)
 
59
            this._startInitialDelayBeforeSamplingTimer();
 
60
        else
 
61
            this._startEventSamplingTimer();
 
62
 
 
63
    }
 
64
 
 
65
    teardown()
 
66
    {
 
67
        const options = {
 
68
            capture: true,
 
69
        };
 
70
        window.removeEventListener("focus", this, options);
 
71
        window.removeEventListener("blur", this, options);
 
72
        window.removeEventListener("keydown", this, options);
 
73
        window.removeEventListener("mousedown", this, options);
 
74
 
 
75
        this._stopInitialDelayBeforeSamplingTimer();
 
76
        this._stopEventSamplingTimer();
 
77
 
 
78
    }
 
79
 
 
80
    // Public
 
81
 
 
82
    handleEvent(event)
 
83
    {
 
84
        switch (event.type) {
 
85
        case "focus":
 
86
            this._handleWindowFocus(event);
 
87
            break;
 
88
        case "blur":
 
89
            this._handleWindowBlur(event);
 
90
            break;
 
91
        case "keydown":
 
92
            this._handleWindowKeyDown(event);
 
93
            break;
 
94
        case "mousedown":
 
95
            this._handleWindowMouseDown(event);
 
96
            break;
 
97
        }
 
98
    }
 
99
 
 
100
    // Private
 
101
 
 
102
    _startInitialDelayBeforeSamplingTimer()
 
103
    {
 
104
        if (this._initialDelayBeforeSamplingTimerIdentifier) {
 
105
            clearTimeout(this._initialDelayBeforeSamplingTimerIdentifier);
 
106
            this._initialDelayBeforeSamplingTimerIdentifier = undefined;
 
107
        }
 
108
 
 
109
        // All intervals are in milliseconds.
 
110
        let maximumInitialDelay = TabActivityDiagnosticEventRecorder.initialDelayBeforeSamplingInterval;
 
111
        let elapsedTime = performance.now() - WI.frontendCompletedLoadTimestamp;
 
112
        let remainingTime = maximumInitialDelay - elapsedTime;
 
113
        let initialDelay = Number.constrain(remainingTime, 0, maximumInitialDelay);
 
114
        this._initialDelayBeforeSamplingTimerIdentifier = setTimeout(this._sampleCurrentTabActivity.bind(this), initialDelay);
 
115
    }
 
116
 
 
117
    _stopInitialDelayBeforeSamplingTimer()
 
118
    {
 
119
        if (this._initialDelayBeforeSamplingTimerIdentifier) {
 
120
            clearTimeout(this._initialDelayBeforeSamplingTimerIdentifier);
 
121
            this._initialDelayBeforeSamplingTimerIdentifier = undefined;
 
122
        }
 
123
    }
 
124
 
 
125
    _startEventSamplingTimer()
 
126
    {
 
127
        if (this._eventSamplingTimerIdentifier) {
 
128
            clearTimeout(this._eventSamplingTimerIdentifier);
 
129
            this._eventSamplingTimerIdentifier = undefined;
 
130
        }
 
131
 
 
132
        this._eventSamplingTimerIdentifier = setTimeout(this._sampleCurrentTabActivity.bind(this), TabActivityDiagnosticEventRecorder.eventSamplingInterval);
 
133
    }
 
134
 
 
135
    _stopEventSamplingTimer()
 
136
    {
 
137
        if (this._eventSamplingTimerIdentifier) {
 
138
            clearTimeout(this._eventSamplingTimerIdentifier);
 
139
            this._eventSamplingTimerIdentifier = undefined;
 
140
        }
 
141
    }
 
142
 
 
143
    _sampleCurrentTabActivity()
 
144
    {
 
145
        // Set up the next timer first so later code can bail out if there's nothing to do.
 
146
        this._stopEventSamplingTimer();
 
147
        this._stopInitialDelayBeforeSamplingTimer();
 
148
        this._startEventSamplingTimer();
 
149
 
 
150
        let intervalSinceLastUserInteraction = performance.now() - this._lastUserInteractionTimestamp;
 
151
        if (intervalSinceLastUserInteraction > TabActivityDiagnosticEventRecorder.eventSamplingInterval) {
 
152
            if (WI.settings.debugAutoLogDiagnosticEvents.valueRespectingDebugUIAvailability)
 
153
                console.log("TabActivity: sample not reported, last user interaction was %.1f seconds ago.".format(intervalSinceLastUserInteraction / 1000));
 
154
            return;
 
155
        }
 
156
 
 
157
        let selectedTabContentView = WI.tabBrowser.selectedTabContentView;
 
158
        console.assert(selectedTabContentView);
 
159
        if (!selectedTabContentView)
 
160
            return;
 
161
 
 
162
        let tabType = selectedTabContentView.type;
 
163
        let interval = TabActivityDiagnosticEventRecorder.eventSamplingInterval / 1000;
 
164
        this.logDiagnosticEvent(this.name, {tabType, interval});
 
165
    }
 
166
 
 
167
    _didObserveUserInteraction()
 
168
    {
 
169
        if (!this._inspectorHasFocus)
 
170
            return;
 
171
 
 
172
        this._lastUserInteractionTimestamp = performance.now();
 
173
    }
 
174
 
 
175
    _handleWindowFocus(event)
 
176
    {
 
177
        if (event.target !== window)
 
178
            return;
 
179
 
 
180
        this._inspectorHasFocus = true;
 
181
    }
 
182
 
 
183
    _handleWindowBlur(event)
 
184
    {
 
185
        if (event.target !== window)
 
186
            return;
 
187
 
 
188
        this._inspectorHasFocus = false;
 
189
    }
 
190
 
 
191
    _handleWindowKeyDown(event)
 
192
    {
 
193
        this._didObserveUserInteraction();
 
194
    }
 
195
 
 
196
    _handleWindowMouseDown(event)
 
197
    {
 
198
        this._didObserveUserInteraction();
 
199
    }
 
200
};
 
201