Home | History | Annotate | Download | only in jni
      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 
     43 DeviceMotionAndOrientationManager::DeviceMotionAndOrientationManager(WebViewCore* webViewCore)
     44     : m_useMock(false)
     45     , m_webViewCore(webViewCore)
     46 {
     47 }
     48 
     49 void DeviceMotionAndOrientationManager::useMock()
     50 {
     51     m_useMock = true;
     52 }
     53 
     54 void DeviceMotionAndOrientationManager::setMockMotion(PassRefPtr<DeviceMotionData> motion)
     55 {
     56     // TODO: There is not yet a DeviceMotion mock.
     57 }
     58 
     59 void DeviceMotionAndOrientationManager::onMotionChange(PassRefPtr<DeviceMotionData> motion)
     60 {
     61     ASSERT(!m_useMock);
     62     static_cast<DeviceMotionClientImpl*>(m_motionClient.get())->onMotionChange(motion);
     63 }
     64 
     65 void DeviceMotionAndOrientationManager::setMockOrientation(PassRefPtr<DeviceOrientation> orientation)
     66 {
     67     if (m_useMock)
     68         static_cast<DeviceOrientationClientMock*>(orientationClient())->setOrientation(orientation);
     69 }
     70 
     71 void DeviceMotionAndOrientationManager::onOrientationChange(PassRefPtr<DeviceOrientation> orientation)
     72 {
     73     ASSERT(!m_useMock);
     74     static_cast<DeviceOrientationClientImpl*>(m_orientationClient.get())->onOrientationChange(orientation);
     75 }
     76 
     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 
     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 
     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 
    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 
    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 
    127 static void useMock(JNIEnv* env, jobject, jobject webViewCoreObject)
    128 {
    129     getWebViewCore(env, webViewCoreObject)->deviceMotionAndOrientationManager()->useMock();
    130 }
    131 
    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 
    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 
    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 
    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