1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_log_logger.h" 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdio.h> 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/json/json_writer.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_number_conversions.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/address_family.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/load_states.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/quic/quic_protocol.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/quic/quic_utils.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace net { 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This should be incremented when significant changes are made that will 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// invalidate the old loading code. 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const int kLogFormatVersion = 1; 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochNetLogLogger::NetLogLogger(FILE* file, const base::Value& constants) 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : file_(file), added_events_(false) { 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(file); 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Write constants to the output file. This allows loading files that have 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // different source and event types, as they may be added and removed 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // between Chrome versions. 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string json; 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::JSONWriter::Write(&constants, &json); 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(file_.get(), "{\"constants\": %s,\n", json.c_str()); 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(file_.get(), "\"events\": [\n"); 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochNetLogLogger::~NetLogLogger() { 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (file_.get()) 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(file_.get(), "]}"); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NetLogLogger::StartObserving(net::NetLog* net_log) { 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log->AddThreadSafeObserver(this, net::NetLog::LOG_ALL_BUT_BYTES); 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NetLogLogger::StopObserving() { 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net_log()->RemoveThreadSafeObserver(this); 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid NetLogLogger::OnAddEntry(const net::NetLog::Entry& entry) { 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add a comma and newline for every event but the first. Newlines are needed 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // so can load partial log files by just ignoring the last line. For this to 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // work, lines cannot be pretty printed. 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<Value> value(entry.ToValue()); 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string json; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::JSONWriter::Write(value.get(), &json); 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(file_.get(), "%s%s", 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (added_events_ ? ",\n" : ""), 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch json.c_str()); 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch added_events_ = true; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::DictionaryValue* NetLogLogger::GetConstants() { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* constants_dict = new DictionaryValue(); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Version of the file format. 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->SetInteger("logFormatVersion", kLogFormatVersion); 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add a dictionary with information on the relationship between event type 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // enums and their symbolic names. 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("logEventTypes", net::NetLog::GetEventTypesAsValue()); 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add a dictionary with information about the relationship between load flag 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // enums and their symbolic names. 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define LOAD_FLAG(label, value) \ 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger(# label, static_cast<int>(value)); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/load_flags_list.h" 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#undef LOAD_FLAG 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("loadFlag", dict); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add a dictionary with information about the relationship between load state 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // enums and their symbolic names. 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define LOAD_STATE(label) \ 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger(# label, net::LOAD_STATE_ ## label); 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/load_states_list.h" 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#undef LOAD_STATE 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("loadState", dict); 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add information on the relationship between net error codes and their 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // symbolic names. 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define NET_ERROR(label, value) \ 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger(# label, static_cast<int>(value)); 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/base/net_error_list.h" 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#undef NET_ERROR 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("netError", dict); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add information on the relationship between QUIC error codes and their 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // symbolic names. 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (net::QuicErrorCode error = net::QUIC_NO_ERROR; 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error < net::QUIC_LAST_ERROR; 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = static_cast<net::QuicErrorCode>(error + 1)) { 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger(net::QuicUtils::ErrorToString(error), 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static_cast<int>(error)); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("quicError", dict); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Add information on the relationship between QUIC RST_STREAM error codes 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // and their symbolic names. 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (net::QuicRstStreamErrorCode error = net::QUIC_STREAM_NO_ERROR; 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error < net::QUIC_STREAM_LAST_ERROR; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error = static_cast<net::QuicRstStreamErrorCode>(error + 1)) { 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger(net::QuicUtils::StreamErrorToString(error), 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static_cast<int>(error)); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("quicRstStreamError", dict); 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Information about the relationship between event phase enums and their 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // symbolic names. 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("PHASE_BEGIN", net::NetLog::PHASE_BEGIN); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("PHASE_END", net::NetLog::PHASE_END); 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("PHASE_NONE", net::NetLog::PHASE_NONE); 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("logEventPhase", dict); 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Information about the relationship between source type enums and 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // their symbolic names. 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("logSourceType", net::NetLog::GetSourceTypesAsValue()); 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Information about the relationship between LogLevel enums and their 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // symbolic names. 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("LOG_ALL", net::NetLog::LOG_ALL); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("LOG_ALL_BUT_BYTES", net::NetLog::LOG_ALL_BUT_BYTES); 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("LOG_BASIC", net::NetLog::LOG_BASIC); 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("logLevelType", dict); 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Information about the relationship between address family enums and 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // their symbolic names. 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DictionaryValue* dict = new DictionaryValue(); 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("ADDRESS_FAMILY_UNSPECIFIED", 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ADDRESS_FAMILY_UNSPECIFIED); 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("ADDRESS_FAMILY_IPV4", 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ADDRESS_FAMILY_IPV4); 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict->SetInteger("ADDRESS_FAMILY_IPV6", 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch net::ADDRESS_FAMILY_IPV6); 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("addressFamily", dict); 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Information about how the "time ticks" values we have given it relate to 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // actual system times. (We used time ticks throughout since they are stable 188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // across system clock changes). 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 cur_time_ms = (base::Time::Now() - base::Time()).InMilliseconds(); 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 cur_time_ticks_ms = 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds(); 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // If we add this number to a time tick value, it gives the timestamp. 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 tick_to_time_ms = cur_time_ms - cur_time_ticks_ms; 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Chrome on all platforms stores times using the Windows epoch 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // (Jan 1 1601), but the javascript wants a unix epoch. 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(eroman): Getting the timestamp relative to the unix epoch should 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // be part of the time library. 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const int64 kUnixEpochMs = 11644473600000LL; 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 tick_to_unix_time_ms = tick_to_time_ms - kUnixEpochMs; 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Pass it as a string, since it may be too large to fit in an integer. 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->SetString("timeTickOffset", 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Int64ToString(tick_to_unix_time_ms)); 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // "clientInfo" key is required for some NetLogLogger log readers. 211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Provide a default empty value for compatibility. 212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch constants_dict->Set("clientInfo", new DictionaryValue()); 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return constants_dict; 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace net 218