| 
									
										
										
										
											2014-10-31 11:17:05 -07:00
										 |  |  | // Copyright (c) 2014 GitHub, Inc.
 | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <set>
 | 
					
						
							| 
									
										
										
										
											2014-10-11 19:11:34 +08:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  | #include <utility>
 | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  | #include "base/files/file_util.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  | #include "base/optional.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-09 16:13:59 +00:00
										 |  |  | #include "base/task/thread_pool.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-05 11:19:06 -07:00
										 |  |  | #include "base/threading/thread_restrictions.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | #include "content/public/browser/tracing_controller.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  | #include "shell/common/gin_converters/callback_converter.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_converters/file_path_converter.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_converters/value_converter.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_helper/dictionary.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  | #include "shell/common/gin_helper/promise.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-19 13:46:59 -07:00
										 |  |  | #include "shell/common/node_includes.h"
 | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using content::TracingController; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  | namespace gin { | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | template <> | 
					
						
							| 
									
										
										
										
											2015-09-02 15:16:49 +08:00
										 |  |  | struct Converter<base::trace_event::TraceConfig> { | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  |   static bool FromV8(v8::Isolate* isolate, | 
					
						
							| 
									
										
										
										
											2015-05-22 19:11:22 +08:00
										 |  |  |                      v8::Local<v8::Value> val, | 
					
						
							| 
									
										
										
										
											2015-09-02 15:16:49 +08:00
										 |  |  |                      base::trace_event::TraceConfig* out) { | 
					
						
							| 
									
										
										
										
											2018-12-20 13:11:17 +01:00
										 |  |  |     // (alexeykuzmin): A combination of "categoryFilter" and "traceOptions"
 | 
					
						
							|  |  |  |     // has to be checked first because none of the fields
 | 
					
						
							|  |  |  |     // in the `memory_dump_config` dict below are mandatory
 | 
					
						
							|  |  |  |     // and we cannot check the config format.
 | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  |     gin_helper::Dictionary options; | 
					
						
							| 
									
										
										
										
											2018-12-20 13:11:17 +01:00
										 |  |  |     if (ConvertFromV8(isolate, val, &options)) { | 
					
						
							|  |  |  |       std::string category_filter, trace_options; | 
					
						
							|  |  |  |       if (options.Get("categoryFilter", &category_filter) && | 
					
						
							|  |  |  |           options.Get("traceOptions", &trace_options)) { | 
					
						
							|  |  |  |         *out = base::trace_event::TraceConfig(category_filter, trace_options); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     base::DictionaryValue memory_dump_config; | 
					
						
							|  |  |  |     if (ConvertFromV8(isolate, val, &memory_dump_config)) { | 
					
						
							|  |  |  |       *out = base::trace_event::TraceConfig(memory_dump_config); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2014-10-11 19:11:34 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  | }  // namespace gin
 | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  | using CompletionCallback = base::OnceCallback<void(const base::FilePath&)>; | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  | base::Optional<base::FilePath> CreateTemporaryFileOnIO() { | 
					
						
							|  |  |  |   base::FilePath temp_file_path; | 
					
						
							|  |  |  |   if (!base::CreateTemporaryFile(&temp_file_path)) | 
					
						
							|  |  |  |     return base::nullopt; | 
					
						
							|  |  |  |   return base::make_optional(std::move(temp_file_path)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  | void StopTracing(gin_helper::Promise<base::FilePath> promise, | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |                  base::Optional<base::FilePath> file_path) { | 
					
						
							|  |  |  |   if (file_path) { | 
					
						
							|  |  |  |     auto endpoint = TracingController::CreateFileEndpoint( | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |         *file_path, base::AdaptCallbackForRepeating(base::BindOnce( | 
					
						
							|  |  |  |                         &gin_helper::Promise<base::FilePath>::ResolvePromise, | 
					
						
							|  |  |  |                         std::move(promise), *file_path))); | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |     TracingController::GetInstance()->StopTracing(endpoint); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     promise.RejectWithErrorMessage( | 
					
						
							|  |  |  |         "Failed to create temporary file for trace data"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  | v8::Local<v8::Promise> StopRecording(gin_helper::Arguments* args) { | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   gin_helper::Promise<base::FilePath> promise(args->isolate()); | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   v8::Local<v8::Promise> handle = promise.GetHandle(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |   base::FilePath path; | 
					
						
							|  |  |  |   if (args->GetNext(&path) && !path.empty()) { | 
					
						
							|  |  |  |     StopTracing(std::move(promise), base::make_optional(path)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // use a temporary file.
 | 
					
						
							| 
									
										
										
										
											2020-03-09 16:13:59 +00:00
										 |  |  |     base::ThreadPool::PostTaskAndReplyWithResult( | 
					
						
							|  |  |  |         FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |         base::BindOnce(CreateTemporaryFileOnIO), | 
					
						
							|  |  |  |         base::BindOnce(StopTracing, std::move(promise))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   return handle; | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 12:39:55 -08:00
										 |  |  | v8::Local<v8::Promise> GetCategories(v8::Isolate* isolate) { | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   gin_helper::Promise<const std::set<std::string>&> promise(isolate); | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   v8::Local<v8::Promise> handle = promise.GetHandle(); | 
					
						
							| 
									
										
										
										
											2019-01-30 12:39:55 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   // Note: This method always succeeds.
 | 
					
						
							| 
									
										
										
										
											2019-03-13 14:30:21 -07:00
										 |  |  |   TracingController::GetInstance()->GetCategories(base::BindOnce( | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |       gin_helper::Promise<const std::set<std::string>&>::ResolvePromise, | 
					
						
							| 
									
										
										
										
											2019-03-13 14:30:21 -07:00
										 |  |  |       std::move(promise))); | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-13 14:30:21 -07:00
										 |  |  |   return handle; | 
					
						
							| 
									
										
										
										
											2019-01-30 18:53:55 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | v8::Local<v8::Promise> StartTracing( | 
					
						
							|  |  |  |     v8::Isolate* isolate, | 
					
						
							|  |  |  |     const base::trace_event::TraceConfig& trace_config) { | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   gin_helper::Promise<void> promise(isolate); | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   v8::Local<v8::Promise> handle = promise.GetHandle(); | 
					
						
							| 
									
										
										
										
											2019-01-30 18:53:55 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |   if (!TracingController::GetInstance()->StartTracing( | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  |           trace_config, | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |           base::BindOnce(gin_helper::Promise<void>::ResolvePromise, | 
					
						
							| 
									
										
										
										
											2019-06-19 14:23:04 -07:00
										 |  |  |                          std::move(promise)))) { | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |     // If StartTracing returns false, that means it didn't invoke its callback.
 | 
					
						
							|  |  |  |     // Return an already-resolved promise and abandon the previous promise (it
 | 
					
						
							|  |  |  |     // was std::move()d into the StartTracing callback and has been deleted by
 | 
					
						
							|  |  |  |     // this point).
 | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |     return gin_helper::Promise<void>::ResolvedPromise(isolate); | 
					
						
							| 
									
										
										
										
											2019-05-28 14:15:42 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   return handle; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 17:03:28 -07:00
										 |  |  | void OnTraceBufferUsageAvailable( | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |     gin_helper::Promise<gin_helper::Dictionary> promise, | 
					
						
							| 
									
										
										
										
											2019-08-22 17:03:28 -07:00
										 |  |  |     float percent_full, | 
					
						
							|  |  |  |     size_t approximate_count) { | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  |   gin_helper::Dictionary dict = gin::Dictionary::CreateEmpty(promise.isolate()); | 
					
						
							| 
									
										
										
										
											2019-02-13 13:24:57 -08:00
										 |  |  |   dict.Set("percentage", percent_full); | 
					
						
							|  |  |  |   dict.Set("value", approximate_count); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   promise.Resolve(dict); | 
					
						
							| 
									
										
										
										
											2019-02-13 13:24:57 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | v8::Local<v8::Promise> GetTraceBufferUsage(v8::Isolate* isolate) { | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   gin_helper::Promise<gin_helper::Dictionary> promise(isolate); | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   v8::Local<v8::Promise> handle = promise.GetHandle(); | 
					
						
							| 
									
										
										
										
											2019-02-13 13:24:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-21 12:32:44 +00:00
										 |  |  |   // Note: This method always succeeds.
 | 
					
						
							|  |  |  |   TracingController::GetInstance()->GetTraceBufferUsage( | 
					
						
							|  |  |  |       base::BindOnce(&OnTraceBufferUsageAvailable, std::move(promise))); | 
					
						
							|  |  |  |   return handle; | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 21:55:30 -04:00
										 |  |  | void Initialize(v8::Local<v8::Object> exports, | 
					
						
							|  |  |  |                 v8::Local<v8::Value> unused, | 
					
						
							|  |  |  |                 v8::Local<v8::Context> context, | 
					
						
							|  |  |  |                 void* priv) { | 
					
						
							| 
									
										
										
										
											2019-10-31 16:56:00 +09:00
										 |  |  |   gin_helper::Dictionary dict(context->GetIsolate(), exports); | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |   dict.SetMethod("getCategories", &GetCategories); | 
					
						
							|  |  |  |   dict.SetMethod("startRecording", &StartTracing); | 
					
						
							| 
									
										
										
										
											2015-08-05 01:42:57 +05:30
										 |  |  |   dict.SetMethod("stopRecording", &StopRecording); | 
					
						
							| 
									
										
										
										
											2019-01-12 06:30:43 +05:30
										 |  |  |   dict.SetMethod("getTraceBufferUsage", &GetTraceBufferUsage); | 
					
						
							| 
									
										
										
										
											2014-07-31 15:08:54 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 03:25:39 -08:00
										 |  |  | NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_content_tracing, Initialize) |