Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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 /*
8 This file provides the implementation for the XUL "controllers"
9 object.
11 */
13 #include "nsString.h"
15 #include "nsIControllers.h"
16 #include "nsIDOMElement.h"
17 #include "nsXULControllers.h"
18 #include "nsDOMClassInfoID.h"
19 #include "nsIController.h"
21 //----------------------------------------------------------------------
23 nsXULControllers::nsXULControllers()
24 : mCurControllerID(0)
25 {
26 }
28 nsXULControllers::~nsXULControllers(void)
29 {
30 DeleteControllers();
31 }
33 void
34 nsXULControllers::DeleteControllers()
35 {
36 uint32_t count = mControllers.Length();
37 for (uint32_t i = 0; i < count; i++)
38 {
39 nsXULControllerData* controllerData = mControllers.ElementAt(i);
40 delete controllerData; // releases the nsIController
41 }
43 mControllers.Clear();
44 }
47 nsresult
48 NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
49 {
50 NS_PRECONDITION(aOuter == nullptr, "no aggregation");
51 if (aOuter)
52 return NS_ERROR_NO_AGGREGATION;
54 nsXULControllers* controllers = new nsXULControllers();
55 if (! controllers)
56 return NS_ERROR_OUT_OF_MEMORY;
58 nsresult rv;
59 NS_ADDREF(controllers);
60 rv = controllers->QueryInterface(aIID, aResult);
61 NS_RELEASE(controllers);
62 return rv;
63 }
65 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULControllers)
67 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULControllers)
68 tmp->DeleteControllers();
69 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
70 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULControllers)
71 {
72 uint32_t i, count = tmp->mControllers.Length();
73 for (i = 0; i < count; ++i) {
74 nsXULControllerData* controllerData = tmp->mControllers[i];
75 if (controllerData) {
76 cb.NoteXPCOMChild(controllerData->mController);
77 }
78 }
79 }
80 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
82 DOMCI_DATA(XULControllers, nsXULControllers)
84 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULControllers)
85 NS_INTERFACE_MAP_ENTRY(nsIControllers)
86 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllers)
87 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XULControllers)
88 NS_INTERFACE_MAP_END
90 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULControllers)
91 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULControllers)
93 NS_IMETHODIMP
94 nsXULControllers::GetControllerForCommand(const char *aCommand, nsIController** _retval)
95 {
96 NS_ENSURE_ARG_POINTER(_retval);
97 *_retval = nullptr;
99 uint32_t count = mControllers.Length();
100 for (uint32_t i=0; i < count; i++)
101 {
102 nsXULControllerData* controllerData = mControllers.ElementAt(i);
103 if (controllerData)
104 {
105 nsCOMPtr<nsIController> controller;
106 controllerData->GetController(getter_AddRefs(controller));
107 if (controller)
108 {
109 bool supportsCommand;
110 controller->SupportsCommand(aCommand, &supportsCommand);
111 if (supportsCommand) {
112 *_retval = controller;
113 NS_ADDREF(*_retval);
114 return NS_OK;
115 }
116 }
117 }
118 }
120 return NS_OK;
121 }
123 NS_IMETHODIMP
124 nsXULControllers::InsertControllerAt(uint32_t aIndex, nsIController *controller)
125 {
126 nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
127 if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
128 #ifdef DEBUG
129 nsXULControllerData** inserted =
130 #endif
131 mControllers.InsertElementAt(aIndex, controllerData);
132 NS_ASSERTION(inserted != nullptr, "Insertion of controller failed");
133 return NS_OK;
134 }
136 NS_IMETHODIMP
137 nsXULControllers::RemoveControllerAt(uint32_t aIndex, nsIController **_retval)
138 {
139 NS_ENSURE_ARG_POINTER(_retval);
140 *_retval = nullptr;
142 nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex);
143 if (!controllerData) return NS_ERROR_FAILURE;
145 mControllers.RemoveElementAt(aIndex);
147 controllerData->GetController(_retval);
148 delete controllerData;
150 return NS_OK;
151 }
154 NS_IMETHODIMP
155 nsXULControllers::GetControllerAt(uint32_t aIndex, nsIController **_retval)
156 {
157 NS_ENSURE_ARG_POINTER(_retval);
158 *_retval = nullptr;
160 nsXULControllerData* controllerData = mControllers.SafeElementAt(aIndex);
161 if (!controllerData) return NS_ERROR_FAILURE;
163 return controllerData->GetController(_retval); // does the addref
164 }
166 NS_IMETHODIMP
167 nsXULControllers::AppendController(nsIController *controller)
168 {
169 // This assigns controller IDs starting at 1 so we can use 0 to test if an ID was obtained
170 nsXULControllerData* controllerData = new nsXULControllerData(++mCurControllerID, controller);
171 if (!controllerData) return NS_ERROR_OUT_OF_MEMORY;
173 #ifdef DEBUG
174 nsXULControllerData** appended =
175 #endif
176 mControllers.AppendElement(controllerData);
177 NS_ASSERTION(appended != nullptr, "Appending controller failed");
178 return NS_OK;
179 }
181 NS_IMETHODIMP
182 nsXULControllers::RemoveController(nsIController *controller)
183 {
184 // first get the identity pointer
185 nsCOMPtr<nsISupports> controllerSup(do_QueryInterface(controller));
186 // then find it
187 uint32_t count = mControllers.Length();
188 for (uint32_t i = 0; i < count; i++)
189 {
190 nsXULControllerData* controllerData = mControllers.ElementAt(i);
191 if (controllerData)
192 {
193 nsCOMPtr<nsIController> thisController;
194 controllerData->GetController(getter_AddRefs(thisController));
195 nsCOMPtr<nsISupports> thisControllerSup(do_QueryInterface(thisController)); // get identity
196 if (thisControllerSup == controllerSup)
197 {
198 mControllers.RemoveElementAt(i);
199 delete controllerData;
200 return NS_OK;
201 }
202 }
203 }
204 return NS_ERROR_FAILURE; // right thing to return if no controller found?
205 }
207 /* unsigned long getControllerId (in nsIController controller); */
208 NS_IMETHODIMP
209 nsXULControllers::GetControllerId(nsIController *controller, uint32_t *_retval)
210 {
211 NS_ENSURE_ARG_POINTER(_retval);
213 uint32_t count = mControllers.Length();
214 for (uint32_t i = 0; i < count; i++)
215 {
216 nsXULControllerData* controllerData = mControllers.ElementAt(i);
217 if (controllerData)
218 {
219 nsCOMPtr<nsIController> thisController;
220 controllerData->GetController(getter_AddRefs(thisController));
221 if (thisController.get() == controller)
222 {
223 *_retval = controllerData->GetControllerID();
224 return NS_OK;
225 }
226 }
227 }
228 return NS_ERROR_FAILURE; // none found
229 }
231 /* nsIController getControllerById (in unsigned long controllerID); */
232 NS_IMETHODIMP
233 nsXULControllers::GetControllerById(uint32_t controllerID, nsIController **_retval)
234 {
235 NS_ENSURE_ARG_POINTER(_retval);
237 uint32_t count = mControllers.Length();
238 for (uint32_t i = 0; i < count; i++)
239 {
240 nsXULControllerData* controllerData = mControllers.ElementAt(i);
241 if (controllerData && controllerData->GetControllerID() == controllerID)
242 {
243 return controllerData->GetController(_retval);
244 }
245 }
246 return NS_ERROR_FAILURE; // none found
247 }
249 NS_IMETHODIMP
250 nsXULControllers::GetControllerCount(uint32_t *_retval)
251 {
252 NS_ENSURE_ARG_POINTER(_retval);
253 *_retval = mControllers.Length();
254 return NS_OK;
255 }