|
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/. */ |
|
5 |
|
6 #include "mozilla/ArrayUtils.h" |
|
7 |
|
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" |
|
19 |
|
20 #if defined(XP_WIN) |
|
21 #include <ole2.h> |
|
22 #endif |
|
23 |
|
24 using namespace mozilla; |
|
25 |
|
26 #define NS_MOZ_DATA_FROM_PRIVATEBROWSING "application/x-moz-private-browsing" |
|
27 |
|
28 NS_IMPL_ISUPPORTS(nsClipboardPrivacyHandler, nsIObserver, nsISupportsWeakReference) |
|
29 |
|
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 } |
|
39 |
|
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"); |
|
48 |
|
49 bool isPrivateData = false; |
|
50 aTransferable->GetIsPrivateData(&isPrivateData); |
|
51 |
|
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); |
|
58 |
|
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); |
|
63 |
|
64 rv = aTransferable->SetTransferData(NS_MOZ_DATA_FROM_PRIVATEBROWSING, data, sizeof(bool)); |
|
65 NS_ENSURE_SUCCESS(rv, rv); |
|
66 } |
|
67 } |
|
68 |
|
69 return rv; |
|
70 } |
|
71 |
|
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); |
|
79 |
|
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 } |
|
105 |
|
106 return NS_OK; |
|
107 } |
|
108 |
|
109 nsresult |
|
110 NS_NewClipboardPrivacyHandler(nsClipboardPrivacyHandler ** aHandler) |
|
111 { |
|
112 NS_PRECONDITION(aHandler != nullptr, "null ptr"); |
|
113 if (!aHandler) |
|
114 return NS_ERROR_NULL_POINTER; |
|
115 |
|
116 *aHandler = new nsClipboardPrivacyHandler(); |
|
117 |
|
118 NS_ADDREF(*aHandler); |
|
119 nsresult rv = (*aHandler)->Init(); |
|
120 if (NS_FAILED(rv)) |
|
121 NS_RELEASE(*aHandler); |
|
122 |
|
123 return rv; |
|
124 } |