package com.android.test.hierarchyviewer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; public class ViewDumpParser { private Map mIds; private List> mViews; public void parse(byte[] data) { Decoder d = new Decoder(ByteBuffer.wrap(data)); mViews = new ArrayList<>(100); boolean dataIncludesWindowPosition = (data[0] == 'S'); Short windowLeftKey = null, windowTopKey = null; Integer windowLeftValue = null, windowTopValue = null; if (dataIncludesWindowPosition) { windowLeftKey = (Short) d.readObject(); windowLeftValue = (Integer) d.readObject(); windowTopKey = (Short) d.readObject(); windowTopValue = (Integer) d.readObject(); } while (d.hasRemaining()) { Object o = d.readObject(); if (o instanceof Map) { //noinspection unchecked mViews.add((Map) o); } } if (mViews.isEmpty()) { return; } if (dataIncludesWindowPosition) { mViews.get(0).put(windowLeftKey, windowLeftValue); mViews.get(0).put(windowTopKey, windowTopValue); } // the last one is the property map Map idMap = mViews.remove(mViews.size() - 1); mIds = reverse(idMap); } public String getFirstView() { if (mViews.isEmpty()) { return null; } Map props = mViews.get(0); Object name = getProperty(props, "__name__"); Object hash = getProperty(props, "__hash__"); if (name instanceof String && hash instanceof Integer) { return String.format(Locale.US, "%s@%x", name, hash); } else { return null; } } private Object getProperty(Map props, String key) { return props.get(mIds.get(key)); } private static Map reverse(Map m) { Map r = new HashMap(m.size()); for (Map.Entry e : m.entrySet()) { r.put((String)e.getValue(), e.getKey()); } return r; } public List> getViews() { return mViews; } public Map getIds() { return mIds; } }