Bug 740190 - Screen Orientation API: implement locking in Android. r=dougt
authorMounir Lamouri <mounir.lamouri@gmail.com>
Thu, 29 Mar 2012 23:31:12 -0700
changeset 94008 8bf3120ed0f8acbe3ceb3cecb6412024859980f0
parent 94007 13bf530d772d3393d50baf522e7f50cb8719b91a
child 94009 1f37e7e66d47b4dd9f942da2d5b6e98ff4a7d8dc
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougt
bugs740190
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 740190 - Screen Orientation API: implement locking in Android. r=dougt
embedding/android/GeckoAppShell.java
embedding/android/GeckoScreenOrientationListener.java
hal/android/AndroidHal.cpp
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoScreenOrientationListener.java
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -1850,9 +1850,17 @@ public class GeckoAppShell
 
     public static void enableScreenOrientationNotifications() {
         GeckoScreenOrientationListener.getInstance().enableNotifications();
     }
 
     public static void disableScreenOrientationNotifications() {
         GeckoScreenOrientationListener.getInstance().disableNotifications();
     }
+
+    public static void lockScreenOrientation(int aOrientation) {
+        GeckoScreenOrientationListener.getInstance().lockScreenOrientation(aOrientation);
+    }
+
+    public static void unlockScreenOrientation() {
+        GeckoScreenOrientationListener.getInstance().unlockScreenOrientation();
+    }
 }
--- a/embedding/android/GeckoScreenOrientationListener.java
+++ b/embedding/android/GeckoScreenOrientationListener.java
@@ -3,37 +3,43 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import android.content.Context;
 import android.util.Log;
 import android.view.OrientationEventListener;
 import android.view.Surface;
+import android.content.pm.ActivityInfo;
 
 public class GeckoScreenOrientationListener
 {
+  private static final String LOGTAG = "GeckoScreenOrientationListener";
+
   static class OrientationEventListenerImpl extends OrientationEventListener {
     public OrientationEventListenerImpl(Context c) {
       super(c);
     }
 
     @Override
     public void onOrientationChanged(int aOrientation) {
       GeckoScreenOrientationListener.getInstance().updateScreenOrientation();
     }
   }
 
   static private GeckoScreenOrientationListener sInstance = null;
 
   // Make sure that any change in dom/base/ScreenOrientation.h happens here too.
+  static public final short eScreenOrientation_None               = 0;
   static public final short eScreenOrientation_PortraitPrimary    = 1;
   static public final short eScreenOrientation_PortraitSecondary  = 2;
+  static public final short eScreenOrientation_Portrait           = 3;
   static public final short eScreenOrientation_LandscapePrimary   = 4;
   static public final short eScreenOrientation_LandscapeSecondary = 8;
+  static public final short eScreenOrientation_Landscape          = 12;
 
   private short mOrientation;
   private OrientationEventListenerImpl mListener = null;
 
   // Whether the listener should be listening to changes.
   private boolean mShouldBeListening = false;
   // Whether the listener should notify Gecko that a change happened.
   private boolean mShouldNotify      = false;
@@ -102,21 +108,56 @@ public class GeckoScreenOrientationListe
       mOrientation = eScreenOrientation_PortraitPrimary;
     } else if (rotation == Surface.ROTATION_180) {
       mOrientation = eScreenOrientation_PortraitSecondary;
     } else if (rotation == Surface.ROTATION_270) {
       mOrientation = eScreenOrientation_LandscapeSecondary;
     } else if (rotation == Surface.ROTATION_90) {
       mOrientation = eScreenOrientation_LandscapePrimary;
     } else {
-      Log.e("GeckoScreenOrientationListener", "Unexpected value received! (" + rotation + ")");
+      Log.e(LOGTAG, "Unexpected value received! (" + rotation + ")");
       return;
     }
 
     if (mShouldNotify && mOrientation != previousOrientation) {
       GeckoAppShell.sendEventToGecko(new GeckoEvent(mOrientation));
     }
   }
 
   public short getScreenOrientation() {
     return mOrientation;
   }
+
+  public void lockScreenOrientation(int aOrientation) {
+    int orientation = 0;
+
+    switch (aOrientation) {
+      case eScreenOrientation_PortraitPrimary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+        break;
+      case eScreenOrientation_PortraitSecondary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+        break;
+      case eScreenOrientation_Portrait:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+        break;
+      case eScreenOrientation_LandscapePrimary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+        break;
+      case eScreenOrientation_LandscapeSecondary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+        break;
+      case eScreenOrientation_Landscape:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+        break;
+      default:
+        Log.e(LOGTAG, "Unexpected value received! (" + aOrientation + ")");
+    }
+
+    GeckoApp.mAppContext.setRequestedOrientation(orientation);
+    updateScreenOrientation();
+  }
+
+  public void unlockScreenOrientation() {
+    GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
+    updateScreenOrientation();
+  }
 }
--- a/hal/android/AndroidHal.cpp
+++ b/hal/android/AndroidHal.cpp
@@ -215,19 +215,31 @@ GetCurrentScreenOrientation(dom::ScreenO
   dom::ScreenOrientationWrapper orientationWrapper;
   bridge->GetScreenOrientation(orientationWrapper);
   *aScreenOrientation = orientationWrapper.orientation;
 }
 
 bool
 LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
 {
-  return false;
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return false;
+  }
+
+  bridge->LockScreenOrientation(dom::ScreenOrientationWrapper(aOrientation));
+  return true;
 }
 
 void
 UnlockScreenOrientation()
 {
+  AndroidBridge* bridge = AndroidBridge::Bridge();
+  if (!bridge) {
+    return;
+  }
+
+  bridge->UnlockScreenOrientation();
 }
 
 } // hal_impl
 } // mozilla
 
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -2047,9 +2047,17 @@ public class GeckoAppShell
 
     public static void enableScreenOrientationNotifications() {
         GeckoScreenOrientationListener.getInstance().enableNotifications();
     }
 
     public static void disableScreenOrientationNotifications() {
         GeckoScreenOrientationListener.getInstance().disableNotifications();
     }
+
+    public static void lockScreenOrientation(int aOrientation) {
+        GeckoScreenOrientationListener.getInstance().lockScreenOrientation(aOrientation);
+    }
+
+    public static void unlockScreenOrientation() {
+        GeckoScreenOrientationListener.getInstance().unlockScreenOrientation();
+    }
 }
--- a/mobile/android/base/GeckoScreenOrientationListener.java
+++ b/mobile/android/base/GeckoScreenOrientationListener.java
@@ -3,37 +3,43 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import android.content.Context;
 import android.util.Log;
 import android.view.OrientationEventListener;
 import android.view.Surface;
+import android.content.pm.ActivityInfo;
 
 public class GeckoScreenOrientationListener
 {
+  private static final String LOGTAG = "GeckoScreenOrientationListener";
+
   static class OrientationEventListenerImpl extends OrientationEventListener {
     public OrientationEventListenerImpl(Context c) {
       super(c);
     }
 
     @Override
     public void onOrientationChanged(int aOrientation) {
       GeckoScreenOrientationListener.getInstance().updateScreenOrientation();
     }
   }
 
   static private GeckoScreenOrientationListener sInstance = null;
 
   // Make sure that any change in dom/base/ScreenOrientation.h happens here too.
+  static public final short eScreenOrientation_None               = 0;
   static public final short eScreenOrientation_PortraitPrimary    = 1;
   static public final short eScreenOrientation_PortraitSecondary  = 2;
+  static public final short eScreenOrientation_Portrait           = 3;
   static public final short eScreenOrientation_LandscapePrimary   = 4;
   static public final short eScreenOrientation_LandscapeSecondary = 8;
+  static public final short eScreenOrientation_Landscape          = 12;
 
   private short mOrientation;
   private OrientationEventListenerImpl mListener = null;
 
   // Whether the listener should be listening to changes.
   private boolean mShouldBeListening = false;
   // Whether the listener should notify Gecko that a change happened.
   private boolean mShouldNotify      = false;
@@ -102,21 +108,56 @@ public class GeckoScreenOrientationListe
       mOrientation = eScreenOrientation_PortraitPrimary;
     } else if (rotation == Surface.ROTATION_180) {
       mOrientation = eScreenOrientation_PortraitSecondary;
     } else if (rotation == Surface.ROTATION_270) {
       mOrientation = eScreenOrientation_LandscapeSecondary;
     } else if (rotation == Surface.ROTATION_90) {
       mOrientation = eScreenOrientation_LandscapePrimary;
     } else {
-      Log.e("GeckoScreenOrientationListener", "Unexpected value received! (" + rotation + ")");
+      Log.e(LOGTAG, "Unexpected value received! (" + rotation + ")");
       return;
     }
 
     if (mShouldNotify && mOrientation != previousOrientation) {
       GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenOrientationEvent(mOrientation));
     }
   }
 
   public short getScreenOrientation() {
     return mOrientation;
   }
+
+  public void lockScreenOrientation(int aOrientation) {
+    int orientation = 0;
+
+    switch (aOrientation) {
+      case eScreenOrientation_PortraitPrimary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+        break;
+      case eScreenOrientation_PortraitSecondary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+        break;
+      case eScreenOrientation_Portrait:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+        break;
+      case eScreenOrientation_LandscapePrimary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+        break;
+      case eScreenOrientation_LandscapeSecondary:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+        break;
+      case eScreenOrientation_Landscape:
+        orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+        break;
+      default:
+        Log.e(LOGTAG, "Unexpected value received! (" + aOrientation + ")");
+    }
+
+    GeckoApp.mAppContext.setRequestedOrientation(orientation);
+    updateScreenOrientation();
+  }
+
+  public void unlockScreenOrientation() {
+    GeckoApp.mAppContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
+    updateScreenOrientation();
+  }
 }
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -179,16 +179,18 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jGetCurrentNetworkInformation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getCurrentNetworkInformation", "()[D");
     jEnableNetworkNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableNetworkNotifications", "()V");
     jDisableNetworkNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableNetworkNotifications", "()V");
     jEmitGeckoAccessibilityEvent = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "emitGeckoAccessibilityEvent", "(I[Ljava/lang/String;Ljava/lang/String;ZZZ)V");
 
     jGetScreenOrientation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getScreenOrientation", "()S");
     jEnableScreenOrientationNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableScreenOrientationNotifications", "()V");
     jDisableScreenOrientationNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableScreenOrientationNotifications", "()V");
+    jLockScreenOrientation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "lockScreenOrientation", "(I)V");
+    jUnlockScreenOrientation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "unlockScreenOrientation", "()V");
 
     jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
     jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
     jEGLSurfaceImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLSurfaceImpl"));
     jEGLContextImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLContextImpl"));
     jEGLConfigImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLConfigImpl"));
     jEGLDisplayImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLDisplayImpl"));
 
@@ -2090,16 +2092,29 @@ AndroidBridge::EnableScreenOrientationNo
 
 void
 AndroidBridge::DisableScreenOrientationNotifications()
 {
     ALOG_BRIDGE("AndroidBridge::DisableScreenOrientationNotifications");
     mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jDisableScreenOrientationNotifications);
 }
 
+void
+AndroidBridge::LockScreenOrientation(const dom::ScreenOrientationWrapper& aOrientation)
+{
+  ALOG_BRIDGE("AndroidBridge::LockScreenOrientation");
+  mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jLockScreenOrientation, aOrientation.orientation);
+}
+
+void
+AndroidBridge::UnlockScreenOrientation()
+{
+  ALOG_BRIDGE("AndroidBridge::UnlockScreenOrientation");
+  mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jUnlockScreenOrientation);
+}
 
 /* attribute nsIAndroidBrowserApp browserApp; */
 NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp)
 {
     if (nsAppShell::gAppShell)
         nsAppShell::gAppShell->GetBrowserApp(aBrowserApp);
     return NS_OK;
 }
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -417,16 +417,18 @@ public:
 
     // This method doesn't take a ScreenOrientation because it's an enum and
     // that would require including the header which requires include IPC
     // headers which requires including basictypes.h which requires a lot of
     // changes...
     void GetScreenOrientation(dom::ScreenOrientationWrapper& aOrientation);
     void EnableScreenOrientationNotifications();
     void DisableScreenOrientationNotifications();
+    void LockScreenOrientation(const dom::ScreenOrientationWrapper& aOrientation);
+    void UnlockScreenOrientation();
 
 protected:
     static AndroidBridge *sBridge;
 
     // the global JavaVM
     JavaVM *mJavaVM;
 
     // the JNIEnv for the main thread
@@ -525,16 +527,18 @@ protected:
 
     jmethodID jGetCurrentNetworkInformation;
     jmethodID jEnableNetworkNotifications;
     jmethodID jDisableNetworkNotifications;
 
     jmethodID jGetScreenOrientation;
     jmethodID jEnableScreenOrientationNotifications;
     jmethodID jDisableScreenOrientationNotifications;
+    jmethodID jLockScreenOrientation;
+    jmethodID jUnlockScreenOrientation;
 
     // stuff we need for CallEglCreateWindowSurface
     jclass jEGLSurfaceImplClass;
     jclass jEGLContextImplClass;
     jclass jEGLConfigImplClass;
     jclass jEGLDisplayImplClass;
     jclass jEGLContextClass;
     jclass jEGL10Class;