12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Given a starting render_process_id and main_render_frame_id, the
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// WebContentsTracker tracks changes to the active RenderFrameHost tree during
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the lifetime of a WebContents instance.  This is used when mirroring tab
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// video and audio so that user navigations, crashes, iframes, etc., during a
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// tab's lifetime allow the capturing code to remain active on the
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// current/latest render frame tree.
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Threading issues: Start(), Stop() and the ChangeCallback are invoked on the
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// same thread.  This can be any thread, and the decision is locked-in by
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WebContentsTracker when Start() is called.
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_TRACKER_H_
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_TRACKER_H_
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MessageLoopProxy;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass RenderWidgetHost;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT WebContentsTracker
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public base::RefCountedThreadSafe<WebContentsTracker>,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public WebContentsObserver {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If |track_fullscreen_rwh| is true, the ChangeCallback will be run when a
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebContents shows/destroys a fullscreen RenderWidgetHost view.  If false,
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // fullscreen events are ignored.  Specify true for video tab capture and
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // false for audio tab capture.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit WebContentsTracker(bool track_fullscreen_rwh);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Callback to indicate a new RenderWidgetHost should be targeted for capture.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is also invoked with NULL to indicate tracking will not continue
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // (i.e., the WebContents instance was not found or has been destroyed).
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef base::Callback<void(RenderWidgetHost* rwh)> ChangeCallback;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Start tracking.  The last-known |render_process_id| and
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |main_render_frame_id| are provided, and |callback| will be run once to
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // indicate the current capture target (this may occur during the invocation
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // of Start(), or in the future).  The callback will be invoked on the same
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // thread calling Start().
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void Start(int render_process_id, int main_render_frame_id,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const ChangeCallback& callback);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Stop tracking.  Once this method returns, the callback is guaranteed not to
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // be invoked again.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Stop();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Current target.  This must only be called on the UI BrowserThread.
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RenderWidgetHost* GetTargetRenderWidgetHost() const;
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class base::RefCountedThreadSafe<WebContentsTracker>;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WebContentsTracker();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Determine the target RenderWidgetHost and, if different from that last
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // reported, runs the ChangeCallback on the appropriate thread.  If
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |force_callback_run| is true, the ChangeCallback is run even if the
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // RenderWidgetHost has not changed.
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnPossibleTargetChange(bool force_callback_run);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Called on the thread that Start()/Stop() are called on.  Checks whether the
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // callback is still valid and, if so, runs it.
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void MaybeDoCallback(RenderWidgetHost* rwh);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Look-up the current WebContents instance associated with the given
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |render_process_id| and |main_render_frame_id| and begin observing it.
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void StartObservingWebContents(int render_process_id,
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 int main_render_frame_id);
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebContentsObserver overrides: According to web_contents_observer.h, these
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // two method overrides are all that is necessary to track the set of active
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // RenderFrameHosts.
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void RenderFrameHostChanged(RenderFrameHost* old_host,
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      RenderFrameHost* new_host) OVERRIDE;
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebContentsObserver override to notify the client that the capture target
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // has been permanently lost.
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void WebContentsDestroyed() OVERRIDE;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebContentsObserver overrides to notify the client that the capture target
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // may have changed due to a separate fullscreen widget shown/destroyed.
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE;
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If true, the client is interested in the showing/destruction of fullscreen
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // RenderWidgetHosts.
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const bool track_fullscreen_rwh_;
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // MessageLoop corresponding to the thread that called Start().
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_;
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Callback to run when the target RenderWidgetHost has changed.
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChangeCallback callback_;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Pointer to the RenderWidgetHost provided in the last run of |callback_|.
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is used to eliminate duplicate callback runs.
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RenderWidgetHost* last_target_;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebContentsTracker);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // CONTENT_BROWSER_MEDIA_CAPTURE_WEB_CONTENTS_TRACKER_H_
118