Index: chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc |
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc |
index cefad21fbc903acd54f389614e2064f38613be4d..6ab96d461e1180b57c36ee538b3bda81ec3751c4 100644 |
--- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc |
+++ b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.cc |
@@ -4,13 +4,16 @@ |
#include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h" |
+#include "base/command_line.h" |
#include "base/hash.h" |
#include "base/logging.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/supports_user_data.h" |
+#include "chrome/browser/download/download_prefs.h" |
#include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
#include "chrome/browser/extensions/extension_tab_util.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/common/chrome_switches.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/site_instance.h" |
@@ -36,12 +39,79 @@ namespace StopRtpDump = api::webrtc_logging_private::StopRtpDump; |
namespace Store = api::webrtc_logging_private::Store; |
namespace Upload = api::webrtc_logging_private::Upload; |
namespace UploadStored = api::webrtc_logging_private::UploadStored; |
+namespace StartAecDump = api::webrtc_logging_private::StartAecDump; |
+namespace StopAecDump = api::webrtc_logging_private::StopAecDump; |
namespace { |
std::string HashIdWithOrigin(const std::string& security_origin, |
const std::string& log_id) { |
return base::UintToString(base::Hash(security_origin + log_id)); |
} |
+ |
+// These global variables must be accessed on the UI thread. |
+uint64 current_aec_dump_id = 0; |
Henrik Grunell
2015/12/18 12:34:21
uint64_t
Henrik Grunell
2015/12/18 12:34:21
Use g_ prefix for these two.
Guido Urdaneta
2015/12/18 18:38:57
Done, but moved to webrtc logging handler
Guido Urdaneta
2015/12/18 18:38:57
Not needed anymore
|
+bool is_dump_in_progress = false; |
+ |
+// Returns a base prefix path to be used for AEC dumps. |
+base::FilePath GetAecDumpPrefixPath(Profile* profile, uint64 dump_id) { |
+ static const char kAecDumpFilePrefix[] = "aecdump."; |
+ DownloadPrefs download_prefs(profile); |
+ base::FilePath dump_dir = download_prefs.GetDefaultDownloadDirectory(); |
+ return dump_dir.Append(kAecDumpFilePrefix + base::Int64ToString(dump_id)); |
+} |
+ |
+// Starts an AEC dump and save the files in the default download directory for |
+// |profile|, provided no dump is in progress. Returns a UTF8 string with the |
+// prefix path for the AEC dump files, or an empty string there is already a |
+// dump in progress. |
+std::string DoStartAecDump(Profile* profile) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ if (is_dump_in_progress) |
+ return std::string(); |
+ |
+ ++current_aec_dump_id; |
+ is_dump_in_progress = true; |
+ base::FilePath prefix_path = |
+ GetAecDumpPrefixPath(profile, current_aec_dump_id); |
Henrik Grunell
2015/12/18 12:34:21
current_aec_dump_id++ and remove increment above.
Henrik Grunell
2015/12/18 12:34:21
I assume the reason for using a incrementing count
Guido Urdaneta
2015/12/18 18:38:57
Done (with preincrement) in new version.
|
+ for (content::RenderProcessHost::iterator i( |
+ content::RenderProcessHost::AllHostsIterator()); |
+ !i.IsAtEnd(); i.Advance()) { |
+ i.GetCurrentValue()->EnableAudioDebugRecordings(prefix_path); |
+ } |
+ |
+ return prefix_path.AsUTF8Unsafe(); |
+} |
+ |
+// If an AEC dump is ongoing, stop the AEC dump if |dump_id| is its ID. |
+// |callback| is invoked with the prefix path of the dump identified with |
+// |dump_id|, and true/false if an AEC dump was actually stopped/not stopped. |
+void DoStopAecDump(Profile* profile, |
+ uint64 dump_id, |
+ base::Callback<void(const std::string&, bool)> callback) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ DCHECK_LE(dump_id, current_aec_dump_id); |
+ std::string prefix_path = |
+ GetAecDumpPrefixPath(profile, dump_id).AsUTF8Unsafe(); |
+ |
+ // Prevent an old posted StopAecDump() call to stop a newer dump. |
+ // This could happen in a sequence like: |
+ // Start(10); //Start dump 1. Post Stop() to run after 10 seconds. |
+ // Stop(); // Manually stop dump 1 before 10 seconds; |
+ // Start(20); // Start dump 2. Posted Stop() for 1 should not stop dump 2. |
+ if (dump_id < current_aec_dump_id || !is_dump_in_progress) { |
+ callback.Run(prefix_path, false); |
Henrik Grunell
2015/12/18 12:34:21
Should we really run the callback if the dump was
Guido Urdaneta
2015/12/18 18:38:57
Since it is the caller who will remove/process fil
|
+ return; |
+ } |
+ |
+ for (content::RenderProcessHost::iterator i( |
+ content::RenderProcessHost::AllHostsIterator()); |
+ !i.IsAtEnd(); i.Advance()) { |
+ i.GetCurrentValue()->DisableAudioDebugRecordings(); |
+ } |
+ |
+ is_dump_in_progress = false; |
+ callback.Run(prefix_path, true); |
+} |
} // namespace |
content::RenderProcessHost* WebrtcLoggingPrivateFunction::RphFromRequest( |
@@ -124,6 +194,26 @@ void WebrtcLoggingPrivateFunctionWithUploadCallback::FireCallback( |
SendResponse(success); |
} |
+void WebrtcLoggingPrivateFunctionWithAecDumpCallback::FireErrorCallback( |
+ const std::string& error_message) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ SetError(error_message); |
+ SendResponse(false); |
+} |
+ |
+void WebrtcLoggingPrivateFunctionWithAecDumpCallback::FireSuccessCallback( |
+ bool is_manual_stop, |
+ const std::string& prefix_path, |
+ bool did_stop) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ api::webrtc_logging_private::AecDumpInfo result; |
+ result.is_manual_stop = is_manual_stop; |
+ result.prefix_path = prefix_path; |
+ result.did_stop = did_stop; |
+ SetResult(result.ToValue().release()); |
+ SendResponse(true); |
+} |
+ |
bool WebrtcLoggingPrivateSetMetaDataFunction::RunAsync() { |
scoped_ptr<SetMetaData::Params> params(SetMetaData::Params::Create(*args_)); |
EXTENSION_FUNCTION_VALIDATE(params.get()); |
@@ -348,4 +438,55 @@ bool WebrtcLoggingPrivateStopRtpDumpFunction::RunAsync() { |
return true; |
} |
+bool WebrtcLoggingPrivateStartAecDumpFunction::RunAsync() { |
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableAecDumpsFromExtension)) { |
+ FireErrorCallback("Not supported"); |
+ return false; |
+ } |
+ |
+ scoped_ptr<StartAecDump::Params> params(StartAecDump::Params::Create(*args_)); |
+ EXTENSION_FUNCTION_VALIDATE(params.get()); |
+ if (params->seconds < 0) { |
+ FireErrorCallback("seconds must be greater than or equal to 0"); |
+ return true; |
+ } |
+ |
+ std::string prefix_path = DoStartAecDump(GetProfile()); |
+ if (prefix_path.empty()) { |
+ FireErrorCallback("AEC Dump already in progress"); |
+ return true; |
+ } |
+ |
+ if (params->seconds == 0) { |
+ FireSuccessCallback(false, prefix_path, false); |
+ return true; |
+ } |
+ |
+ BrowserThread::PostDelayedTask( |
Henrik Grunell
2015/12/18 12:34:21
Maybe use a Timer? It wraps a delayed task and can
Guido Urdaneta
2015/12/18 18:38:57
Using PostDelayedTask looked more straightforward
|
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind( |
+ &DoStopAecDump, GetProfile(), current_aec_dump_id, |
+ base::Bind( |
+ &WebrtcLoggingPrivateStartAecDumpFunction::FireSuccessCallback, |
+ this, false)), |
+ base::TimeDelta::FromSeconds(params->seconds)); |
+ |
+ return true; |
+} |
+ |
+bool WebrtcLoggingPrivateStopAecDumpFunction::RunAsync() { |
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableAecDumpsFromExtension)) { |
+ FireErrorCallback("Not supported"); |
+ return false; |
+ } |
+ |
+ DoStopAecDump( |
+ GetProfile(), current_aec_dump_id, |
+ base::Bind(&WebrtcLoggingPrivateStopAecDumpFunction::FireSuccessCallback, |
+ this, true)); |
+ return true; |
+} |
+ |
} // namespace extensions |