in flutter-idea/src/io/flutter/perf/FlutterWidgetPerf.java [159:290]
public void onWidgetPerfEvent(PerfReportKind kind, JsonObject json) {
// Read access to the Document objects on background thread is needed so
// a ReadAction is required. Document objects are used to determine the
// widget names at specific locations in documents.
final Runnable action = () -> {
synchronized (this) {
final long startTimeMicros = json.get("startTime").getAsLong();
final int startTimeMilis = (int)(startTimeMicros / 1000);
lastLocalPerfEventTime = System.currentTimeMillis();
final StatsForReportKind statsForReportKind = getStatsForKind(kind);
if (statsForReportKind.lastStartTime > startTimeMilis) {
// We went backwards in time. There must have been a hot restart so
// clear all old stats.
statsForReportKind.data.forEachValue((SlidingWindowStats entry) -> {
entry.clear();
return true;
});
}
statsForReportKind.lastStartTime = startTimeMilis;
// Prefer the new 'locations' format if it exists; else read from 'newLocations'.
if (json.has("locations")) {
final JsonObject fileLocationsMap = json.getAsJsonObject("locations");
for (Map.Entry<String, JsonElement> entry : fileLocationsMap.entrySet()) {
final String path = entry.getKey();
final FileLocationMapper locationMapper = fileLocationMapperFactory.create(path);
final JsonObject locations = entry.getValue().getAsJsonObject();
final JsonArray ids = locations.getAsJsonArray("ids");
final JsonArray lines = locations.getAsJsonArray("lines");
final JsonArray columns = locations.getAsJsonArray("columns");
final JsonArray names = locations.getAsJsonArray("names");
for (int i = 0; i < ids.size(); i++) {
final int id = ids.get(i).getAsInt();
final int line = lines.get(i).getAsInt();
final int column = columns.get(i).getAsInt();
final TextRange textRange = locationMapper.getIdentifierRange(line, column);
final Location location = new Location(
locationMapper.getPath(),
line,
column,
id,
textRange,
names.get(i).getAsString()
);
final Location existingLocation = knownLocationIds.get(id);
if (existingLocation == null) {
addNewLocation(id, location);
}
else {
if (!location.equals(existingLocation)) {
// Cleanup all references to the old location as it is stale.
// This occurs if there is a hot restart or reload that we weren't aware of.
locationsPerFile.remove(existingLocation.path, existingLocation);
for (StatsForReportKind statsForKind : stats.values()) {
statsForKind.data.remove(id);
}
addNewLocation(id, location);
}
}
}
}
}
else if (json.has("newLocations")) {
final JsonObject newLocations = json.getAsJsonObject("newLocations");
for (Map.Entry<String, JsonElement> entry : newLocations.entrySet()) {
final String path = entry.getKey();
final FileLocationMapper locationMapper = fileLocationMapperFactory.create(path);
final JsonArray entries = entry.getValue().getAsJsonArray();
assert (entries.size() % 3 == 0);
for (int i = 0; i < entries.size(); i += 3) {
final int id = entries.get(i).getAsInt();
final int line = entries.get(i + 1).getAsInt();
final int column = entries.get(i + 2).getAsInt();
final TextRange textRange = locationMapper.getIdentifierRange(line, column);
String name = locationMapper.getText(textRange);
if (name == null) {
name = "";
}
final Location location = new Location(locationMapper.getPath(), line, column, id, textRange, name);
final Location existingLocation = knownLocationIds.get(id);
if (existingLocation == null) {
addNewLocation(id, location);
}
else {
if (!location.equals(existingLocation)) {
// Cleanup all references to the old location as it is stale.
// This occurs if there is a hot restart or reload that we weren't aware of.
locationsPerFile.remove(existingLocation.path, existingLocation);
for (StatsForReportKind statsForKind : stats.values()) {
statsForKind.data.remove(id);
}
addNewLocation(id, location);
}
}
}
}
}
final StatsForReportKind statsForKind = getStatsForKind(kind);
final PerfSourceReport report = new PerfSourceReport(json.getAsJsonArray("events"), kind, startTimeMicros);
if (report.getEntries().size() > 0) {
statsForReportKind.lastNonEmptyReportTime = startTimeMilis;
}
for (PerfSourceReport.Entry entry : report.getEntries()) {
final int locationId = entry.locationId;
SlidingWindowStats statsForLocation = statsForKind.data.get(locationId);
if (statsForLocation == null) {
statsForLocation = new SlidingWindowStats();
statsForKind.data.put(locationId, statsForLocation);
}
statsForLocation.add(entry.total, startTimeMilis);
}
}
};
final Application application = ApplicationManager.getApplication();
if (application != null) {
application.runReadAction(action);
}
else {
// Unittest case.
action.run();
}
}