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

#include "ui/base/clipboard/clipboard_android.h"

#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"

namespace ui {

class ClipboardAndroidTest : public ::testing::Test {
 public:
  ~ClipboardAndroidTest() override {
    Clipboard::DestroyClipboardForCurrentThread();
  };

 protected:
  Clipboard& clipboard() { return *Clipboard::GetForCurrentThread(); }
};

// Test that if another application writes some text to the pasteboard the
// clipboard properly invalidates other types.
TEST_F(ClipboardAndroidTest, InternalClipboardInvalidation) {
  // Write a Webkit smart paste tag to our clipboard.
  {
    ScopedClipboardWriter clipboard_writer(CLIPBOARD_TYPE_COPY_PASTE);
    clipboard_writer.WriteWebSmartPaste();
  }
  EXPECT_TRUE(clipboard().IsFormatAvailable(
      Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));

  //
  // Simulate that another application copied something in the Clipboard
  //
  std::string new_value("Some text copied by some other app");
  using base::android::ConvertUTF8ToJavaString;
  using base::android::MethodID;
  using base::android::ScopedJavaLocalRef;

  JNIEnv* env = base::android::AttachCurrentThread();
  ASSERT_TRUE(env);

  ScopedJavaLocalRef<jclass> context_class =
      base::android::GetClass(env, "android/content/Context");

  jmethodID get_system_service = MethodID::Get<MethodID::TYPE_INSTANCE>(
      env, context_class.obj(), "getSystemService",
      "(Ljava/lang/String;)Ljava/lang/Object;");

  // Retrieve the system service.
  ScopedJavaLocalRef<jstring> service_name =
      ConvertUTF8ToJavaString(env, "clipboard");
  ScopedJavaLocalRef<jobject> clipboard_manager(
      env,
      env->CallObjectMethod(base::android::GetApplicationContext(),
                            get_system_service, service_name.obj()));
  ASSERT_TRUE(clipboard_manager.obj() && !base::android::ClearException(env));

  ScopedJavaLocalRef<jclass> clipboard_class =
      base::android::GetClass(env, "android/text/ClipboardManager");
  jmethodID set_text = MethodID::Get<MethodID::TYPE_INSTANCE>(
      env, clipboard_class.obj(), "setText", "(Ljava/lang/CharSequence;)V");
  ScopedJavaLocalRef<jstring> new_value_string =
      ConvertUTF8ToJavaString(env, new_value.c_str());

  // Will need to call toString as CharSequence is not always a String.
  env->CallVoidMethod(clipboard_manager.obj(), set_text,
                      new_value_string.obj());

  // The WebKit smart paste tag should now be gone.
  EXPECT_FALSE(clipboard().IsFormatAvailable(
      Clipboard::GetWebKitSmartPasteFormatType(), CLIPBOARD_TYPE_COPY_PASTE));

  // Make sure some text is available
  EXPECT_TRUE(clipboard().IsFormatAvailable(
      Clipboard::GetPlainTextWFormatType(), CLIPBOARD_TYPE_COPY_PASTE));

  // Make sure the text is what we inserted while simulating the other app
  std::string contents;
  clipboard().ReadAsciiText(CLIPBOARD_TYPE_COPY_PASTE, &contents);
  EXPECT_EQ(contents, new_value);
}

}  // namespace ui

#include "ui/base/clipboard/clipboard_test_template.h"
