• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {exists} from '../base/utils';
16import {Actions} from '../common/actions';
17import {getLegacySelection} from '../common/state';
18
19import {Flow, globals} from './globals';
20import {focusHorizontalRange, verticalScrollToTrack} from './scroll_helper';
21
22type Direction = 'Forward' | 'Backward';
23
24// Search |boundFlows| for |flowId| and return the id following it.
25// Returns the first flow id if nothing was found or |flowId| was the last flow
26// in |boundFlows|, and -1 if |boundFlows| is empty
27function findAnotherFlowExcept(boundFlows: Flow[], flowId: number): number {
28  let selectedFlowFound = false;
29
30  if (boundFlows.length === 0) {
31    return -1;
32  }
33
34  for (const flow of boundFlows) {
35    if (selectedFlowFound) {
36      return flow.id;
37    }
38
39    if (flow.id === flowId) {
40      selectedFlowFound = true;
41    }
42  }
43  return boundFlows[0].id;
44}
45
46// Change focus to the next flow event (matching the direction)
47export function focusOtherFlow(direction: Direction) {
48  const currentSelection = getLegacySelection(globals.state);
49  if (!currentSelection || currentSelection.kind !== 'SLICE') {
50    return;
51  }
52  const sliceId = currentSelection.id;
53  if (sliceId === -1) {
54    return;
55  }
56
57  const boundFlows = globals.connectedFlows.filter(
58    (flow) =>
59      (flow.begin.sliceId === sliceId && direction === 'Forward') ||
60      (flow.end.sliceId === sliceId && direction === 'Backward'),
61  );
62
63  if (direction === 'Backward') {
64    const nextFlowId = findAnotherFlowExcept(
65      boundFlows,
66      globals.state.focusedFlowIdLeft,
67    );
68    globals.dispatch(Actions.setHighlightedFlowLeftId({flowId: nextFlowId}));
69  } else {
70    const nextFlowId = findAnotherFlowExcept(
71      boundFlows,
72      globals.state.focusedFlowIdRight,
73    );
74    globals.dispatch(Actions.setHighlightedFlowRightId({flowId: nextFlowId}));
75  }
76}
77
78// Select the slice connected to the flow in focus
79export function moveByFocusedFlow(direction: Direction): void {
80  const currentSelection = getLegacySelection(globals.state);
81  if (!currentSelection || currentSelection.kind !== 'SLICE') {
82    return;
83  }
84
85  const sliceId = currentSelection.id;
86  const flowId =
87    direction === 'Backward'
88      ? globals.state.focusedFlowIdLeft
89      : globals.state.focusedFlowIdRight;
90
91  if (sliceId === -1 || flowId === -1) {
92    return;
93  }
94
95  // Find flow that is in focus and select corresponding slice
96  for (const flow of globals.connectedFlows) {
97    if (flow.id === flowId) {
98      const flowPoint = direction === 'Backward' ? flow.begin : flow.end;
99      const trackKeyByTrackId = globals.trackManager.trackKeyByTrackId;
100      const trackKey = trackKeyByTrackId.get(flowPoint.trackId);
101      if (trackKey) {
102        globals.setLegacySelection(
103          {
104            kind: 'SLICE',
105            id: flowPoint.sliceId,
106            trackKey,
107            table: 'slice',
108          },
109          {
110            clearSearch: true,
111            pendingScrollId: flowPoint.sliceId,
112            switchToCurrentSelectionTab: true,
113          },
114        );
115      }
116    }
117  }
118}
119
120export async function findCurrentSelection() {
121  const selection = getLegacySelection(globals.state);
122  if (selection === null) return;
123
124  const range = await globals.findTimeRangeOfSelection();
125  if (exists(range)) {
126    focusHorizontalRange(range.start, range.end);
127  }
128
129  if (selection.trackKey) {
130    verticalScrollToTrack(selection.trackKey, true);
131  }
132}
133