1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation
18 : * Portions created by the Initial Developer are Copyright (C) 2011
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "SmsRequest.h"
39 : #include "nsIDOMClassInfo.h"
40 : #include "nsDOMString.h"
41 : #include "nsContentUtils.h"
42 : #include "nsIDOMSmsMessage.h"
43 : #include "nsIDOMSmsCursor.h"
44 : #include "nsISmsRequestManager.h"
45 : #include "SmsManager.h"
46 :
47 : DOMCI_DATA(MozSmsRequest, mozilla::dom::sms::SmsRequest)
48 :
49 : namespace mozilla {
50 : namespace dom {
51 : namespace sms {
52 :
53 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(SmsRequest)
54 :
55 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SmsRequest,
56 : nsDOMEventTargetHelper)
57 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
58 0 : NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
59 0 : NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
60 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCursor)
61 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
62 :
63 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SmsRequest,
64 : nsDOMEventTargetHelper)
65 0 : if (tmp->mResultRooted) {
66 0 : tmp->mResult = JSVAL_VOID;
67 0 : tmp->UnrootResult();
68 : }
69 0 : NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
70 0 : NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
71 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCursor)
72 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
73 :
74 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(SmsRequest,
75 : nsDOMEventTargetHelper)
76 0 : if (JSVAL_IS_GCTHING(tmp->mResult)) {
77 0 : void *gcThing = JSVAL_TO_GCTHING(tmp->mResult);
78 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResult")
79 : }
80 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
81 :
82 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SmsRequest)
83 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMMozSmsRequest)
84 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozSmsRequest)
85 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSmsRequest)
86 0 : NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
87 :
88 0 : NS_IMPL_ADDREF_INHERITED(SmsRequest, nsDOMEventTargetHelper)
89 0 : NS_IMPL_RELEASE_INHERITED(SmsRequest, nsDOMEventTargetHelper)
90 :
91 0 : NS_IMPL_EVENT_HANDLER(SmsRequest, success)
92 0 : NS_IMPL_EVENT_HANDLER(SmsRequest, error)
93 :
94 0 : SmsRequest::SmsRequest(SmsManager* aManager)
95 : : mResult(JSVAL_VOID)
96 : , mResultRooted(false)
97 : , mError(nsISmsRequestManager::SUCCESS_NO_ERROR)
98 0 : , mDone(false)
99 : {
100 0 : BindToOwner(aManager);
101 0 : }
102 :
103 0 : SmsRequest::~SmsRequest()
104 : {
105 0 : if (mResultRooted) {
106 0 : UnrootResult();
107 : }
108 0 : }
109 :
110 : void
111 0 : SmsRequest::Reset()
112 : {
113 0 : NS_ASSERTION(mDone, "mDone should be true if we try to reset!");
114 0 : NS_ASSERTION(mResult != JSVAL_VOID, "mResult should be set if we try to reset!");
115 0 : NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
116 : "There should be no error if we try to reset!");
117 :
118 0 : if (mResultRooted) {
119 0 : UnrootResult();
120 : }
121 :
122 0 : mResult = JSVAL_VOID;
123 0 : mDone = false;
124 0 : }
125 :
126 : void
127 0 : SmsRequest::RootResult()
128 : {
129 0 : NS_ASSERTION(!mResultRooted, "Don't call RootResult() if already rooted!");
130 0 : NS_HOLD_JS_OBJECTS(this, SmsRequest);
131 0 : mResultRooted = true;
132 0 : }
133 :
134 : void
135 0 : SmsRequest::UnrootResult()
136 : {
137 0 : NS_ASSERTION(mResultRooted, "Don't call UnrotResult() if not rooted!");
138 0 : NS_DROP_JS_OBJECTS(this, SmsRequest);
139 0 : mResultRooted = false;
140 0 : }
141 :
142 : void
143 0 : SmsRequest::SetSuccess(nsIDOMMozSmsMessage* aMessage)
144 : {
145 0 : SetSuccessInternal(aMessage);
146 0 : }
147 :
148 : void
149 0 : SmsRequest::SetSuccess(bool aResult)
150 : {
151 0 : NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
152 0 : NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
153 : "mError shouldn't have been set!");
154 0 : NS_PRECONDITION(mResult == JSVAL_NULL, "mResult shouldn't have been set!");
155 :
156 0 : mResult.setBoolean(aResult);
157 0 : mDone = true;
158 0 : }
159 :
160 : void
161 0 : SmsRequest::SetSuccess(nsIDOMMozSmsCursor* aCursor)
162 : {
163 0 : if (!SetSuccessInternal(aCursor)) {
164 0 : return;
165 : }
166 :
167 0 : NS_ASSERTION(!mCursor || mCursor == aCursor,
168 : "SmsRequest can't change it's cursor!");
169 :
170 0 : if (!mCursor) {
171 0 : mCursor = aCursor;
172 : }
173 : }
174 :
175 : bool
176 0 : SmsRequest::SetSuccessInternal(nsISupports* aObject)
177 : {
178 0 : NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
179 0 : NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
180 : "mError shouldn't have been set!");
181 0 : NS_PRECONDITION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
182 :
183 : nsresult rv;
184 0 : nsIScriptContext* sc = GetContextForEventHandlers(&rv);
185 0 : if (!sc) {
186 0 : SetError(nsISmsRequestManager::INTERNAL_ERROR);
187 0 : return false;
188 : }
189 :
190 0 : JSContext* cx = sc->GetNativeContext();
191 0 : NS_ASSERTION(cx, "Failed to get a context!");
192 :
193 0 : JSObject* global = sc->GetNativeGlobal();
194 0 : NS_ASSERTION(global, "Failed to get global object!");
195 :
196 0 : JSAutoRequest ar(cx);
197 0 : JSAutoEnterCompartment ac;
198 0 : if (!ac.enter(cx, global)) {
199 0 : SetError(nsISmsRequestManager::INTERNAL_ERROR);
200 0 : return false;
201 : }
202 :
203 0 : RootResult();
204 :
205 0 : if (NS_FAILED(nsContentUtils::WrapNative(cx, global, aObject, &mResult))) {
206 0 : UnrootResult();
207 0 : mResult = JSVAL_VOID;
208 0 : SetError(nsISmsRequestManager::INTERNAL_ERROR);
209 0 : return false;
210 : }
211 :
212 0 : mDone = true;
213 0 : return true;
214 : }
215 :
216 : void
217 0 : SmsRequest::SetError(PRInt32 aError)
218 : {
219 0 : NS_PRECONDITION(!mDone, "mDone shouldn't have been set to true already!");
220 0 : NS_PRECONDITION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
221 : "mError shouldn't have been set!");
222 0 : NS_PRECONDITION(mResult == JSVAL_VOID, "mResult shouldn't have been set!");
223 :
224 0 : mDone = true;
225 0 : mError = aError;
226 0 : mCursor = nsnull;
227 0 : }
228 :
229 : NS_IMETHODIMP
230 0 : SmsRequest::GetReadyState(nsAString& aReadyState)
231 : {
232 0 : if (mDone) {
233 0 : aReadyState.AssignLiteral("done");
234 : } else {
235 0 : aReadyState.AssignLiteral("processing");
236 : }
237 :
238 0 : return NS_OK;
239 : }
240 :
241 : NS_IMETHODIMP
242 0 : SmsRequest::GetError(nsAString& aError)
243 : {
244 0 : if (!mDone) {
245 0 : NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR,
246 : "There should be no error if the request is still processing!");
247 :
248 0 : SetDOMStringToNull(aError);
249 0 : return NS_OK;
250 : }
251 :
252 0 : NS_ASSERTION(mError == nsISmsRequestManager::SUCCESS_NO_ERROR ||
253 : mResult == JSVAL_VOID,
254 : "mResult should be void when there is an error!");
255 :
256 0 : switch (mError) {
257 : case nsISmsRequestManager::SUCCESS_NO_ERROR:
258 0 : SetDOMStringToNull(aError);
259 0 : break;
260 : case nsISmsRequestManager::NO_SIGNAL_ERROR:
261 0 : aError.AssignLiteral("NoSignalError");
262 0 : break;
263 : case nsISmsRequestManager::NOT_FOUND_ERROR:
264 0 : aError.AssignLiteral("NotFoundError");
265 0 : break;
266 : case nsISmsRequestManager::UNKNOWN_ERROR:
267 0 : aError.AssignLiteral("UnknownError");
268 0 : break;
269 : case nsISmsRequestManager::INTERNAL_ERROR:
270 0 : aError.AssignLiteral("InternalError");
271 0 : break;
272 : default:
273 0 : MOZ_ASSERT(false, "Unknown error value.");
274 : }
275 :
276 0 : return NS_OK;
277 : }
278 :
279 : NS_IMETHODIMP
280 0 : SmsRequest::GetResult(jsval* aResult)
281 : {
282 0 : if (!mDone) {
283 0 : NS_ASSERTION(mResult == JSVAL_VOID,
284 : "When not done, result should be null!");
285 :
286 0 : *aResult = JSVAL_VOID;
287 0 : return NS_OK;
288 : }
289 :
290 0 : *aResult = mResult;
291 0 : return NS_OK;
292 : }
293 :
294 : } // namespace sms
295 : } // namespace dom
296 4392 : } // namespace mozilla
|