146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#ifndef CHROME_BROWSER_MEDIA_WEBRTC_RTP_DUMP_HANDLER_H_
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define CHROME_BROWSER_MEDIA_WEBRTC_RTP_DUMP_HANDLER_H_
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/basictypes.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/callback.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/files/file_path.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/weak_ptr.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/media/rtp_dump_type.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class WebRtcRtpDumpWriter;
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// WebRtcRtpDumpHandler handles operations regarding the WebRTC RTP dump:
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// - Starts or stops the RTP dumping on behalf of the client.
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// - Stops the RTP dumping when the max dump file size is reached.
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// - Writes the dump file.
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// - Provides the dump file to the client code to be uploaded when
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//   ReleaseRtpDump is called.
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// - Cleans up the dump file if not transferred to the client before the object
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//   is destroyed.
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Must be created/used/destroyed on the browser IO thread.
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class WebRtcRtpDumpHandler {
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  typedef base::Callback<void(bool, const std::string&)> GenericDoneCallback;
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  struct ReleasedDumps {
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ReleasedDumps(const base::FilePath& incoming_dump,
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                  const base::FilePath& outgoing_dump)
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        : incoming_dump_path(incoming_dump),
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          outgoing_dump_path(outgoing_dump) {}
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::FilePath incoming_dump_path;
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::FilePath outgoing_dump_path;
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  };
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The caller must make sure |dump_dir| exists. RTP dump files are saved under
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |dump_dir| as "rtpdump_$DIRECTION_$TIMESTAMP.gz", where $DIRECTION is
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // 'send' for outgoing dump or 'recv' for incoming dump. $TIMESTAMP is the
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // dump started time converted to a double number in microsecond precision,
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // which should guarantee the uniqueness across tabs and dump streams in
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // practice.
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  explicit WebRtcRtpDumpHandler(const base::FilePath& dump_dir);
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ~WebRtcRtpDumpHandler();
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Starts the specified type of dumping. Incoming/outgoing dumping can be
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // started separately. Returns true if called in a valid state, i.e. the
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // specified type of dump has not been started.
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool StartDump(RtpDumpType type, std::string* error_message);
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stops the specified type of dumping. Incoming/outgoing dumping can be
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // stopped separately. Returns asynchronously through |callback|, where
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |success| is true if StopDump is called in a valid state. The callback is
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // called when the writer finishes writing the dumps.
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void StopDump(RtpDumpType type, const GenericDoneCallback& callback);
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns true if it's valid to call ReleaseDumps, i.e. no dumping is ongoing
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // or being stopped.
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool ReadyToRelease() const;
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Releases all the dumps and resets the state.
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // It should only be called when both incoming and outgoing dumping has been
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // stopped, i.e. ReadyToRelease() returns true. Returns the dump file paths.
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  //
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The caller will own the dump file after the method returns. If ReleaseDump
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // is not called before this object goes away, the dump file will be deleted
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // by this object.
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ReleasedDumps ReleaseDumps();
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Adds an RTP packet to the dump. The caller must make sure it's a valid RTP
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // packet.
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnRtpPacket(const uint8* packet_header,
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   size_t header_length,
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   size_t packet_length,
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   bool incoming);
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stops all ongoing dumps and call |callback| when finished.
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void StopOngoingDumps(const base::Closure& callback);
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  friend class WebRtcRtpDumpHandlerTest;
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // State transitions:
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // initial --> STATE_NONE
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // StartDump --> STATE_STARTED
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // StopDump --> STATE_STOPPED
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // ReleaseDump --> STATE_RELEASING
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // ReleaseDump done --> STATE_NONE
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  enum State {
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATE_NONE,
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATE_STARTED,
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATE_STOPPING,
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    STATE_STOPPED,
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  };
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // For unit test to inject a fake writer.
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SetDumpWriterForTesting(scoped_ptr<WebRtcRtpDumpWriter> writer);
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Callback from the dump writer when the max dump size is reached.
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnMaxDumpSizeReached();
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Callback from the dump writer when ending dumps finishes. Calls |callback|
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // when finished.
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnDumpEnded(const base::Closure& callback,
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   RtpDumpType ended_type,
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   bool incoming_succeeded,
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   bool outgoing_succeeded);
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The absolute path to the directory containing the incoming/outgoing dumps.
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const base::FilePath dump_dir_;
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The dump file paths.
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::FilePath incoming_dump_path_;
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::FilePath outgoing_dump_path_;
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The states of the incoming and outgoing dump.
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  State incoming_state_;
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  State outgoing_state_;
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The object used to create and write the dump file.
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<WebRtcRtpDumpWriter> dump_writer_;
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::WeakPtrFactory<WebRtcRtpDumpHandler> weak_ptr_factory_;
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebRtcRtpDumpHandler);
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // CHROME_BROWSER_MEDIA_WEBRTC_RTP_DUMP_HANDLER_H_
132