From d68a05a9d5eb7dbe2280b5838d379f8807cae22d Mon Sep 17 00:00:00 2001 From: Yash Malik Date: Fri, 2 Mar 2018 01:06:54 +0000 Subject: [PATCH] VR: Add java-side plumbing for updating GVR Keyboard Note that this path is not exercised yet. Bug: 799584 Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_vr;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel Change-Id: I45f34d54eabcbd539c17d3d87ba8c029489a0f28 Reviewed-on: https://chromium-review.googlesource.com/944750 Commit-Queue: Yash Malik Reviewed-by: Michael Thiessen Cr-Commit-Position: refs/heads/master@{#540391} --- .../chrome/browser/vr_shell/VrShellDelegate.java | 14 ++++++++++++++ .../chrome/browser/vr_shell/VrShellImpl.java | 15 +++++++++++++++ .../browser/android/vr/gvr_keyboard_delegate.cc | 14 ++++++++++++-- chrome/browser/android/vr/gvr_keyboard_shim.cc | 9 ++++++++- chrome/browser/android/vr/vr_gl_thread.cc | 2 ++ chrome/browser/android/vr/vr_shell.cc | 5 +++++ chrome/browser/vr/model/modal_prompt_type.cc | 2 ++ chrome/browser/vr/model/modal_prompt_type.h | 1 + chrome/browser/vr/model/model.h | 1 + chrome/browser/vr/ui.cc | 4 ++++ chrome/browser/vr/ui.h | 1 + chrome/browser/vr/ui_unsupported_mode.h | 1 + tools/metrics/histograms/enums.xml | 2 ++ 13 files changed, 68 insertions(+), 3 deletions(-) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index c59ef4c27500..00a7861d3a9a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java @@ -87,6 +87,7 @@ public class VrShellDelegate // when used with startActivityForResult... public static final int EXIT_VR_RESULT = 7212; public static final int VR_SERVICES_UPDATE_RESULT = 7213; + public static final int GVR_KEYBOARD_UPDATE_RESULT = 7214; private static final int ENTER_VR_NOT_NECESSARY = 0; private static final int ENTER_VR_CANCELLED = 1; @@ -113,6 +114,9 @@ public class VrShellDelegate private static final String VR_CORE_MARKET_URI = "market://details?id=" + VrCoreVersionChecker.VR_CORE_PACKAGE_ID; + private static final String GVR_KEYBOARD_MARKET_URI = + "market://details?id=com.google.android.vr.inputmethod"; + // This value is intentionally probably overkill. This is the time we need to wait from when // Chrome is resumed, to when Chrome actually renders a black frame, so that we can cancel the // stay_hidden animation and not see a white monoscopic frame in-headset. 150ms is definitely @@ -322,6 +326,10 @@ public static boolean onActivityResultWithNative(int requestCode, int resultCode if (sInstance != null) sInstance.onVrServicesMaybeUpdated(); return true; } + // Handles the result of requesting to update GVR Keyboard. + if (requestCode == GVR_KEYBOARD_UPDATE_RESULT) { + return true; + } return false; } @@ -1776,6 +1784,12 @@ public boolean onInfoBarButtonClicked(boolean isPrimary) { buttonText, null, true); } + /* package */ void promptForKeyboardUpdate() { + mActivity.startActivityForResult( + new Intent(Intent.ACTION_VIEW, Uri.parse(GVR_KEYBOARD_MARKET_URI)), + GVR_KEYBOARD_UPDATE_RESULT); + } + private boolean createVrShell() { assert mVrShell == null; if (mVrClassesWrapper == null) return false; diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 42468f84452a..aac100831ac4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java @@ -513,6 +513,21 @@ public void onDenied() {} }, UiUnsupportedMode.VOICE_SEARCH_NEEDS_RECORD_AUDIO_OS_PERMISSION); } + // Called when the user has an older GVR Keyboard installed on their device and we need them to + // have a newer one. + @CalledByNative + public void onNeedsKeyboardUpdate() { + VrShellDelegate.requestToExitVr(new OnExitVrRequestListener() { + @Override + public void onSucceeded() { + mDelegate.promptForKeyboardUpdate(); + } + + @Override + public void onDenied() {} + }, UiUnsupportedMode.NEEDS_KEYBOARD_UPDATE); + } + // Exits CCT, returning to the app that opened it. @CalledByNative public void exitCct() { diff --git a/chrome/browser/android/vr/gvr_keyboard_delegate.cc b/chrome/browser/android/vr/gvr_keyboard_delegate.cc index bb7eec83fdf7..fa28bcb43152 100644 --- a/chrome/browser/android/vr/gvr_keyboard_delegate.cc +++ b/chrome/browser/android/vr/gvr_keyboard_delegate.cc @@ -17,10 +17,14 @@ // This method is supplied by the VR keyboard shim, but is not part of the // GVR interface. -bool gvr_keyboard_supports_selection(gvr_keyboard_context* context); +bool gvr_keyboard_supports_selection(); +int64_t gvr_keyboard_version(); namespace vr { +// The minimum keyboard version required for the needed features to work. +constexpr int64_t kMinRequiredApiVersion = 2; + namespace { void OnKeyboardEvent(void* closure, GvrKeyboardDelegate::EventType event) { @@ -38,6 +42,12 @@ std::unique_ptr GvrKeyboardDelegate::Create() { auto* gvr_keyboard = gvr_keyboard_create(callback, OnKeyboardEvent); if (!gvr_keyboard) return nullptr; + + if (gvr_keyboard_version() < kMinRequiredApiVersion) { + gvr_keyboard_destroy(&gvr_keyboard); + return nullptr; + } + delegate->Init(gvr_keyboard); return delegate; } @@ -126,7 +136,7 @@ void GvrKeyboardDelegate::Draw(const CameraModel& model) { } bool GvrKeyboardDelegate::SupportsSelection() { - return gvr_keyboard_supports_selection(gvr_keyboard_); + return gvr_keyboard_supports_selection(); } void GvrKeyboardDelegate::OnTouchStateUpdated( diff --git a/chrome/browser/android/vr/gvr_keyboard_shim.cc b/chrome/browser/android/vr/gvr_keyboard_shim.cc index 14ad8e0c052c..c64cd3e7bfd3 100644 --- a/chrome/browser/android/vr/gvr_keyboard_shim.cc +++ b/chrome/browser/android/vr/gvr_keyboard_shim.cc @@ -282,7 +282,14 @@ void gvr_keyboard_hide(gvr_keyboard_context* context) { keyboard_api->impl_gvr_keyboard_hide(context); } -bool gvr_keyboard_supports_selection(gvr_keyboard_context* context) { +bool gvr_keyboard_supports_selection() { + if (!keyboard_api) + return false; return keyboard_api->min_version >= kSelectionSupportApiVersion; } +int64_t gvr_keyboard_version() { + if (!keyboard_api) + return -1; + return keyboard_api->min_version; +} diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc index bb47a45f130a..fd8de652cfc3 100644 --- a/chrome/browser/android/vr/vr_gl_thread.cc +++ b/chrome/browser/android/vr/vr_gl_thread.cc @@ -64,6 +64,8 @@ void VrGLThread::Init() { } auto* keyboard_delegate = !keyboard_delegate_ ? nullptr : keyboard_delegate_.get(); + if (!keyboard_delegate) + ui_initial_state_.needs_keyboard_update = true; auto ui = std::make_unique(this, this, keyboard_delegate, text_input_delegate_.get(), ui_initial_state_); if (keyboard_enabled) { diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index 685d0348d1c5..37021782cae5 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc @@ -729,6 +729,11 @@ void VrShell::OnUnsupportedMode(UiUnsupportedMode mode) { Java_VrShellImpl_onUnhandledPermissionPrompt(env, j_vr_shell_); return; } + case UiUnsupportedMode::kNeedsKeyboardUpdate: { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_VrShellImpl_onNeedsKeyboardUpdate(env, j_vr_shell_); + return; + } case UiUnsupportedMode::kCount: NOTREACHED(); // Should never be used as a mode. return; diff --git a/chrome/browser/vr/model/modal_prompt_type.cc b/chrome/browser/vr/model/modal_prompt_type.cc index b6e7f95f44d0..222a3e430bd1 100644 --- a/chrome/browser/vr/model/modal_prompt_type.cc +++ b/chrome/browser/vr/model/modal_prompt_type.cc @@ -16,6 +16,8 @@ UiUnsupportedMode GetReasonForPrompt(ModalPromptType prompt) { return UiUnsupportedMode::kVoiceSearchNeedsRecordAudioOsPermission; case kModalPromptTypeGenericUnsupportedFeature: return UiUnsupportedMode::kGenericUnsupportedFeature; + case kModalPromptTypeUpdateKeyboard: + return UiUnsupportedMode::kNeedsKeyboardUpdate; case kModalPromptTypeNone: return UiUnsupportedMode::kCount; } diff --git a/chrome/browser/vr/model/modal_prompt_type.h b/chrome/browser/vr/model/modal_prompt_type.h index 86c349d07131..88f2bf62dbcb 100644 --- a/chrome/browser/vr/model/modal_prompt_type.h +++ b/chrome/browser/vr/model/modal_prompt_type.h @@ -14,6 +14,7 @@ enum ModalPromptType { kModalPromptTypeExitVRForSiteInfo, kModalPromptTypeExitVRForVoiceSearchRecordAudioOsPermission, kModalPromptTypeGenericUnsupportedFeature, + kModalPromptTypeUpdateKeyboard, }; UiUnsupportedMode GetReasonForPrompt(ModalPromptType prompt); diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h index 15653b9960b7..6f33dd32b86f 100644 --- a/chrome/browser/vr/model/model.h +++ b/chrome/browser/vr/model/model.h @@ -49,6 +49,7 @@ struct Model { bool can_apply_new_background = false; bool background_loaded = false; bool supports_selection = true; + bool needs_keyboard_update = false; // WebVR state. WebVrModel web_vr; diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index ace026cccfb6..020b9703384a 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc @@ -160,6 +160,9 @@ void Ui::ShowExitVrPrompt(UiUnsupportedMode reason) { model_->active_modal_prompt_type = kModalPromptTypeGenericUnsupportedFeature; return; + case UiUnsupportedMode::kNeedsKeyboardUpdate: + model_->active_modal_prompt_type = kModalPromptTypeUpdateKeyboard; + return; case UiUnsupportedMode::kCount: NOTREACHED(); // Should never be used as a mode (when |enabled| is true). return; @@ -439,6 +442,7 @@ void Ui::InitializeModel(const UiInitialState& ui_initial_state) { ui_initial_state.skips_redraw_when_not_dirty; model_->waiting_for_background = ui_initial_state.assets_available; model_->supports_selection = ui_initial_state.supports_selection; + model_->needs_keyboard_update = ui_initial_state.needs_keyboard_update; } void Ui::AcceptDoffPromptForTesting() { diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index f7b4e1665803..41ab75fc3ff7 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h @@ -43,6 +43,7 @@ struct UiInitialState { // TODO(tiborg): Remove this flag. bool assets_available = false; bool supports_selection = true; + bool needs_keyboard_update = false; }; // This class manages all GLThread owned objects and GL rendering for VrShell. diff --git a/chrome/browser/vr/ui_unsupported_mode.h b/chrome/browser/vr/ui_unsupported_mode.h index 8cbd070c0b76..e850e0fb12bb 100644 --- a/chrome/browser/vr/ui_unsupported_mode.h +++ b/chrome/browser/vr/ui_unsupported_mode.h @@ -18,6 +18,7 @@ enum class UiUnsupportedMode : int { // kURLWithStrongRTLChars = 3, // Obsolete. kVoiceSearchNeedsRecordAudioOsPermission = 4, // TODO(ddorwin): Android only. kGenericUnsupportedFeature = 5, + kNeedsKeyboardUpdate = 6, // This must be last. kCount, }; diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index dd1b3f6c52a6..997de6b4e621 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml @@ -45293,6 +45293,8 @@ Called by update_traffic_annotation_histograms.py.--> + +