app_modal_dialog_view_android.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) 2012 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. #include "components/javascript_dialogs/android/app_modal_dialog_view_android.h"
  5. #include "base/android/jni_android.h"
  6. #include "base/android/jni_string.h"
  7. #include "base/memory/ptr_util.h"
  8. #include "base/metrics/histogram_macros.h"
  9. #include "components/javascript_dialogs/android/jni_headers/JavascriptAppModalDialog_jni.h"
  10. #include "components/javascript_dialogs/app_modal_dialog_controller.h"
  11. #include "components/javascript_dialogs/app_modal_dialog_manager.h"
  12. #include "components/javascript_dialogs/app_modal_dialog_queue.h"
  13. #include "content/public/browser/browser_thread.h"
  14. #include "content/public/browser/web_contents.h"
  15. #include "content/public/browser/web_contents_delegate.h"
  16. #include "content/public/common/javascript_dialog_type.h"
  17. #include "ui/android/window_android.h"
  18. using base::android::AttachCurrentThread;
  19. using base::android::ConvertUTF16ToJavaString;
  20. using base::android::JavaParamRef;
  21. using base::android::ScopedJavaGlobalRef;
  22. using base::android::ScopedJavaLocalRef;
  23. namespace javascript_dialogs {
  24. AppModalDialogViewAndroid::AppModalDialogViewAndroid(
  25. JNIEnv* env,
  26. AppModalDialogController* controller,
  27. gfx::NativeWindow parent)
  28. : controller_(controller),
  29. parent_jobject_weak_ref_(env, parent->GetJavaObject().obj()) {
  30. controller->web_contents()->GetDelegate()->ActivateContents(
  31. controller->web_contents());
  32. }
  33. void AppModalDialogViewAndroid::ShowAppModalDialog() {
  34. JNIEnv* env = AttachCurrentThread();
  35. // Keep a strong ref to the parent window while we make the call to java to
  36. // display the dialog.
  37. ScopedJavaLocalRef<jobject> parent_jobj = parent_jobject_weak_ref_.get(env);
  38. if (parent_jobj.is_null()) {
  39. CancelAppModalDialog();
  40. return;
  41. }
  42. ScopedJavaLocalRef<jobject> dialog_object;
  43. ScopedJavaLocalRef<jstring> title =
  44. ConvertUTF16ToJavaString(env, controller_->title());
  45. ScopedJavaLocalRef<jstring> message =
  46. ConvertUTF16ToJavaString(env, controller_->message_text());
  47. switch (controller_->javascript_dialog_type()) {
  48. case content::JAVASCRIPT_DIALOG_TYPE_ALERT: {
  49. dialog_object = Java_JavascriptAppModalDialog_createAlertDialog(
  50. env, title, message, controller_->display_suppress_checkbox());
  51. break;
  52. }
  53. case content::JAVASCRIPT_DIALOG_TYPE_CONFIRM: {
  54. if (controller_->is_before_unload_dialog()) {
  55. dialog_object = Java_JavascriptAppModalDialog_createBeforeUnloadDialog(
  56. env, title, message, controller_->is_reload(),
  57. controller_->display_suppress_checkbox());
  58. } else {
  59. dialog_object = Java_JavascriptAppModalDialog_createConfirmDialog(
  60. env, title, message, controller_->display_suppress_checkbox());
  61. }
  62. break;
  63. }
  64. case content::JAVASCRIPT_DIALOG_TYPE_PROMPT: {
  65. ScopedJavaLocalRef<jstring> default_prompt_text =
  66. ConvertUTF16ToJavaString(env, controller_->default_prompt_text());
  67. dialog_object = Java_JavascriptAppModalDialog_createPromptDialog(
  68. env, title, message, controller_->display_suppress_checkbox(),
  69. default_prompt_text);
  70. break;
  71. }
  72. default:
  73. NOTREACHED();
  74. }
  75. // Keep a ref to the java side object until we get a confirm or cancel.
  76. dialog_jobject_.Reset(dialog_object);
  77. Java_JavascriptAppModalDialog_showJavascriptAppModalDialog(
  78. env, dialog_object, parent_jobj, reinterpret_cast<intptr_t>(this));
  79. }
  80. void AppModalDialogViewAndroid::ActivateAppModalDialog() {
  81. // This is called on desktop (Views) when interacting with a browser window
  82. // that does not host the currently active app modal dialog, as a way to
  83. // redirect activation to the app modal dialog host. It's not relevant on
  84. // Android.
  85. NOTREACHED();
  86. }
  87. void AppModalDialogViewAndroid::CloseAppModalDialog() {
  88. CancelAppModalDialog();
  89. }
  90. void AppModalDialogViewAndroid::AcceptAppModalDialog() {
  91. std::u16string prompt_text;
  92. controller_->OnAccept(prompt_text, false);
  93. delete this;
  94. }
  95. void AppModalDialogViewAndroid::DidAcceptAppModalDialog(
  96. JNIEnv* env,
  97. const JavaParamRef<jobject>&,
  98. const JavaParamRef<jstring>& prompt,
  99. bool should_suppress_js_dialogs) {
  100. std::u16string prompt_text =
  101. base::android::ConvertJavaStringToUTF16(env, prompt);
  102. controller_->OnAccept(prompt_text, should_suppress_js_dialogs);
  103. delete this;
  104. }
  105. void AppModalDialogViewAndroid::CancelAppModalDialog() {
  106. controller_->OnCancel(false);
  107. delete this;
  108. }
  109. bool AppModalDialogViewAndroid::IsShowing() const {
  110. return true;
  111. }
  112. void AppModalDialogViewAndroid::DidCancelAppModalDialog(
  113. JNIEnv* env,
  114. const JavaParamRef<jobject>&,
  115. bool should_suppress_js_dialogs) {
  116. controller_->OnCancel(should_suppress_js_dialogs);
  117. delete this;
  118. }
  119. const ScopedJavaGlobalRef<jobject>& AppModalDialogViewAndroid::GetDialogObject()
  120. const {
  121. return dialog_jobject_;
  122. }
  123. AppModalDialogViewAndroid::~AppModalDialogViewAndroid() {
  124. // In case the dialog is still displaying, tell it to close itself.
  125. // This can happen if you trigger a dialog but close the Tab before it's
  126. // shown, and then accept the dialog.
  127. if (!dialog_jobject_.is_null()) {
  128. JNIEnv* env = AttachCurrentThread();
  129. Java_JavascriptAppModalDialog_dismiss(env, dialog_jobject_);
  130. }
  131. }
  132. // static
  133. ScopedJavaLocalRef<jobject> JNI_JavascriptAppModalDialog_GetCurrentModalDialog(
  134. JNIEnv* env) {
  135. AppModalDialogController* controller =
  136. AppModalDialogQueue::GetInstance()->active_dialog();
  137. if (!controller || !controller->view())
  138. return ScopedJavaLocalRef<jobject>();
  139. AppModalDialogViewAndroid* js_dialog =
  140. static_cast<AppModalDialogViewAndroid*>(controller->view());
  141. return ScopedJavaLocalRef<jobject>(js_dialog->GetDialogObject());
  142. }
  143. } // namespace javascript_dialogs