summaryrefslogtreecommitdiffstats
path: root/devtools/client/performance-new/components/panel/ProfilerEventHandling.js
blob: 1b415bdf1993983a9e5e80671d0ae4ed3f303ad5 (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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// @ts-check

/**
 * @typedef {import("../../@types/perf").PerfFront} PerfFront
 * @typedef {import("../../@types/perf").RecordingState} RecordingState
 * @typedef {import("../../@types/perf").State} StoreState
 * @typedef {import("../../@types/perf").RootTraits} RootTraits
 * @typedef {import("../../@types/perf").PanelWindow} PanelWindow
 */

/**
 * @template P
 * @typedef {import("react-redux").ResolveThunks<P>} ResolveThunks<P>
 */

/**
 * @typedef {Object} StateProps
 * @property {RecordingState} recordingState
 * @property {boolean?} isSupportedPlatform
 */

/**
 * @typedef {Object} ThunkDispatchProps
 * @property {typeof actions.reportProfilerReady} reportProfilerReady
 * @property {typeof actions.reportProfilerStarted} reportProfilerStarted
 * @property {typeof actions.reportProfilerStopped} reportProfilerStopped
 */

/**
 * @typedef {Object} OwnProps
 * @property {PerfFront} perfFront
 * @property {RootTraits} traits
 */

/**
 * @typedef {ResolveThunks<ThunkDispatchProps>} DispatchProps
 * @typedef {StateProps & DispatchProps & OwnProps} Props
 */

"use strict";

const {
  PureComponent,
} = require("resource://devtools/client/shared/vendor/react.js");
const {
  connect,
} = require("resource://devtools/client/shared/vendor/react-redux.js");
const actions = require("resource://devtools/client/performance-new/store/actions.js");
const selectors = require("resource://devtools/client/performance-new/store/selectors.js");

/**
 * This component state changes for the performance recording. e.g. If the profiler
 * suddenly becomes unavailable, it needs to react to those changes, and update the
 * recordingState in the store.
 *
 * @extends {React.PureComponent<Props>}
 */
class ProfilerEventHandling extends PureComponent {
  componentDidMount() {
    const {
      perfFront,
      isSupportedPlatform,
      reportProfilerReady,
      reportProfilerStarted,
      reportProfilerStopped,
    } = this.props;

    if (!isSupportedPlatform) {
      return;
    }

    // Ask for the initial state of the profiler.
    perfFront.isActive().then(isActive => reportProfilerReady(isActive));

    // Handle when the profiler changes state. It might be us, it might be someone else.
    this.props.perfFront.on("profiler-started", reportProfilerStarted);
    this.props.perfFront.on("profiler-stopped", reportProfilerStopped);
  }

  componentWillUnmount() {
    switch (this.props.recordingState) {
      case "not-yet-known":
      case "available-to-record":
      case "request-to-stop-profiler":
      case "request-to-get-profile-and-stop-profiler":
        // Do nothing for these states.
        break;

      case "recording":
      case "request-to-start-recording":
        this.props.perfFront.stopProfilerAndDiscardProfile();
        break;

      default:
        throw new Error("Unhandled recording state.");
    }
  }

  render() {
    return null;
  }
}

/**
 * @param {StoreState} state
 * @returns {StateProps}
 */
function mapStateToProps(state) {
  return {
    recordingState: selectors.getRecordingState(state),
    isSupportedPlatform: selectors.getIsSupportedPlatform(state),
  };
}

/** @type {ThunkDispatchProps} */
const mapDispatchToProps = {
  reportProfilerReady: actions.reportProfilerReady,
  reportProfilerStarted: actions.reportProfilerStarted,
  reportProfilerStopped: actions.reportProfilerStopped,
};

module.exports = connect(
  mapStateToProps,
  mapDispatchToProps
)(ProfilerEventHandling);