Bug 966467 - Proxy clipboard service in content process (r=vlad)

This commit is contained in:
Bill McCloskey 2014-02-09 16:13:10 -08:00
parent 32e8ab9b4c
commit ab1717c10c
8 changed files with 146 additions and 46 deletions

View File

@ -1599,25 +1599,25 @@ ContentParent::RecvSetClipboardText(const nsString& text,
nsCOMPtr<nsISupportsString> dataWrapper = nsCOMPtr<nsISupportsString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
rv = dataWrapper->SetData(text); rv = dataWrapper->SetData(text);
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv); nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
trans->Init(nullptr); trans->Init(nullptr);
// If our data flavor has already been added, this will fail. But we don't care // If our data flavor has already been added, this will fail. But we don't care
trans->AddDataFlavor(kUnicodeMime); trans->AddDataFlavor(kUnicodeMime);
trans->SetIsPrivateData(isPrivateData); trans->SetIsPrivateData(isPrivateData);
nsCOMPtr<nsISupports> nsisupportsDataWrapper = nsCOMPtr<nsISupports> nsisupportsDataWrapper =
do_QueryInterface(dataWrapper); do_QueryInterface(dataWrapper);
rv = trans->SetTransferData(kUnicodeMime, nsisupportsDataWrapper, rv = trans->SetTransferData(kUnicodeMime, nsisupportsDataWrapper,
text.Length() * sizeof(char16_t)); text.Length() * sizeof(char16_t));
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
clipboard->SetData(trans, nullptr, whichClipboard); clipboard->SetData(trans, nullptr, whichClipboard);
return true; return true;
} }
@ -1632,43 +1632,44 @@ ContentParent::RecvGetClipboardText(const int32_t& whichClipboard, nsString* tex
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv); nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
trans->Init(nullptr); trans->Init(nullptr);
trans->AddDataFlavor(kUnicodeMime);
clipboard->GetData(trans, whichClipboard); clipboard->GetData(trans, whichClipboard);
nsCOMPtr<nsISupports> tmp; nsCOMPtr<nsISupports> tmp;
uint32_t len; uint32_t len;
rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len); rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return false; return true;
nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp); nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
// No support for non-text data // No support for non-text data
if (!supportsString) if (!supportsString)
return false; return true;
supportsString->GetData(*text); supportsString->GetData(*text);
return true; return true;
} }
bool bool
ContentParent::RecvEmptyClipboard() ContentParent::RecvEmptyClipboard(const int32_t& whichClipboard)
{ {
nsresult rv; nsresult rv;
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv)); nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
clipboard->EmptyClipboard(nsIClipboard::kGlobalClipboard); clipboard->EmptyClipboard(whichClipboard);
return true; return true;
} }
bool bool
ContentParent::RecvClipboardHasText(bool* hasText) ContentParent::RecvClipboardHasText(const int32_t& whichClipboard, bool* hasText)
{ {
nsresult rv; nsresult rv;
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv)); nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
NS_ENSURE_SUCCESS(rv, true); NS_ENSURE_SUCCESS(rv, true);
clipboard->HasDataMatchingFlavors(sClipboardTextFlavors, 1, clipboard->HasDataMatchingFlavors(sClipboardTextFlavors, 1,
nsIClipboard::kGlobalClipboard, hasText); whichClipboard, hasText);
return true; return true;
} }

View File

@ -408,8 +408,8 @@ private:
const bool& isPrivateData, const bool& isPrivateData,
const int32_t& whichClipboard) MOZ_OVERRIDE; const int32_t& whichClipboard) MOZ_OVERRIDE;
virtual bool RecvGetClipboardText(const int32_t& whichClipboard, nsString* text) MOZ_OVERRIDE; virtual bool RecvGetClipboardText(const int32_t& whichClipboard, nsString* text) MOZ_OVERRIDE;
virtual bool RecvEmptyClipboard() MOZ_OVERRIDE; virtual bool RecvEmptyClipboard(const int32_t& whichClipboard) MOZ_OVERRIDE;
virtual bool RecvClipboardHasText(bool* hasText) MOZ_OVERRIDE; virtual bool RecvClipboardHasText(const int32_t& whichClipboard, bool* hasText) MOZ_OVERRIDE;
virtual bool RecvGetSystemColors(const uint32_t& colorsCount, virtual bool RecvGetSystemColors(const uint32_t& colorsCount,
InfallibleTArray<uint32_t>* colors) MOZ_OVERRIDE; InfallibleTArray<uint32_t>* colors) MOZ_OVERRIDE;

View File

@ -439,13 +439,11 @@ parent:
// nsIPermissionManager messages // nsIPermissionManager messages
sync ReadPermissions() returns (Permission[] permissions); sync ReadPermissions() returns (Permission[] permissions);
// These clipboard methods are only really used on Android since
// the clipboard is not available in the content process.
SetClipboardText(nsString text, bool isPrivateData, int32_t whichClipboard); SetClipboardText(nsString text, bool isPrivateData, int32_t whichClipboard);
sync GetClipboardText(int32_t whichClipboard) sync GetClipboardText(int32_t whichClipboard)
returns (nsString text); returns (nsString text);
EmptyClipboard(); EmptyClipboard(int32_t whichClipboard);
sync ClipboardHasText() sync ClipboardHasText(int32_t whichClipboard)
returns (bool hasText); returns (bool hasText);
sync GetSystemColors(uint32_t colorsCount) sync GetSystemColors(uint32_t colorsCount)

View File

@ -43,14 +43,7 @@ nsClipboard::SetData(nsITransferable *aTransferable,
nsAutoString buffer; nsAutoString buffer;
supportsString->GetData(buffer); supportsString->GetData(buffer);
if (XRE_GetProcessType() == GeckoProcessType_Default) { Clipboard::SetClipboardText(buffer);
Clipboard::SetClipboardText(buffer);
} else {
bool isPrivateData = false;
aTransferable->GetIsPrivateData(&isPrivateData);
ContentChild::GetSingleton()->SendSetClipboardText(buffer, isPrivateData,
aWhichClipboard);
}
return NS_OK; return NS_OK;
} }
@ -62,14 +55,10 @@ nsClipboard::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
nsAutoString buffer; nsAutoString buffer;
if (XRE_GetProcessType() == GeckoProcessType_Default) { if (!AndroidBridge::Bridge())
if (!AndroidBridge::Bridge()) return NS_ERROR_NOT_IMPLEMENTED;
return NS_ERROR_NOT_IMPLEMENTED; if (!AndroidBridge::Bridge()->GetClipboardText(buffer))
if (!AndroidBridge::Bridge()->GetClipboardText(buffer)) return NS_ERROR_UNEXPECTED;
return NS_ERROR_UNEXPECTED;
} else {
ContentChild::GetSingleton()->SendGetClipboardText(aWhichClipboard, &buffer);
}
nsresult rv; nsresult rv;
nsCOMPtr<nsISupportsString> dataWrapper = nsCOMPtr<nsISupportsString> dataWrapper =
@ -96,11 +85,7 @@ nsClipboard::EmptyClipboard(int32_t aWhichClipboard)
{ {
if (aWhichClipboard != kGlobalClipboard) if (aWhichClipboard != kGlobalClipboard)
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
if (XRE_GetProcessType() == GeckoProcessType_Default) { Clipboard::ClearText();
Clipboard::ClearText();
} else {
ContentChild::GetSingleton()->SendEmptyClipboard();
}
return NS_OK; return NS_OK;
} }
@ -113,11 +98,7 @@ nsClipboard::HasDataMatchingFlavors(const char **aFlavorList,
*aHasText = false; *aHasText = false;
if (aWhichClipboard != kGlobalClipboard) if (aWhichClipboard != kGlobalClipboard)
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
if (XRE_GetProcessType() == GeckoProcessType_Default) { *aHasText = Clipboard::HasText();
*aHasText = Clipboard::HasText();
} else {
ContentChild::GetSingleton()->SendClipboardHasText(aHasText);
}
return NS_OK; return NS_OK;
} }

View File

@ -25,6 +25,7 @@ UNIFIED_SOURCES += [
'nsBaseScreen.cpp', 'nsBaseScreen.cpp',
'nsClipboardHelper.cpp', 'nsClipboardHelper.cpp',
'nsClipboardPrivacyHandler.cpp', 'nsClipboardPrivacyHandler.cpp',
'nsClipboardProxy.cpp',
'nsContentProcessWidgetFactory.cpp', 'nsContentProcessWidgetFactory.cpp',
'nsFilePickerProxy.cpp', 'nsFilePickerProxy.cpp',
'nsHTMLFormatConverter.cpp', 'nsHTMLFormatConverter.cpp',

View File

@ -0,0 +1,93 @@
/* 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/dom/ContentChild.h"
#include "nsClipboardProxy.h"
#include "nsISupportsPrimitives.h"
#include "nsCOMPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsXULAppAPI.h"
using namespace mozilla;
using mozilla::dom::ContentChild;
NS_IMPL_ISUPPORTS1(nsClipboardProxy, nsIClipboard)
nsClipboardProxy::nsClipboardProxy()
{
}
NS_IMETHODIMP
nsClipboardProxy::SetData(nsITransferable *aTransferable,
nsIClipboardOwner *anOwner, int32_t aWhichClipboard)
{
nsCOMPtr<nsISupports> tmp;
uint32_t len;
nsresult rv = aTransferable->GetTransferData(kUnicodeMime, getter_AddRefs(tmp),
&len);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
// No support for non-text data
NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED);
nsAutoString buffer;
supportsString->GetData(buffer);
bool isPrivateData = false;
aTransferable->GetIsPrivateData(&isPrivateData);
ContentChild::GetSingleton()->SendSetClipboardText(buffer, isPrivateData,
aWhichClipboard);
return NS_OK;
}
NS_IMETHODIMP
nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
{
nsAutoString buffer;
ContentChild::GetSingleton()->SendGetClipboardText(aWhichClipboard, &buffer);
nsresult rv;
nsCOMPtr<nsISupportsString> 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<nsISupports> nsisupportsDataWrapper =
do_QueryInterface(dataWrapper);
rv = aTransferable->SetTransferData(kUnicodeMime, nsisupportsDataWrapper,
buffer.Length() * sizeof(char16_t));
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard)
{
ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard);
return NS_OK;
}
NS_IMETHODIMP
nsClipboardProxy::HasDataMatchingFlavors(const char **aFlavorList,
uint32_t aLength, int32_t aWhichClipboard,
bool *aHasText)
{
*aHasText = false;
ContentChild::GetSingleton()->SendClipboardHasText(aWhichClipboard, aHasText);
return NS_OK;
}
NS_IMETHODIMP
nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported)
{
*aIsSupported = false;
return NS_OK;
}

View File

@ -0,0 +1,20 @@
/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
#ifndef NS_CLIPBOARD_PROXY_H
#define NS_CLIPBOARD_PROXY_H
#include "nsIClipboard.h"
class nsClipboardProxy MOZ_FINAL : public nsIClipboard
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICLIPBOARD
nsClipboardProxy();
};
#endif

View File

@ -7,23 +7,29 @@
#include "mozilla/ModuleUtils.h" #include "mozilla/ModuleUtils.h"
#include "nsWidgetsCID.h" #include "nsWidgetsCID.h"
#include "nsClipboardProxy.h"
#include "nsFilePickerProxy.h" #include "nsFilePickerProxy.h"
using namespace mozilla; using namespace mozilla;
#ifndef MOZ_B2G #ifndef MOZ_B2G
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardProxy)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePickerProxy) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePickerProxy)
NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID); NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
static const mozilla::Module::CIDEntry kWidgetCIDs[] = { static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardProxyConstructor,
Module::CONTENT_PROCESS_ONLY },
{ &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerProxyConstructor, { &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerProxyConstructor,
Module::CONTENT_PROCESS_ONLY }, Module::CONTENT_PROCESS_ONLY },
{ nullptr } { nullptr }
}; };
static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
{ "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID, Module::CONTENT_PROCESS_ONLY },
{ "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::CONTENT_PROCESS_ONLY }, { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::CONTENT_PROCESS_ONLY },
{ nullptr } { nullptr }
}; };