| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/android/modal_dialog_bridge.h" |
| |
| #include "base/android/jni_android.h" |
| #include "base/android/scoped_java_ref.h" |
| #include "base/logging.h" |
| #include "ui/android/window_android.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/models/dialog_model.h" |
| #include "ui/strings/grit/ui_strings.h" |
| |
| // Must come after all headers that specialize FromJniType() / ToJniType(). |
| #include "ui/android/ui_android_jni_headers/ModalDialogBridge_jni.h" |
| |
| using base::android::ConvertUTF16ToJavaString; |
| using base::android::JavaParamRef; |
| using base::android::ScopedJavaLocalRef; |
| |
| namespace ui { |
| namespace { |
| static const int kDialogDismissalCause_DISMISSED_BY_NATIVE = 4; |
| } |
| |
| // static |
| void ModalDialogBridge::ShowTabModal( |
| std::unique_ptr<ui::DialogModel> dialog_model, |
| ui::WindowAndroid* web_contents) { |
| ModalDialogBridge* delegate = new ModalDialogBridge(std::move(dialog_model)); |
| delegate->BuildPropertyModel(); |
| delegate->Show(web_contents); |
| // delegate will delete itself when dialog is dismissed. |
| } |
| |
| ModalDialogBridge::ModalDialogBridge(std::unique_ptr<DialogModel> dialog_model) |
| : dialog_model_(std::move(dialog_model)) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| java_obj_ = |
| Java_ModalDialogBridge_create(env, reinterpret_cast<uintptr_t>(this)); |
| } |
| |
| ModalDialogBridge::~ModalDialogBridge() = default; |
| |
| void ModalDialogBridge::BuildPropertyModel() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> title = ConvertUTF16ToJavaString( |
| env, dialog_model_->title(DialogModelHost::GetPassKey())); |
| auto* ok_button = dialog_model_->ok_button(DialogModelHost::GetPassKey()); |
| ScopedJavaLocalRef<jstring> ok_button_label; |
| if (ok_button) { |
| ok_button_label = ConvertUTF16ToJavaString( |
| env, ok_button->label().empty() ? l10n_util::GetStringUTF16(IDS_APP_OK) |
| : ok_button->label()); |
| } |
| auto* cancel_button = |
| dialog_model_->cancel_button(DialogModelHost::GetPassKey()); |
| ScopedJavaLocalRef<jstring> cancel_button_label; |
| if (cancel_button) { |
| cancel_button_label = ConvertUTF16ToJavaString( |
| env, cancel_button->label().empty() |
| ? l10n_util::GetStringUTF16(IDS_APP_CANCEL) |
| : cancel_button->label()); |
| } |
| |
| Java_ModalDialogBridge_withTitleAndButtons( |
| env, java_obj_, title, ok_button_label, cancel_button_label); |
| |
| int paragraph_count = 0; |
| for (const auto& field : |
| dialog_model_->fields(DialogModelHost::GetPassKey())) { |
| switch (field->type()) { |
| case DialogModelField::kParagraph: { |
| // TODO(joelhockey): Add multi-paragraph support - clank supports 2. |
| CHECK_EQ(++paragraph_count, 1) << "Only single paragraph supported. " |
| "Fix me if you need multi-paragraph,"; |
| std::u16string text; |
| const DialogModelLabel& label = field->AsParagraph()->label(); |
| auto replacements = label.replacements(); |
| if (replacements.empty()) { |
| text = label.GetString(); |
| } else { |
| std::vector<std::u16string> string_replacements; |
| for (auto replacement : replacements) { |
| string_replacements.push_back(replacement.text()); |
| } |
| text = l10n_util::GetStringFUTF16(label.message_id(), |
| string_replacements, nullptr); |
| } |
| Java_ModalDialogBridge_withParagraph1( |
| env, java_obj_, ConvertUTF16ToJavaString(env, text)); |
| break; |
| } |
| default: |
| NOTREACHED() << "Unsupported DialogModel field type " << field->type() |
| << ". Support should be added before this dialog is used " |
| "in android"; |
| } |
| } |
| } |
| |
| void ModalDialogBridge::Show(ui::WindowAndroid* web_contents) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_ModalDialogBridge_showTabModal(env, java_obj_, |
| web_contents->GetJavaObject()); |
| } |
| |
| void ModalDialogBridge::Dismiss(int dismissalCause) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_ModalDialogBridge_onDismiss(env, java_obj_, nullptr, dismissalCause); |
| } |
| |
| void ModalDialogBridge::PositiveButtonClicked(JNIEnv* env) { |
| dialog_model_->OnDialogAcceptAction(DialogModelHost::GetPassKey()); |
| } |
| |
| void ModalDialogBridge::NegativeButtonClicked(JNIEnv* env) { |
| dialog_model_->OnDialogCancelAction(DialogModelHost::GetPassKey()); |
| } |
| |
| void ModalDialogBridge::Dismissed(JNIEnv* env) { |
| dialog_model_->OnDialogCloseAction(DialogModelHost::GetPassKey()); |
| } |
| |
| void ModalDialogBridge::Destroy(JNIEnv* env) { |
| delete this; |
| } |
| |
| void ModalDialogBridge::Close() { |
| Dismiss(kDialogDismissalCause_DISMISSED_BY_NATIVE); |
| } |
| |
| void ModalDialogBridge::OnDialogButtonChanged() {} |
| |
| } // namespace ui |