| // Copyright (c) 2021 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_FOCUS_DELEGATE_H_ |
| #define CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_FOCUS_DELEGATE_H_ |
| |
| #include "build/build_config.h" |
| |
| #if BUILDFLAG(IS_ANDROID) |
| #error "Unsupported on Android." |
| #endif // BUILDFLAG(IS_ANDROID) |
| |
| #include "base/compiler_specific.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/bad_message.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" |
| #include "content/public/browser/desktop_media_id.h" |
| #include "content/public/browser/web_contents.h" |
| |
| // When tab/window-capture is initiated, a window of opportunity opens, |
| // during which the render process can instruct the browser process as to |
| // whether to focus the tab/window or not. |
| // The window of opportunity is closed when either: |
| // (a) The render process sends its decision. |
| // (b) After 1s elapses (MediaStreamManager independently calls SetFocus). |
| // (c) The user changes the focused tab. |
| // (d) The user changes the activated window. |
| class MediaStreamFocusDelegate : public TabStripModelObserver { |
| public: |
| explicit MediaStreamFocusDelegate(content::WebContents* web_contents); |
| |
| ~MediaStreamFocusDelegate() override; |
| |
| MediaStreamFocusDelegate(const MediaStreamFocusDelegate&) = delete; |
| MediaStreamFocusDelegate& operator=(const MediaStreamFocusDelegate&) = delete; |
| |
| void SetFocus(const content::DesktopMediaID& media_id, |
| bool focus, |
| bool is_from_microtask, |
| bool is_from_timer); |
| |
| // TabStripModelObserver implementation. |
| void OnTabStripModelChanged( |
| TabStripModel* tab_strip_model, |
| const TabStripModelChange& change, |
| const TabStripSelectionChange& selection) override; |
| |
| private: |
| bool IsWidgetFocused() const; |
| void FocusTab(const content::DesktopMediaID& media_id); |
| void FocusWindow(const content::DesktopMediaID& media_id); |
| |
| // Returns a bool representing the validity of the call. |
| // If |false|, the call was found to be invalid, the capturer's render |
| // process was killed off, and execution of the focus-delegate logic |
| // should not proceed. |
| bool UpdateUMA(bool focus, |
| bool is_from_microtask, |
| bool is_from_timer) WARN_UNUSED_RESULT; |
| |
| // Kills off capturer render-process. |
| // Returns |false| to make UpdateUMA()'s code a bit nicer. |
| bool BadMessage(bad_message::BadMessageReason reason) WARN_UNUSED_RESULT; |
| |
| // UMA-related. |
| const base::TimeTicks capture_start_time_; |
| bool microtask_fired_ = false; |
| bool timer_expired_ = false; |
| bool explicit_decision_ = false; |
| |
| // |focus_window_of_opportunity_open_| tracks whether the window of |
| // opportunity is open or closed. |
| // |capturing_web_contents_| is used to check whether the Chrome window from |
| // which the capture was initiated is still the active one. If not, then we |
| // want to avoid yanking the user's focus around. |
| base::WeakPtr<content::WebContents> capturing_web_contents_ = nullptr; |
| bool focus_window_of_opportunity_open_ = true; |
| }; |
| |
| #endif // CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_STREAM_FOCUS_DELEGATE_H_ |