1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file.
4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/test/chromedriver/chrome/log.h"
6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_reader.h"
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_writer.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h"
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void Log::AddEntry(Level level, const std::string& message) {
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddEntry(level, "", message);
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Log::AddEntry(Level level,
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   const std::string& source,
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   const std::string& message) {
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddEntryTimestamped(base::Time::Now(), level, source, message);
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)IsVLogOnFunc g_is_vlog_on_func = NULL;
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TruncateString(std::string* data) {
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const size_t kMaxLength = 200;
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (data->length() > kMaxLength) {
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    data->resize(kMaxLength);
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    data->replace(kMaxLength - 3, 3, "...");
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)scoped_ptr<base::Value> SmartDeepCopy(const base::Value* value) {
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const size_t kMaxChildren = 20;
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const base::ListValue* list = NULL;
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const base::DictionaryValue* dict = NULL;
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string data;
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (value->GetAsDictionary(&dict)) {
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<base::DictionaryValue> dict_copy(new base::DictionaryValue());
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd();
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)         it.Advance()) {
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (dict_copy->size() >= kMaxChildren - 1) {
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        dict_copy->SetStringWithoutPathExpansion("~~~", "...");
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        break;
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const base::Value* child = NULL;
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dict->GetWithoutPathExpansion(it.key(), &child);
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      dict_copy->SetWithoutPathExpansion(it.key(),
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         SmartDeepCopy(child).release());
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return dict_copy.PassAs<base::Value>();
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else if (value->GetAsList(&list)) {
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<base::ListValue> list_copy(new base::ListValue());
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const base::Value* child = NULL;
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (!list->Get(i, &child))
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        continue;
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      if (list_copy->GetSize() >= kMaxChildren - 1) {
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        list_copy->AppendString("...");
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        break;
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      list_copy->Append(SmartDeepCopy(child).release());
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return list_copy.PassAs<base::Value>();
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  } else if (value->GetAsString(&data)) {
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TruncateString(&data);
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return scoped_ptr<base::Value>(new base::StringValue(data));
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return scoped_ptr<base::Value>(value->DeepCopy());
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void InitLogging(IsVLogOnFunc is_vlog_on_func) {
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  g_is_vlog_on_func = is_vlog_on_func;
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool IsVLogOn(int vlog_level) {
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!g_is_vlog_on_func)
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return g_is_vlog_on_func(vlog_level);
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string PrettyPrintValue(const base::Value& value) {
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string json;
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::JSONWriter::WriteWithOptions(
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json);
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN)
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RemoveChars(json, "\r", &json);
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Remove the trailing newline.
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (json.length())
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    json.resize(json.length() - 1);
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return json;
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string FormatValueForDisplay(const base::Value& value) {
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<base::Value> copy(SmartDeepCopy(&value));
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return PrettyPrintValue(*copy);
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string FormatJsonForDisplay(const std::string& json) {
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<base::Value> value(base::JSONReader::Read(json));
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!value)
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    value.reset(new base::StringValue(json));
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return FormatValueForDisplay(*value);
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
109