summaryrefslogtreecommitdiffstats
path: root/widget/android/nsClipboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/android/nsClipboard.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/widget/android/nsClipboard.cpp b/widget/android/nsClipboard.cpp
new file mode 100644
index 0000000000..c2a03dd540
--- /dev/null
+++ b/widget/android/nsClipboard.cpp
@@ -0,0 +1,214 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/java/ClipboardWrappers.h"
+#include "mozilla/java/GeckoAppShellWrappers.h"
+#include "nsClipboard.h"
+#include "nsISupportsPrimitives.h"
+#include "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsMemory.h"
+#include "nsStringStream.h"
+#include "nsPrimitiveHelpers.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsClipboard, nsBaseClipboard)
+
+/* The Android clipboard only supports text and doesn't support mime types
+ * so we assume all clipboard data is text/plain for now. Documentation
+ * indicates that support for other data types is planned for future
+ * releases.
+ */
+
+nsClipboard::nsClipboard()
+ : nsBaseClipboard(mozilla::dom::ClipboardCapabilities(
+ false /* supportsSelectionClipboard */,
+ false /* supportsFindClipboard */,
+ false /* supportsSelectionCache */)) {
+ java::Clipboard::StartTrackingClipboardData(
+ java::GeckoAppShell::GetApplicationContext());
+}
+
+nsClipboard::~nsClipboard() {
+ java::Clipboard::StopTrackingClipboardData(
+ java::GeckoAppShell::GetApplicationContext());
+}
+
+// static
+nsresult nsClipboard::GetTextFromTransferable(nsITransferable* aTransferable,
+ nsString& aText,
+ nsString& aHTML) {
+ nsTArray<nsCString> flavors;
+ nsresult rv = aTransferable->FlavorsTransferableCanImport(flavors);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ for (auto& flavorStr : flavors) {
+ if (flavorStr.EqualsLiteral(kTextMime)) {
+ nsCOMPtr<nsISupports> item;
+ nsresult rv =
+ aTransferable->GetTransferData(kTextMime, getter_AddRefs(item));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+ nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(item);
+ if (supportsString) {
+ supportsString->GetData(aText);
+ }
+ } else if (flavorStr.EqualsLiteral(kHTMLMime)) {
+ nsCOMPtr<nsISupports> item;
+ nsresult rv =
+ aTransferable->GetTransferData(kHTMLMime, getter_AddRefs(item));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+ nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(item);
+ if (supportsString) {
+ supportsString->GetData(aHTML);
+ }
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable,
+ int32_t aWhichClipboard) {
+ MOZ_DIAGNOSTIC_ASSERT(aTransferable);
+ MOZ_DIAGNOSTIC_ASSERT(
+ nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
+
+ if (!jni::IsAvailable()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ nsString text;
+ nsString html;
+ nsresult rv = GetTextFromTransferable(aTransferable, text, html);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ if (!html.IsEmpty() &&
+ java::Clipboard::SetHTML(java::GeckoAppShell::GetApplicationContext(),
+ text, html)) {
+ return NS_OK;
+ }
+ if (!text.IsEmpty() &&
+ java::Clipboard::SetText(java::GeckoAppShell::GetApplicationContext(),
+ text)) {
+ return NS_OK;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable,
+ int32_t aWhichClipboard) {
+ MOZ_DIAGNOSTIC_ASSERT(aTransferable);
+ MOZ_DIAGNOSTIC_ASSERT(
+ nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
+
+ if (!jni::IsAvailable()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ nsTArray<nsCString> flavors;
+ aTransferable->FlavorsTransferableCanImport(flavors);
+
+ for (auto& flavorStr : flavors) {
+ if (flavorStr.EqualsLiteral(kTextMime) ||
+ flavorStr.EqualsLiteral(kHTMLMime)) {
+ auto text = java::Clipboard::GetTextData(
+ java::GeckoAppShell::GetApplicationContext(), flavorStr);
+ if (!text) {
+ continue;
+ }
+ nsString buffer = text->ToString();
+ if (buffer.IsEmpty()) {
+ continue;
+ }
+ nsCOMPtr<nsISupports> wrapper;
+ nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, buffer.get(),
+ buffer.Length() * 2,
+ getter_AddRefs(wrapper));
+ if (wrapper) {
+ aTransferable->SetTransferData(flavorStr.get(), wrapper);
+ return NS_OK;
+ }
+ continue;
+ }
+
+ mozilla::jni::ByteArray::LocalRef bytes;
+ nsresult rv = java::Clipboard::GetRawData(flavorStr, &bytes);
+ if (NS_FAILED(rv) || !bytes) {
+ continue;
+ }
+ nsCOMPtr<nsIInputStream> byteStream;
+ rv = NS_NewByteInputStream(
+ getter_AddRefs(byteStream),
+ mozilla::Span(
+ reinterpret_cast<const char*>(bytes->GetElements().Elements()),
+ bytes->Length()),
+ NS_ASSIGNMENT_COPY);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+ rv = aTransferable->SetTransferData(flavorStr.get(), byteStream);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ continue;
+ }
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+nsresult nsClipboard::EmptyNativeClipboardData(int32_t aWhichClipboard) {
+ MOZ_DIAGNOSTIC_ASSERT(
+ nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
+
+ if (!jni::IsAvailable()) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ java::Clipboard::Clear(java::GeckoAppShell::GetApplicationContext());
+
+ return NS_OK;
+}
+
+mozilla::Result<int32_t, nsresult>
+nsClipboard::GetNativeClipboardSequenceNumber(int32_t aWhichClipboard) {
+ MOZ_DIAGNOSTIC_ASSERT(
+ nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
+
+ if (!jni::IsAvailable()) {
+ return Err(NS_ERROR_NOT_AVAILABLE);
+ }
+
+ return java::Clipboard::GetSequenceNumber(
+ java::GeckoAppShell::GetApplicationContext());
+}
+
+mozilla::Result<bool, nsresult>
+nsClipboard::HasNativeClipboardDataMatchingFlavors(
+ const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard) {
+ MOZ_DIAGNOSTIC_ASSERT(
+ nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
+
+ if (!jni::IsAvailable()) {
+ return Err(NS_ERROR_NOT_AVAILABLE);
+ }
+
+ for (auto& flavor : aFlavorList) {
+ if (java::Clipboard::HasData(java::GeckoAppShell::GetApplicationContext(),
+ NS_ConvertASCIItoUTF16(flavor))) {
+ return true;
+ }
+ }
+
+ return false;
+}