• 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 {searchSegment} from '../base/binary_search';
16import {assertUnreachable} from '../base/logging';
17import {Actions} from '../common/actions';
18import {globals} from './globals';
19import {verticalScrollToTrack} from './scroll_helper';
20
21function setToPrevious(current: number) {
22  let index = current - 1;
23  if (index < 0) {
24    index = globals.currentSearchResults.totalResults - 1;
25  }
26  globals.dispatch(Actions.setSearchIndex({index}));
27}
28
29function setToNext(current: number) {
30  const index = (current + 1) % globals.currentSearchResults.totalResults;
31  globals.dispatch(Actions.setSearchIndex({index}));
32}
33
34export function executeSearch(reverse = false) {
35  const index = globals.state.searchIndex;
36  const vizWindow = globals.stateVisibleTime();
37  const startNs = vizWindow.start;
38  const endNs = vizWindow.end;
39  const currentTs = globals.currentSearchResults.tses[index];
40
41  // If the value of |globals.currentSearchResults.totalResults| is 0,
42  // it means that the query is in progress or no results are found.
43  if (globals.currentSearchResults.totalResults === 0) {
44    return;
45  }
46
47  // If this is a new search or the currentTs is not in the viewport,
48  // select the first/last item in the viewport.
49  if (
50    index === -1 ||
51    (currentTs !== -1n && (currentTs < startNs || currentTs > endNs))
52  ) {
53    if (reverse) {
54      const [smaller] = searchSegment(globals.currentSearchResults.tses, endNs);
55      // If there is no item in the viewport just go to the previous.
56      if (smaller === -1) {
57        setToPrevious(index);
58      } else {
59        globals.dispatch(Actions.setSearchIndex({index: smaller}));
60      }
61    } else {
62      const [, larger] = searchSegment(
63        globals.currentSearchResults.tses,
64        startNs,
65      );
66      // If there is no item in the viewport just go to the next.
67      if (larger === -1) {
68        setToNext(index);
69      } else {
70        globals.dispatch(Actions.setSearchIndex({index: larger}));
71      }
72    }
73  } else {
74    // If the currentTs is in the viewport, increment the index.
75    if (reverse) {
76      setToPrevious(index);
77    } else {
78      setToNext(index);
79    }
80  }
81  selectCurrentSearchResult();
82}
83
84function selectCurrentSearchResult() {
85  const searchIndex = globals.state.searchIndex;
86  const source = globals.currentSearchResults.sources[searchIndex];
87  const currentId = globals.currentSearchResults.eventIds[searchIndex];
88  const trackKey = globals.currentSearchResults.trackKeys[searchIndex];
89
90  if (currentId === undefined) return;
91
92  switch (source) {
93    case 'track':
94      verticalScrollToTrack(trackKey, true);
95      break;
96    case 'cpu':
97      globals.setLegacySelection(
98        {
99          kind: 'SCHED_SLICE',
100          id: currentId,
101          trackKey,
102        },
103        {
104          clearSearch: false,
105          pendingScrollId: currentId,
106          switchToCurrentSelectionTab: true,
107        },
108      );
109      break;
110    case 'log':
111      globals.setLegacySelection(
112        {
113          kind: 'LOG',
114          id: currentId,
115          trackKey,
116        },
117        {
118          clearSearch: false,
119          pendingScrollId: currentId,
120          switchToCurrentSelectionTab: true,
121        },
122      );
123      break;
124    case 'slice':
125      // Search results only include slices from the slice table for now.
126      // When we include annotations we need to pass the correct table.
127      globals.setLegacySelection(
128        {
129          kind: 'SLICE',
130          id: currentId,
131          trackKey,
132          table: 'slice',
133        },
134        {
135          clearSearch: false,
136          pendingScrollId: currentId,
137          switchToCurrentSelectionTab: true,
138        },
139      );
140      break;
141    default:
142      assertUnreachable(source);
143  }
144}
145