| Index: chrome/browser/net/net_log_temp_file.cc
 | 
| ===================================================================
 | 
| --- chrome/browser/net/net_log_temp_file.cc	(revision 0)
 | 
| +++ chrome/browser/net/net_log_temp_file.cc	(revision 0)
 | 
| @@ -0,0 +1,208 @@
 | 
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
 | 
| +// Use of this source code is governed by a BSD-style license that can be
 | 
| +// found in the LICENSE file.
 | 
| +
 | 
| +#include "chrome/browser/net/net_log_temp_file.h"
 | 
| +
 | 
| +#include <stdio.h>
 | 
| +
 | 
| +#include "base/bind.h"
 | 
| +#include "base/file_util.h"
 | 
| +#include "base/json/json_writer.h"
 | 
| +#include "base/logging.h"
 | 
| +#include "base/message_loop.h"
 | 
| +#include "base/string_number_conversions.h"
 | 
| +#include "base/string_util.h"
 | 
| +#include "base/threading/platform_thread.h"
 | 
| +#include "base/utf_string_conversions.h"
 | 
| +#include "base/values.h"
 | 
| +#include "chrome/browser/browser_process.h"
 | 
| +#include "chrome/browser/net/chrome_net_log.h"
 | 
| +#include "chrome/browser/net/net_log_logger.h"
 | 
| +#include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
 | 
| +#include "content/public/browser/browser_thread.h"
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +#include "chrome/browser/android/intent_helper.h"
 | 
| +#endif
 | 
| +
 | 
| +using content::BrowserThread;
 | 
| +
 | 
| +NetLogTempFile::NetLogTempFile() : state_(UNINITIALIZED) {
 | 
| +  BrowserThread::PostTask(
 | 
| +      BrowserThread::FILE_USER_BLOCKING,
 | 
| +      FROM_HERE,
 | 
| +      base::Bind(&NetLogTempFile::Init, base::Unretained(this)));
 | 
| +}
 | 
| +
 | 
| +NetLogTempFile::~NetLogTempFile() {
 | 
| +}
 | 
| +
 | 
| +void NetLogTempFile::ProcessCommand(Command command) {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +  switch (command) {
 | 
| +    case DO_START:
 | 
| +      StartNetLog();
 | 
| +      break;
 | 
| +    case DO_STOP:
 | 
| +      StopNetLog();
 | 
| +      break;
 | 
| +    case DO_SEND:
 | 
| +      SendNetLog();
 | 
| +      break;
 | 
| +    default:
 | 
| +      break;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +Value* NetLogTempFile::NetLogTempFileToValue() {
 | 
| +  base::DictionaryValue* dict = new base::DictionaryValue;
 | 
| +
 | 
| +#ifndef NDEBUG
 | 
| +  dict->SetString("file", log_path_.MaybeAsASCII());
 | 
| +#endif  // NDEBUG
 | 
| +
 | 
| +  base::AutoLock lock(lock_);
 | 
| +  switch (state_) {
 | 
| +    case ALLOW_STOP:
 | 
| +      dict->SetString("state", "ALLOW_STOP");
 | 
| +      break;
 | 
| +    case ALLOW_START_SEND:
 | 
| +      dict->SetString("state", "ALLOW_START_SEND");
 | 
| +      break;
 | 
| +    default:
 | 
| +      dict->SetString("state", "ALLOW_START");
 | 
| +      break;
 | 
| +  }
 | 
| +  return dict;
 | 
| +}
 | 
| +
 | 
| +bool GetTempNetLogDir(FilePath* path) {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +
 | 
| +  FilePath temp_dir;
 | 
| +  if (!file_util::GetTempDir(&temp_dir))
 | 
| +    return false;
 | 
| +
 | 
| +  FilePath net_log_dir = temp_dir.Append(FILE_PATH_LITERAL("NetLog"));
 | 
| +  if (file_util::PathExists(net_log_dir)) {
 | 
| +    *path = net_log_dir;
 | 
| +    return true;
 | 
| +  }
 | 
| +
 | 
| +  if (!file_util::CreateDirectory(net_log_dir))
 | 
| +    return false;
 | 
| +
 | 
| +  *path = net_log_dir;
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +void NetLogTempFile::Init() {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +
 | 
| +  FilePath net_log_dir;
 | 
| +
 | 
| +  base::AutoLock lock(lock_);
 | 
| +  if (!GetTempNetLogDir(&net_log_dir)) {
 | 
| +    state_ = ALLOW_START;
 | 
| +    return;
 | 
| +  }
 | 
| +  if (file_util::IsDirectoryEmpty(net_log_dir))
 | 
| +    state_ = ALLOW_START;
 | 
| +  else
 | 
| +    state_ = ALLOW_START_SEND;
 | 
| +}
 | 
| +
 | 
| +void NetLogTempFile::StartNetLog() {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +
 | 
| +  if (!g_browser_process->net_log())
 | 
| +    return;
 | 
| +
 | 
| +  base::AutoLock lock(lock_);
 | 
| +  if (state_ == ALLOW_STOP)
 | 
| +    return;
 | 
| +
 | 
| +  FilePath net_log_dir;
 | 
| +  if (!GetTempNetLogDir(&net_log_dir))
 | 
| +    return;
 | 
| +
 | 
| +  file_util::FileEnumerator file_iter(
 | 
| +      net_log_dir, false, file_util::FileEnumerator::FILES);
 | 
| +  for (FilePath current = file_iter.Next(); !current.empty();
 | 
| +       current = file_iter.Next()) {
 | 
| +    file_util::Delete(current, false);
 | 
| +  }
 | 
| +
 | 
| +  if (!file_util::CreateTemporaryFileInDir(net_log_dir, &log_path_))
 | 
| +    return;
 | 
| +
 | 
| +  net_log_logger_.reset(new NetLogLogger(log_path_));
 | 
| +  net_log_logger_->StartObserving(g_browser_process->net_log());
 | 
| +  state_ = ALLOW_STOP;
 | 
| +}
 | 
| +
 | 
| +void NetLogTempFile::StopNetLog() {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +
 | 
| +  if (!g_browser_process->net_log())
 | 
| +    return;
 | 
| +
 | 
| +  base::AutoLock lock(lock_);
 | 
| +  if (state_ != ALLOW_STOP)
 | 
| +    return;
 | 
| +
 | 
| +  net_log_logger_->StopObserving();
 | 
| +  net_log_logger_.reset();
 | 
| +  state_ = ALLOW_START_SEND;
 | 
| +}
 | 
| +
 | 
| +void NetLogTempFile::SendNetLog() {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING));
 | 
| +
 | 
| +  base::AutoLock lock(lock_);
 | 
| +  if (state_ != ALLOW_START_SEND)
 | 
| +    return;
 | 
| +
 | 
| +  FilePath net_log_dir;
 | 
| +  if (!GetTempNetLogDir(&net_log_dir))
 | 
| +    return;
 | 
| +
 | 
| +  FilePath file_to_send;
 | 
| +  file_util::FileEnumerator file_iter(
 | 
| +      net_log_dir, false, file_util::FileEnumerator::FILES);
 | 
| +  for (FilePath current = file_iter.Next(); !current.empty();
 | 
| +       current = file_iter.Next()) {
 | 
| +    file_to_send = current;
 | 
| +    break;
 | 
| +  }
 | 
| +  if (file_to_send.empty())
 | 
| +    return;
 | 
| +
 | 
| +#if defined(OS_POSIX)
 | 
| +  // Users, group and others can read, write and traverse.
 | 
| +  int mode = file_util::FILE_PERMISSION_MASK;
 | 
| +  file_util::SetPosixFilePermissions(file_to_send, mode);
 | 
| +#endif  // defined(OS_POSIX)
 | 
| +
 | 
| +  BrowserThread::PostTask(
 | 
| +      BrowserThread::UI,
 | 
| +      FROM_HERE,
 | 
| +      base::Bind(&NetLogTempFile::SendEmail, file_to_send));
 | 
| +}
 | 
| +
 | 
| +// static
 | 
| +void NetLogTempFile::SendEmail(const FilePath& file_to_send) {
 | 
| +  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 | 
| +
 | 
| +#if defined(OS_ANDROID)
 | 
| +  std::string email;
 | 
| +  std::string subject = "net_internals_log";
 | 
| +  std::string title = "test_title";
 | 
| +  std::string body = "Net Internals log data";
 | 
| +  FilePath::StringType file_to_attach(file_to_send.value());
 | 
| +  chrome::android::SendEmail(
 | 
| +      UTF8ToUTF16(email), UTF8ToUTF16(subject),
 | 
| +      UTF8ToUTF16(body), UTF8ToUTF16(title), UTF8ToUTF16(file_to_attach));
 | 
| +#endif
 | 
| +}
 | 
| 
 |