Commit e80104fb authored by Steven Bennetts's avatar Steven Bennetts Committed by Commit Bot

CrOS: chrome://network: Add network-logs-ui

This CL moves storing of crOS system logs from chrome://net-internals
(which is deprecated) to chrome://network.

This also re-factors the UI code as a separate handler that supports
multiple options, instead of disparate function calls doing similar
tasks. See the issue for screenshots.

      debugging logs are exported to the Downloads directory.

Bug: 921726
Test: Export logs with each set of options and ensure that the correct
Change-Id: I2ddbbc936edc7251cda0e69a9faf6289d3794ef2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2258894Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Reviewed-by: default avatarEric Roman <eroman@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Commit-Queue: Steven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781978}
parent 0cd49d1a
......@@ -3411,6 +3411,9 @@
<message name="IDS_NETWORK_UI_TAB_NETWORK_HEALTH" desc="Network health tab name">
Network Health
</message>
<message name="IDS_NETWORK_UI_TAB_NETWORK_LOGS" desc="Network logs tab name">
Network Logs
</message>
<message name="IDS_NETWORK_UI_TAB_NETWORK_STATE" desc="Network state tab name">
Network State
</message>
......@@ -3480,9 +3483,36 @@
<message name="IDS_NETWORK_UI_IMPORT_ONC_BUTTON_TEXT" desc="Text for button which, when pressed, selects and imports an ONC file for network configuration.">
Import ONC File
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_DESCRIPTION" desc="Text describing the section for storing network logs in the chrome://network debugging UI.">
Store system logs to the Downloads directory.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_SYSTEM_LOGS" desc="Text describing the checkbox option for storing the system logs file sent in feedback reports.">
Include the system_logs.txt file sent in feedback reports.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_FILTER_PII" desc="Text describing the checkbox option for striping personally identifiable information from the system logs.">
Strip Personally Identifiable Information from system_logs.txt.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_POLICIES" desc="Text describing the checkbox option for storing the policies.json file.">
Include a policies.json file with policy configurations.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_DEBUG_LOGS" desc="Text describing the checkbox option for storing the debugd logs files.">
Include all log files collected by debugd as a separate archive.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_CHROME_LOGS" desc="Text describing the checkbox option for including the chrome logs in the stored logs file.">
Include Chrome log files in the archive.
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_STORE_BUTTON" desc="Text displayed on the button for storing system logs.">
Store system logs
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_STATUS" desc="Message displayed while storing logs.">
Generating log files...
</message>
<message name="IDS_NETWORK_UI_NETWORK_LOGS_SUCCESS" desc="Message displayed when system logs are successfully written.">
Logs successfully written to Downloads directory.
</message>
<message name="IDS_DEVICE_LOG_LINK_TEXT" desc="Message preceeding link to chrome://device-log">
For network logs, see: <ph name="DEVICE_LOG_LINK">&lt;a href="chrome://device-log"&gt;chrome://device-log&lt;/a&gt;</ph>
To view network UI logs, see: <ph name="DEVICE_LOG_LINK">&lt;a href="chrome://device-log"&gt;chrome://device-log&lt;/a&gt;</ph>
</message>
<!-- Network Health display strings -->
......
......@@ -336,6 +336,8 @@
<include name="IDR_NETWORK_UI_JS" file="resources\chromeos\network_ui\network_ui.js" type="BINDATA" />
<include name="IDR_NETWORK_STATE_UI_HTML" file="resources\chromeos\network_ui\network_state_ui.html" type="BINDATA" />
<include name="IDR_NETWORK_STATE_UI_JS" file="resources\chromeos\network_ui\network_state_ui.js" type="BINDATA" />
<include name="IDR_NETWORK_LOGS_UI_HTML" file="resources\chromeos\network_ui\network_logs_ui.html" type="BINDATA" />
<include name="IDR_NETWORK_LOGS_UI_JS" file="resources\chromeos\network_ui\network_logs_ui.js" type="BINDATA" />
</if>
<if expr="_google_chrome">
<include name="IDR_PREF_HASH_SEED_BIN" file="resources\settings_internal\pref_hash_seed.bin" type="BINDATA" />
......
......@@ -25,9 +25,13 @@
#include "content/public/browser/browser_thread.h"
namespace chromeos {
namespace debug_log_writer {
namespace {
using StoreLogsCallback =
base::OnceCallback<void(base::Optional<base::FilePath> log_path)>;
// Callback for returning status of executed external command.
typedef base::OnceCallback<void(bool succeeded)> CommandCompletionCallback;
......@@ -44,31 +48,30 @@ base::LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner =
// descriptor, deletes log file in the case of failure and calls
// |callback|.
void WriteDebugLogToFileCompleted(const base::FilePath& file_path,
DebugLogWriter::StoreLogsCallback callback,
StoreLogsCallback callback,
bool succeeded) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!succeeded) {
bool posted = g_sequenced_task_runner.Get()->PostTaskAndReply(
FROM_HERE, base::BindOnce(base::GetDeleteFileCallback(), file_path),
base::BindOnce(std::move(callback), file_path, false));
base::BindOnce(std::move(callback), base::nullopt));
DCHECK(posted);
return;
}
if (!callback.is_null())
std::move(callback).Run(file_path, true);
std::move(callback).Run(file_path);
}
// Stores into |file_path| debug logs in the .tgz format. Calls
// |callback| upon completion.
// Stores debug logs into |file_path| as a tar file. Invokes |callback| upon
// completion.
void WriteDebugLogToFile(std::unique_ptr<base::File> file,
const base::FilePath& file_path,
bool should_compress,
DebugLogWriter::StoreLogsCallback callback) {
StoreLogsCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (!file->IsValid()) {
LOG(ERROR) << "Can't create debug log file: " << file_path.AsUTF8Unsafe()
<< ", "
<< "error: " << file->error_details();
<< ", error: " << file->error_details();
return;
}
chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->DumpDebugLogs(
......@@ -110,33 +113,30 @@ void RunCommand(const std::vector<std::string>& argv,
// the final outcome of log retreival process at via |callback|.
void OnCompressArchiveCompleted(const base::FilePath& tar_file_path,
const base::FilePath& compressed_output_path,
DebugLogWriter::StoreLogsCallback callback,
StoreLogsCallback callback,
bool compression_command_success) {
if (!compression_command_success) {
LOG(ERROR) << "Failed compressing " << compressed_output_path.value();
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), base::FilePath(), false));
FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
base::DeleteFile(tar_file_path, false);
base::DeleteFile(compressed_output_path, false);
return;
}
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), compressed_output_path, true));
FROM_HERE, base::BindOnce(std::move(callback), compressed_output_path));
}
// Gzips |tar_file_path| and stores results in |compressed_output_path|.
void CompressArchive(const base::FilePath& tar_file_path,
const base::FilePath& compressed_output_path,
DebugLogWriter::StoreLogsCallback callback,
StoreLogsCallback callback,
bool add_user_logs_command_success) {
if (!add_user_logs_command_success) {
LOG(ERROR) << "Failed adding user logs to " << tar_file_path.value();
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), base::FilePath(), false));
FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
base::DeleteFile(tar_file_path, false);
return;
}
......@@ -153,37 +153,34 @@ void CompressArchive(const base::FilePath& tar_file_path,
// produce |compressed_output_path|.
void AddUserLogsToArchive(const base::FilePath& user_log_dir,
const base::FilePath& tar_file_path,
const base::FilePath& compressed_output_path,
DebugLogWriter::StoreLogsCallback callback) {
StoreLogsCallback callback) {
std::vector<std::string> argv;
argv.push_back(kTarCommand);
argv.push_back("-rvf");
argv.push_back(tar_file_path.value());
argv.push_back(user_log_dir.value());
base::FilePath compressed_output_path =
tar_file_path.AddExtension(FILE_PATH_LITERAL(".gz"));
RunCommand(argv, base::BindOnce(&CompressArchive, tar_file_path,
compressed_output_path, std::move(callback)));
}
// Appends user logs after system logs are archived into |tar_file_path|.
void OnSystemLogsAdded(DebugLogWriter::StoreLogsCallback callback,
const base::FilePath& tar_file_path,
bool succeeded) {
if (!succeeded) {
void OnSystemLogsAdded(StoreLogsCallback callback,
base::Optional<base::FilePath> tar_file_path) {
if (!tar_file_path) {
if (!callback.is_null())
std::move(callback).Run(base::FilePath(), false);
std::move(callback).Run(base::nullopt);
return;
}
base::FilePath compressed_output_path =
tar_file_path.AddExtension(FILE_PATH_LITERAL(".gz"));
base::FilePath user_log_dir =
logging::GetSessionLogDir(*base::CommandLine::ForCurrentProcess());
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&AddUserLogsToArchive, user_log_dir, tar_file_path,
compressed_output_path, std::move(callback)));
base::BindOnce(&AddUserLogsToArchive, user_log_dir, *tar_file_path,
std::move(callback)));
}
void InitializeLogFile(base::File* file,
......@@ -204,7 +201,7 @@ void InitializeLogFile(base::File* file,
// derived from |file_name_template|.
void StartLogRetrieval(const base::FilePath& file_name_template,
bool should_compress,
DebugLogWriter::StoreLogsCallback callback) {
StoreLogsCallback callback) {
base::FilePath file_path =
logging::GenerateTimestampedName(file_name_template, base::Time::Now());
......@@ -222,31 +219,26 @@ void StartLogRetrieval(const base::FilePath& file_name_template,
} // namespace
// static.
void DebugLogWriter::StoreLogs(const base::FilePath& fileshelf,
bool should_compress,
StoreLogsCallback callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!callback.is_null());
base::FilePath file_path =
fileshelf.Append(should_compress ? FILE_PATH_LITERAL("debug-logs.tgz")
: FILE_PATH_LITERAL("debug-logs.tar"));
StartLogRetrieval(file_path, should_compress, std::move(callback));
}
// static.
void DebugLogWriter::StoreCombinedLogs(const base::FilePath& fileshelf,
StoreLogsCallback callback) {
void StoreLogs(
const base::FilePath& out_dir,
bool include_chrome_logs,
base::OnceCallback<void(base::Optional<base::FilePath> logs_path)>
callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!callback.is_null());
base::FilePath file_path =
fileshelf.Append(FILE_PATH_LITERAL("combined-logs.tar"));
// Get system logs from /var/log first, then add user-specific stuff.
StartLogRetrieval(file_path, false,
base::BindOnce(&OnSystemLogsAdded, std::move(callback)));
if (include_chrome_logs) {
base::FilePath file_path =
out_dir.Append(FILE_PATH_LITERAL("combined-logs.tar"));
// Get system logs from /var/log first, then add user-specific stuff.
StartLogRetrieval(file_path, /*should_compress=*/false,
base::BindOnce(&OnSystemLogsAdded, std::move(callback)));
} else {
base::FilePath file_path =
out_dir.Append(FILE_PATH_LITERAL("debug-logs.tgz"));
StartLogRetrieval(file_path, /*should_compress=*/true, std::move(callback));
}
}
} // namespace debug_log_writer
} // namespace chromeos
......@@ -8,39 +8,22 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/optional.h"
namespace chromeos {
// Class for writing logs collected from debugd to a specified location. Also
// supports writing the Chrome user log. Currently used by
// chrome://net-internals#chromeos.
class DebugLogWriter {
public:
// Called once StoreDebugLogs is complete. Takes two parameters:
// - log_path: where the log file was saved in the case of success;
// - succeeded: was the log file saved successfully.
typedef base::OnceCallback<void(const base::FilePath& log_path,
bool succeeded)>
StoreLogsCallback;
// Stores debug logs in either .tgz or .tar archive (depending on value of
// |should_compress|) on the |fileshelf|. The file is created on the
// worker pool, then writing to it is triggered from the UI thread, and
// finally it is closed (on success) or deleted (on failure) on the worker
// pool, prior to calling |callback|.
static void StoreLogs(const base::FilePath& fileshelf,
bool should_compress,
StoreLogsCallback callback);
// Stores both system and user logs in .tgz archive on the |fileshelf|.
static void StoreCombinedLogs(const base::FilePath& fileshelf,
StoreLogsCallback callback);
private:
DebugLogWriter();
DISALLOW_COPY_AND_ASSIGN(DebugLogWriter);
};
namespace debug_log_writer {
// Stores debug logs collected from debugd as a .tgz archive to |out_dir|.
// If |include_chrome_logs| is true, the Chrome user logs are included.
// |callback| is invoked on success with the full file path of the archive,
// or with nullopt on failure.
void StoreLogs(
const base::FilePath& out_dir,
bool include_chrome_logs,
base::OnceCallback<void(base::Optional<base::FilePath> logs_path)>
callback);
} // namespace debug_log_writer
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_LOGS_DEBUG_LOG_WRITER_H_
......@@ -74,9 +74,10 @@ namespace system_logs_writer {
void WriteSystemLogs(
const base::FilePath& dest_dir,
bool scrub_data,
base::OnceCallback<void(base::Optional<base::FilePath>)> callback) {
system_logs::BuildChromeSystemLogsFetcher()->Fetch(
base::BindOnce(FetchCompleted, dest_dir, std::move(callback)));
system_logs::BuildChromeSystemLogsFetcher(scrub_data)
->Fetch(base::BindOnce(FetchCompleted, dest_dir, std::move(callback)));
}
} // namespace system_logs_writer
......
......@@ -17,10 +17,12 @@ namespace chromeos {
namespace system_logs_writer {
// Writes system_logs.txt.zip to |dest_dir|, containing the contents from
// Feedback reports. Runs |callback| on completion with the complete file path
// on success, or nullopt on failure.
// Feedback reports. If |scrub_data| is true then the logs are scrubbed of PII.
// Runs |callback| on completion with the complete file path on success, or
// nullopt on failure.
void WriteSystemLogs(
const base::FilePath& dest_dir,
bool scrub_data,
base::OnceCallback<void(base::Optional<base::FilePath>)> callback);
} // namespace system_logs_writer
......
......@@ -118,7 +118,7 @@ ChromeFeedbackPrivateDelegate::GetStrings(
system_logs::SystemLogsFetcher*
ChromeFeedbackPrivateDelegate::CreateSystemLogsFetcher(
content::BrowserContext* context) const {
return system_logs::BuildChromeSystemLogsFetcher();
return system_logs::BuildChromeSystemLogsFetcher(/*scrub_data=*/true);
}
#if defined(OS_CHROMEOS)
......
......@@ -61,7 +61,7 @@ void SendSysLogFeedback(Profile* profile,
bool send_tab_titles) {
// |fetcher| deletes itself after calling its callback.
system_logs::SystemLogsFetcher* fetcher =
system_logs::BuildChromeSystemLogsFetcher();
system_logs::BuildChromeSystemLogsFetcher(/*scrub_data=*/true);
fetcher->Fetch(base::BindOnce(&OnGetSystemInformation, profile, description,
callback, send_tab_titles));
}
......
......@@ -26,8 +26,7 @@
namespace system_logs {
SystemLogsFetcher* BuildChromeSystemLogsFetcher() {
const bool scrub_data = true;
SystemLogsFetcher* BuildChromeSystemLogsFetcher(bool scrub_data) {
SystemLogsFetcher* fetcher = new SystemLogsFetcher(
scrub_data, extension_misc::kBuiltInFirstPartyExtensionIds);
......
......@@ -10,8 +10,9 @@ namespace system_logs {
class SystemLogsFetcher;
// Creates a SystemLogsFetcher to aggregate the scrubbed logs for sending with
// feedback reports. The fetcher deletes itself once it finishes fetching data.
SystemLogsFetcher* BuildChromeSystemLogsFetcher();
// feedback reports. If |scrub_data| is true then the logs are scrubbed of PII.
// The fetcher deletes itself once it finishes fetching data.
SystemLogsFetcher* BuildChromeSystemLogsFetcher(bool scrub_data);
} // namespace system_logs
......
......@@ -6,6 +6,7 @@ import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [
":network_logs_ui",
":network_state_ui",
":network_ui",
]
......@@ -22,6 +23,10 @@ js_library("network_ui") {
]
}
js_library("network_logs_ui") {
deps = [ "//ui/webui/resources/js:i18n_behavior" ]
}
js_library("network_state_ui") {
deps = [
"//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile",
......
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="chrome://resources/cr_elements/cr_checkbox/cr_checkbox.html">
<link rel="import" href="chrome://resources/cr_elements/shared_style_css.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<dom-module id="network-logs-ui">
<template>
<style include="cr-shared-style">
cr-button,
cr-checkbox {
margin: 5px 0;
}
.error {
color: red;
}
.indented {
margin-inline-start: 10px;
}
#storeResult {
margin: 10px 0;
white-space: pre-wrap;
}
</style>
<div>
<h2>$i18n{networkLogsTab}</h2>
<p>$i18n{networkLogsDescription}</p>
<span>$i18nRaw{deviceLogLinkText}</span>
<h3>Options</h3>
<div class="indented">
<cr-checkbox checked="{{systemLogs_}}">
$i18n{networkLogsSystemLogs}
</cr-checkbox>
<div class="indented">
<cr-checkbox class="indented" checked="{{filterPII_}}"
disabled="[[!systemLogs_]]">
$i18n{networkLogsFilterPii}
</cr-checkbox>
</div>
<cr-checkbox checked="{{policies_}}">
$i18n{networkLogsPolicies}
</cr-checkbox>
<cr-checkbox checked="{{debugLogs_}}">
$i18n{networkLogsDebugLogs}
</cr-checkbox>
<div class="indented">
<cr-checkbox checked="{{chromeLogs_}}" class="indented"
disabled="[[!debugLogs_]]">
$i18n{networkLogsChromeLogs}
</cr-checkbox>
</div>
</div>
<cr-button on-click="onStore_"
disabled="[[!validOptions_(systemLogs_, policies_, debugLogs_)]]">
$i18n{networkLogsStoreButton}
</cr-button>
<div id="storeResult"></div>
</template>
<script src="network_logs_ui.js"></script>
</dom-module>
// Copyright 2020 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.
/**
* @fileoverview
* Polymer element for UI controlling the storing of system logs.
*/
Polymer({
is: 'network-logs-ui',
behaviors: [I18nBehavior],
properties: {
/**
* Whether to store the system_logs file sent with Feedback reports.
* @private
*/
systemLogs_: {
type: Boolean,
value: true,
},
/**
* Whether to filter PII in the system_logs file.
* @private
*/
filterPII_: {
type: Boolean,
value: true,
},
/**
* Whether to store the zipped debugd log files.
* @private
*/
debugLogs_: {
type: Boolean,
value: false,
},
/**
* Whether to store the chrome logs with the zipped log files.
* @private
*/
chromeLogs_: {
type: Boolean,
value: false,
},
/**
* Whether to store the policies .json file.
* @private
*/
policies_: {
type: Boolean,
value: false,
},
},
/** @override */
attached() {},
/* @private */
validOptions_() {
return this.systemLogs_ || this.policies_ || this.debugLogs_;
},
/* @private */
onStore_() {
const options = {
systemLogs: this.systemLogs_,
filterPII: this.filterPII_,
debugLogs: this.debugLogs_,
chromeLogs: this.chromeLogs_,
policies: this.policies_,
};
this.$.storeResult.innerText = this.i18n('networkLogsStatus');
this.$.storeResult.classList.toggle('error', false);
cr.sendWithPromise('storeLogs', options).then((response) => {
const result = response.shift();
const isError = response.shift();
this.$.storeResult.innerText = result;
this.$.storeResult.classList.toggle('error', isError);
});
},
});
......@@ -13,6 +13,7 @@
<link rel="import" href="chrome://resources/cr_components/chromeos/network_health/network_health_summary.html">
<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
<link rel="import" href="network_state_ui.html">
<link rel="import" href="network_logs_ui.html">
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/cr/ui.js"></script>
......@@ -57,14 +58,13 @@
<tabs>
<tab>$i18n{generalTab}</tab>
<tab>$i18n{networkHealthTab}</tab>
<tab>$i18n{networkLogsTab}</tab>
<tab>$i18n{networkStateTab}</tab>
<tab>$i18n{networkSelectTab}</tab>
</tabs>
<tabpanels>
<tabpanel id="general">
<h2>$i18n{titleText}</h2>
<span>$i18nRaw{deviceLogLinkText}</span>
<div>
<h2>$i18n{globalPolicyLabel}</h2>
<div id="global-policy"></div>
......@@ -99,6 +99,10 @@
<network-health-summary></network-health-summary>
</tabpanel>
<tabpanel id="logs">
<network-logs-ui></network-logs-ui>
</tabpanel>
<tabpanel id="state">
<network-state-ui></network-state-ui>
</tabpanel>
......
......@@ -69,7 +69,7 @@ cr.define('network_ui', function() {
const importONCResponse = function(args) {
const result = args.shift();
const isError = args.shift();
$('onc-import-result').innerHTML = result;
$('onc-import-result').innerText = result;
if (isError) {
$('onc-import-result').classList.add('error');
} else {
......
......@@ -18,7 +18,6 @@ const BrowserBridge = (function() {
// List of observers for various bits of browser state.
this.hstsObservers_ = [];
this.expectCTObservers_ = [];
this.storeDebugLogsObservers_ = [];
this.setNetworkDebugModeObservers_ = [];
}
......@@ -88,18 +87,6 @@ const BrowserBridge = (function() {
this.send('flushSocketPools');
},
storeDebugLogs() {
this.send('storeDebugLogs');
},
storeCombinedDebugLogs() {
this.send('storeCombinedDebugLogs');
},
storeFeedbackSystemLogs() {
this.send('storeFeedbackSystemLogs');
},
setNetworkDebugMode(subsystem) {
this.send('setNetworkDebugMode', [subsystem]);
},
......@@ -130,24 +117,6 @@ const BrowserBridge = (function() {
}
},
receivedStoreDebugLogs(status) {
for (let i = 0; i < this.storeDebugLogsObservers_.length; i++) {
this.storeDebugLogsObservers_[i].onStoreDebugLogs(status);
}
},
receivedStoreCombinedDebugLogs(status) {
for (let i = 0; i < this.storeDebugLogsObservers_.length; i++) {
this.storeDebugLogsObservers_[i].onStoreCombinedDebugLogs(status);
}
},
receivedStoreFeedbackSystemLogs(status) {
for (let i = 0; i < this.storeDebugLogsObservers_.length; i++) {
this.storeDebugLogsObservers_[i].onStoreFeedbackSystemLogs(status);
}
},
receivedSetNetworkDebugMode(status) {
for (let i = 0; i < this.setNetworkDebugModeObservers_.length; i++) {
this.setNetworkDebugModeObservers_[i].onSetNetworkDebugMode(status);
......@@ -176,17 +145,6 @@ const BrowserBridge = (function() {
this.expectCTObservers_.push(observer);
},
/**
* Adds a listener for storing log file status. The observer will be called
* back with:
*
* observer.onStoreDebugLogs(status);
* observer.onStoreCombinedDebugLogs(status);
*/
addStoreDebugLogsObserver(observer) {
this.storeDebugLogsObservers_.push(observer);
},
/**
* Adds a listener for network debugging mode status. The observer
* will be called back with:
......
......@@ -4,43 +4,13 @@
Import ONC File has moved to
<a href="chrome://network#general">chrome://network#general</a>.
</div>
<div id="chromeos-view-store-debug-logs-div">
<h4>Store system logs</h4>
<div>
<p>This stores system_logs_{date}-{time}.txt.zip to the Downloads
directory. The archive contains a single file identical to the
system_logs file attached to Feedback reports.</p>
<p>Also writes a policies_{date}-{time}.json file for providing policy
configurations when that might be a factor.</p>
<p>Prefer this when uploading logs to issues or sending logs to developers
(unless otherwise requested).</p>
<input type="button"
id="chromeos-view-store-feedback-system-logs"
value="Store Feedback Report System Logs">
<label id="chromeos-view-store-feedback-system-logs-status"></label>
</div>
<h4>Store debugd system logs</h4>
<div>
<p>This stores the logs collected by debugd as individual files in a
single archive file in the Downloads directory:
debug-logs_{date}-{time}.tgz.
</p>
<p>Also writes a policies_{date}-{time}.json file for providing policy
configurations when that might be a factor.</p>
<input type="button"
id="chromeos-view-store-debug-logs"
value="Store System Logs">
<label id="chromeos-view-store-debug-logs-status"></label>
</div>
<div>
<p>Identical to the above, but also incldes the Chrome user logs.
The output file is named combined-logs_{date}-{time}.tgz.</p>
<input type="button"
id="chromeos-view-store-combined-debug-logs"
value="Store System and User Logs">
<label id="chromeos-view-store-combined-debug-logs-status"></label>
</div>
<h4>Store system logs</h4>
<div>
Store system logs has moved to
<a href="chrome://network#logs">chrome://network#logs</a>.
</div>
<div id="chromeos-view-network-debugging-div">
<h4>Network Debugging</h4>
<dl>
......
......@@ -8,34 +8,6 @@
const CrosView = (function() {
'use strict';
/**
* Set storing debug logs status.
*
* @private
*/
function setStoreDebugLogsStatus_(status) {
$(CrosView.STORE_DEBUG_LOGS_STATUS_ID).innerText = status;
}
/**
* Set storing combined debug logs status.
*
* @private
*/
function setStoreCombinedDebugLogsStatus_(status) {
$(CrosView.STORE_COMBINED_DEBUG_LOGS_STATUS_ID).innerText = status;
}
/**
* Set storing combined debug logs status.
*
* @private
*/
function setStoreFeedbackSystemLogsStatus_(status) {
$(CrosView.STORE_FEEDBACK_SYSTEM_LOGS_STATUS_ID).innerText = status;
}
/**
* Set status for current debug mode.
*
......@@ -52,21 +24,6 @@ const CrosView = (function() {
* @private
*/
function addEventListeners_() {
$(CrosView.STORE_DEBUG_LOGS_ID).addEventListener('click', function(event) {
$(CrosView.STORE_DEBUG_LOGS_STATUS_ID).innerText = '';
g_browser.storeDebugLogs();
}, false);
$(CrosView.STORE_COMBINED_DEBUG_LOGS_ID)
.addEventListener('click', function(event) {
$(CrosView.STORE_COMBINED_DEBUG_LOGS_STATUS_ID).innerText = '';
g_browser.storeCombinedDebugLogs();
}, false);
$(CrosView.STORE_FEEDBACK_SYSTEM_LOGS_ID)
.addEventListener('click', function(event) {
$(CrosView.STORE_FEEDBACK_SYSTEM_LOGS_STATUS_ID).innerText = '';
g_browser.storeFeedbackSystemLogs();
}, false);
$(CrosView.DEBUG_WIFI_ID).addEventListener('click', function(event) {
setNetworkDebugMode_('wifi');
}, false);
......@@ -101,7 +58,6 @@ const CrosView = (function() {
// Call superclass's constructor.
DivView.call(this, CrosView.MAIN_BOX_ID);
g_browser.addStoreDebugLogsObserver(this);
g_browser.addSetNetworkDebugModeObserver(this);
addEventListeners_();
}
......@@ -111,16 +67,6 @@ const CrosView = (function() {
CrosView.TAB_HASH = '#chromeos';
CrosView.MAIN_BOX_ID = 'chromeos-view-tab-content';
CrosView.STORE_DEBUG_LOGS_ID = 'chromeos-view-store-debug-logs';
CrosView.STORE_DEBUG_LOGS_STATUS_ID = 'chromeos-view-store-debug-logs-status';
CrosView.STORE_COMBINED_DEBUG_LOGS_ID =
'chromeos-view-store-combined-debug-logs';
CrosView.STORE_COMBINED_DEBUG_LOGS_STATUS_ID =
'chromeos-view-store-combined-debug-logs-status';
CrosView.STORE_FEEDBACK_SYSTEM_LOGS_ID =
'chromeos-view-store-feedback-system-logs';
CrosView.STORE_FEEDBACK_SYSTEM_LOGS_STATUS_ID =
'chromeos-view-store-feedback-system-logs-status';
CrosView.DEBUG_WIFI_ID = 'chromeos-view-network-debugging-wifi';
CrosView.DEBUG_ETHERNET_ID = 'chromeos-view-network-debugging-ethernet';
CrosView.DEBUG_CELLULAR_ID = 'chromeos-view-network-debugging-cellular';
......@@ -133,9 +79,6 @@ const CrosView = (function() {
// Inherit from DivView.
__proto__: DivView.prototype,
onStoreDebugLogs: setStoreDebugLogsStatus_,
onStoreCombinedDebugLogs: setStoreCombinedDebugLogsStatus_,
onStoreFeedbackSystemLogs: setStoreFeedbackSystemLogsStatus_,
onSetNetworkDebugMode: setNetworkDebugModeStatus_,
};
......
......@@ -2256,6 +2256,8 @@ static_library("ui") {
"webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h",
"webui/chromeos/network_element_localized_strings_provider.cc",
"webui/chromeos/network_element_localized_strings_provider.h",
"webui/chromeos/network_logs_message_handler.cc",
"webui/chromeos/network_logs_message_handler.h",
"webui/chromeos/network_ui.cc",
"webui/chromeos/network_ui.h",
"webui/chromeos/onc_import_message_handler.cc",
......
// Copyright 2020 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/ui/webui/chromeos/network_logs_message_handler.h"
#include <iostream>
#include "base/files/file_util.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#include "chrome/browser/chromeos/system_logs/debug_log_writer.h"
#include "chrome/browser/chromeos/system_logs/system_logs_writer.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/policy/chrome_policy_conversions_client.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/grit/generated_resources.h"
#include "components/policy/core/browser/policy_conversions.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "ui/base/l10n/l10n_util.h"
namespace chromeos {
namespace {
base::FilePath GetDownloadsDirectory(content::WebUI* web_ui) {
Profile* profile = Profile::FromWebUI(web_ui);
const DownloadPrefs* const prefs = DownloadPrefs::FromBrowserContext(profile);
base::FilePath path = prefs->DownloadPath();
if (file_manager::util::IsUnderNonNativeLocalPath(profile, path))
path = prefs->GetDefaultDownloadDirectoryForProfile();
return path;
}
std::string GetJsonPolicies(content::WebUI* web_ui) {
auto client = std::make_unique<policy::ChromePolicyConversionsClient>(
web_ui->GetWebContents()->GetBrowserContext());
return policy::DictionaryPolicyConversions(std::move(client)).ToJSON();
}
bool WriteTimestampedFile(const base::FilePath& file_path,
const std::string& contents) {
base::FilePath timestamped_file_path =
logging::GenerateTimestampedName(file_path, base::Time::Now());
int bytes_written =
base::WriteFile(timestamped_file_path, contents.data(), contents.size());
return bytes_written > 0;
}
bool GetBoolOrFalse(const base::Value* dict, const char* keyname) {
const base::Value* key = dict->FindKey(keyname);
return key && key->GetBool();
}
} // namespace
NetworkLogsMessageHandler::NetworkLogsMessageHandler() = default;
NetworkLogsMessageHandler::~NetworkLogsMessageHandler() = default;
void NetworkLogsMessageHandler::RegisterMessages() {
out_dir_ = GetDownloadsDirectory(web_ui());
web_ui()->RegisterMessageCallback(
"storeLogs", base::BindRepeating(&NetworkLogsMessageHandler::OnStoreLogs,
base::Unretained(this)));
}
void NetworkLogsMessageHandler::Respond(const std::string& callback_id,
const std::string& result,
bool is_error) {
base::Value response(base::Value::Type::LIST);
response.Append(result);
response.Append(is_error);
ResolveJavascriptCallback(base::Value(callback_id), response);
}
void NetworkLogsMessageHandler::OnStoreLogs(const base::ListValue* list) {
CHECK_EQ(2u, list->GetSize());
std::string callback_id;
CHECK(list->GetString(0, &callback_id));
const base::Value* options;
CHECK(list->Get(1, &options));
AllowJavascript();
if (GetBoolOrFalse(options, "systemLogs")) {
bool scrub_data = GetBoolOrFalse(options, "scrubData");
chromeos::system_logs_writer::WriteSystemLogs(
out_dir_, scrub_data,
base::BindOnce(&NetworkLogsMessageHandler::OnWriteSystemLogs,
weak_factory_.GetWeakPtr(), callback_id,
options->Clone()));
} else {
MaybeWriteDebugLogs(callback_id, options->Clone());
}
}
void NetworkLogsMessageHandler::OnWriteSystemLogs(
const std::string& callback_id,
base::Value&& options,
base::Optional<base::FilePath> syslogs_path) {
if (!syslogs_path) {
Respond(callback_id, "Error writing system logs file.", /*is_error=*/true);
return;
}
MaybeWriteDebugLogs(callback_id, std::move(options));
}
void NetworkLogsMessageHandler::MaybeWriteDebugLogs(
const std::string& callback_id,
base::Value&& options) {
if (GetBoolOrFalse(&options, "debugLogs")) {
if (!base::SysInfo::IsRunningOnChromeOS()) {
Respond(callback_id, "Debug logs unavailable on Linux build.",
/*is_error=*/true);
return;
}
bool include_chrome = GetBoolOrFalse(&options, "chromeLogs");
chromeos::debug_log_writer::StoreLogs(
out_dir_, include_chrome,
base::BindOnce(&NetworkLogsMessageHandler::OnWriteDebugLogs,
weak_factory_.GetWeakPtr(), callback_id,
std::move(options)));
} else {
MaybeWritePolicies(callback_id, std::move(options));
}
}
void NetworkLogsMessageHandler::OnWriteDebugLogs(
const std::string& callback_id,
base::Value&& options,
base::Optional<base::FilePath> logs_path) {
if (!logs_path) {
Respond(callback_id, "Error writing debug logs.", /*is_error=*/true);
return;
}
MaybeWritePolicies(callback_id, std::move(options));
}
void NetworkLogsMessageHandler::MaybeWritePolicies(
const std::string& callback_id,
base::Value&& options) {
if (GetBoolOrFalse(&options, "policies")) {
std::string json_policies = GetJsonPolicies(web_ui());
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce(WriteTimestampedFile, out_dir_.Append("policies.json"),
json_policies),
base::BindOnce(&NetworkLogsMessageHandler::OnWritePolicies,
weak_factory_.GetWeakPtr(), callback_id));
} else {
OnWriteSystemLogsCompleted(callback_id);
}
}
void NetworkLogsMessageHandler::OnWritePolicies(const std::string& callback_id,
bool result) {
if (!result) {
Respond(callback_id, "Error writing policies.", /*is_error=*/true);
return;
}
OnWriteSystemLogsCompleted(callback_id);
}
void NetworkLogsMessageHandler::OnWriteSystemLogsCompleted(
const std::string& callback_id) {
Respond(callback_id,
l10n_util::GetStringUTF8(IDS_NETWORK_UI_NETWORK_LOGS_SUCCESS),
/*is_error=*/false);
}
} // namespace chromeos
// Copyright 2020 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.
#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_LOGS_MESSAGE_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_LOGS_MESSAGE_HANDLER_H_
#include <string>
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/values.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace chromeos {
class NetworkLogsMessageHandler : public content::WebUIMessageHandler {
public:
NetworkLogsMessageHandler();
~NetworkLogsMessageHandler() override;
NetworkLogsMessageHandler(const NetworkLogsMessageHandler&) = delete;
NetworkLogsMessageHandler& operator=(const NetworkLogsMessageHandler&) =
delete;
private:
// WebUIMessageHandler
void RegisterMessages() override;
void Respond(const std::string& callback_id,
const std::string& result,
bool is_error);
void OnStoreLogs(const base::ListValue* list);
void OnWriteSystemLogs(const std::string& callback_id,
base::Value&& options,
base::Optional<base::FilePath> syslogs_path);
void MaybeWriteDebugLogs(const std::string& callback_id,
base::Value&& options);
void OnWriteDebugLogs(const std::string& callback_id,
base::Value&& options,
base::Optional<base::FilePath> logs_path);
void MaybeWritePolicies(const std::string& callback_id,
base::Value&& options);
void OnWritePolicies(const std::string& callback_id, bool result);
void OnWriteSystemLogsCompleted(const std::string& callback_id);
base::FilePath out_dir_;
base::WeakPtrFactory<NetworkLogsMessageHandler> weak_factory_{this};
};
} // namespace chromeos
#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_LOGS_MESSAGE_HANDLER_H_
......@@ -21,6 +21,7 @@
#include "chrome/browser/ui/webui/chromeos/internet_config_dialog.h"
#include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
#include "chrome/browser/ui/webui/chromeos/network_element_localized_strings_provider.h"
#include "chrome/browser/ui/webui/chromeos/network_logs_message_handler.h"
#include "chrome/browser/ui/webui/chromeos/onc_import_message_handler.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
......@@ -322,6 +323,9 @@ void NetworkUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) {
localized_strings->SetString(
"networkHealthTab",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_TAB_NETWORK_HEALTH));
localized_strings->SetString(
"networkLogsTab",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_TAB_NETWORK_LOGS));
localized_strings->SetString(
"networkStateTab",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_TAB_NETWORK_STATE));
......@@ -397,12 +401,39 @@ void NetworkUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) {
localized_strings->SetString(
"importOncButtonText",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_IMPORT_ONC_BUTTON_TEXT));
// Network logs
localized_strings->SetString(
"networkLogsDescription",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_DESCRIPTION));
localized_strings->SetString(
"networkLogsSystemLogs",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_SYSTEM_LOGS));
localized_strings->SetString(
"networkLogsFilterPii",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_FILTER_PII));
localized_strings->SetString(
"networkLogsPolicies",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_POLICIES));
localized_strings->SetString(
"networkLogsDebugLogs",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_DEBUG_LOGS));
localized_strings->SetString(
"networkLogsChromeLogs",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_CHROME_LOGS));
localized_strings->SetString(
"networkLogsStoreButton",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_STORE_BUTTON));
localized_strings->SetString(
"networkLogsStatus",
l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LOGS_STATUS));
}
NetworkUI::NetworkUI(content::WebUI* web_ui)
: ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {
web_ui->AddMessageHandler(std::make_unique<NetworkConfigMessageHandler>());
web_ui->AddMessageHandler(std::make_unique<OncImportMessageHandler>());
web_ui->AddMessageHandler(std::make_unique<NetworkLogsMessageHandler>());
// Enable extension API calls in the WebUI.
extensions::TabHelper::CreateForWebContents(web_ui->GetWebContents());
......@@ -422,6 +453,8 @@ NetworkUI::NetworkUI(content::WebUI* web_ui)
html->AddResourcePath("network_ui.js", IDR_NETWORK_UI_JS);
html->AddResourcePath("network_state_ui.html", IDR_NETWORK_STATE_UI_HTML);
html->AddResourcePath("network_state_ui.js", IDR_NETWORK_STATE_UI_JS);
html->AddResourcePath("network_logs_ui.html", IDR_NETWORK_LOGS_UI_HTML);
html->AddResourcePath("network_logs_ui.js", IDR_NETWORK_LOGS_UI_JS);
html->SetDefaultResource(IDR_NETWORK_UI_HTML);
content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
......
......@@ -12,19 +12,14 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/weak_ptr.h"
#include "base/task/thread_pool.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/net/net_export_helper.h"
#include "chrome/browser/policy/chrome_policy_conversions_client.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h"
#include "chrome/grit/net_internals_resources.h"
#include "components/policy/core/browser/policy_conversions.h"
#include "components/prefs/pref_member.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
......@@ -40,10 +35,6 @@
#include "services/network/public/mojom/network_context.mojom.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
#include "chrome/browser/chromeos/system_logs/debug_log_writer.h"
#include "chrome/browser/chromeos/system_logs/system_logs_writer.h"
#include "chrome/common/logging_chrome.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
#endif
......@@ -67,28 +58,6 @@ content::WebUIDataSource* CreateNetInternalsHTMLSource() {
void IgnoreBoolCallback(bool result) {}
#if defined(OS_CHROMEOS)
base::FilePath GetDownloadsDirectory(content::WebUI* web_ui) {
Profile* profile = Profile::FromWebUI(web_ui);
const DownloadPrefs* const prefs = DownloadPrefs::FromBrowserContext(profile);
base::FilePath path = prefs->DownloadPath();
if (file_manager::util::IsUnderNonNativeLocalPath(profile, path))
path = prefs->GetDefaultDownloadDirectoryForProfile();
return path;
}
std::string GetJsonPolicies(content::WebUI* web_ui) {
auto client = std::make_unique<policy::ChromePolicyConversionsClient>(
web_ui->GetWebContents()->GetBrowserContext());
return policy::DictionaryPolicyConversions(std::move(client)).ToJSON();
}
void WriteTimestampedFile(base::FilePath file_path, std::string contents) {
file_path = logging::GenerateTimestampedName(file_path, base::Time::Now());
base::WriteFile(file_path, contents.data(), contents.size());
}
#endif
// This class receives javascript messages from the renderer.
// Note that the WebUI infrastructure runs on the UI thread, therefore all of
// this class's methods are expected to run on the UI thread.
......@@ -128,21 +97,6 @@ class NetInternalsMessageHandler
void OnCloseIdleSockets(const base::ListValue* list);
void OnFlushSocketPools(const base::ListValue* list);
#if defined(OS_CHROMEOS)
void OnWritePolicyLogsCompleted(const base::FilePath& path,
bool should_compress,
bool combined,
const char* received_event);
void OnStoreDebugLogs(bool combined,
const char* received_event,
const base::ListValue* list);
void OnStoreDebugLogsCompleted(const char* received_event,
const base::FilePath& log_path,
bool succeeded);
void OnStoreFeedbackSystemLogs(const char* received_event,
const base::ListValue* list);
void OnStoreFeedbackSystemLogsCompleted(
const char* received_event,
base::Optional<base::FilePath> system_logs_path);
void OnSetNetworkDebugMode(const base::ListValue* list);
void OnSetNetworkDebugModeCompleted(const std::string& subsystem,
bool succeeded);
......@@ -203,21 +157,6 @@ void NetInternalsMessageHandler::RegisterMessages() {
base::BindRepeating(&NetInternalsMessageHandler::OnFlushSocketPools,
base::Unretained(this)));
#if defined(OS_CHROMEOS)
web_ui()->RegisterMessageCallback(
"storeDebugLogs",
base::BindRepeating(&NetInternalsMessageHandler::OnStoreDebugLogs,
base::Unretained(this), false /* combined */,
"receivedStoreDebugLogs"));
web_ui()->RegisterMessageCallback(
"storeCombinedDebugLogs",
base::BindRepeating(&NetInternalsMessageHandler::OnStoreDebugLogs,
base::Unretained(this), true /* combined */,
"receivedStoreCombinedDebugLogs"));
web_ui()->RegisterMessageCallback(
"storeFeedbackSystemLogs",
base::BindRepeating(
&NetInternalsMessageHandler::OnStoreFeedbackSystemLogs,
base::Unretained(this), "receivedStoreFeedbackSystemLogs"));
web_ui()->RegisterMessageCallback(
"setNetworkDebugMode",
base::BindRepeating(&NetInternalsMessageHandler::OnSetNetworkDebugMode,
......@@ -371,92 +310,6 @@ void NetInternalsMessageHandler::OnCloseIdleSockets(
#if defined(OS_CHROMEOS)
void NetInternalsMessageHandler::OnStoreDebugLogs(bool combined,
const char* received_event,
const base::ListValue* list) {
DCHECK(list);
SendJavascriptCommand(received_event, base::Value("Creating log file..."));
base::FilePath path = GetDownloadsDirectory(web_ui());
std::string json_policies = GetJsonPolicies(web_ui());
base::ThreadPool::PostTaskAndReply(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
base::BindOnce(WriteTimestampedFile, path.Append("policies.json"),
json_policies),
base::BindOnce(&NetInternalsMessageHandler::OnWritePolicyLogsCompleted,
AsWeakPtr(), path, true /* should_compress */, combined,
received_event));
}
void NetInternalsMessageHandler::OnWritePolicyLogsCompleted(
const base::FilePath& path,
bool should_compress,
bool combined,
const char* received_event) {
if (combined) {
chromeos::DebugLogWriter::StoreCombinedLogs(
path,
base::BindOnce(&NetInternalsMessageHandler::OnStoreDebugLogsCompleted,
AsWeakPtr(), received_event));
} else {
chromeos::DebugLogWriter::StoreLogs(
path, should_compress,
base::BindOnce(&NetInternalsMessageHandler::OnStoreDebugLogsCompleted,
AsWeakPtr(), received_event));
}
}
void NetInternalsMessageHandler::OnStoreDebugLogsCompleted(
const char* received_event,
const base::FilePath& log_path,
bool succeeded) {
std::string status;
if (succeeded)
status = "Created log file: " + log_path.BaseName().AsUTF8Unsafe();
else
status = "Failed to create log file";
SendJavascriptCommand(received_event, base::Value(status));
}
void NetInternalsMessageHandler::OnStoreFeedbackSystemLogs(
const char* received_event,
const base::ListValue* list) {
DCHECK(list);
SendJavascriptCommand(received_event,
base::Value("Creating system logs file..."));
base::FilePath downloads_path = GetDownloadsDirectory(web_ui());
std::string json_policies = GetJsonPolicies(web_ui());
// Write the policies file to disk as a blocking task, then call
// system_logs_writer::WriteSystemLogs to asynchronously write the system
// logs and respond when complete.
base::ThreadPool::PostTaskAndReply(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
base::BindOnce(WriteTimestampedFile,
downloads_path.Append("policies.json"), json_policies),
base::BindOnce(
chromeos::system_logs_writer::WriteSystemLogs, downloads_path,
base::BindOnce(
&NetInternalsMessageHandler::OnStoreFeedbackSystemLogsCompleted,
AsWeakPtr(), received_event)));
}
void NetInternalsMessageHandler::OnStoreFeedbackSystemLogsCompleted(
const char* received_event,
base::Optional<base::FilePath> system_logs_path) {
std::string status = system_logs_path
? "Created system_logs file: " +
system_logs_path->BaseName().AsUTF8Unsafe()
: "Failed to create system logs file.";
SendJavascriptCommand(received_event, base::Value(status));
}
void NetInternalsMessageHandler::OnSetNetworkDebugMode(
const base::ListValue* list) {
std::string subsystem;
......
......@@ -85,7 +85,6 @@ if (include_js_tests) {
"load_time_data_browsertest.js",
"management/a11y/management_a11y_test.js",
"mock4js_browsertest.js",
"net_internals/chromeos_view.js",
"net_internals/dns_view.js",
"net_internals/domain_security_policy_view.js",
"net_internals/main.js",
......
// Copyright 2014 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 test fixture.
GEN_INCLUDE(['net_internals_test.js']);
GEN('#include "content/public/test/browser_test.h"');
// Anonymous namespace
(function() {
function DebugLogsStatusWatcher() {
NetInternalsTest.Task.call(this);
this.setCompleteAsync(true);
}
DebugLogsStatusWatcher.prototype = {
__proto__: NetInternalsTest.Task.prototype,
start: function() {
g_browser.addStoreDebugLogsObserver(this);
$('chromeos-view-store-debug-logs').click();
},
onStoreDebugLogs: function(status) {
if (status.indexOf('Created') !== -1) {
this.onTaskDone(true);
return;
}
if (status.indexOf('Failed') !== -1) {
this.onTaskDone(false);
return;
}
}
};
function ResultChecker() {
NetInternalsTest.Task.call(this);
}
ResultChecker.prototype = {
__proto__: NetInternalsTest.Task.prototype,
start: function(success) {
assertTrue(success);
this.onTaskDone();
}
};
TEST_F(
'NetInternalsTest', 'netInternalsChromeOSViewStoreDebugLogs', function() {
if (!cr.isChromeOS) {
testDone();
return;
}
NetInternalsTest.switchToView('chromeos');
var taskQueue = new NetInternalsTest.TaskQueue(true);
taskQueue.addTask(new DebugLogsStatusWatcher());
taskQueue.addTask(new ResultChecker());
taskQueue.run();
});
})(); // Anonymous namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment