chromium/chrome/browser/ui/android/infobars/simple_confirm_infobar_builder.cc

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "components/infobars/android/confirm_infobar.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/models/image_model.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/image/image.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "chrome/browser/ui/messages/android/jni_headers/SimpleConfirmInfoBarBuilder_jni.h"

using base::android::JavaParamRef;

namespace {

// Delegate for a simple ConfirmInfoBar triggered via JNI.
class SimpleConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
 public:
  SimpleConfirmInfoBarDelegate(
      const JavaParamRef<jobject>& j_listener,
      infobars::InfoBarDelegate::InfoBarIdentifier infobar_identifier,
      const gfx::Image& bitmap,
      const std::u16string& message_str,
      const std::u16string& primary_str,
      const std::u16string& secondary_str,
      const std::u16string& link_text_str,
      bool auto_expire);

  SimpleConfirmInfoBarDelegate(const SimpleConfirmInfoBarDelegate&) = delete;
  SimpleConfirmInfoBarDelegate& operator=(const SimpleConfirmInfoBarDelegate&) =
      delete;

  ~SimpleConfirmInfoBarDelegate() override;

  // ConfirmInfoBarDelegate:
  infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
  ui::ImageModel GetIcon() const override;
  std::u16string GetLinkText() const override;
  bool ShouldExpire(const NavigationDetails& details) const override;
  bool LinkClicked(WindowOpenDisposition disposition) override;
  void InfoBarDismissed() override;
  std::u16string GetMessageText() const override;
  int GetButtons() const override;
  std::u16string GetButtonLabel(InfoBarButton button) const override;
  bool Accept() override;
  bool Cancel() override;

 private:
  base::android::ScopedJavaGlobalRef<jobject> java_listener_;
  infobars::InfoBarDelegate::InfoBarIdentifier identifier_;
  gfx::Image icon_bitmap_;
  std::u16string message_str_;
  std::u16string primary_str_;
  std::u16string secondary_str_;
  std::u16string link_text_str_;
  bool auto_expire_;
};

SimpleConfirmInfoBarDelegate::SimpleConfirmInfoBarDelegate(
    const JavaParamRef<jobject>& j_listener,
    infobars::InfoBarDelegate::InfoBarIdentifier identifier,
    const gfx::Image& bitmap,
    const std::u16string& message_str,
    const std::u16string& primary_str,
    const std::u16string& secondary_str,
    const std::u16string& link_text_str,
    bool auto_expire)
    : identifier_(identifier),
      icon_bitmap_(bitmap),
      message_str_(message_str),
      primary_str_(primary_str),
      secondary_str_(secondary_str),
      link_text_str_(link_text_str),
      auto_expire_(auto_expire) {
  java_listener_.Reset(j_listener);
}

SimpleConfirmInfoBarDelegate::~SimpleConfirmInfoBarDelegate() {
}

infobars::InfoBarDelegate::InfoBarIdentifier
SimpleConfirmInfoBarDelegate::GetIdentifier() const {
  return identifier_;
}

ui::ImageModel SimpleConfirmInfoBarDelegate::GetIcon() const {
  return icon_bitmap_.IsEmpty() ? ConfirmInfoBarDelegate::GetIcon()
                                : ui::ImageModel::FromImage(icon_bitmap_);
}

std::u16string SimpleConfirmInfoBarDelegate::GetLinkText() const {
  return link_text_str_;
}

bool SimpleConfirmInfoBarDelegate::ShouldExpire(
    const NavigationDetails& details) const {
  return auto_expire_ && ConfirmInfoBarDelegate::ShouldExpire(details);
}

bool SimpleConfirmInfoBarDelegate::LinkClicked(
    WindowOpenDisposition disposition) {
  return !Java_SimpleConfirmInfoBarBuilder_onInfoBarLinkClicked(
      base::android::AttachCurrentThread(), java_listener_);
}

void SimpleConfirmInfoBarDelegate::InfoBarDismissed() {
  Java_SimpleConfirmInfoBarBuilder_onInfoBarDismissed(
      base::android::AttachCurrentThread(), java_listener_);
}

std::u16string SimpleConfirmInfoBarDelegate::GetMessageText() const {
  return message_str_;
}

int SimpleConfirmInfoBarDelegate::GetButtons() const {
  return (primary_str_.empty() ? 0 : BUTTON_OK) |
      (secondary_str_.empty() ? 0 : BUTTON_CANCEL);
}

std::u16string SimpleConfirmInfoBarDelegate::GetButtonLabel(
    InfoBarButton button) const {
  return button == BUTTON_OK ? primary_str_ : secondary_str_;
}

bool SimpleConfirmInfoBarDelegate::Accept() {
  return !Java_SimpleConfirmInfoBarBuilder_onInfoBarButtonClicked(
      base::android::AttachCurrentThread(), java_listener_, true);
}

bool SimpleConfirmInfoBarDelegate::Cancel() {
  return !Java_SimpleConfirmInfoBarBuilder_onInfoBarButtonClicked(
      base::android::AttachCurrentThread(), java_listener_, false);
}

}  // anonymous namespace

// Native JNI methods ---------------------------------------------------------

void JNI_SimpleConfirmInfoBarBuilder_Create(
    JNIEnv* env,
    const JavaParamRef<jobject>& j_web_contents,
    jint j_identifier,
    const JavaParamRef<jobject>& j_icon,
    const JavaParamRef<jstring>& j_message,
    const JavaParamRef<jstring>& j_primary,
    const JavaParamRef<jstring>& j_secondary,
    const JavaParamRef<jstring>& j_link_text,
    jboolean auto_expire,
    const JavaParamRef<jobject>& j_listener) {
  infobars::InfoBarDelegate::InfoBarIdentifier infobar_identifier =
      static_cast<infobars::InfoBarDelegate::InfoBarIdentifier>(j_identifier);

  gfx::Image icon_bitmap;
  if (j_icon) {
    icon_bitmap = gfx::Image::CreateFrom1xBitmap(
        gfx::CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(j_icon)));
  }

  std::u16string message_str =
      j_message.is_null()
          ? std::u16string()
          : base::android::ConvertJavaStringToUTF16(env, j_message);
  std::u16string primary_str =
      j_primary.is_null()
          ? std::u16string()
          : base::android::ConvertJavaStringToUTF16(env, j_primary);
  std::u16string secondary_str =
      j_secondary.is_null()
          ? std::u16string()
          : base::android::ConvertJavaStringToUTF16(env, j_secondary);
  std::u16string link_text_str =
      j_link_text.is_null()
          ? std::u16string()
          : base::android::ConvertJavaStringToUTF16(env, j_link_text);

  infobars::ContentInfoBarManager* manager =
      infobars::ContentInfoBarManager::FromWebContents(
          content::WebContents::FromJavaWebContents(j_web_contents));
  manager->AddInfoBar(std::make_unique<infobars::ConfirmInfoBar>(
      std::make_unique<SimpleConfirmInfoBarDelegate>(
          j_listener, infobar_identifier, icon_bitmap, message_str, primary_str,
          secondary_str, link_text_str, auto_expire)));
}