Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/webui/net_export_ui.h" | 5 #include "chrome/browser/ui/webui/net_export_ui.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "components/grit/components_resources.h" | 24 #include "components/grit/components_resources.h" |
| 25 #include "components/net_log/chrome_net_log.h" | 25 #include "components/net_log/chrome_net_log.h" |
| 26 #include "components/net_log/net_export_ui_constants.h" | 26 #include "components/net_log/net_export_ui_constants.h" |
| 27 #include "components/net_log/net_log_file_writer.h" | 27 #include "components/net_log/net_log_file_writer.h" |
| 28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/url_data_source.h" | 29 #include "content/public/browser/url_data_source.h" |
| 30 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
| 31 #include "content/public/browser/web_ui.h" | 31 #include "content/public/browser/web_ui.h" |
| 32 #include "content/public/browser/web_ui_data_source.h" | 32 #include "content/public/browser/web_ui_data_source.h" |
| 33 #include "content/public/browser/web_ui_message_handler.h" | 33 #include "content/public/browser/web_ui_message_handler.h" |
| 34 #include "net/log/net_log_util.h" | |
| 35 #include "net/url_request/url_request_context_getter.h" | |
| 34 #include "ui/shell_dialogs/select_file_dialog.h" | 36 #include "ui/shell_dialogs/select_file_dialog.h" |
| 35 | 37 |
| 36 #if BUILDFLAG(ANDROID_JAVA_UI) | 38 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 37 #include "chrome/browser/android/intent_helper.h" | 39 #include "chrome/browser/android/intent_helper.h" |
| 38 #endif | 40 #endif |
| 39 | 41 |
| 40 using content::BrowserThread; | 42 using content::BrowserThread; |
| 41 using content::WebContents; | 43 using content::WebContents; |
| 42 using content::WebUIMessageHandler; | 44 using content::WebUIMessageHandler; |
| 43 | 45 |
| 44 namespace { | 46 namespace { |
| 45 | 47 |
| 46 // May only be accessed on the UI thread | 48 // May only be accessed on the UI thread |
| 47 base::LazyInstance<base::FilePath>::Leaky | 49 base::LazyInstance<base::FilePath>::Leaky |
| 48 last_save_dir = LAZY_INSTANCE_INITIALIZER; | 50 last_save_dir = LAZY_INSTANCE_INITIALIZER; |
| 49 | 51 |
| 50 content::WebUIDataSource* CreateNetExportHTMLSource() { | 52 content::WebUIDataSource* CreateNetExportHTMLSource() { |
| 51 content::WebUIDataSource* source = | 53 content::WebUIDataSource* source = |
| 52 content::WebUIDataSource::Create(chrome::kChromeUINetExportHost); | 54 content::WebUIDataSource::Create(chrome::kChromeUINetExportHost); |
| 53 | 55 |
| 54 source->SetJsonPath("strings.js"); | 56 source->SetJsonPath("strings.js"); |
| 55 source->AddResourcePath(net_log::kNetExportUIJS, IDR_NET_LOG_NET_EXPORT_JS); | 57 source->AddResourcePath(net_log::kNetExportUIJS, IDR_NET_LOG_NET_EXPORT_JS); |
| 56 source->SetDefaultResource(IDR_NET_LOG_NET_EXPORT_HTML); | 58 source->SetDefaultResource(IDR_NET_LOG_NET_EXPORT_HTML); |
| 57 return source; | 59 return source; |
| 58 } | 60 } |
| 59 | 61 |
| 60 // This class receives javascript messages from the renderer. | 62 // This class receives javascript messages from the renderer. |
| 61 // Note that the WebUI infrastructure runs on the UI thread, therefore all of | 63 // Note that the WebUI infrastructure runs on the UI thread, therefore all of |
| 62 // this class's public methods are expected to run on the UI thread. All static | 64 // this class's public methods are expected to run on the UI thread. |
| 63 // functions except SendEmail run on FILE_USER_BLOCKING thread. | |
| 64 class NetExportMessageHandler | 65 class NetExportMessageHandler |
| 65 : public WebUIMessageHandler, | 66 : public WebUIMessageHandler, |
| 66 public base::SupportsWeakPtr<NetExportMessageHandler>, | 67 public base::SupportsWeakPtr<NetExportMessageHandler>, |
| 67 public ui::SelectFileDialog::Listener { | 68 public ui::SelectFileDialog::Listener { |
| 68 public: | 69 public: |
| 69 NetExportMessageHandler(); | 70 NetExportMessageHandler(); |
| 70 ~NetExportMessageHandler() override; | 71 ~NetExportMessageHandler() override; |
| 71 | 72 |
| 72 // WebUIMessageHandler implementation. | 73 // WebUIMessageHandler implementation. |
| 73 void RegisterMessages() override; | 74 void RegisterMessages() override; |
| 74 | 75 |
| 75 // Messages. | 76 // Messages. |
| 76 void OnGetExportNetLogInfo(const base::ListValue* list); | 77 void OnGetExportNetLogInfo(const base::ListValue* list); |
| 77 void OnStartNetLog(const base::ListValue* list); | 78 void OnStartNetLog(const base::ListValue* list); |
| 78 void OnStopNetLog(const base::ListValue* list); | 79 void OnStopNetLog(const base::ListValue* list); |
| 79 void OnSendNetLog(const base::ListValue* list); | 80 void OnSendNetLog(const base::ListValue* list); |
| 80 | 81 |
| 81 // ui::SelectFileDialog::Listener: | 82 // ui::SelectFileDialog::Listener: |
| 82 void FileSelected(const base::FilePath& path, | 83 void FileSelected(const base::FilePath& path, |
| 83 int index, | 84 int index, |
| 84 void* params) override; | 85 void* params) override; |
| 85 void FileSelectionCanceled(void* params) override; | 86 void FileSelectionCanceled(void* params) override; |
| 86 | 87 |
| 87 private: | 88 private: |
| 88 // Calls NetLogFileWriter's ProcessCommand with DO_START and DO_STOP commands. | 89 // If |log_path| is empty, then the NetLogFileWriter will use its default |
| 89 static void ProcessNetLogCommand( | 90 // log path. |
| 90 base::WeakPtr<NetExportMessageHandler> net_export_message_handler, | 91 void StartNetLogThenNotifyUI(const base::FilePath& log_path, |
| 91 net_log::NetLogFileWriter* net_log_file_writer, | 92 net::NetLogCaptureMode capture_mode); |
| 92 net_log::NetLogFileWriter::Command command); | |
| 93 | 93 |
| 94 // Returns the path to the file which has NetLog data. | 94 void StopNetLogThenNotifyUI(); |
| 95 static base::FilePath GetNetLogFileName( | |
| 96 net_log::NetLogFileWriter* net_log_file_writer); | |
| 97 | 95 |
| 98 // Send state/file information from NetLogFileWriter. | 96 // Send NetLog data via email. |
| 99 static void SendExportNetLogInfo( | |
| 100 base::WeakPtr<NetExportMessageHandler> net_export_message_handler, | |
| 101 net_log::NetLogFileWriter* net_log_file_writer); | |
| 102 | |
| 103 // Send NetLog data via email. This runs on UI thread. | |
| 104 static void SendEmail(const base::FilePath& file_to_send); | 97 static void SendEmail(const base::FilePath& file_to_send); |
| 105 | 98 |
| 106 // chrome://net-export can be used on both mobile and desktop platforms. | 99 // chrome://net-export can be used on both mobile and desktop platforms. |
| 107 // On mobile a user cannot pick where their NetLog file is saved to. | 100 // On mobile a user cannot pick where their NetLog file is saved to. |
| 108 // Instead, everything is saved on the user's temp directory. Thus the | 101 // Instead, everything is saved on the user's temp directory. Thus the |
| 109 // mobile user has the UI available to send their NetLog file as an | 102 // mobile user has the UI available to send their NetLog file as an |
| 110 // email while the desktop user, who gets to chose their NetLog file's | 103 // email while the desktop user, who gets to chose their NetLog file's |
| 111 // location, does not. Furthermore, since every time a user starts logging | 104 // location, does not. Furthermore, since every time a user starts logging |
| 112 // to a new NetLog file on mobile platforms it overwrites the previous | 105 // to a new NetLog file on mobile platforms it overwrites the previous |
| 113 // NetLog file, a warning message appears on the Start Logging button | 106 // NetLog file, a warning message appears on the Start Logging button |
| 114 // that informs the user of this. This does not exist on the desktop | 107 // that informs the user of this. This does not exist on the desktop |
| 115 // UI. | 108 // UI. |
| 116 static bool UsingMobileUI(); | 109 static bool UsingMobileUI(); |
| 117 | 110 |
| 118 // Sets the correct start command and sends this to ProcessNetLogCommand. | 111 // Calls NetExportView.onExportNetLogInfoChanged JavsScript function in the |
|
eroman
2017/01/11 19:18:38
typo: javascript
wangyix1
2017/01/14 02:15:46
Done.
| |
| 119 void StartNetLog(); | 112 // renderer, passing in |file_writer_state|. |
| 120 | 113 void NotifyUIWithNetLogFileWriterState( |
| 121 // Call NetExportView.onExportNetLogInfoChanged JavsScript function in the | 114 std::unique_ptr<base::DictionaryValue> file_writer_state); |
| 122 // renderer, passing in |arg|. Takes ownership of |arg|. | |
| 123 void OnExportNetLogInfoChanged(base::Value* arg); | |
| 124 | 115 |
| 125 // Opens the SelectFileDialog UI with the default path to save a | 116 // Opens the SelectFileDialog UI with the default path to save a |
| 126 // NetLog file. | 117 // NetLog file. |
| 127 void ShowSelectFileDialog(const base::FilePath& default_path); | 118 void ShowSelectFileDialog(const base::FilePath& default_path); |
| 128 | 119 |
| 129 // Cache of g_browser_process->net_log()->net_log_file_writer(). This | 120 // Cache of g_browser_process->net_log()->net_log_file_writer(). This |
| 130 // is owned by ChromeNetLog which is owned by BrowserProcessImpl. There are | 121 // is owned by ChromeNetLog which is owned by BrowserProcessImpl. |
| 131 // four instances in this class where a pointer to net_log_file_writer_ is | |
| 132 // posted to the FILE_USER_BLOCKING thread. Base::Unretained is used here | |
| 133 // because BrowserProcessImpl is destroyed on the UI thread after joining the | |
| 134 // FILE_USER_BLOCKING thread making it impossible for there to be an invalid | |
| 135 // pointer to this object when going back to the UI thread. Furthermore this | |
| 136 // pointer is never dereferenced prematurely on the UI thread. Thus the | |
| 137 // lifetime of this object is assured and can be safely used with | |
| 138 // base::Unretained. | |
| 139 net_log::NetLogFileWriter* net_log_file_writer_; | 122 net_log::NetLogFileWriter* net_log_file_writer_; |
| 140 | 123 |
| 141 std::string log_mode_; | 124 // The capture mode the user chose in the UI when logging started is cached |
| 125 // here and is read after a file path is chosen in the save dialog. | |
| 126 // Its value is only valid when the save dialog is open on the desktop UI. | |
| 127 net::NetLogCaptureMode capture_mode_; | |
| 142 | 128 |
| 143 scoped_refptr<ui::SelectFileDialog> select_file_dialog_; | 129 scoped_refptr<ui::SelectFileDialog> select_file_dialog_; |
| 144 | 130 |
| 145 base::WeakPtrFactory<NetExportMessageHandler> weak_ptr_factory_; | 131 base::WeakPtrFactory<NetExportMessageHandler> weak_ptr_factory_; |
| 146 | 132 |
| 147 DISALLOW_COPY_AND_ASSIGN(NetExportMessageHandler); | 133 DISALLOW_COPY_AND_ASSIGN(NetExportMessageHandler); |
| 148 }; | 134 }; |
| 149 | 135 |
| 150 NetExportMessageHandler::NetExportMessageHandler() | 136 NetExportMessageHandler::NetExportMessageHandler() |
| 151 : net_log_file_writer_(g_browser_process->net_log()->net_log_file_writer()), | 137 : net_log_file_writer_(g_browser_process->net_log()->net_log_file_writer()), |
| 152 weak_ptr_factory_(this) {} | 138 weak_ptr_factory_(this) { |
| 139 net_log_file_writer_->SetTaskRunners( | |
| 140 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE_USER_BLOCKING), | |
| 141 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); | |
| 142 } | |
| 153 | 143 |
| 154 NetExportMessageHandler::~NetExportMessageHandler() { | 144 NetExportMessageHandler::~NetExportMessageHandler() { |
| 155 // There may be a pending file dialog, it needs to be told that the user | 145 // There may be a pending file dialog, it needs to be told that the user |
| 156 // has gone away so that it doesn't try to call back. | 146 // has gone away so that it doesn't try to call back. |
| 157 if (select_file_dialog_.get()) | 147 if (select_file_dialog_.get()) |
| 158 select_file_dialog_->ListenerDestroyed(); | 148 select_file_dialog_->ListenerDestroyed(); |
| 159 | 149 |
| 160 // Cancel any in-progress requests to collect net_log into a file. | 150 net_log_file_writer_->StopNetLog( |
| 161 BrowserThread::PostTask(BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | 151 nullptr, |
| 162 base::Bind(&net_log::NetLogFileWriter::ProcessCommand, | 152 Profile::FromWebUI(web_ui())->GetRequestContext(), |
| 163 base::Unretained(net_log_file_writer_), | 153 base::Bind([](std::unique_ptr<base::DictionaryValue>) {})); |
| 164 net_log::NetLogFileWriter::DO_STOP)); | |
| 165 } | 154 } |
| 166 | 155 |
| 167 void NetExportMessageHandler::RegisterMessages() { | 156 void NetExportMessageHandler::RegisterMessages() { |
| 168 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 157 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 169 | 158 |
| 170 web_ui()->RegisterMessageCallback( | 159 web_ui()->RegisterMessageCallback( |
| 171 net_log::kGetExportNetLogInfoHandler, | 160 net_log::kGetExportNetLogInfoHandler, |
| 172 base::Bind(&NetExportMessageHandler::OnGetExportNetLogInfo, | 161 base::Bind(&NetExportMessageHandler::OnGetExportNetLogInfo, |
| 173 base::Unretained(this))); | 162 base::Unretained(this))); |
| 174 web_ui()->RegisterMessageCallback( | 163 web_ui()->RegisterMessageCallback( |
| 175 net_log::kStartNetLogHandler, | 164 net_log::kStartNetLogHandler, |
| 176 base::Bind(&NetExportMessageHandler::OnStartNetLog, | 165 base::Bind(&NetExportMessageHandler::OnStartNetLog, |
| 177 base::Unretained(this))); | 166 base::Unretained(this))); |
| 178 web_ui()->RegisterMessageCallback( | 167 web_ui()->RegisterMessageCallback( |
| 179 net_log::kStopNetLogHandler, | 168 net_log::kStopNetLogHandler, |
| 180 base::Bind(&NetExportMessageHandler::OnStopNetLog, | 169 base::Bind(&NetExportMessageHandler::OnStopNetLog, |
| 181 base::Unretained(this))); | 170 base::Unretained(this))); |
| 182 web_ui()->RegisterMessageCallback( | 171 web_ui()->RegisterMessageCallback( |
| 183 net_log::kSendNetLogHandler, | 172 net_log::kSendNetLogHandler, |
| 184 base::Bind(&NetExportMessageHandler::OnSendNetLog, | 173 base::Bind(&NetExportMessageHandler::OnSendNetLog, |
| 185 base::Unretained(this))); | 174 base::Unretained(this))); |
| 186 } | 175 } |
| 187 | 176 |
| 188 void NetExportMessageHandler::OnGetExportNetLogInfo( | 177 void NetExportMessageHandler::OnGetExportNetLogInfo( |
| 189 const base::ListValue* list) { | 178 const base::ListValue* list) { |
| 190 BrowserThread::PostTask( | 179 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 191 BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | 180 net_log_file_writer_->GetState( |
| 192 base::Bind(&NetExportMessageHandler::SendExportNetLogInfo, | 181 base::Bind(&NetExportMessageHandler::NotifyUIWithNetLogFileWriterState, |
| 193 weak_ptr_factory_.GetWeakPtr(), net_log_file_writer_)); | 182 weak_ptr_factory_.GetWeakPtr())); |
| 194 } | 183 } |
| 195 | 184 |
| 196 void NetExportMessageHandler::OnStartNetLog(const base::ListValue* list) { | 185 void NetExportMessageHandler::OnStartNetLog(const base::ListValue* list) { |
| 197 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 186 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 198 bool result = list->GetString(0, &log_mode_); | 187 std::string capture_mode_string; |
| 188 bool result = list->GetString(0, &capture_mode_string); | |
| 199 DCHECK(result); | 189 DCHECK(result); |
| 200 | 190 |
| 191 capture_mode_ = | |
| 192 net_log::NetLogFileWriter::CaptureModeFromString(capture_mode_string); | |
| 193 | |
| 201 if (UsingMobileUI()) { | 194 if (UsingMobileUI()) { |
| 202 StartNetLog(); | 195 StartNetLogThenNotifyUI(base::FilePath(), capture_mode_); |
| 203 } else { | 196 } else { |
| 204 base::FilePath initial_dir = last_save_dir.Pointer()->empty() ? | 197 base::FilePath initial_dir = last_save_dir.Pointer()->empty() ? |
| 205 DownloadPrefs::FromBrowserContext( | 198 DownloadPrefs::FromBrowserContext( |
| 206 web_ui()->GetWebContents()->GetBrowserContext())->DownloadPath() : | 199 web_ui()->GetWebContents()->GetBrowserContext())->DownloadPath() : |
| 207 *last_save_dir.Pointer(); | 200 *last_save_dir.Pointer(); |
| 208 base::FilePath initial_path = | 201 base::FilePath initial_path = |
| 209 initial_dir.Append(FILE_PATH_LITERAL("chrome-net-export-log.json")); | 202 initial_dir.Append(FILE_PATH_LITERAL("chrome-net-export-log.json")); |
| 210 ShowSelectFileDialog(initial_path); | 203 ShowSelectFileDialog(initial_path); |
| 211 } | 204 } |
| 212 } | 205 } |
| 213 | 206 |
| 214 void NetExportMessageHandler::OnStopNetLog(const base::ListValue* list) { | 207 void NetExportMessageHandler::OnStopNetLog(const base::ListValue* list) { |
| 215 ProcessNetLogCommand(weak_ptr_factory_.GetWeakPtr(), net_log_file_writer_, | 208 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 216 net_log::NetLogFileWriter::DO_STOP); | 209 StopNetLogThenNotifyUI(); |
| 217 } | 210 } |
| 218 | 211 |
| 219 void NetExportMessageHandler::OnSendNetLog(const base::ListValue* list) { | 212 void NetExportMessageHandler::OnSendNetLog(const base::ListValue* list) { |
| 220 content::BrowserThread::PostTaskAndReplyWithResult( | 213 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 221 content::BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | 214 net_log_file_writer_->GetFilePath( |
| 222 base::Bind(&NetExportMessageHandler::GetNetLogFileName, | |
| 223 base::Unretained(net_log_file_writer_)), | |
| 224 base::Bind(&NetExportMessageHandler::SendEmail)); | 215 base::Bind(&NetExportMessageHandler::SendEmail)); |
| 225 } | 216 } |
| 226 | 217 |
| 227 void NetExportMessageHandler::StartNetLog() { | 218 void NetExportMessageHandler::StartNetLogThenNotifyUI( |
| 228 net_log::NetLogFileWriter::Command command; | 219 const base::FilePath& log_path, |
| 229 if (log_mode_ == "LOG_BYTES") { | 220 net::NetLogCaptureMode capture_mode) { |
| 230 command = net_log::NetLogFileWriter::DO_START_LOG_BYTES; | 221 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 231 } else if (log_mode_ == "NORMAL") { | |
| 232 command = net_log::NetLogFileWriter::DO_START; | |
| 233 } else { | |
| 234 DCHECK_EQ("STRIP_PRIVATE_DATA", log_mode_); | |
| 235 command = net_log::NetLogFileWriter::DO_START_STRIP_PRIVATE_DATA; | |
| 236 } | |
| 237 | 222 |
| 238 ProcessNetLogCommand(weak_ptr_factory_.GetWeakPtr(), net_log_file_writer_, | 223 net_log_file_writer_->StartNetLog(log_path, capture_mode, |
| 239 command); | 224 base::Bind(&NetExportMessageHandler::NotifyUIWithNetLogFileWriterState, |
| 225 weak_ptr_factory_.GetWeakPtr())); | |
| 226 } | |
| 227 | |
| 228 void NetExportMessageHandler::StopNetLogThenNotifyUI() { | |
| 229 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 230 | |
| 231 std::unique_ptr<base::DictionaryValue> polled_data; | |
|
eroman
2017/01/11 19:18:38
[optional] I suggest renaming this something like:
wangyix1
2017/01/14 02:15:46
Done.
| |
| 232 | |
| 233 // TODO(crbug.com/438656): fill polled_data with browser-specific polled data. | |
| 234 | |
| 235 net_log_file_writer_->StopNetLog( | |
| 236 std::move(polled_data), | |
| 237 Profile::FromWebUI(web_ui())->GetRequestContext(), | |
| 238 base::Bind(&NetExportMessageHandler::NotifyUIWithNetLogFileWriterState, | |
| 239 weak_ptr_factory_.GetWeakPtr())); | |
| 240 } | 240 } |
| 241 | 241 |
| 242 // static | 242 // static |
| 243 void NetExportMessageHandler::ProcessNetLogCommand( | |
| 244 base::WeakPtr<NetExportMessageHandler> net_export_message_handler, | |
| 245 net_log::NetLogFileWriter* net_log_file_writer, | |
| 246 net_log::NetLogFileWriter::Command command) { | |
| 247 if (!BrowserThread::CurrentlyOn(BrowserThread::FILE_USER_BLOCKING)) { | |
| 248 BrowserThread::PostTask( | |
| 249 BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | |
| 250 base::Bind(&NetExportMessageHandler::ProcessNetLogCommand, | |
| 251 net_export_message_handler, net_log_file_writer, command)); | |
| 252 return; | |
| 253 } | |
| 254 | |
| 255 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING); | |
| 256 net_log_file_writer->ProcessCommand(command); | |
| 257 SendExportNetLogInfo(net_export_message_handler, net_log_file_writer); | |
| 258 } | |
| 259 | |
| 260 // static | |
| 261 base::FilePath NetExportMessageHandler::GetNetLogFileName( | |
| 262 net_log::NetLogFileWriter* net_log_file_writer) { | |
| 263 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING); | |
| 264 base::FilePath net_export_file_path; | |
| 265 net_log_file_writer->GetFilePath(&net_export_file_path); | |
| 266 return net_export_file_path; | |
| 267 } | |
| 268 | |
| 269 // static | |
| 270 void NetExportMessageHandler::SendExportNetLogInfo( | |
| 271 base::WeakPtr<NetExportMessageHandler> net_export_message_handler, | |
| 272 net_log::NetLogFileWriter* net_log_file_writer) { | |
| 273 DCHECK_CURRENTLY_ON(BrowserThread::FILE_USER_BLOCKING); | |
| 274 base::DictionaryValue* dict = net_log_file_writer->GetState(); | |
| 275 dict->SetBoolean("useMobileUI", UsingMobileUI()); | |
| 276 base::Value* value = dict; | |
| 277 if (!BrowserThread::PostTask( | |
| 278 BrowserThread::UI, FROM_HERE, | |
| 279 base::Bind(&NetExportMessageHandler::OnExportNetLogInfoChanged, | |
| 280 net_export_message_handler, | |
| 281 value))) { | |
| 282 // Failed posting the task, avoid leaking. | |
| 283 delete value; | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 // static | |
| 288 void NetExportMessageHandler::SendEmail(const base::FilePath& file_to_send) { | 243 void NetExportMessageHandler::SendEmail(const base::FilePath& file_to_send) { |
| 289 if (file_to_send.empty()) | 244 if (file_to_send.empty()) |
| 290 return; | 245 return; |
| 291 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 246 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 292 | 247 |
| 293 #if BUILDFLAG(ANDROID_JAVA_UI) | 248 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 294 std::string email; | 249 std::string email; |
| 295 std::string subject = "net_internals_log"; | 250 std::string subject = "net_internals_log"; |
| 296 std::string title = "Issue number: "; | 251 std::string title = "Issue number: "; |
| 297 std::string body = | 252 std::string body = |
| 298 "Please add some informative text about the network issues."; | 253 "Please add some informative text about the network issues."; |
| 299 base::FilePath::StringType file_to_attach(file_to_send.value()); | 254 base::FilePath::StringType file_to_attach(file_to_send.value()); |
| 300 chrome::android::SendEmail( | 255 chrome::android::SendEmail( |
| 301 base::UTF8ToUTF16(email), base::UTF8ToUTF16(subject), | 256 base::UTF8ToUTF16(email), base::UTF8ToUTF16(subject), |
| 302 base::UTF8ToUTF16(body), base::UTF8ToUTF16(title), | 257 base::UTF8ToUTF16(body), base::UTF8ToUTF16(title), |
| 303 base::UTF8ToUTF16(file_to_attach)); | 258 base::UTF8ToUTF16(file_to_attach)); |
| 304 #endif | 259 #endif |
| 305 } | 260 } |
| 306 | 261 |
| 307 // static | 262 // static |
| 308 bool NetExportMessageHandler::UsingMobileUI() { | 263 bool NetExportMessageHandler::UsingMobileUI() { |
| 309 #if defined(OS_ANDROID) || defined(OS_IOS) | 264 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 310 return true; | 265 return true; |
| 311 #else | 266 #else |
| 312 return false; | 267 return false; |
| 313 #endif | 268 #endif |
| 314 } | 269 } |
| 315 | 270 |
| 316 void NetExportMessageHandler::OnExportNetLogInfoChanged(base::Value* arg) { | 271 void NetExportMessageHandler::NotifyUIWithNetLogFileWriterState( |
| 317 std::unique_ptr<base::Value> value(arg); | 272 std::unique_ptr<base::DictionaryValue> file_writer_state) { |
| 318 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 273 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 274 file_writer_state->SetBoolean("useMobileUI", UsingMobileUI()); | |
| 319 web_ui()->CallJavascriptFunctionUnsafe(net_log::kOnExportNetLogInfoChanged, | 275 web_ui()->CallJavascriptFunctionUnsafe(net_log::kOnExportNetLogInfoChanged, |
| 320 *arg); | 276 *file_writer_state); |
| 321 } | 277 } |
| 322 | 278 |
| 323 void NetExportMessageHandler::ShowSelectFileDialog( | 279 void NetExportMessageHandler::ShowSelectFileDialog( |
| 324 const base::FilePath& default_path) { | 280 const base::FilePath& default_path) { |
| 325 // User may have clicked more than once before the save dialog appears. | 281 // User may have clicked more than once before the save dialog appears. |
| 326 // This prevents creating more than one save dialog. | 282 // This prevents creating more than one save dialog. |
| 327 if (select_file_dialog_) | 283 if (select_file_dialog_) |
| 328 return; | 284 return; |
| 329 | 285 |
| 330 WebContents* webcontents = web_ui()->GetWebContents(); | 286 WebContents* webcontents = web_ui()->GetWebContents(); |
| 331 | 287 |
| 332 select_file_dialog_ = ui::SelectFileDialog::Create( | 288 select_file_dialog_ = ui::SelectFileDialog::Create( |
| 333 this, new ChromeSelectFilePolicy(webcontents)); | 289 this, new ChromeSelectFilePolicy(webcontents)); |
| 334 ui::SelectFileDialog::FileTypeInfo file_type_info; | 290 ui::SelectFileDialog::FileTypeInfo file_type_info; |
| 335 file_type_info.extensions = {{FILE_PATH_LITERAL("json")}}; | 291 file_type_info.extensions = {{FILE_PATH_LITERAL("json")}}; |
| 336 gfx::NativeWindow owning_window = webcontents->GetTopLevelNativeWindow(); | 292 gfx::NativeWindow owning_window = webcontents->GetTopLevelNativeWindow(); |
| 337 select_file_dialog_->SelectFile( | 293 select_file_dialog_->SelectFile( |
| 338 ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(), default_path, | 294 ui::SelectFileDialog::SELECT_SAVEAS_FILE, base::string16(), default_path, |
| 339 &file_type_info, 0, base::FilePath::StringType(), owning_window, nullptr); | 295 &file_type_info, 0, base::FilePath::StringType(), owning_window, nullptr); |
| 340 } | 296 } |
| 341 | 297 |
| 342 void NetExportMessageHandler::FileSelected(const base::FilePath& path, | 298 void NetExportMessageHandler::FileSelected(const base::FilePath& path, |
| 343 int index, | 299 int index, |
| 344 void* params) { | 300 void* params) { |
| 345 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 301 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 346 DCHECK(select_file_dialog_); | 302 DCHECK(select_file_dialog_); |
| 347 select_file_dialog_ = nullptr; | 303 select_file_dialog_ = nullptr; |
| 304 *last_save_dir.Pointer() = path.DirName(); | |
| 348 | 305 |
| 349 *last_save_dir.Pointer() = path.DirName(); | 306 StartNetLogThenNotifyUI(path, capture_mode_); |
| 350 BrowserThread::PostTaskAndReply( | |
| 351 BrowserThread::FILE_USER_BLOCKING, FROM_HERE, | |
| 352 base::Bind(&net_log::NetLogFileWriter::SetUpNetExportLogPath, | |
| 353 base::Unretained(net_log_file_writer_), path), | |
| 354 // NetExportMessageHandler is tied to the lifetime of the tab | |
| 355 // so it cannot be assured that it will be valid when this | |
| 356 // StartNetLog is called. Instead of using base::Unretained a | |
| 357 // weak pointer is used to adjust for this. | |
| 358 base::Bind(&NetExportMessageHandler::StartNetLog, | |
| 359 weak_ptr_factory_.GetWeakPtr())); | |
| 360 } | 307 } |
| 361 | 308 |
| 362 void NetExportMessageHandler::FileSelectionCanceled(void* params) { | 309 void NetExportMessageHandler::FileSelectionCanceled(void* params) { |
| 363 DCHECK(select_file_dialog_); | 310 DCHECK(select_file_dialog_); |
| 364 select_file_dialog_ = nullptr; | 311 select_file_dialog_ = nullptr; |
| 365 } | 312 } |
| 366 | 313 |
| 367 } // namespace | 314 } // namespace |
| 368 | 315 |
| 369 NetExportUI::NetExportUI(content::WebUI* web_ui) : WebUIController(web_ui) { | 316 NetExportUI::NetExportUI(content::WebUI* web_ui) : WebUIController(web_ui) { |
| 370 web_ui->AddMessageHandler(new NetExportMessageHandler()); | 317 web_ui->AddMessageHandler(new NetExportMessageHandler()); |
| 371 | 318 |
| 372 // Set up the chrome://net-export/ source. | 319 // Set up the chrome://net-export/ source. |
| 373 Profile* profile = Profile::FromWebUI(web_ui); | 320 Profile* profile = Profile::FromWebUI(web_ui); |
| 374 content::WebUIDataSource::Add(profile, CreateNetExportHTMLSource()); | 321 content::WebUIDataSource::Add(profile, CreateNetExportHTMLSource()); |
| 375 } | 322 } |
| OLD | NEW |