diff --git a/embedding/android/GeckoAppShell.java b/embedding/android/GeckoAppShell.java index b567dae9830..f98b598893c 100644 --- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -423,4 +423,20 @@ class GeckoAppShell return false; } } + + static String getClipboardText() { + Context context = GeckoApp.surfaceView.getContext(); + ClipboardManager cm = (ClipboardManager) + context.getSystemService(Context.CLIPBOARD_SERVICE); + if (!cm.hasText()) + return null; + return cm.getText().toString(); + } + + static void setClipboardText(String text) { + Context context = GeckoApp.surfaceView.getContext(); + ClipboardManager cm = (ClipboardManager) + context.getSystemService(Context.CLIPBOARD_SERVICE); + cm.setText(text); + } } diff --git a/widget/src/android/AndroidBridge.cpp b/widget/src/android/AndroidBridge.cpp index cbec8a590cf..aa1e599c98b 100644 --- a/widget/src/android/AndroidBridge.cpp +++ b/widget/src/android/AndroidBridge.cpp @@ -108,6 +108,8 @@ AndroidBridge::Init(JNIEnv *jEnv, jOpenUriExternal = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"); jGetMimeTypeFromExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getMimeTypeFromExtension", "(Ljava/lang/String;)Ljava/lang/String;"); jMoveTaskToBack = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "moveTaskToBack", "()V"); + jGetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getClipboardText", "()Ljava/lang/String;"); + jSetClipboardText = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setClipboardText", "(Ljava/lang/String;)V"); jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext")); @@ -360,6 +362,47 @@ AndroidBridge::MoveTaskToBack() mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jMoveTaskToBack); } +bool +AndroidBridge::GetClipboardText(nsAString& aText) +{ + jstring jstrType = + static_cast(mJNIEnv-> + CallStaticObjectMethod(mGeckoAppShellClass, + jGetClipboardText)); + if (!jstrType) + return PR_FALSE; + nsJNIString jniStr(jstrType); + aText.Assign(jniStr); + return PR_TRUE; +} + +void +AndroidBridge::SetClipboardText(const nsAString& aText) +{ + const PRUnichar* wText; + PRUint32 wTextLen = NS_StringGetData(aText, &wText); + jstring jstr = mJNIEnv->NewString(wText, wTextLen); + mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass, jSetClipboardText, jstr); +} + +bool +AndroidBridge::ClipboardHasText() +{ + jstring jstrType = + static_cast(mJNIEnv-> + CallStaticObjectMethod(mGeckoAppShellClass, + jGetClipboardText)); + if (!jstrType) + return PR_FALSE; + return PR_TRUE; +} + +void +AndroidBridge::EmptyClipboard() +{ + mJNIEnv->CallStaticObjectMethod(mGeckoAppShellClass, jSetClipboardText, nsnull); +} + void AndroidBridge::SetSurfaceView(jobject obj) { diff --git a/widget/src/android/AndroidBridge.h b/widget/src/android/AndroidBridge.h index fdd298f489b..fe74aaa67e2 100644 --- a/widget/src/android/AndroidBridge.h +++ b/widget/src/android/AndroidBridge.h @@ -126,6 +126,14 @@ public: void MoveTaskToBack(); + bool GetClipboardText(nsAString& aText); + + void SetClipboardText(const nsAString& aText); + + void EmptyClipboard(); + + bool ClipboardHasText(); + struct AutoLocalJNIFrame { AutoLocalJNIFrame(int nEntries = 128) : mEntries(nEntries) { AndroidBridge::Bridge()->JNI()->PushLocalFrame(mEntries); @@ -181,6 +189,8 @@ protected: jmethodID jOpenUriExternal; jmethodID jGetMimeTypeFromExtension; jmethodID jMoveTaskToBack; + jmethodID jGetClipboardText; + jmethodID jSetClipboardText; // stuff we need for CallEglCreateWindowSurface jclass jEGLSurfaceImplClass; diff --git a/widget/src/android/Makefile.in b/widget/src/android/Makefile.in index d775f5e50a8..722bfc63ec0 100644 --- a/widget/src/android/Makefile.in +++ b/widget/src/android/Makefile.in @@ -62,11 +62,11 @@ CPPSRCS = \ nsLookAndFeel.cpp \ nsScreenManagerAndroid.cpp \ nsIdleServiceAndroid.cpp \ + nsClipboard.cpp \ $(NULL) NOT_THERE_YET_CPPSRCS = \ nsQtKeyUtils.cpp \ - nsClipboard.cpp \ nsBidiKeyboard.cpp \ nsDragService.cpp \ nsNativeThemeQt.cpp \ diff --git a/widget/src/android/nsClipboard.cpp b/widget/src/android/nsClipboard.cpp new file mode 100644 index 00000000000..ad8e343ade0 --- /dev/null +++ b/widget/src/android/nsClipboard.cpp @@ -0,0 +1,141 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Android code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Lassey + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsClipboard.h" +#include "nsISupportsPrimitives.h" +#include "AndroidBridge.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" + +using namespace mozilla; + +NS_IMPL_ISUPPORTS1(nsClipboard, nsIClipboard) + +/* The Android clipboard only supports text and doesn't support mime types + * so we assume all clipboard data is text/unicode for now. Documentation + * indicates that support for other data types is planned for future + * releases. + */ + +nsClipboard::nsClipboard() +{ +} + +NS_IMETHODIMP +nsClipboard::SetData(nsITransferable *aTransferable, + nsIClipboardOwner *anOwner, PRInt32 aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + + nsCOMPtr tmp; + PRUint32 len; + nsresult rv = aTransferable->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), + &len); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr supportsString = do_QueryInterface(tmp); + // No support for non-text data + NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED); + nsAutoString buffer; + supportsString->GetData(buffer); + AndroidBridge::Bridge()->SetClipboardText(buffer); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::GetData(nsITransferable *aTransferable, PRInt32 aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + + nsAutoString buffer; + if (!AndroidBridge::Bridge()->GetClipboardText(buffer)) + return NS_ERROR_UNEXPECTED; + + nsresult rv; + nsCOMPtr dataWrapper = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = dataWrapper->SetData(buffer); + NS_ENSURE_SUCCESS(rv, rv); + + // If our data flavor has already been added, this will fail. But we don't care + aTransferable->AddDataFlavor(kUnicodeMime); + + nsCOMPtr nsisupportsDataWrapper = + do_QueryInterface(dataWrapper); + rv = aTransferable->SetTransferData(kUnicodeMime, nsisupportsDataWrapper, + buffer.Length() * sizeof(PRUnichar)); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard) +{ + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + if (AndroidBridge::Bridge()) + AndroidBridge::Bridge()->EmptyClipboard(); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::HasDataMatchingFlavors(const char **aFlavorList, + PRUint32 aLength, PRInt32 aWhichClipboard, + PRBool *aHasText NS_OUTPARAM) +{ + *aHasText = PR_FALSE; + if (aWhichClipboard != kGlobalClipboard) + return NS_ERROR_NOT_IMPLEMENTED; + if (AndroidBridge::Bridge()) + *aHasText = AndroidBridge::Bridge()->ClipboardHasText(); + return NS_OK; +} + +NS_IMETHODIMP +nsClipboard::SupportsSelectionClipboard(PRBool *aIsSupported NS_OUTPARAM) +{ + *aIsSupported = PR_FALSE; + return NS_OK; +} + diff --git a/widget/src/android/nsClipboard.h b/widget/src/android/nsClipboard.h new file mode 100644 index 00000000000..a7097d36ca2 --- /dev/null +++ b/widget/src/android/nsClipboard.h @@ -0,0 +1,51 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Android code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brad Lassey + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NS_CLIPBOARD_H +#define NS_CLIPBOARD_H + +#include "nsIClipboard.h" + +class nsClipboard : public nsIClipboard +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSICLIPBOARD + + nsClipboard(); +}; + +#endif diff --git a/widget/src/android/nsWidgetFactory.cpp b/widget/src/android/nsWidgetFactory.cpp index 68c4c09c907..74d05fd05f2 100644 --- a/widget/src/android/nsWidgetFactory.cpp +++ b/widget/src/android/nsWidgetFactory.cpp @@ -49,12 +49,18 @@ #include "nsScreenManagerAndroid.h" #include "nsIdleServiceAndroid.h" +#include "nsClipboard.h" +#include "nsClipboardHelper.h" +#include "nsTransferable.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit) NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel) NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerAndroid) NS_GENERIC_FACTORY_CONSTRUCTOR(nsIdleServiceAndroid) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper) NS_DEFINE_NAMED_CID(NS_TOOLKIT_CID); NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); @@ -63,6 +69,9 @@ NS_DEFINE_NAMED_CID(NS_CHILD_CID); NS_DEFINE_NAMED_CID(NS_LOOKANDFEEL_CID); NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID); NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID); +NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID); +NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID); +NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID); static const mozilla::Module::CIDEntry kWidgetCIDs[] = { { &kNS_WINDOW_CID, false, NULL, nsWindowConstructor }, @@ -72,6 +81,9 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = { { &kNS_LOOKANDFEEL_CID, false, NULL, nsLookAndFeelConstructor }, { &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerAndroidConstructor }, { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceAndroidConstructor }, + { &kNS_TRANSFERABLE_CID, false, NULL, nsTransferableConstructor }, + { &kNS_CLIPBOARD_CID, false, NULL, nsClipboardConstructor }, + { &kNS_CLIPBOARDHELPER_CID, false, NULL, nsClipboardHelperConstructor }, { NULL } }; @@ -83,6 +95,9 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { { "@mozilla.org/widget/lookandfeel/android;1", &kNS_LOOKANDFEEL_CID }, { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID }, { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID }, + { "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID }, + { "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID }, + { "@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID }, { NULL } };