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