1 /*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "DeviceMotionAndOrientationManager.h"
28
29 #include "DeviceMotionClientImpl.h"
30 #include "DeviceOrientationClientImpl.h"
31 #include "DeviceOrientationController.h"
32 #include "WebViewCore.h"
33 #include "Frame.h"
34 #include "Page.h"
35
36 #include <DeviceOrientationClientMock.h>
37 #include <JNIHelp.h>
38
39 using namespace WebCore;
40
41 namespace android {
42
DeviceMotionAndOrientationManager(WebViewCore * webViewCore)43 DeviceMotionAndOrientationManager::DeviceMotionAndOrientationManager(WebViewCore* webViewCore)
44 : m_useMock(false)
45 , m_webViewCore(webViewCore)
46 {
47 }
48
useMock()49 void DeviceMotionAndOrientationManager::useMock()
50 {
51 m_useMock = true;
52 }
53
setMockMotion(PassRefPtr<DeviceMotionData> motion)54 void DeviceMotionAndOrientationManager::setMockMotion(PassRefPtr<DeviceMotionData> motion)
55 {
56 // TODO: There is not yet a DeviceMotion mock.
57 }
58
onMotionChange(PassRefPtr<DeviceMotionData> motion)59 void DeviceMotionAndOrientationManager::onMotionChange(PassRefPtr<DeviceMotionData> motion)
60 {
61 ASSERT(!m_useMock);
62 static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->onMotionChange(motion);
63 }
64
setMockOrientation(PassRefPtr<DeviceOrientation> orientation)65 void DeviceMotionAndOrientationManager::setMockOrientation(PassRefPtr<DeviceOrientation> orientation)
66 {
67 if (m_useMock)
68 static_cast<DeviceOrientationClientMock*>(orientationClient())->setOrientation(orientation);
69 }
70
onOrientationChange(PassRefPtr<DeviceOrientation> orientation)71 void DeviceMotionAndOrientationManager::onOrientationChange(PassRefPtr<DeviceOrientation> orientation)
72 {
73 ASSERT(!m_useMock);
74 static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->onOrientationChange(orientation);
75 }
76
maybeSuspendClients()77 void DeviceMotionAndOrientationManager::maybeSuspendClients()
78 {
79 if (!m_useMock) {
80 if (m_motionClient)
81 static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->suspend();
82 if (m_orientationClient)
83 static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->suspend();
84 }
85 }
86
maybeResumeClients()87 void DeviceMotionAndOrientationManager::maybeResumeClients()
88 {
89 if (!m_useMock) {
90 if (m_motionClient)
91 static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->resume();
92 if (m_orientationClient)
93 static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->resume();
94 }
95 }
96
motionClient()97 DeviceMotionClient* DeviceMotionAndOrientationManager::motionClient()
98 {
99 // TODO: There is not yet a DeviceMotion mock.
100 if (!m_motionClient)
101 m_motionClient.set(m_useMock ? 0
102 : static_cast<DeviceMotionClient*>(new DeviceMotionClientImpl(m_webViewCore)));
103 ASSERT(m_motionClient);
104 return m_motionClient.get();
105 }
106
orientationClient()107 DeviceOrientationClient* DeviceMotionAndOrientationManager::orientationClient()
108 {
109 if (!m_orientationClient)
110 m_orientationClient.set(m_useMock ? new DeviceOrientationClientMock
111 : static_cast<DeviceOrientationClient*>(new DeviceOrientationClientImpl(m_webViewCore)));
112 ASSERT(m_orientationClient);
113 return m_orientationClient.get();
114 }
115
116 // JNI for android.webkit.DeviceMotionAndOrientationManager
117 static const char* javaDeviceMotionAndOrientationManagerClass = "android/webkit/DeviceMotionAndOrientationManager";
118
getWebViewCore(JNIEnv * env,jobject webViewCoreObject)119 static WebViewCore* getWebViewCore(JNIEnv* env, jobject webViewCoreObject)
120 {
121 jclass webViewCoreClass = env->FindClass("android/webkit/WebViewCore");
122 jfieldID nativeClassField = env->GetFieldID(webViewCoreClass, "mNativeClass", "I");
123 env->DeleteLocalRef(webViewCoreClass);
124 return reinterpret_cast<WebViewCore*>(env->GetIntField(webViewCoreObject, nativeClassField));
125 }
126
useMock(JNIEnv * env,jobject,jobject webViewCoreObject)127 static void useMock(JNIEnv* env, jobject, jobject webViewCoreObject)
128 {
129 getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->useMock();
130 }
131
onMotionChange(JNIEnv * env,jobject,jobject webViewCoreObject,bool canProvideX,double x,bool canProvideY,double y,bool canProvideZ,double z,double interval)132 static void onMotionChange(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideX, double x, bool canProvideY, double y, bool canProvideZ, double z, double interval)
133 {
134 // We only provide accelerationIncludingGravity.
135 RefPtr<DeviceMotionData::Acceleration> accelerationIncludingGravity = DeviceMotionData::Acceleration::create(canProvideX, x, canProvideY, y, canProvideZ, z);
136 bool canProvideInterval = canProvideX || canProvideY || canProvideZ;
137 RefPtr<DeviceMotionData> motion = DeviceMotionData::create(0, accelerationIncludingGravity.release(), 0, canProvideInterval, interval);
138 getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->onMotionChange(motion.release());
139 }
140
setMockOrientation(JNIEnv * env,jobject,jobject webViewCoreObject,bool canProvideAlpha,double alpha,bool canProvideBeta,double beta,bool canProvideGamma,double gamma)141 static void setMockOrientation(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
142 {
143 RefPtr<DeviceOrientation> orientation = DeviceOrientation::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
144 getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->setMockOrientation(orientation.release());
145 }
146
onOrientationChange(JNIEnv * env,jobject,jobject webViewCoreObject,bool canProvideAlpha,double alpha,bool canProvideBeta,double beta,bool canProvideGamma,double gamma)147 static void onOrientationChange(JNIEnv* env, jobject, jobject webViewCoreObject, bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
148 {
149 RefPtr<DeviceOrientation> orientation = DeviceOrientation::create(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
150 getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->onOrientationChange(orientation.release());
151 }
152
153 static JNINativeMethod gDeviceMotionAndOrientationManagerMethods[] = {
154 { "nativeUseMock", "(Landroid/webkit/WebViewCore;)V", (void*) useMock },
155 { "nativeOnMotionChange", "(Landroid/webkit/WebViewCore;ZDZDZDD)V", (void*) onMotionChange },
156 { "nativeSetMockOrientation", "(Landroid/webkit/WebViewCore;ZDZDZD)V", (void*) setMockOrientation },
157 { "nativeOnOrientationChange", "(Landroid/webkit/WebViewCore;ZDZDZD)V", (void*) onOrientationChange }
158 };
159
registerDeviceMotionAndOrientationManager(JNIEnv * env)160 int registerDeviceMotionAndOrientationManager(JNIEnv* env)
161 {
162 #ifndef NDEBUG
163 jclass deviceMotionAndOrientationManager = env->FindClass(javaDeviceMotionAndOrientationManagerClass);
164 LOG_ASSERT(deviceMotionAndOrientationManager, "Unable to find class");
165 env->DeleteLocalRef(deviceMotionAndOrientationManager);
166 #endif
167
168 return jniRegisterNativeMethods(env, javaDeviceMotionAndOrientationManagerClass, gDeviceMotionAndOrientationManagerMethods, NELEM(gDeviceMotionAndOrientationManagerMethods));
169 }
170
171 } // namespace android
172