Home | History | Annotate | Download | only in net
      1 // Copyright (c) 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/browser/net/net_log_temp_file.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/net/chrome_net_log.h"
     10 #include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
     11 #include "content/public/browser/browser_thread.h"
     12 #include "net/base/net_log_logger.h"
     13 
     14 using content::BrowserThread;
     15 
     16 NetLogTempFile::NetLogTempFile(ChromeNetLog* chrome_net_log)
     17     : state_(STATE_UNINITIALIZED),
     18       log_filename_(FILE_PATH_LITERAL("chrome-net-export-log.json")),
     19       chrome_net_log_(chrome_net_log) {
     20 }
     21 
     22 NetLogTempFile::~NetLogTempFile() {
     23   if (net_log_logger_)
     24     net_log_logger_->StopObserving();
     25 }
     26 
     27 void NetLogTempFile::ProcessCommand(Command command) {
     28   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
     29   if (!EnsureInit())
     30     return;
     31 
     32   switch (command) {
     33     case DO_START:
     34       StartNetLog();
     35       break;
     36     case DO_STOP:
     37       StopNetLog();
     38       break;
     39     default:
     40       NOTREACHED();
     41       break;
     42   }
     43 }
     44 
     45 DictionaryValue* NetLogTempFile::GetState() {
     46   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
     47   base::DictionaryValue* dict = new base::DictionaryValue;
     48 
     49   EnsureInit();
     50 
     51 #ifndef NDEBUG
     52   dict->SetString("file", log_path_.LossyDisplayName());
     53 #endif  // NDEBUG
     54 
     55   switch (state_) {
     56     case STATE_ALLOW_START:
     57       dict->SetString("state", "ALLOW_START");
     58       break;
     59     case STATE_ALLOW_STOP:
     60       dict->SetString("state", "ALLOW_STOP");
     61       break;
     62     case STATE_ALLOW_START_SEND:
     63       dict->SetString("state", "ALLOW_START_SEND");
     64       break;
     65     default:
     66       dict->SetString("state", "UNINITIALIZED");
     67       break;
     68   }
     69   return dict;
     70 }
     71 
     72 bool NetLogTempFile::EnsureInit() {
     73   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
     74   if (state_ != STATE_UNINITIALIZED)
     75     return true;
     76 
     77   if (!GetNetExportLog())
     78     return false;
     79 
     80   if (NetExportLogExists())
     81     state_ = STATE_ALLOW_START_SEND;
     82   else
     83     state_ = STATE_ALLOW_START;
     84 
     85   return true;
     86 }
     87 
     88 void NetLogTempFile::StartNetLog() {
     89   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
     90   if (state_ == STATE_ALLOW_STOP)
     91     return;
     92 
     93   DCHECK_NE(STATE_UNINITIALIZED, state_);
     94   DCHECK(!log_path_.empty());
     95 
     96   // Try to make sure we can create the file.
     97   // TODO(rtenneti): Find a better for doing the following. Surface some error
     98   // to the user if we couldn't create the file.
     99   FILE* file = base::OpenFile(log_path_, "w");
    100   if (file == NULL)
    101     return;
    102 
    103   scoped_ptr<base::Value> constants(NetInternalsUI::GetConstants());
    104   net_log_logger_.reset(new net::NetLogLogger(file, *constants));
    105   net_log_logger_->StartObserving(chrome_net_log_);
    106   state_ = STATE_ALLOW_STOP;
    107 }
    108 
    109 void NetLogTempFile::StopNetLog() {
    110   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
    111   if (state_ != STATE_ALLOW_STOP)
    112     return;
    113 
    114   net_log_logger_->StopObserving();
    115   net_log_logger_.reset();
    116   state_ = STATE_ALLOW_START_SEND;
    117 }
    118 
    119 bool NetLogTempFile::GetFilePath(base::FilePath* path) {
    120   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
    121   if (state_ != STATE_ALLOW_START_SEND)
    122     return false;
    123 
    124   if (!NetExportLogExists())
    125     return false;
    126 
    127   DCHECK(!log_path_.empty());
    128 #if defined(OS_POSIX)
    129   // Users, group and others can read, write and traverse.
    130   int mode = base::FILE_PERMISSION_MASK;
    131   base::SetPosixFilePermissions(log_path_, mode);
    132 #endif  // defined(OS_POSIX)
    133 
    134   *path = log_path_;
    135   return true;
    136 }
    137 
    138 bool NetLogTempFile::GetNetExportLog() {
    139   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
    140   base::FilePath temp_dir;
    141   if (!GetNetExportLogDirectory(&temp_dir))
    142     return false;
    143 
    144   log_path_ = temp_dir.Append(log_filename_);
    145   return true;
    146 }
    147 
    148 bool NetLogTempFile::GetNetExportLogDirectory(base::FilePath* path) {
    149   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
    150   return base::GetTempDir(path);
    151 }
    152 
    153 bool NetLogTempFile::NetExportLogExists() {
    154   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
    155   DCHECK(!log_path_.empty());
    156   return base::PathExists(log_path_);
    157 }
    158