/* * Copyright 2020, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Find the index of the last element matching the predicate in a sorted array function findLastMatchingSorted(array, predicate) { let a = 0; let b = array.length - 1; while (b - a > 1) { const m = Math.floor((a + b) / 2); if (predicate(array, m)) { a = m; } else { b = m - 1; } } return predicate(array, b) ? b : a; } // Make sure stableId is unique (makes old versions of proto compatible) function stableIdCompatibilityFixup(item) { // For backwards compatibility // (the only item that doesn't have a unique stable ID in the tree) if (item.stableId === 'winToken|-|') { return item.stableId + item.children[0].stableId; } return item.stableId; } const DIRECTION = Object.freeze({ BACKWARD: -1, FORWARD: 1, }); const TimeUnits = Object.freeze({ NANO_SECONDS: 'ns', MILLI_SECONDS: 'ms', SECONDS: 's', MINUTES: 'm', HOURS: 'h', DAYS: 'd', }); function nanosToString(elapsedRealtimeNanos, precision) { const units = [ [1000000, TimeUnits.NANO_SECONDS], [1000, TimeUnits.MILLI_SECONDS], [60, TimeUnits.SECONDS], [60, TimeUnits.MINUTES], [24, TimeUnits.HOURS], [Infinity, TimeUnits.DAYS], ]; const parts = []; let precisionThresholdReached = false; units.some(([div, timeUnit], i) => { const part = (elapsedRealtimeNanos % div).toFixed() if (timeUnit === precision) { precisionThresholdReached = true; } if (precisionThresholdReached) { parts.push(part + timeUnit); } elapsedRealtimeNanos = Math.floor(elapsedRealtimeNanos / div); return elapsedRealtimeNanos == 0; }); return parts.reverse().join(''); } /** Checks for match in window manager properties taskId, layerId, or windowToken, * or surface flinger property id */ function isPropertyMatch(flickerItem, entryItem) { return flickerItem.taskId === entryItem.taskId || (flickerItem.windowToken === entryItem.windowToken) || ((flickerItem.layerId === entryItem.layerId) && flickerItem.layerId !== 0) || flickerItem.layerId === entryItem.id; } export { DIRECTION, findLastMatchingSorted, isPropertyMatch, stableIdCompatibilityFixup, nanosToString, TimeUnits }