1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/test/chromedriver/chrome/heap_snapshot_taker.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/logging.h"
9 #include "base/values.h"
10 #include "chrome/test/chromedriver/chrome/devtools_client.h"
11 #include "chrome/test/chromedriver/chrome/status.h"
12
HeapSnapshotTaker(DevToolsClient * client)13 HeapSnapshotTaker::HeapSnapshotTaker(DevToolsClient* client)
14 : client_(client) {
15 client_->AddListener(this);
16 }
17
~HeapSnapshotTaker()18 HeapSnapshotTaker::~HeapSnapshotTaker() {}
19
TakeSnapshot(scoped_ptr<base::Value> * snapshot)20 Status HeapSnapshotTaker::TakeSnapshot(scoped_ptr<base::Value>* snapshot) {
21 Status status1 = TakeSnapshotInternal();
22 base::DictionaryValue params;
23 Status status2 = client_->SendCommand("Debugger.disable", params);
24
25 Status status3(kOk);
26 if (status1.IsOk() && status2.IsOk()) {
27 scoped_ptr<base::Value> value(base::JSONReader::Read(snapshot_));
28 if (!value) {
29 status3 = Status(kUnknownError, "heap snapshot not in JSON format");
30 } else {
31 *snapshot = value.Pass();
32 }
33 }
34 snapshot_.clear();
35 if (status1.IsError()) {
36 return status1;
37 } else if (status2.IsError()) {
38 return status2;
39 } else {
40 return status3;
41 }
42 }
43
TakeSnapshotInternal()44 Status HeapSnapshotTaker::TakeSnapshotInternal() {
45 base::DictionaryValue params;
46 const char* kMethods[] = {
47 "Debugger.enable",
48 "HeapProfiler.collectGarbage",
49 "HeapProfiler.takeHeapSnapshot"
50 };
51 for (size_t i = 0; i < arraysize(kMethods); ++i) {
52 Status status = client_->SendCommand(kMethods[i], params);
53 if (status.IsError())
54 return status;
55 }
56
57 return Status(kOk);
58 }
59
OnEvent(DevToolsClient * client,const std::string & method,const base::DictionaryValue & params)60 Status HeapSnapshotTaker::OnEvent(DevToolsClient* client,
61 const std::string& method,
62 const base::DictionaryValue& params) {
63 if (method == "HeapProfiler.addHeapSnapshotChunk") {
64 std::string chunk;
65 if (!params.GetString("chunk", &chunk)) {
66 return Status(kUnknownError,
67 "HeapProfiler.addHeapSnapshotChunk has no 'chunk'");
68 }
69 snapshot_.append(chunk);
70 }
71 return Status(kOk);
72 }
73