| // Copyright 2016 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_ANDROID_VR_VR_SHELL_H_ |
| #define CHROME_BROWSER_ANDROID_VR_VR_SHELL_H_ |
| |
| #include <jni.h> |
| |
| #include <memory> |
| |
| #include "base/android/scoped_java_ref.h" |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/strings/string16.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/ui/page_info/page_info_ui.h" |
| #include "chrome/browser/ui/toolbar/chrome_location_bar_model_delegate.h" |
| #include "chrome/browser/vr/assets_load_status.h" |
| #include "chrome/browser/vr/exit_vr_prompt_choice.h" |
| #include "chrome/browser/vr/metrics/session_metrics_helper.h" |
| #include "chrome/browser/vr/model/capturing_state_model.h" |
| #include "chrome/browser/vr/platform_ui_input_delegate.h" |
| #include "chrome/browser/vr/speech_recognizer.h" |
| #include "chrome/browser/vr/ui_browser_interface.h" |
| #include "chrome/browser/vr/ui_initial_state.h" |
| #include "chrome/browser/vr/ui_unsupported_mode.h" |
| #include "content/public/browser/web_contents_observer.h" |
| #include "device/vr/android/gvr/cardboard_gamepad_data_provider.h" |
| #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" |
| #include "device/vr/public/mojom/vr_service.mojom.h" |
| #include "device/vr/vr_device.h" |
| #include "services/device/public/mojom/geolocation_config.mojom.h" |
| #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" |
| |
| namespace base { |
| class Version; |
| } // namespace base |
| |
| namespace content { |
| class WebContents; |
| } // namespace content |
| |
| namespace gl { |
| class SurfaceTexture; |
| } |
| |
| namespace vr { |
| |
| class BrowserUiInterface; |
| class AndroidUiGestureTarget; |
| class AutocompleteController; |
| class LocationBarHelper; |
| class VrGLThread; |
| class VrInputConnection; |
| class VrShellDelegate; |
| class VrWebContentsObserver; |
| enum class UiTestOperationType; |
| enum class UiTestOperationResult; |
| struct Assets; |
| struct AutocompleteRequest; |
| |
| // The native instance of the Java VrShell. This class is not threadsafe and |
| // must only be used on the UI thread. |
| class VrShell : device::GvrGamepadDataProvider, |
| device::CardboardGamepadDataProvider, |
| VoiceResultDelegate, |
| public ChromeLocationBarModelDelegate, |
| public PageInfoUI { |
| public: |
| VrShell(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| const UiInitialState& ui_initial_state, |
| VrShellDelegate* delegate, |
| gvr_context* gvr_api, |
| bool reprojected_rendering, |
| float display_width_meters, |
| float display_height_meters, |
| int display_width_pixels, |
| int display_height_pixels, |
| bool pause_content, |
| bool low_density); |
| bool HasUiFinishedLoading(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| void SwapContents(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| const base::android::JavaParamRef<jobject>& web_contents); |
| void SetAndroidGestureTarget( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| const base::android::JavaParamRef<jobject>& android_ui_gesture_target); |
| void SetDialogGestureTarget( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| const base::android::JavaParamRef<jobject>& dialog_gesture_target); |
| void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); |
| void OnTriggerEvent(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| bool touched); |
| void OnPause(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); |
| void OnResume(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); |
| void SetSurface(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| const base::android::JavaParamRef<jobject>& surface); |
| void SetWebVrMode(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| bool enabled); |
| bool GetWebVrMode(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| bool IsDisplayingUrlForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| base::android::ScopedJavaLocalRef<jobject> GetVrInputConnectionForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| void OnLoadProgressChanged(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| double progress); |
| void OnTabListCreated( |
| JNIEnv* env, |
| const base::android::JavaRef<jobject>& obj, |
| const base::android::JavaRef<jobjectArray>& tabs, |
| const base::android::JavaRef<jobjectArray>& incognito_tabs); |
| void OnTabUpdated(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jboolean incognito, |
| jint id, |
| jstring jtitle); |
| void OnTabRemoved(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jboolean incognito, |
| jint id); |
| void Navigate(GURL url, NavigationMethod method); |
| void NavigateBack(); |
| void NavigateForward(); |
| void ReloadTab(); |
| void OpenNewTab(bool incognito); |
| void OpenBookmarks(); |
| void OpenRecentTabs(); |
| void OpenHistory(); |
| void OpenDownloads(); |
| void OpenShare(); |
| void OpenSettings(); |
| void CloseAllIncognitoTabs(); |
| void OpenFeedback(); |
| void CloseHostedDialog(); |
| void ToggleCardboardGamepad(bool enabled); |
| void ToggleGvrGamepad(bool enabled); |
| void SetHistoryButtonsEnabled(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jboolean can_go_back, |
| jboolean can_go_forward); |
| void RequestToExitVr(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| int reason); |
| void LogUnsupportedModeUserMetric( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| int mode); |
| |
| void ShowSoftInput(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| bool show); |
| void UpdateWebInputIndices(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| int selection_start, |
| int selection_end, |
| int composition_start, |
| int composition_end); |
| void ResumeContentRendering(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| void OnOverlayTextureEmptyChanged( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jboolean empty); |
| |
| void ContentWebContentsDestroyed(); |
| |
| void ContentSurfaceCreated(jobject surface, gl::SurfaceTexture* texture); |
| void ContentOverlaySurfaceCreated(jobject surface, |
| gl::SurfaceTexture* texture); |
| void GvrDelegateReady(gvr::ViewerType viewer_type); |
| void SendRequestPresentReply(device::mojom::XRSessionPtr); |
| |
| void DialogSurfaceCreated(jobject surface, gl::SurfaceTexture* texture); |
| |
| void BufferBoundsChanged(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& object, |
| jint content_width, |
| jint content_height, |
| jint overlay_width, |
| jint overlay_height); |
| |
| void ForceExitVr(); |
| void ExitPresent(); |
| void ExitFullscreen(); |
| void LogUnsupportedModeUserMetric(UiUnsupportedMode mode); |
| void RecordVrStartAction(VrStartAction action); |
| void RecordPresentationStartAction(PresentationStartAction action); |
| void OnUnsupportedMode(UiUnsupportedMode mode); |
| void OnExitVrPromptResult(UiUnsupportedMode reason, |
| ExitVrPromptChoice choice); |
| void OnContentScreenBoundsChanged(const gfx::SizeF& bounds); |
| void SetVoiceSearchActive(bool active); |
| void StartAutocomplete(const AutocompleteRequest& request); |
| void StopAutocomplete(); |
| void ShowPageInfo(); |
| bool HasRecordAudioPermission() const; |
| bool CanRequestRecordAudioPermission() const; |
| void RequestRecordAudioPermissionResult( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& object, |
| jboolean can_record_audio); |
| |
| void ClearFocusedElement(); |
| void ProcessContentGesture(std::unique_ptr<InputEvent> event, int content_id); |
| |
| void ProcessDialogGesture(std::unique_ptr<InputEvent> event); |
| |
| void SetAlertDialog(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| float width, |
| float height); |
| void CloseAlertDialog(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| void SetDialogBufferSize(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| int width, |
| int height); |
| void SetAlertDialogSize(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| float width, |
| float height); |
| void SetDialogLocation(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| float x, |
| float y); |
| void SetDialogFloating(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| bool floating); |
| |
| void ShowToast(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jstring text); |
| void CancelToast(JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| |
| void ConnectPresentingService( |
| device::mojom::VRDisplayInfoPtr display_info, |
| device::mojom::XRRuntimeSessionOptionsPtr options); |
| |
| // device::GvrGamepadDataProvider implementation. |
| void UpdateGamepadData(device::GvrGamepadData) override; |
| void RegisterGvrGamepadDataFetcher(device::GvrGamepadDataFetcher*) override; |
| |
| // device::CardboardGamepadDataProvider implementation. |
| void RegisterCardboardGamepadDataFetcher( |
| device::CardboardGamepadDataFetcher*) override; |
| |
| // ChromeLocationBarModelDelegate implementation. |
| content::WebContents* GetActiveWebContents() const override; |
| bool ShouldDisplayURL() const override; |
| |
| void OnVoiceResults(const base::string16& result) override; |
| |
| void OnAssetsLoaded(AssetsLoadStatus status, |
| std::unique_ptr<Assets> assets, |
| const base::Version& component_version); |
| |
| // PageInfoUI implementation. |
| void SetCookieInfo(const CookieInfoList& cookie_info_list) override; |
| void SetPermissionInfo(const PermissionInfoList& permission_info_list, |
| ChosenObjectInfoList chosen_object_info_list) override; |
| void SetIdentityInfo(const IdentityInfo& identity_info) override; |
| void SetPageFeatureInfo(const PageFeatureInfo& info) override; |
| |
| void AcceptDoffPromptForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj); |
| |
| void SetUiExpectingActivityForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jint quiescence_timeout_ms); |
| |
| void SaveNextFrameBufferToDiskForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jstring filepath_base); |
| |
| void WatchElementForVisibilityStatusForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jint element_name, |
| jint timeout_ms, |
| jboolean visibility); |
| |
| void ReportUiOperationResultForTesting(UiTestOperationType action_type, |
| UiTestOperationResult result); |
| |
| void PerformControllerActionForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jint element_name, |
| jint action_type, |
| jfloat x, |
| jfloat y); |
| |
| void PerformKeyboardInputForTesting( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& obj, |
| jint input_type, |
| jstring input_string); |
| gfx::AcceleratedWidget GetRenderSurface(); |
| |
| private: |
| ~VrShell() override; |
| void PostToGlThread(const base::Location& from_here, base::OnceClosure task); |
| void SetUiState(); |
| |
| void PollCapturingState(); |
| |
| bool HasDaydreamSupport(JNIEnv* env); |
| |
| content::WebContents* GetNonNativePageWebContents() const; |
| |
| void LoadAssets(); |
| void OnAssetsComponentReady(); |
| void OnAssetsComponentWaitTimeout(); |
| |
| void SetWebContents(content::WebContents* contents); |
| std::unique_ptr<PageInfo> CreatePageInfo(); |
| |
| bool webvr_mode_ = false; |
| |
| content::WebContents* web_contents_ = nullptr; |
| bool web_contents_is_native_page_ = false; |
| base::android::ScopedJavaGlobalRef<jobject> j_motion_event_synthesizer_; |
| |
| std::unique_ptr<VrWebContentsObserver> vr_web_contents_observer_; |
| // Note this must be destroyed after VrGLThread is destroyed in the |
| // destruction of VrShell. VrGLThread keeps a raw pointer of VrInputConnection |
| // and uses the pointer on GL thread. |
| std::unique_ptr<VrInputConnection> vr_input_connection_; |
| |
| VrShellDelegate* delegate_provider_ = nullptr; |
| base::android::ScopedJavaGlobalRef<jobject> j_vr_shell_; |
| |
| std::unique_ptr<AndroidUiGestureTarget> android_ui_gesture_target_; |
| std::unique_ptr<AndroidUiGestureTarget> dialog_gesture_target_; |
| |
| scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; |
| std::unique_ptr<VrGLThread> gl_thread_; |
| BrowserUiInterface* ui_; |
| |
| // These instances make use of ui_ (provided by gl_thread_), and hence must be |
| // destroyed before gl_thread_; |
| std::unique_ptr<LocationBarHelper> toolbar_; |
| std::unique_ptr<vr::AutocompleteController> autocomplete_controller_; |
| std::unique_ptr<SpeechRecognizer> speech_recognizer_; |
| |
| bool reprojected_rendering_; |
| |
| device::mojom::GeolocationConfigPtr geolocation_config_; |
| |
| base::CancelableClosure poll_capturing_state_task_; |
| CapturingStateModel active_capturing_; |
| CapturingStateModel background_capturing_; |
| CapturingStateModel potential_capturing_; |
| |
| // Are we currently providing a gamepad factory to the gamepad manager? |
| bool gvr_gamepad_source_active_ = false; |
| bool cardboard_gamepad_source_active_ = false; |
| bool pending_cardboard_trigger_ = false; |
| |
| // Registered fetchers, must remain alive for UpdateGamepadData calls. |
| // That's ok since the fetcher is only destroyed from VrShell's destructor. |
| device::GvrGamepadDataFetcher* gvr_gamepad_data_fetcher_ = nullptr; |
| device::CardboardGamepadDataFetcher* cardboard_gamepad_data_fetcher_ = |
| nullptr; |
| int64_t cardboard_gamepad_timer_ = 0; |
| |
| // Content id |
| int content_id_ = 0; |
| |
| gfx::SizeF display_size_meters_; |
| gfx::Size display_size_pixels_; |
| |
| gl::SurfaceTexture* content_surface_texture_ = nullptr; |
| gl::SurfaceTexture* overlay_surface_texture_ = nullptr; |
| gl::SurfaceTexture* ui_surface_texture_ = nullptr; |
| |
| base::OneShotTimer waiting_for_assets_component_timer_; |
| bool can_load_new_assets_ = false; |
| bool ui_finished_loading_ = false; |
| |
| base::WaitableEvent gl_surface_created_event_; |
| gfx::AcceleratedWidget surface_window_ = nullptr; |
| |
| std::set<int> regular_tab_ids_; |
| std::set<int> incognito_tab_ids_; |
| |
| base::WeakPtrFactory<VrShell> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(VrShell); |
| }; |
| |
| } // namespace vr |
| |
| #endif // CHROME_BROWSER_ANDROID_VR_VR_SHELL_H_ |