| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/messages/android/message_wrapper.h" |
| #include <string> |
| |
| #include "base/android/jni_string.h" |
| #include "base/logging.h" |
| #include "content/public/browser/web_contents.h" |
| #include "ui/gfx/android/java_bitmap.h" |
| |
| // Must come after all headers that specialize FromJniType() / ToJniType(). |
| #include "components/messages/android/jni_headers/MessageWrapper_jni.h" |
| |
| namespace messages { |
| |
| MessageWrapper::MessageWrapper(MessageIdentifier message_identifier) |
| : MessageWrapper(message_identifier, |
| base::NullCallback(), |
| base::NullCallback()) {} |
| |
| MessageWrapper::MessageWrapper(MessageIdentifier message_identifier, |
| base::OnceClosure action_callback, |
| DismissCallback dismiss_callback) |
| : action_callback_(std::move(action_callback)), |
| dismiss_callback_(std::move(dismiss_callback)), |
| message_enqueued_(false) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| java_message_wrapper_ = |
| Java_MessageWrapper_create(env, reinterpret_cast<int64_t>(this), |
| static_cast<int>(message_identifier)); |
| } |
| |
| MessageWrapper::~MessageWrapper() { |
| CHECK(!message_enqueued_); |
| } |
| |
| std::u16string MessageWrapper::GetTitle() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jtitle = |
| Java_MessageWrapper_getTitle(env, java_message_wrapper_); |
| return jtitle.is_null() ? std::u16string() |
| : base::android::ConvertJavaStringToUTF16(jtitle); |
| } |
| |
| void MessageWrapper::SetTitle(const std::u16string& title) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jtitle = |
| base::android::ConvertUTF16ToJavaString(env, title); |
| Java_MessageWrapper_setTitle(env, java_message_wrapper_, jtitle); |
| } |
| |
| std::u16string MessageWrapper::GetDescription() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jdescription = |
| Java_MessageWrapper_getDescription(env, java_message_wrapper_); |
| return jdescription.is_null() |
| ? std::u16string() |
| : base::android::ConvertJavaStringToUTF16(jdescription); |
| } |
| |
| void MessageWrapper::SetDescription(const std::u16string& description) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jdescription = |
| base::android::ConvertUTF16ToJavaString(env, description); |
| Java_MessageWrapper_setDescription(env, java_message_wrapper_, jdescription); |
| } |
| |
| int MessageWrapper::GetDescriptionMaxLines() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_MessageWrapper_getDescriptionMaxLines(env, java_message_wrapper_); |
| } |
| |
| void MessageWrapper::SetDescriptionMaxLines(int max_lines) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setDescriptionMaxLines(env, java_message_wrapper_, |
| max_lines); |
| } |
| |
| std::u16string MessageWrapper::GetPrimaryButtonText() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jprimary_button_text = |
| Java_MessageWrapper_getPrimaryButtonText(env, java_message_wrapper_); |
| return jprimary_button_text.is_null() |
| ? std::u16string() |
| : base::android::ConvertJavaStringToUTF16(jprimary_button_text); |
| } |
| |
| void MessageWrapper::SetPrimaryButtonText( |
| const std::u16string& primary_button_text) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jprimary_button_text = |
| base::android::ConvertUTF16ToJavaString(env, primary_button_text); |
| Java_MessageWrapper_setPrimaryButtonText(env, java_message_wrapper_, |
| jprimary_button_text); |
| } |
| |
| int MessageWrapper::GetPrimaryButtonTextMaxLines() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_MessageWrapper_getPrimaryButtonTextMaxLines( |
| env, java_message_wrapper_); |
| } |
| |
| void MessageWrapper::SetPrimaryButtonTextMaxLines(int max_lines) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setPrimaryButtonTextMaxLines(env, java_message_wrapper_, |
| max_lines); |
| } |
| |
| std::u16string MessageWrapper::GetSecondaryButtonMenuText() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jsecondary_button_menu_text = |
| Java_MessageWrapper_getSecondaryButtonMenuText(env, |
| java_message_wrapper_); |
| return jsecondary_button_menu_text.is_null() |
| ? std::u16string() |
| : base::android::ConvertJavaStringToUTF16( |
| jsecondary_button_menu_text); |
| } |
| |
| void MessageWrapper::SetSecondaryButtonMenuText( |
| const std::u16string& secondary_button_menu_text) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jsecondary_button_menu_text = |
| base::android::ConvertUTF16ToJavaString(env, secondary_button_menu_text); |
| Java_MessageWrapper_setSecondaryButtonMenuText(env, java_message_wrapper_, |
| jsecondary_button_menu_text); |
| } |
| |
| void MessageWrapper::SetSecondaryMenuMaxSize(SecondaryMenuMaxSize max_size) { |
| secondary_menu_max_size_ = max_size; |
| } |
| |
| void MessageWrapper::AddSecondaryMenuItem(int item_id, |
| int resource_id, |
| const std::u16string& item_text) { |
| DCHECK(!secondary_menu_item_selected_callback_.is_null()); |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jitem_text = |
| base::android::ConvertUTF16ToJavaString(env, item_text); |
| Java_MessageWrapper_addSecondaryMenuItem(env, java_message_wrapper_, item_id, |
| resource_id, jitem_text); |
| } |
| |
| void MessageWrapper::AddSecondaryMenuItem( |
| int item_id, |
| int resource_id, |
| const std::u16string& item_text, |
| const std::u16string& item_description) { |
| DCHECK(secondary_menu_item_selected_callback_); |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jstring> jitem_text = |
| base::android::ConvertUTF16ToJavaString(env, item_text); |
| base::android::ScopedJavaLocalRef<jstring> jitem_desc = |
| base::android::ConvertUTF16ToJavaString(env, item_description); |
| Java_MessageWrapper_addSecondaryMenuItem(env, java_message_wrapper_, item_id, |
| resource_id, jitem_text, jitem_desc); |
| } |
| |
| void MessageWrapper::ClearSecondaryMenuItems() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_clearSecondaryMenuItems(env, java_message_wrapper_); |
| } |
| |
| void MessageWrapper::AddSecondaryMenuItemDivider() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_addSecondaryMenuItemDivider(env, java_message_wrapper_); |
| } |
| |
| int MessageWrapper::GetIconResourceId() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_MessageWrapper_getIconResourceId(env, java_message_wrapper_); |
| } |
| |
| void MessageWrapper::SetIconResourceId(int resource_id) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setIconResourceId(env, java_message_wrapper_, |
| resource_id); |
| } |
| |
| bool MessageWrapper::IsValidIcon() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_MessageWrapper_isValidIcon(env, java_message_wrapper_); |
| } |
| |
| void MessageWrapper::SetIcon(const SkBitmap& icon) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jobject> java_bitmap = |
| gfx::ConvertToJavaBitmap(icon); |
| Java_MessageWrapper_setIcon(env, java_message_wrapper_, java_bitmap); |
| } |
| |
| void MessageWrapper::EnableLargeIcon(bool enabled) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setLargeIcon(env, java_message_wrapper_, enabled); |
| } |
| |
| void MessageWrapper::SetIconRoundedCornerRadius(int radius) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setIconRoundedCornerRadius(env, java_message_wrapper_, |
| radius); |
| } |
| |
| void MessageWrapper::DisableIconTint() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_disableIconTint(env, java_message_wrapper_); |
| } |
| |
| int MessageWrapper::GetSecondaryIconResourceId() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_MessageWrapper_getSecondaryIconResourceId(env, |
| java_message_wrapper_); |
| } |
| |
| void MessageWrapper::SetSecondaryIconResourceId(int resource_id) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setSecondaryIconResourceId(env, java_message_wrapper_, |
| resource_id); |
| } |
| |
| void MessageWrapper::SetSecondaryActionCallback( |
| base::RepeatingClosure callback) { |
| secondary_action_callback_ = std::move(callback); |
| } |
| |
| void MessageWrapper::SetSecondaryMenuItemSelectedCallback( |
| base::RepeatingCallback<void(int)> callback) { |
| secondary_menu_item_selected_callback_ = std::move(callback); |
| } |
| |
| void MessageWrapper::SetDuration(long customDuration) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_setDuration(env, java_message_wrapper_, customDuration); |
| } |
| |
| void MessageWrapper::SetActionClick(base::OnceClosure callback) { |
| action_callback_ = std::move(callback); |
| } |
| |
| void MessageWrapper::SetDismissCallback(DismissCallback callback) { |
| dismiss_callback_ = std::move(callback); |
| } |
| |
| void MessageWrapper::HandleActionClick(JNIEnv* env) { |
| if (!action_callback_.is_null()) |
| std::move(action_callback_).Run(); |
| } |
| |
| void MessageWrapper::HandleSecondaryActionClick(JNIEnv* env) { |
| if (!secondary_action_callback_.is_null()) |
| secondary_action_callback_.Run(); |
| } |
| |
| void MessageWrapper::HandleSecondaryMenuItemSelected(JNIEnv* env, int item_id) { |
| if (!secondary_menu_item_selected_callback_.is_null()) |
| secondary_menu_item_selected_callback_.Run(item_id); |
| } |
| |
| void MessageWrapper::HandleDismissCallback(JNIEnv* env, int dismiss_reason) { |
| // Make sure message dismissed callback is called exactly once. |
| message_enqueued_ = false; |
| Java_MessageWrapper_clearNativePtr(env, java_message_wrapper_); |
| if (!dismiss_callback_.is_null()) |
| std::move(dismiss_callback_) |
| .Run(static_cast<DismissReason>(dismiss_reason)); |
| // Dismiss callback typically deletes the instance of MessageWrapper, |
| // invalidating |this| pointer. Don't call any methods after dismiss_callback_ |
| // is invoked. |
| } |
| |
| const base::android::JavaRef<jobject>& MessageWrapper::GetJavaMessageWrapper() |
| const { |
| return java_message_wrapper_; |
| } |
| |
| void MessageWrapper::SetMessageEnqueued( |
| const base::android::JavaRef<jobject>& java_window_android) { |
| message_enqueued_ = true; |
| java_window_android_ = java_window_android; |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_MessageWrapper_initializeSecondaryMenu( |
| env, java_message_wrapper_, java_window_android_, |
| static_cast<int>(secondary_menu_max_size_)); |
| } |
| |
| const SkBitmap MessageWrapper::GetIconBitmap() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| base::android::ScopedJavaLocalRef<jobject> bitmap = |
| Java_MessageWrapper_getIconBitmap(env, java_message_wrapper_); |
| gfx::JavaBitmap java_bitmap_lock(bitmap); |
| return gfx::CreateSkBitmapFromJavaBitmap(java_bitmap_lock); |
| } |
| |
| } // namespace messages |