public void onWidgetPerfEvent()

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();
    }
  }