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 {Actions} from '../common/actions'; 16 17import {globals} from './globals'; 18import {toggleHelp} from './help_modal'; 19import { 20 horizontalScrollAndZoomToRange, 21 verticalScrollToTrack 22} from './scroll_helper'; 23import {executeSearch} from './search_handler'; 24 25// Handles all key events than are not handled by the 26// pan and zoom handler. 27export function handleKey(e: KeyboardEvent, down: boolean) { 28 const key = e.key.toLowerCase(); 29 if (down && 'm' === key) { 30 const selectedArea = globals.frontendLocalState.selectedArea.area; 31 if (!selectedArea && globals.state.currentSelection !== null) { 32 selectSliceSpan(); 33 } 34 if (selectedArea) { 35 globals.frontendLocalState.toggleLockArea(); 36 } 37 } 38 if (down && 'f' === key) { 39 findCurrentSelection(); 40 } 41 if (down && 'v' === key) { 42 globals.dispatch(Actions.toggleVideo({})); 43 } 44 if (down && 'p' === key) { 45 globals.dispatch(Actions.toggleFlagPause({})); 46 } 47 if (down && 't' === key) { 48 globals.dispatch(Actions.toggleScrubbing({})); 49 if (globals.frontendLocalState.vidTimestamp < 0) { 50 globals.frontendLocalState.setVidTimestamp(Number.MAX_SAFE_INTEGER); 51 } else { 52 globals.frontendLocalState.setVidTimestamp(Number.MIN_SAFE_INTEGER); 53 } 54 } 55 if (down && 'b' === key && (e.ctrlKey || e.metaKey)) { 56 globals.frontendLocalState.toggleSidebar(); 57 } 58 if (down && '?' === key) { 59 toggleHelp(); 60 } 61 if (down && 'enter' === key) { 62 e.preventDefault(); 63 executeSearch(e.shiftKey); 64 } 65} 66 67function findTimeRangeOfSelection() { 68 const selection = globals.state.currentSelection; 69 let startTs = -1; 70 let endTs = -1; 71 if (selection !== null) { 72 if (selection.kind === 'SLICE' || selection.kind === 'CHROME_SLICE') { 73 const slice = globals.sliceDetails; 74 if (slice.ts && slice.dur) { 75 startTs = slice.ts + globals.state.traceTime.startSec; 76 endTs = startTs + slice.dur; 77 } 78 } else if (selection.kind === 'THREAD_STATE') { 79 startTs = selection.ts; 80 endTs = startTs + selection.dur; 81 } else if (selection.kind === 'COUNTER') { 82 startTs = selection.leftTs; 83 endTs = selection.rightTs; 84 } 85 } 86 return {startTs, endTs}; 87} 88 89function selectSliceSpan() { 90 const range = findTimeRangeOfSelection(); 91 if (range.startTs !== -1 && range.endTs !== -1 && 92 globals.state.currentSelection) { 93 const tracks = globals.state.currentSelection.trackId ? 94 [globals.state.currentSelection.trackId] : 95 []; 96 globals.frontendLocalState.selectArea(range.startTs, range.endTs, tracks); 97 } 98} 99 100function findCurrentSelection() { 101 const selection = globals.state.currentSelection; 102 if (selection === null) return; 103 104 const range = findTimeRangeOfSelection(); 105 if (range.startTs !== -1 && range.endTs !== -1) { 106 horizontalScrollAndZoomToRange(range.startTs, range.endTs); 107 } 108 109 if (selection.trackId) { 110 verticalScrollToTrack(selection.trackId, true); 111 } 112} 113