Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set sw=4 ts=8 et tw=80 :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "FilePickerParent.h"
8 #include "nsComponentManagerUtils.h"
9 #include "nsDOMFile.h"
10 #include "nsNetCID.h"
11 #include "nsIDocument.h"
12 #include "nsIDOMFile.h"
13 #include "nsIDOMWindow.h"
14 #include "nsIFile.h"
15 #include "nsISimpleEnumerator.h"
16 #include "mozilla/unused.h"
17 #include "mozilla/dom/ContentParent.h"
18 #include "mozilla/dom/Element.h"
19 #include "mozilla/dom/TabParent.h"
20 #include "mozilla/dom/ipc/Blob.h"
22 using mozilla::unused;
23 using namespace mozilla::dom;
25 NS_IMPL_ISUPPORTS(FilePickerParent::FilePickerShownCallback,
26 nsIFilePickerShownCallback);
28 NS_IMETHODIMP
29 FilePickerParent::FilePickerShownCallback::Done(int16_t aResult)
30 {
31 if (mFilePickerParent) {
32 mFilePickerParent->Done(aResult);
33 }
34 return NS_OK;
35 }
37 void
38 FilePickerParent::FilePickerShownCallback::Destroy()
39 {
40 mFilePickerParent = nullptr;
41 }
43 FilePickerParent::~FilePickerParent()
44 {
45 }
47 // Before sending a blob to the child, we need to get its size and modification
48 // date. Otherwise it will be sent as a "mystery blob" by
49 // GetOrCreateActorForBlob, which will cause problems for the child
50 // process. This runnable stat()s the file off the main thread.
51 //
52 // We run code in three places:
53 // 1. The main thread calls Dispatch() to start the runnable.
54 // 2. The stream transport thread stat()s the file in Run() and then dispatches
55 // the same runnable on the main thread.
56 // 3. The main thread sends the results over IPC.
57 FilePickerParent::FileSizeAndDateRunnable::FileSizeAndDateRunnable(FilePickerParent *aFPParent,
58 nsCOMArray<nsIDOMFile>& aDomfiles)
59 : mFilePickerParent(aFPParent)
60 {
61 mDomfiles.SwapElements(aDomfiles);
62 }
64 bool
65 FilePickerParent::FileSizeAndDateRunnable::Dispatch()
66 {
67 MOZ_ASSERT(NS_IsMainThread());
69 mEventTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
70 if (!mEventTarget) {
71 return false;
72 }
74 nsresult rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
75 return NS_SUCCEEDED(rv);
76 }
78 NS_IMETHODIMP
79 FilePickerParent::FileSizeAndDateRunnable::Run()
80 {
81 // If we're on the main thread, then that means we're done. Just send the
82 // results.
83 if (NS_IsMainThread()) {
84 if (mFilePickerParent) {
85 mFilePickerParent->SendFiles(mDomfiles);
86 }
87 return NS_OK;
88 }
90 // We're not on the main thread, so do the stat().
91 for (unsigned i = 0; i < mDomfiles.Length(); i++) {
92 uint64_t size, lastModified;
93 mDomfiles[i]->GetSize(&size);
94 mDomfiles[i]->GetMozLastModifiedDate(&lastModified);
95 }
97 // Dispatch ourselves back on the main thread.
98 if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
99 // It's hard to see how we can recover gracefully in this case. The child
100 // process is waiting for an IPC, but that can only happen on the main
101 // thread.
102 MOZ_CRASH();
103 }
104 return NS_OK;
105 }
107 void
108 FilePickerParent::FileSizeAndDateRunnable::Destroy()
109 {
110 mFilePickerParent = nullptr;
111 }
113 void
114 FilePickerParent::SendFiles(const nsCOMArray<nsIDOMFile>& aDomfiles)
115 {
116 ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager());
117 InfallibleTArray<PBlobParent*> files;
119 for (unsigned i = 0; i < aDomfiles.Length(); i++) {
120 BlobParent* blob = parent->GetOrCreateActorForBlob(aDomfiles[i]);
121 if (blob) {
122 files.AppendElement(blob);
123 }
124 }
126 InputFiles infiles;
127 infiles.filesParent().SwapElements(files);
128 unused << Send__delete__(this, infiles, mResult);
129 }
131 void
132 FilePickerParent::Done(int16_t aResult)
133 {
134 mResult = aResult;
136 if (mResult != nsIFilePicker::returnOK) {
137 unused << Send__delete__(this, void_t(), mResult);
138 return;
139 }
141 nsCOMArray<nsIDOMFile> domfiles;
142 if (mMode == nsIFilePicker::modeOpenMultiple) {
143 nsCOMPtr<nsISimpleEnumerator> iter;
144 NS_ENSURE_SUCCESS_VOID(mFilePicker->GetFiles(getter_AddRefs(iter)));
146 nsCOMPtr<nsISupports> supports;
147 bool loop = true;
148 while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
149 iter->GetNext(getter_AddRefs(supports));
150 if (supports) {
151 nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
152 nsCOMPtr<nsIDOMFile> domfile = new nsDOMFileFile(file);
153 domfiles.AppendElement(domfile);
154 }
155 }
156 } else {
157 nsCOMPtr<nsIFile> file;
158 mFilePicker->GetFile(getter_AddRefs(file));
159 if (file) {
160 nsCOMPtr<nsIDOMFile> domfile = new nsDOMFileFile(file);
161 domfiles.AppendElement(domfile);
162 }
163 }
165 MOZ_ASSERT(!mRunnable);
166 mRunnable = new FileSizeAndDateRunnable(this, domfiles);
167 if (!mRunnable->Dispatch()) {
168 unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
169 }
170 }
172 bool
173 FilePickerParent::CreateFilePicker()
174 {
175 mFilePicker = do_CreateInstance("@mozilla.org/filepicker;1");
176 if (!mFilePicker) {
177 return false;
178 }
180 Element* element = static_cast<TabParent*>(Manager())->GetOwnerElement();
181 if (!element) {
182 return false;
183 }
185 nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(element->OwnerDoc()->GetWindow());
186 if (!window) {
187 return false;
188 }
190 return NS_SUCCEEDED(mFilePicker->Init(window, mTitle, mMode));
191 }
193 bool
194 FilePickerParent::RecvOpen(const int16_t& aSelectedType,
195 const bool& aAddToRecentDocs,
196 const nsString& aDefaultFile,
197 const nsString& aDefaultExtension,
198 const InfallibleTArray<nsString>& aFilters,
199 const InfallibleTArray<nsString>& aFilterNames)
200 {
201 if (!CreateFilePicker()) {
202 unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
203 return true;
204 }
206 mFilePicker->SetAddToRecentDocs(aAddToRecentDocs);
208 for (uint32_t i = 0; i < aFilters.Length(); ++i) {
209 mFilePicker->AppendFilter(aFilterNames[i], aFilters[i]);
210 }
212 mFilePicker->SetDefaultString(aDefaultFile);
213 mFilePicker->SetDefaultExtension(aDefaultExtension);
214 mFilePicker->SetFilterIndex(aSelectedType);
216 mCallback = new FilePickerShownCallback(this);
218 mFilePicker->Open(mCallback);
219 return true;
220 }
222 void
223 FilePickerParent::ActorDestroy(ActorDestroyReason aWhy)
224 {
225 if (mCallback) {
226 mCallback->Destroy();
227 mCallback = nullptr;
228 }
229 if (mRunnable) {
230 mRunnable->Destroy();
231 mRunnable = nullptr;
232 }
233 }