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: 4 -*-
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 "nsBrowserStatusFilter.h"
7 #include "nsIChannel.h"
8 #include "nsITimer.h"
9 #include "nsIServiceManager.h"
10 #include "nsString.h"
12 // XXX
13 // XXX DO NOT TOUCH THIS CODE UNLESS YOU KNOW WHAT YOU'RE DOING !!!
14 // XXX
16 //-----------------------------------------------------------------------------
17 // nsBrowserStatusFilter <public>
18 //-----------------------------------------------------------------------------
20 nsBrowserStatusFilter::nsBrowserStatusFilter()
21 : mCurProgress(0)
22 , mMaxProgress(0)
23 , mStatusIsDirty(true)
24 , mCurrentPercentage(0)
25 , mTotalRequests(0)
26 , mFinishedRequests(0)
27 , mUseRealProgressFlag(false)
28 , mDelayedStatus(false)
29 , mDelayedProgress(false)
30 {
31 }
33 nsBrowserStatusFilter::~nsBrowserStatusFilter()
34 {
35 if (mTimer) {
36 mTimer->Cancel();
37 }
38 }
40 //-----------------------------------------------------------------------------
41 // nsBrowserStatusFilter::nsISupports
42 //-----------------------------------------------------------------------------
44 NS_IMPL_ISUPPORTS(nsBrowserStatusFilter,
45 nsIWebProgress,
46 nsIWebProgressListener,
47 nsIWebProgressListener2,
48 nsISupportsWeakReference)
50 //-----------------------------------------------------------------------------
51 // nsBrowserStatusFilter::nsIWebProgress
52 //-----------------------------------------------------------------------------
54 NS_IMETHODIMP
55 nsBrowserStatusFilter::AddProgressListener(nsIWebProgressListener *aListener,
56 uint32_t aNotifyMask)
57 {
58 mListener = aListener;
59 return NS_OK;
60 }
62 NS_IMETHODIMP
63 nsBrowserStatusFilter::RemoveProgressListener(nsIWebProgressListener *aListener)
64 {
65 if (aListener == mListener)
66 mListener = nullptr;
67 return NS_OK;
68 }
70 NS_IMETHODIMP
71 nsBrowserStatusFilter::GetDOMWindow(nsIDOMWindow **aResult)
72 {
73 NS_NOTREACHED("nsBrowserStatusFilter::GetDOMWindow");
74 return NS_ERROR_NOT_IMPLEMENTED;
75 }
77 NS_IMETHODIMP
78 nsBrowserStatusFilter::GetDOMWindowID(uint64_t *aResult)
79 {
80 *aResult = 0;
81 NS_NOTREACHED("nsBrowserStatusFilter::GetDOMWindowID");
82 return NS_ERROR_NOT_IMPLEMENTED;
83 }
85 NS_IMETHODIMP
86 nsBrowserStatusFilter::GetIsTopLevel(bool *aIsTopLevel)
87 {
88 *aIsTopLevel = false;
89 NS_NOTREACHED("nsBrowserStatusFilter::GetIsTopLevel");
90 return NS_ERROR_NOT_IMPLEMENTED;
91 }
93 NS_IMETHODIMP
94 nsBrowserStatusFilter::GetIsLoadingDocument(bool *aIsLoadingDocument)
95 {
96 NS_NOTREACHED("nsBrowserStatusFilter::GetIsLoadingDocument");
97 return NS_ERROR_NOT_IMPLEMENTED;
98 }
100 NS_IMETHODIMP
101 nsBrowserStatusFilter::GetLoadType(uint32_t *aLoadType)
102 {
103 *aLoadType = 0;
104 NS_NOTREACHED("nsBrowserStatusFilter::GetLoadType");
105 return NS_ERROR_NOT_IMPLEMENTED;
106 }
108 //-----------------------------------------------------------------------------
109 // nsBrowserStatusFilter::nsIWebProgressListener
110 //-----------------------------------------------------------------------------
112 NS_IMETHODIMP
113 nsBrowserStatusFilter::OnStateChange(nsIWebProgress *aWebProgress,
114 nsIRequest *aRequest,
115 uint32_t aStateFlags,
116 nsresult aStatus)
117 {
118 if (!mListener)
119 return NS_OK;
121 if (aStateFlags & STATE_START) {
122 if (aStateFlags & STATE_IS_NETWORK) {
123 ResetMembers();
124 }
125 if (aStateFlags & STATE_IS_REQUEST) {
126 ++mTotalRequests;
128 // if the total requests exceeds 1, then we'll base our progress
129 // notifications on the percentage of completed requests.
130 // otherwise, progress for the single request will be reported.
131 mUseRealProgressFlag = (mTotalRequests == 1);
132 }
133 }
134 else if (aStateFlags & STATE_STOP) {
135 if (aStateFlags & STATE_IS_REQUEST) {
136 ++mFinishedRequests;
137 // Note: Do not return from here. This is necessary so that the
138 // STATE_STOP can still be relayed to the listener if needed
139 // (bug 209330)
140 if (!mUseRealProgressFlag && mTotalRequests)
141 OnProgressChange(nullptr, nullptr, 0, 0,
142 mFinishedRequests, mTotalRequests);
143 }
144 }
145 else if (aStateFlags & STATE_TRANSFERRING) {
146 if (aStateFlags & STATE_IS_REQUEST) {
147 if (!mUseRealProgressFlag && mTotalRequests)
148 return OnProgressChange(nullptr, nullptr, 0, 0,
149 mFinishedRequests, mTotalRequests);
150 }
152 // no need to forward this state change
153 return NS_OK;
154 } else {
155 // no need to forward this state change
156 return NS_OK;
157 }
159 // If we're here, we have either STATE_START or STATE_STOP. The
160 // listener only cares about these in certain conditions.
161 bool isLoadingDocument = false;
162 if ((aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK ||
163 (aStateFlags & nsIWebProgressListener::STATE_IS_REQUEST &&
164 mFinishedRequests == mTotalRequests &&
165 (aWebProgress->GetIsLoadingDocument(&isLoadingDocument),
166 !isLoadingDocument)))) {
167 if (mTimer && (aStateFlags & nsIWebProgressListener::STATE_STOP)) {
168 mTimer->Cancel();
169 ProcessTimeout();
170 }
172 return mListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
173 aStatus);
174 }
176 return NS_OK;
177 }
179 NS_IMETHODIMP
180 nsBrowserStatusFilter::OnProgressChange(nsIWebProgress *aWebProgress,
181 nsIRequest *aRequest,
182 int32_t aCurSelfProgress,
183 int32_t aMaxSelfProgress,
184 int32_t aCurTotalProgress,
185 int32_t aMaxTotalProgress)
186 {
187 if (!mListener)
188 return NS_OK;
190 if (!mUseRealProgressFlag && aRequest)
191 return NS_OK;
193 //
194 // limit frequency of calls to OnProgressChange
195 //
197 mCurProgress = (int64_t)aCurTotalProgress;
198 mMaxProgress = (int64_t)aMaxTotalProgress;
200 if (mDelayedProgress)
201 return NS_OK;
203 if (!mDelayedStatus) {
204 MaybeSendProgress();
205 StartDelayTimer();
206 }
208 mDelayedProgress = true;
210 return NS_OK;
211 }
213 NS_IMETHODIMP
214 nsBrowserStatusFilter::OnLocationChange(nsIWebProgress *aWebProgress,
215 nsIRequest *aRequest,
216 nsIURI *aLocation,
217 uint32_t aFlags)
218 {
219 if (!mListener)
220 return NS_OK;
222 return mListener->OnLocationChange(aWebProgress, aRequest, aLocation,
223 aFlags);
224 }
226 NS_IMETHODIMP
227 nsBrowserStatusFilter::OnStatusChange(nsIWebProgress *aWebProgress,
228 nsIRequest *aRequest,
229 nsresult aStatus,
230 const char16_t *aMessage)
231 {
232 if (!mListener)
233 return NS_OK;
235 //
236 // limit frequency of calls to OnStatusChange
237 //
238 if (mStatusIsDirty || !mCurrentStatusMsg.Equals(aMessage)) {
239 mStatusIsDirty = true;
240 mStatusMsg = aMessage;
241 }
243 if (mDelayedStatus)
244 return NS_OK;
246 if (!mDelayedProgress) {
247 MaybeSendStatus();
248 StartDelayTimer();
249 }
251 mDelayedStatus = true;
253 return NS_OK;
254 }
256 NS_IMETHODIMP
257 nsBrowserStatusFilter::OnSecurityChange(nsIWebProgress *aWebProgress,
258 nsIRequest *aRequest,
259 uint32_t aState)
260 {
261 if (!mListener)
262 return NS_OK;
264 return mListener->OnSecurityChange(aWebProgress, aRequest, aState);
265 }
267 //-----------------------------------------------------------------------------
268 // nsBrowserStatusFilter::nsIWebProgressListener2
269 //-----------------------------------------------------------------------------
270 NS_IMETHODIMP
271 nsBrowserStatusFilter::OnProgressChange64(nsIWebProgress *aWebProgress,
272 nsIRequest *aRequest,
273 int64_t aCurSelfProgress,
274 int64_t aMaxSelfProgress,
275 int64_t aCurTotalProgress,
276 int64_t aMaxTotalProgress)
277 {
278 // XXX truncates 64-bit to 32-bit
279 return OnProgressChange(aWebProgress, aRequest,
280 (int32_t)aCurSelfProgress,
281 (int32_t)aMaxSelfProgress,
282 (int32_t)aCurTotalProgress,
283 (int32_t)aMaxTotalProgress);
284 }
286 NS_IMETHODIMP
287 nsBrowserStatusFilter::OnRefreshAttempted(nsIWebProgress *aWebProgress,
288 nsIURI *aUri,
289 int32_t aDelay,
290 bool aSameUri,
291 bool *allowRefresh)
292 {
293 nsCOMPtr<nsIWebProgressListener2> listener =
294 do_QueryInterface(mListener);
295 if (!listener) {
296 *allowRefresh = true;
297 return NS_OK;
298 }
300 return listener->OnRefreshAttempted(aWebProgress, aUri, aDelay, aSameUri,
301 allowRefresh);
302 }
304 //-----------------------------------------------------------------------------
305 // nsBrowserStatusFilter <private>
306 //-----------------------------------------------------------------------------
308 void
309 nsBrowserStatusFilter::ResetMembers()
310 {
311 mTotalRequests = 0;
312 mFinishedRequests = 0;
313 mUseRealProgressFlag = false;
314 mMaxProgress = 0;
315 mCurProgress = 0;
316 mCurrentPercentage = 0;
317 mStatusIsDirty = true;
318 }
320 void
321 nsBrowserStatusFilter::MaybeSendProgress()
322 {
323 if (mCurProgress > mMaxProgress || mCurProgress <= 0)
324 return;
326 // check our percentage
327 int32_t percentage = (int32_t) double(mCurProgress) * 100 / mMaxProgress;
329 // The progress meter only updates for increases greater than 3 percent
330 if (percentage > (mCurrentPercentage + 3)) {
331 mCurrentPercentage = percentage;
332 // XXX truncates 64-bit to 32-bit
333 mListener->OnProgressChange(nullptr, nullptr, 0, 0,
334 (int32_t)mCurProgress,
335 (int32_t)mMaxProgress);
336 }
337 }
339 void
340 nsBrowserStatusFilter::MaybeSendStatus()
341 {
342 if (mStatusIsDirty) {
343 mListener->OnStatusChange(nullptr, nullptr, NS_OK, mStatusMsg.get());
344 mCurrentStatusMsg = mStatusMsg;
345 mStatusIsDirty = false;
346 }
347 }
349 nsresult
350 nsBrowserStatusFilter::StartDelayTimer()
351 {
352 NS_ASSERTION(!DelayInEffect(), "delay should not be in effect");
354 mTimer = do_CreateInstance("@mozilla.org/timer;1");
355 if (!mTimer)
356 return NS_ERROR_FAILURE;
358 return mTimer->InitWithFuncCallback(TimeoutHandler, this, 160,
359 nsITimer::TYPE_ONE_SHOT);
360 }
362 void
363 nsBrowserStatusFilter::ProcessTimeout()
364 {
365 mTimer = nullptr;
367 if (!mListener)
368 return;
370 if (mDelayedStatus) {
371 mDelayedStatus = false;
372 MaybeSendStatus();
373 }
375 if (mDelayedProgress) {
376 mDelayedProgress = false;
377 MaybeSendProgress();
378 }
379 }
381 void
382 nsBrowserStatusFilter::TimeoutHandler(nsITimer *aTimer, void *aClosure)
383 {
384 nsBrowserStatusFilter *self = reinterpret_cast<nsBrowserStatusFilter *>(aClosure);
385 if (!self) {
386 NS_ERROR("no self");
387 return;
388 }
390 self->ProcessTimeout();
391 }