1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_TRACING_BRIDGE_H_ 6 #define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_TRACING_BRIDGE_H_ 7 8 #include <memory> 9 #include <set> 10 #include <string> 11 #include <vector> 12 13 #include "base/callback_forward.h" 14 #include "base/containers/ring_buffer.h" 15 #include "base/files/file_descriptor_watcher_posix.h" 16 #include "base/files/scoped_file.h" 17 #include "base/macros.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/synchronization/lock.h" 20 #include "base/thread_annotations.h" 21 #include "components/arc/mojom/tracing.mojom-forward.h" 22 #include "components/arc/session/connection_observer.h" 23 #include "components/keyed_service/core/keyed_service.h" 24 #include "services/tracing/public/cpp/base_agent.h" 25 26 namespace content { 27 class BrowserContext; 28 } // namespace content 29 30 namespace arc { 31 32 class ArcBridgeService; 33 34 // This class provides the interface to trigger tracing in the container. 35 class ArcTracingBridge : public KeyedService, 36 public ConnectionObserver<mojom::TracingInstance> { 37 public: 38 // Returns singleton instance for the given BrowserContext, 39 // or nullptr if the browser |context| is not allowed to use ARC. 40 static ArcTracingBridge* GetForBrowserContext( 41 content::BrowserContext* context); 42 43 ArcTracingBridge(content::BrowserContext* context, 44 ArcBridgeService* bridge_service); 45 ~ArcTracingBridge() override; 46 47 void GetCategories(std::set<std::string>* category_set); 48 49 // ConnectionObserver<mojom::TracingInstance> overrides: 50 void OnConnectionReady() override; 51 52 // State of the tracing activity of the bridge. 53 enum class State { kDisabled, kStarting, kEnabled, kStopping }; state()54 State state() const { return state_; } 55 56 using SuccessCallback = base::OnceCallback<void(bool)>; 57 using TraceDataCallback = base::OnceCallback<void(const std::string& data)>; 58 59 // Starts tracing and calls |callback| when started indicating whether tracing 60 // was started successfully via its parameter. 61 void StartTracing(const std::string& config, SuccessCallback callback); 62 63 // Stops tracing and calls |callback| with the recorded trace data once 64 // stopped. If unsuccessful, calls |callback| with an empty data string. 65 void StopAndFlush(TraceDataCallback callback); 66 67 private: 68 // TODO(crbug.com/839086): Remove once we have replaced the legacy tracing 69 // service with perfetto. 70 class ArcTracingAgent : public tracing::BaseAgent { 71 public: 72 explicit ArcTracingAgent(ArcTracingBridge* bridge); 73 ~ArcTracingAgent() override; 74 75 private: 76 // tracing::BaseAgent. 77 void GetCategories(std::set<std::string>* category_set) override; 78 79 ArcTracingBridge* const bridge_; 80 81 DISALLOW_COPY_AND_ASSIGN(ArcTracingAgent); 82 }; 83 84 // A helper class for reading trace data from the client side. We separate 85 // this from |ArcTracingAgentImpl| to isolate the logic that runs on browser's 86 // IO thread. All the functions in this class except for constructor are 87 // expected to be run on browser's IO thread. 88 class ArcTracingReader { 89 public: 90 ArcTracingReader(); 91 ~ArcTracingReader(); 92 93 // Starts reading trace data from the given file descriptor. 94 void StartTracing(base::ScopedFD read_fd); 95 // Stops reading and returns the collected trace data. 96 std::string StopTracing(); 97 98 private: 99 void OnTraceDataAvailable(); 100 101 // Number of events for the ring buffer. 102 static constexpr size_t kTraceEventBufferSize = 64000; 103 104 base::ScopedFD read_fd_; 105 std::unique_ptr<base::FileDescriptorWatcher::Controller> fd_watcher_; 106 base::RingBuffer<std::string, kTraceEventBufferSize> ring_buffer_; 107 108 DISALLOW_COPY_AND_ASSIGN(ArcTracingReader); 109 }; 110 111 struct Category; 112 113 // Callback for QueryAvailableCategories. 114 void OnCategoriesReady(const std::vector<std::string>& categories); 115 116 void OnArcTracingStarted(SuccessCallback callback, bool success); 117 void OnArcTracingStopped(TraceDataCallback tracing_stopped_callback, 118 bool success); 119 void OnTracingReaderStopped(TraceDataCallback tracing_stopped_callback, 120 const std::string& data); 121 122 ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. 123 124 // List of available categories. 125 base::Lock categories_lock_; 126 std::vector<Category> categories_ GUARDED_BY(categories_lock_); 127 128 ArcTracingAgent agent_; 129 130 std::unique_ptr<ArcTracingReader> reader_; 131 132 State state_ = State::kDisabled; 133 134 // NOTE: Weak pointers must be invalidated before all other member variables 135 // so it must be the last member. 136 base::WeakPtrFactory<ArcTracingBridge> weak_ptr_factory_{this}; 137 138 DISALLOW_COPY_AND_ASSIGN(ArcTracingBridge); 139 }; 140 141 } // namespace arc 142 143 #endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_TRACING_BRIDGE_H_ 144