1 // Copyright 2014 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_MEDIA_WEBRTC_WEBRTC_RTP_DUMP_HANDLER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_RTP_DUMP_HANDLER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 
13 #include "base/callback.h"
14 #include "base/files/file_path.h"
15 #include "base/macros.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/sequence_checker.h"
18 #include "chrome/browser/media/webrtc/rtp_dump_type.h"
19 
20 class WebRtcRtpDumpWriter;
21 
22 // WebRtcRtpDumpHandler handles operations regarding the WebRTC RTP dump:
23 // - Starts or stops the RTP dumping on behalf of the client.
24 // - Stops the RTP dumping when the max dump file size is reached.
25 // - Writes the dump file.
26 // - Provides the dump file to the client code to be uploaded when
27 //   ReleaseRtpDump is called.
28 // - Cleans up the dump file if not transferred to the client before the object
29 //   is destroyed.
30 //
31 // Must be created/used/destroyed on the browser IO thread.
32 class WebRtcRtpDumpHandler {
33  public:
34   typedef base::OnceCallback<void(bool, const std::string&)>
35       GenericDoneCallback;
36 
37   struct ReleasedDumps {
ReleasedDumpsReleasedDumps38     ReleasedDumps(const base::FilePath& incoming_dump,
39                   const base::FilePath& outgoing_dump)
40         : incoming_dump_path(incoming_dump),
41           outgoing_dump_path(outgoing_dump) {}
42 
43     const base::FilePath incoming_dump_path;
44     const base::FilePath outgoing_dump_path;
45   };
46 
47   // The caller must make sure |dump_dir| exists. RTP dump files are saved under
48   // |dump_dir| as "rtpdump_$DIRECTION_$TIMESTAMP.gz", where $DIRECTION is
49   // 'send' for outgoing dump or 'recv' for incoming dump. $TIMESTAMP is the
50   // dump started time converted to a double number in microsecond precision,
51   // which should guarantee the uniqueness across tabs and dump streams in
52   // practice.
53   explicit WebRtcRtpDumpHandler(const base::FilePath& dump_dir);
54   ~WebRtcRtpDumpHandler();
55 
56   // Starts the specified type of dumping. Incoming/outgoing dumping can be
57   // started separately. Returns true if called in a valid state, i.e. the
58   // specified type of dump has not been started.
59   bool StartDump(RtpDumpType type, std::string* error_message);
60 
61   // Stops the specified type of dumping. Incoming/outgoing dumping can be
62   // stopped separately. Returns asynchronously through |callback|, where
63   // |success| is true if StopDump is called in a valid state. The callback is
64   // called when the writer finishes writing the dumps.
65   void StopDump(RtpDumpType type, GenericDoneCallback callback);
66 
67   // Returns true if it's valid to call ReleaseDumps, i.e. no dumping is ongoing
68   // or being stopped.
69   bool ReadyToRelease() const;
70 
71   // Releases all the dumps and resets the state.
72   // It should only be called when both incoming and outgoing dumping has been
73   // stopped, i.e. ReadyToRelease() returns true. Returns the dump file paths.
74   //
75   // The caller will own the dump file after the method returns. If ReleaseDump
76   // is not called before this object goes away, the dump file will be deleted
77   // by this object.
78   ReleasedDumps ReleaseDumps();
79 
80   // Adds an RTP packet to the dump. The caller must make sure it's a valid RTP
81   // packet.
82   void OnRtpPacket(const uint8_t* packet_header,
83                    size_t header_length,
84                    size_t packet_length,
85                    bool incoming);
86 
87   // Stops all ongoing dumps and call |callback| when finished.
88   void StopOngoingDumps(base::OnceClosure callback);
89 
90  private:
91   friend class WebRtcRtpDumpHandlerTest;
92 
93   // State transitions:
94   // initial --> STATE_NONE
95   // StartDump --> STATE_STARTED
96   // StopDump --> STATE_STOPPED
97   // ReleaseDump --> STATE_RELEASING
98   // ReleaseDump done --> STATE_NONE
99   enum State {
100     STATE_NONE,
101     STATE_STARTED,
102     STATE_STOPPING,
103     STATE_STOPPED,
104   };
105 
106   // For unit test to inject a fake writer.
107   void SetDumpWriterForTesting(std::unique_ptr<WebRtcRtpDumpWriter> writer);
108 
109   // Callback from the dump writer when the max dump size is reached.
110   void OnMaxDumpSizeReached();
111 
112   // Callback from the dump writer when ending dumps finishes. Calls |callback|
113   // when finished.
114   void OnDumpEnded(base::OnceClosure callback,
115                    RtpDumpType ended_type,
116                    bool incoming_succeeded,
117                    bool outgoing_succeeded);
118 
119   SEQUENCE_CHECKER(main_sequence_);
120 
121   // The absolute path to the directory containing the incoming/outgoing dumps.
122   const base::FilePath dump_dir_;
123 
124   // The dump file paths.
125   base::FilePath incoming_dump_path_;
126   base::FilePath outgoing_dump_path_;
127 
128   // The states of the incoming and outgoing dump.
129   State incoming_state_;
130   State outgoing_state_;
131 
132   // The object used to create and write the dump file.
133   std::unique_ptr<WebRtcRtpDumpWriter> dump_writer_;
134 
135   base::WeakPtrFactory<WebRtcRtpDumpHandler> weak_ptr_factory_{this};
136 
137   DISALLOW_COPY_AND_ASSIGN(WebRtcRtpDumpHandler);
138 };
139 
140 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_WEBRTC_RTP_DUMP_HANDLER_H_
141