capture_mode_camera_preview_view.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright 2022 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. #ifndef ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_
  5. #define ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_
  6. #include "ash/accessibility/accessibility_controller_impl.h"
  7. #include "ash/accessibility/accessibility_observer.h"
  8. #include "ash/capture_mode/camera_video_frame_renderer.h"
  9. #include "ash/capture_mode/capture_mode_button.h"
  10. #include "ash/capture_mode/capture_mode_camera_controller.h"
  11. #include "ash/capture_mode/capture_mode_session_focus_cycler.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/scoped_observation.h"
  14. #include "mojo/public/cpp/bindings/remote.h"
  15. #include "ui/base/metadata/metadata_header_macros.h"
  16. #include "ui/gfx/geometry/size.h"
  17. #include "ui/views/view.h"
  18. namespace media {
  19. struct VideoCaptureFormat;
  20. } // namespace media
  21. namespace video_capture::mojom {
  22. class VideoSource;
  23. } // namespace video_capture::mojom
  24. namespace views {
  25. class NativeViewHost;
  26. } // namespace views
  27. namespace ash {
  28. class CaptureModeCameraController;
  29. class ScopedA11yOverrideWindowSetter;
  30. // Resize button inside the camera preview view.
  31. class CameraPreviewResizeButton : public CaptureModeButton {
  32. public:
  33. METADATA_HEADER(CameraPreviewResizeButton);
  34. CameraPreviewResizeButton(CameraPreviewView* camera_preview_view,
  35. views::Button::PressedCallback callback,
  36. const gfx::VectorIcon& icon);
  37. CameraPreviewResizeButton(const CameraPreviewResizeButton&) = delete;
  38. CameraPreviewResizeButton& operator=(const CameraPreviewResizeButton&) =
  39. delete;
  40. ~CameraPreviewResizeButton() override;
  41. // CaptureModeSessionFocusCycler::HighlightableView:
  42. void PseudoFocus() override;
  43. void PseudoBlur() override;
  44. private:
  45. CameraPreviewView* const camera_preview_view_; // not owned.
  46. };
  47. // A view that acts as the contents view of the camera preview widget. It will
  48. // be responsible for painting the latest camera video frame inside its bounds.
  49. class CameraPreviewView
  50. : public views::View,
  51. public CaptureModeSessionFocusCycler::HighlightableView,
  52. public AccessibilityObserver {
  53. public:
  54. METADATA_HEADER(CameraPreviewView);
  55. CameraPreviewView(
  56. CaptureModeCameraController* camera_controller,
  57. const CameraId& camera_id,
  58. mojo::Remote<video_capture::mojom::VideoSource> camera_video_source,
  59. const media::VideoCaptureFormat& capture_format,
  60. bool should_flip_frames_horizontally);
  61. CameraPreviewView(const CameraPreviewView&) = delete;
  62. CameraPreviewView& operator=(const CameraPreviewView&) = delete;
  63. ~CameraPreviewView() override;
  64. const CameraId& camera_id() const { return camera_id_; }
  65. CameraPreviewResizeButton* resize_button() const { return resize_button_; }
  66. bool is_collapsible() const { return is_collapsible_; }
  67. bool should_flip_frames_horizontally() const {
  68. return camera_video_renderer_.should_flip_frames_horizontally();
  69. }
  70. // Sets this camera preview collapsability to the given `value`, which will
  71. // update the resize button visibility.
  72. void SetIsCollapsible(bool value);
  73. // Returns true if the `event` has been handled by CameraPrevieView. It
  74. // happens if it is control+arrow keys, which will be used to move the camera
  75. // preview to different snap positions.
  76. bool MaybeHandleKeyEvent(const ui::KeyEvent* event);
  77. // Called to update visibility of the `resize_button_` when necessary.
  78. void RefreshResizeButtonVisibility();
  79. // Updates the a11y override window when focus state changes on the camera
  80. // preview. The a11y override window will be set to nullptr if neither the
  81. // camera preview nor the resize button has focus. This is done to make sure
  82. // a11y focus can be moved to others appropriately.
  83. void UpdateA11yOverrideWindow();
  84. // Removes the focus from camera preview when necessary. Happens if mouse
  85. // pressing outside of the camera preview when it has focus. A11y override
  86. // window will be updated as well.
  87. void MaybeBlurFocus(const ui::MouseEvent& event);
  88. // views::View:
  89. void AddedToWidget() override;
  90. bool OnMousePressed(const ui::MouseEvent& event) override;
  91. bool OnMouseDragged(const ui::MouseEvent& event) override;
  92. void OnMouseReleased(const ui::MouseEvent& event) override;
  93. void OnGestureEvent(ui::GestureEvent* event) override;
  94. void OnMouseEntered(const ui::MouseEvent& event) override;
  95. void OnMouseExited(const ui::MouseEvent& event) override;
  96. void Layout() override;
  97. void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  98. // CaptureModeSessionFocusCycler::HighlightableView:
  99. views::View* GetView() override;
  100. std::unique_ptr<views::HighlightPathGenerator> CreatePathGenerator() override;
  101. // AccessibilityObserver:
  102. void OnAccessibilityStatusChanged() override;
  103. void OnAccessibilityControllerShutdown() override;
  104. base::OneShotTimer* resize_button_hide_timer_for_test() {
  105. return &resize_button_hide_timer_;
  106. }
  107. private:
  108. friend class CameraPreviewResizeButton;
  109. friend class CaptureModeTestApi;
  110. // Called when the resize button is clicked or touched.
  111. void OnResizeButtonPressed();
  112. // Updates the icon of the `resize_button_` based on value of
  113. // `is_camera_preview_collapsed()` inferred from the `camera_controller`.
  114. void UpdateResizeButton();
  115. // Updates the tooltip of the `resize_button_`. The `resize_button_` can be an
  116. // expand button or collapse button.
  117. void UpdateResizeButtonTooltip();
  118. // Located events within the bounds of this view should be sent to, and
  119. // handled by this view only (e.g. for drag and drop). They should not be sent
  120. // to any native window hosting the camera video frames, otherwise we will
  121. // lose those events. This function disable event targeting for the
  122. // `camera_video_host_view_` and all the native windows it is hosting.
  123. void DisableEventHandlingInCameraVideoHostHierarchy();
  124. // Fades in or out the `resize_button_` and updates its visibility
  125. // accordingly.
  126. void FadeInResizeButton();
  127. void FadeOutResizeButton();
  128. // Called when the mouse exits the camera preview, after the latest tap inside
  129. // the camera preview or when focus being removed from the resize button to
  130. // start the `resize_button_hide_timer_`.
  131. void ScheduleRefreshResizeButtonVisibility();
  132. // Returns the target opacity for resize button.
  133. float CalculateResizeButtonTargetOpacity();
  134. // Removes the focus from the camera preview and updates the a11y override
  135. // window.
  136. void BlurA11yFocus();
  137. CaptureModeCameraController* const camera_controller_;
  138. // The ID of the camera for which this preview was created.
  139. const CameraId camera_id_;
  140. // Renders the camera video frames into its `host_window()`.
  141. CameraVideoFrameRenderer camera_video_renderer_;
  142. // The view that hosts the native window `host_window()` of the
  143. // `camera_video_renderer_` into this view's hierarchy.
  144. views::NativeViewHost* const camera_video_host_view_;
  145. CameraPreviewResizeButton* const resize_button_;
  146. // Started when the mouse exits the camera preview or after the latest tap
  147. // inside the camera preview. Runs RefreshResizeButtonVisibility() to fade out
  148. // the resize button if possible.
  149. base::OneShotTimer resize_button_hide_timer_;
  150. // True if the size of the preview in the expanded state is big enough to
  151. // allow it to be collapsible.
  152. bool is_collapsible_ = true;
  153. // True only while handling a gesture tap event on this view.
  154. bool has_been_tapped_ = false;
  155. base::ScopedObservation<AccessibilityControllerImpl, AccessibilityObserver>
  156. accessibility_observation_{this};
  157. // Helps to update the current a11y override window. It will be the native
  158. // window of the camera preview or nullptr, depends on whether the camera
  159. // preview has focus or not. Accessibility features will focus on the window
  160. // after it is set. Once `this` goes out of scope, the a11y override window is
  161. // set to nullptr.
  162. std::unique_ptr<ScopedA11yOverrideWindowSetter> scoped_a11y_overrider_;
  163. base::WeakPtrFactory<CameraPreviewView> weak_ptr_factory_{this};
  164. };
  165. } // namespace ash
  166. #endif // ASH_CAPTURE_MODE_CAPTURE_MODE_CAMERA_PREVIEW_VIEW_H_