Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/ArrayUtils.h"
8 #include "nsClipboardPrivacyHandler.h"
9 #include "nsITransferable.h"
10 #include "nsISupportsPrimitives.h"
11 #include "nsIObserverService.h"
12 #include "nsIClipboard.h"
13 #include "nsComponentManagerUtils.h"
14 #include "nsServiceManagerUtils.h"
15 #include "nsLiteralString.h"
16 #include "nsNetCID.h"
17 #include "nsXPCOM.h"
18 #include "mozilla/Services.h"
20 #if defined(XP_WIN)
21 #include <ole2.h>
22 #endif
24 using namespace mozilla;
26 #define NS_MOZ_DATA_FROM_PRIVATEBROWSING "application/x-moz-private-browsing"
28 NS_IMPL_ISUPPORTS(nsClipboardPrivacyHandler, nsIObserver, nsISupportsWeakReference)
30 nsresult
31 nsClipboardPrivacyHandler::Init()
32 {
33 nsCOMPtr<nsIObserverService> observerService =
34 mozilla::services::GetObserverService();
35 if (!observerService)
36 return NS_ERROR_FAILURE;
37 return observerService->AddObserver(this, "last-pb-context-exited", true);
38 }
40 /**
41 * Prepare the transferable object to be inserted into the clipboard
42 *
43 */
44 nsresult
45 nsClipboardPrivacyHandler::PrepareDataForClipboard(nsITransferable * aTransferable)
46 {
47 NS_ASSERTION(aTransferable, "clipboard given a null transferable");
49 bool isPrivateData = false;
50 aTransferable->GetIsPrivateData(&isPrivateData);
52 nsresult rv = NS_OK;
53 if (isPrivateData) {
54 nsCOMPtr<nsISupportsPRBool> data = do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
55 if (data) {
56 rv = data->SetData(true);
57 NS_ENSURE_SUCCESS(rv, rv);
59 // Ignore the error code of AddDataFlavor, since we might have added
60 // this flavor before. If this call really fails, so will the next
61 // one (SetTransferData).
62 aTransferable->AddDataFlavor(NS_MOZ_DATA_FROM_PRIVATEBROWSING);
64 rv = aTransferable->SetTransferData(NS_MOZ_DATA_FROM_PRIVATEBROWSING, data, sizeof(bool));
65 NS_ENSURE_SUCCESS(rv, rv);
66 }
67 }
69 return rv;
70 }
72 NS_IMETHODIMP
73 nsClipboardPrivacyHandler::Observe(nsISupports *aSubject, char const *aTopic, char16_t const *aData)
74 {
75 nsresult rv;
76 nsCOMPtr<nsIClipboard> clipboard =
77 do_GetService("@mozilla.org/widget/clipboard;1", &rv);
78 NS_ENSURE_SUCCESS(rv, rv);
80 const char * flavors[] = { NS_MOZ_DATA_FROM_PRIVATEBROWSING };
81 bool haveFlavors;
82 rv = clipboard->HasDataMatchingFlavors(flavors,
83 ArrayLength(flavors),
84 nsIClipboard::kGlobalClipboard,
85 &haveFlavors);
86 if (NS_SUCCEEDED(rv) && haveFlavors) {
87 #if defined(XP_WIN)
88 // Workaround for bug 518412. On Windows 7 x64, there is a bug
89 // in handling clipboard data without any formats between
90 // 32-bit/64-bit boundaries, which could lead Explorer to crash.
91 // We work around the problem by clearing the clipboard using
92 // the usual Win32 API.
93 NS_ENSURE_TRUE(SUCCEEDED(::OleSetClipboard(nullptr)), NS_ERROR_FAILURE);
94 #else
95 // Empty the native clipboard by copying an empty transferable
96 nsCOMPtr<nsITransferable> nullData =
97 do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
98 NS_ENSURE_SUCCESS(rv, rv);
99 nullData->Init(nullptr);
100 rv = clipboard->SetData(nullData, nullptr,
101 nsIClipboard::kGlobalClipboard);
102 NS_ENSURE_SUCCESS(rv, rv);
103 #endif
104 }
106 return NS_OK;
107 }
109 nsresult
110 NS_NewClipboardPrivacyHandler(nsClipboardPrivacyHandler ** aHandler)
111 {
112 NS_PRECONDITION(aHandler != nullptr, "null ptr");
113 if (!aHandler)
114 return NS_ERROR_NULL_POINTER;
116 *aHandler = new nsClipboardPrivacyHandler();
118 NS_ADDREF(*aHandler);
119 nsresult rv = (*aHandler)->Init();
120 if (NS_FAILED(rv))
121 NS_RELEASE(*aHandler);
123 return rv;
124 }