• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17function transform({obj, kind, name, children, timestamp, rect, bounds, highlight, rects_transform, chips, visible, flattened}) {
18	function call(fn, arg) {
19		return (typeof fn == 'function') ? fn(arg) : fn;
20	}
21	function handle_children(arg, transform) {
22		return [].concat(...arg.map((item) => {
23			var childrenFunc = item[0];
24			var transformFunc = item[1];
25			var childs = call(childrenFunc, obj);
26			if (childs) {
27				if (typeof childs.map != 'function'){
28					throw 'Childs should be an array, but is: ' + (typeof childs) + '.'
29				}
30				return transform ? childs.map(transformFunc) : childs;
31			} else {
32				return [];
33			}
34		}));
35	}
36	function concat(arg, args, argsmap) {
37		var validArg = arg !== undefined && arg !== null;
38
39		if (Array.isArray(args)) {
40			if (validArg) {
41				return [arg].concat(...args.map(argsmap));
42			} else {
43				return [].concat(...args.map(argsmap));
44			}
45		} else if (validArg) {
46			return [arg];
47		} else {
48			return undefined;
49		}
50	}
51
52	var transformed_children = handle_children(children, true /* transform */);
53	rects_transform = (rects_transform === undefined) ? (e) => e : rects_transform;
54
55	var kindResolved = call(kind, obj);
56	var nameResolved = call(name, obj);
57	var rectResolved = call(rect, obj);
58
59	var result = {
60		kind: kindResolved,
61		name: nameResolved,
62		children: transformed_children,
63		obj: obj,
64		timestamp: call(timestamp, obj),
65		skip: handle_children(children, false /* transform */),
66		bounds: call(bounds, obj) || transformed_children.map((e) => e.bounds).find((e) => true) || undefined,
67		rect: rectResolved,
68		rects: rects_transform(concat(rectResolved, transformed_children, (e) => e.rects)),
69		highlight: call(highlight, obj),
70		chips: call(chips, obj),
71		stableId: kindResolved + "|-|" + nameResolved,
72		visible: call(visible, obj),
73		childrenVisible: transformed_children.some((c) => {
74				return c.childrenVisible || c.visible
75			}),
76		flattened: call(flattened, obj),
77	};
78
79	if (rectResolved) {
80		rectResolved.ref = result;
81	}
82
83	return Object.freeze(result);
84}
85
86
87function transform_json(obj, name, options) {
88	let {skip, formatter} = options;
89
90	var children = [];
91	var formatted = undefined;
92
93	if (skip && skip.includes(obj)) {
94		// skip
95	} else if ((formatted = formatter(obj))) {
96		children.push(transform_json(null, formatted, options));
97	} else if (Array.isArray(obj)) {
98		obj.forEach((e, i) => {
99			children.push(transform_json(e, ""+i, options));
100		})
101	} else if (typeof obj == 'string') {
102		children.push(transform_json(null, obj, options));
103	} else if (typeof obj == 'number' || typeof obj == 'boolean') {
104		children.push(transform_json(null, ""+obj, options));
105	} else if (obj && typeof obj == 'object') {
106		Object.keys(obj).forEach((key) => {
107			children.push(transform_json(obj[key], key, options));
108		});
109	}
110
111	if (children.length == 1 && !children[0].combined) {
112		return Object.freeze({
113			kind: "",
114			name: name + ": " + children[0].name,
115			children: children[0].children,
116			combined: true
117		});
118	}
119
120	return Object.freeze({
121		kind: "",
122		name: name,
123		children: children,
124	});
125}
126
127function nanos_to_string(elapsedRealtimeNanos) {
128	var units = [
129		[1000000, '(ns)'],
130		[1000, 'ms'],
131		[60, 's'],
132		[60, 'm'],
133		[24, 'h'],
134		[Infinity, 'd'],
135	];
136
137	var parts = []
138	units.some(([div, str], i) => {
139		var part = (elapsedRealtimeNanos % div).toFixed()
140		if (!str.startsWith('(')) {
141			parts.push(part + str);
142		}
143		elapsedRealtimeNanos = Math.floor(elapsedRealtimeNanos / div);
144		return elapsedRealtimeNanos == 0;
145	});
146
147	return parts.reverse().join('');
148}
149
150 // Returns a UI element used highlight a visible entry.
151 function get_visible_chip() {
152	return {short: 'V', long: "visible", class: 'default'};
153 }
154
155export {transform, transform_json, nanos_to_string, get_visible_chip};
156