1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is mozilla.org code.
16 * The Initial Developer of the Original Code is
17 * Doug Turner <dougt@dougt.org>
18 * Portions created by the Initial Developer are Copyright (C) 2009
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "nsAccelerometer.h"
39 #include "nsAutoPtr.h"
40 #include "nsIDOMEvent.h"
41 #include "nsIDOMWindow.h"
42 #include "nsIDOMDocument.h"
43 #include "nsIDOMEventTarget.h"
44 #include "nsIServiceManager.h"
45 #include "nsIPrivateDOMEvent.h"
46 #include "nsIDOMDocumentEvent.h"
47 #include "nsIDOMOrientationEvent.h"
48 #include "nsIServiceManager.h"
49 #include "nsIPrefService.h"
51 class nsAcceleration
: public nsIAcceleration
55 NS_DECL_NSIACCELERATION
57 nsAcceleration(double x
, double y
, double z
);
63 /* additional members */
67 /* Implementation file */
68 NS_IMPL_ISUPPORTS1(nsAcceleration
, nsIAcceleration
)
70 nsAcceleration::nsAcceleration(double x
, double y
, double z
)
75 nsAcceleration::~nsAcceleration()
79 NS_IMETHODIMP
nsAcceleration::GetX(double *aX
)
81 NS_ENSURE_ARG_POINTER(aX
);
86 NS_IMETHODIMP
nsAcceleration::GetY(double *aY
)
88 NS_ENSURE_ARG_POINTER(aY
);
93 NS_IMETHODIMP
nsAcceleration::GetZ(double *aZ
)
95 NS_ENSURE_ARG_POINTER(aZ
);
100 NS_IMPL_ISUPPORTS2(nsAccelerometer
, nsIAccelerometer
, nsIAccelerometerUpdate
)
102 nsAccelerometer::nsAccelerometer()
103 : mLastX(10), /* initialize to values that can't be possible */
107 mNewListener(PR_FALSE
),
108 mUpdateInterval(50), /* default to 50 ms */
111 nsCOMPtr
<nsIPrefBranch
> prefSrv
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
114 nsresult rv
= prefSrv
->GetIntPref("accelerometer.update.interval", &value
);
115 if (NS_SUCCEEDED(rv
))
116 mUpdateInterval
= value
;
119 rv
= prefSrv
->GetBoolPref("accelerometer.enabled", &bvalue
);
120 if (NS_SUCCEEDED(rv
) && bvalue
== PR_FALSE
)
125 nsAccelerometer::~nsAccelerometer()
128 mTimeoutTimer
->Cancel();
132 nsAccelerometer::StartDisconnectTimer()
135 mTimeoutTimer
->Cancel();
137 mTimeoutTimer
= do_CreateInstance("@mozilla.org/timer;1");
139 mTimeoutTimer
->InitWithFuncCallback(TimeoutHandler
,
142 nsITimer::TYPE_ONE_SHOT
);
146 nsAccelerometer::TimeoutHandler(nsITimer
*aTimer
, void *aClosure
)
148 // the reason that we use self, instead of just using nsITimerCallback or nsIObserver
149 // is so that subclasses are free to use timers without worry about the base classes's
151 nsAccelerometer
*self
= reinterpret_cast<nsAccelerometer
*>(aClosure
);
157 // what about listeners that don't clean up properly? they will leak
158 if (self
->mListeners
.Count() == 0 && self
->mWindowListeners
.Count() == 0) {
160 self
->mStarted
= PR_FALSE
;
164 NS_IMETHODIMP
nsAccelerometer::AddListener(nsIAccelerationListener
*aListener
)
166 if (mListeners
.IndexOf(aListener
) >= 0)
167 return NS_OK
; // already exists
169 if (mStarted
== PR_FALSE
) {
171 mNewListener
= PR_TRUE
;
175 mListeners
.AppendObject(aListener
);
179 NS_IMETHODIMP
nsAccelerometer::RemoveListener(nsIAccelerationListener
*aListener
)
181 if (mListeners
.IndexOf(aListener
) < 0)
182 return NS_OK
; // doesn't exist
184 mListeners
.RemoveObject(aListener
);
185 StartDisconnectTimer();
189 NS_IMETHODIMP
nsAccelerometer::AddWindowListener(nsIDOMWindow
*aWindow
)
191 if (mWindowListeners
.IndexOf(aWindow
) >= 0)
192 return NS_OK
; // already exists
194 if (mStarted
== PR_FALSE
) {
196 mNewListener
= PR_TRUE
;
200 mWindowListeners
.AppendObject(aWindow
);
204 NS_IMETHODIMP
nsAccelerometer::RemoveWindowListener(nsIDOMWindow
*aWindow
)
206 if (mWindowListeners
.IndexOf(aWindow
) < 0)
207 return NS_OK
; // doesn't exist
209 mWindowListeners
.RemoveObject(aWindow
);
210 StartDisconnectTimer();
216 nsAccelerometer::AccelerationChanged(double x
, double y
, double z
)
219 return NS_ERROR_NOT_INITIALIZED
;
235 if (PR_ABS(mLastX
- x
) < .01 &&
236 PR_ABS(mLastY
- y
) < .01 &&
237 PR_ABS(mLastZ
- z
) < .01)
244 mNewListener
= PR_FALSE
;
246 for (PRUint32 i
= mListeners
.Count(); i
> 0 ; ) {
248 nsRefPtr
<nsIAcceleration
> a
= new nsAcceleration(x
, y
, z
);
249 mListeners
[i
]->OnAccelerationChange(a
);
252 for (PRUint32 i
= mWindowListeners
.Count(); i
> 0 ; ) {
255 nsCOMPtr
<nsIDOMDocument
> domdoc
;
256 mWindowListeners
[i
]->GetDocument(getter_AddRefs(domdoc
));
258 nsCOMPtr
<nsIDOMDocumentEvent
> docevent(do_QueryInterface(domdoc
));
259 nsCOMPtr
<nsIDOMEvent
> event
;
261 PRBool defaultActionEnabled
= PR_TRUE
;
264 docevent
->CreateEvent(NS_LITERAL_STRING("orientation"), getter_AddRefs(event
));
266 nsCOMPtr
<nsIDOMOrientationEvent
> oe
= do_QueryInterface(event
);
269 oe
->InitOrientationEvent(NS_LITERAL_STRING("MozOrientation"),
276 nsCOMPtr
<nsIPrivateDOMEvent
> privateEvent
= do_QueryInterface(event
);
278 privateEvent
->SetTrusted(PR_TRUE
);
280 nsCOMPtr
<nsIDOMEventTarget
> target(do_QueryInterface(mWindowListeners
[i
]));
281 target
->DispatchEvent(event
, &defaultActionEnabled
);