17a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo/*
27a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo * Copyright 2014 Google Inc.
37a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo *
47a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo * Use of this source code is governed by a BSD-style license that can be
57a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo * found in the LICENSE file.
67a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo */
77a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
87a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "DMJsonWriter.h"
97a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
10c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary#include "ProcStats.h"
117a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "SkCommonFlags.h"
1262bd1a69ea49318aa5022151262c842887e0ecf4mtklein#include "SkData.h"
137a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "SkJSONCPP.h"
141b24933e52f50773de29332387a12721811f3012mtklein#include "SkMutex.h"
157a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "SkOSFile.h"
167a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "SkStream.h"
177a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo#include "SkTArray.h"
187a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
197a10fb6bead0f63623307a7ff71b1dd323534a7fscroggonamespace DM {
207a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
217a10fb6bead0f63623307a7ff71b1dd323534a7fscroggoSkTArray<JsonWriter::BitmapResult> gBitmapResults;
227a10fb6bead0f63623307a7ff71b1dd323534a7fscroggoSK_DECLARE_STATIC_MUTEX(gBitmapResultLock);
237a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
247a10fb6bead0f63623307a7ff71b1dd323534a7fscroggovoid JsonWriter::AddBitmapResult(const BitmapResult& result) {
257a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    SkAutoMutexAcquire lock(&gBitmapResultLock);
267a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    gBitmapResults.push_back(result);
277a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo}
287a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
290ee2627026370bbb25e4efda490e14e468ac86fbscroggoSkTArray<skiatest::Failure> gFailures;
300ee2627026370bbb25e4efda490e14e468ac86fbscroggoSK_DECLARE_STATIC_MUTEX(gFailureLock);
310ee2627026370bbb25e4efda490e14e468ac86fbscroggo
320ee2627026370bbb25e4efda490e14e468ac86fbscroggovoid JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
330ee2627026370bbb25e4efda490e14e468ac86fbscroggo    SkAutoMutexAcquire lock(gFailureLock);
340ee2627026370bbb25e4efda490e14e468ac86fbscroggo    gFailures.push_back(failure);
350ee2627026370bbb25e4efda490e14e468ac86fbscroggo}
360ee2627026370bbb25e4efda490e14e468ac86fbscroggo
377a10fb6bead0f63623307a7ff71b1dd323534a7fscroggovoid JsonWriter::DumpJson() {
387a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    if (FLAGS_writePath.isEmpty()) {
397a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        return;
407a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    }
417a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
427a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    Json::Value root;
437a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
447a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
457a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
467a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    }
477a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    for (int i = 1; i < FLAGS_key.count(); i += 2) {
487a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
497a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    }
507a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
517a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    {
527a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        SkAutoMutexAcquire lock(&gBitmapResultLock);
537a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        for (int i = 0; i < gBitmapResults.count(); i++) {
547a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo            Json::Value result;
5520c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            result["key"]["name"]        = gBitmapResults[i].name.c_str();
5620c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            result["key"]["config"]      = gBitmapResults[i].config.c_str();
5720c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            result["key"]["source_type"] = gBitmapResults[i].sourceType.c_str();
5820c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            result["options"]["ext"]     = gBitmapResults[i].ext.c_str();
5920c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            result["md5"]                = gBitmapResults[i].md5.c_str();
6020c1c047e0800385c8729e304a6a511f41fd3cfcmtklein
6120c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            // Source options only need to be part of the key if they exist.
6220c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            // Source type by source type, we either always set options or never set options.
6320c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            if (!gBitmapResults[i].sourceOptions.isEmpty()) {
6420c1c047e0800385c8729e304a6a511f41fd3cfcmtklein                result["key"]["source_options"] = gBitmapResults[i].sourceOptions.c_str();
6520c1c047e0800385c8729e304a6a511f41fd3cfcmtklein            }
667a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
677a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo            root["results"].append(result);
687a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo        }
697a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    }
707a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
710ee2627026370bbb25e4efda490e14e468ac86fbscroggo    {
720ee2627026370bbb25e4efda490e14e468ac86fbscroggo        SkAutoMutexAcquire lock(gFailureLock);
730ee2627026370bbb25e4efda490e14e468ac86fbscroggo        for (int i = 0; i < gFailures.count(); i++) {
740ee2627026370bbb25e4efda490e14e468ac86fbscroggo            Json::Value result;
750ee2627026370bbb25e4efda490e14e468ac86fbscroggo            result["file_name"]     = gFailures[i].fileName;
760ee2627026370bbb25e4efda490e14e468ac86fbscroggo            result["line_no"]       = gFailures[i].lineNo;
770ee2627026370bbb25e4efda490e14e468ac86fbscroggo            result["condition"]     = gFailures[i].condition;
780ee2627026370bbb25e4efda490e14e468ac86fbscroggo            result["message"]       = gFailures[i].message.c_str();
790ee2627026370bbb25e4efda490e14e468ac86fbscroggo
800ee2627026370bbb25e4efda490e14e468ac86fbscroggo            root["test_results"]["failures"].append(result);
810ee2627026370bbb25e4efda490e14e468ac86fbscroggo        }
820ee2627026370bbb25e4efda490e14e468ac86fbscroggo    }
830ee2627026370bbb25e4efda490e14e468ac86fbscroggo
84c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary    int maxResidentSetSizeMB = sk_tools::getMaxResidentSetSizeMB();
85c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary    if (maxResidentSetSizeMB != -1) {
86c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary        root["max_rss_MB"] = sk_tools::getMaxResidentSetSizeMB();
87c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary    }
88c79a391a38c68503e43dc0ca775db9ed161f00b0halcanary
897a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
90022afb8384019b448c7c1c62a9ff63fa9e477737halcanary    sk_mkdir(FLAGS_writePath[0]);
917a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    SkFILEWStream stream(path.c_str());
927a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    stream.writeText(Json::StyledWriter().write(root).c_str());
937a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo    stream.flush();
947a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo}
957a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo
9662bd1a69ea49318aa5022151262c842887e0ecf4mtkleinbool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) {
9762bd1a69ea49318aa5022151262c842887e0ecf4mtklein    SkAutoTUnref<SkData> json(SkData::NewFromFileName(path));
9862bd1a69ea49318aa5022151262c842887e0ecf4mtklein    if (!json) {
9962bd1a69ea49318aa5022151262c842887e0ecf4mtklein        return false;
10062bd1a69ea49318aa5022151262c842887e0ecf4mtklein    }
10162bd1a69ea49318aa5022151262c842887e0ecf4mtklein
10262bd1a69ea49318aa5022151262c842887e0ecf4mtklein    Json::Reader reader;
10362bd1a69ea49318aa5022151262c842887e0ecf4mtklein    Json::Value root;
10462bd1a69ea49318aa5022151262c842887e0ecf4mtklein    const char* data = (const char*)json->data();
10562bd1a69ea49318aa5022151262c842887e0ecf4mtklein    if (!reader.parse(data, data+json->size(), root)) {
10662bd1a69ea49318aa5022151262c842887e0ecf4mtklein        return false;
10762bd1a69ea49318aa5022151262c842887e0ecf4mtklein    }
10862bd1a69ea49318aa5022151262c842887e0ecf4mtklein
10962bd1a69ea49318aa5022151262c842887e0ecf4mtklein    const Json::Value& results = root["results"];
11062bd1a69ea49318aa5022151262c842887e0ecf4mtklein    BitmapResult br;
11162bd1a69ea49318aa5022151262c842887e0ecf4mtklein    for (unsigned i = 0; i < results.size(); i++) {
11262bd1a69ea49318aa5022151262c842887e0ecf4mtklein        const Json::Value& r = results[i];
1130ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        br.name       = r["key"]["name"].asCString();
1140ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        br.config     = r["key"]["config"].asCString();
1150ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        br.sourceType = r["key"]["source_type"].asCString();
1160ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        br.ext        = r["options"]["ext"].asCString();
1170ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        br.md5        = r["md5"].asCString();
1180ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein
1190ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        if (!r["key"]["source_options"].isNull()) {
1200ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein            br.sourceOptions = r["key"]["source_options"].asCString();
1210ea6d7150eb661f51f736ec32ce6fe3fd9922e97mtklein        }
12262bd1a69ea49318aa5022151262c842887e0ecf4mtklein        callback(br);
12362bd1a69ea49318aa5022151262c842887e0ecf4mtklein    }
12462bd1a69ea49318aa5022151262c842887e0ecf4mtklein    return true;
12562bd1a69ea49318aa5022151262c842887e0ecf4mtklein}
12662bd1a69ea49318aa5022151262c842887e0ecf4mtklein
1277a10fb6bead0f63623307a7ff71b1dd323534a7fscroggo} // namespace DM
128