1// Copyright (C) 2018 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'; 16import {FrontendLocalState as FrontendState} from '../common/state'; 17import {TimeSpan} from '../common/time'; 18 19import {globals} from './globals'; 20import {TimeScale} from './time_scale'; 21 22/** 23 * State that is shared between several frontend components, but not the 24 * controller. This state is updated at 60fps. 25 */ 26export class FrontendLocalState { 27 visibleWindowTime = new TimeSpan(0, 10); 28 timeScale = new TimeScale(this.visibleWindowTime, [0, 0]); 29 private _lastUpdate = 0; 30 private pendingGlobalTimeUpdate = false; 31 perfDebug = false; 32 hoveredUtid = -1; 33 hoveredPid = -1; 34 hoveredTimestamp = -1; 35 showTimeSelectPreview = false; 36 showNotePreview = false; 37 38 // TODO: there is some redundancy in the fact that both |visibleWindowTime| 39 // and a |timeScale| have a notion of time range. That should live in one 40 // place only. 41 updateVisibleTime(ts: TimeSpan) { 42 const startSec = Math.max(ts.start, globals.state.traceTime.startSec); 43 const endSec = Math.min(ts.end, globals.state.traceTime.endSec); 44 this.visibleWindowTime = new TimeSpan(startSec, endSec); 45 this.timeScale.setTimeBounds(this.visibleWindowTime); 46 this._lastUpdate = Date.now() / 1000; 47 48 // Post a delayed update to the controller. 49 if (this.pendingGlobalTimeUpdate) return; 50 setTimeout(() => { 51 this._lastUpdate = Date.now() / 1000; 52 globals.dispatch(Actions.setVisibleTraceTime({ 53 time: { 54 startSec: this.visibleWindowTime.start, 55 endSec: this.visibleWindowTime.end, 56 }, 57 lastUpdate: this._lastUpdate, 58 })); 59 this.pendingGlobalTimeUpdate = false; 60 }, 100); 61 } 62 63 mergeState(frontendLocalState: FrontendState): void { 64 if (this._lastUpdate >= frontendLocalState.lastUpdate) { 65 return; 66 } 67 const visible = frontendLocalState.visibleTraceTime; 68 this.updateVisibleTime(new TimeSpan(visible.startSec, visible.endSec)); 69 } 70 71 togglePerfDebug() { 72 this.perfDebug = !this.perfDebug; 73 globals.rafScheduler.scheduleFullRedraw(); 74 } 75 76 setHoveredUtidAndPid(utid: number, pid: number) { 77 this.hoveredUtid = utid; 78 this.hoveredPid = pid; 79 globals.rafScheduler.scheduleRedraw(); 80 } 81 82 // Sets the timestamp at which a vertical line will be drawn. 83 setHoveredTimestamp(ts: number) { 84 if (this.hoveredTimestamp === ts) return; 85 this.hoveredTimestamp = ts; 86 globals.rafScheduler.scheduleRedraw(); 87 } 88 89 setShowNotePreview(show: boolean) { 90 this.showNotePreview = show; 91 globals.rafScheduler.scheduleRedraw(); 92 } 93 94 setShowTimeSelectPreview(show: boolean) { 95 this.showTimeSelectPreview = show; 96 globals.rafScheduler.scheduleRedraw(); 97 } 98} 99