summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormlamouri@chromium.org <mlamouri@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 15:13:24 +0000
committermlamouri@chromium.org <mlamouri@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-14 15:13:24 +0000
commit67c757401a88b3465e411c1c3f1968489d0502ba (patch)
tree31e94d606388ac9fd1acf620a1f94940f5d90b27
parent57d12ab669b4be8e9adcf4789da61dc73d2b375c (diff)
downloadchromium_src-67c757401a88b3465e411c1c3f1968489d0502ba.zip
chromium_src-67c757401a88b3465e411c1c3f1968489d0502ba.tar.gz
chromium_src-67c757401a88b3465e411c1c3f1968489d0502ba.tar.bz2
Implement ScreenOrientationProvider for Chrome Android.
This allows screen.lockOrientation() and screen.unlockOrientation() to work on Chrome Android. It does not work for the Android WebView yet and there is no permission/security checks yet. BUG=162827 Review URL: https://codereview.chromium.org/196193002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257113 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/Android.mk1
-rw-r--r--android_webview/all_webview.gyp2
-rw-r--r--content/browser/android/browser_jni_registrar.cc3
-rw-r--r--content/browser/screen_orientation/screen_orientation_dispatcher_host.cc2
-rw-r--r--content/browser/screen_orientation/screen_orientation_provider.h2
-rw-r--r--content/browser/screen_orientation/screen_orientation_provider_android.cc51
-rw-r--r--content/browser/screen_orientation/screen_orientation_provider_android.h34
-rw-r--r--content/content.gyp13
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_common.gypi1
-rw-r--r--content/content_jni.gypi1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java3
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java85
-rw-r--r--content/public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template11
-rw-r--r--content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java61
-rw-r--r--content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java172
-rw-r--r--content/public/common/assert_matching_enums.cc26
-rw-r--r--content/public/common/screen_orientation_values.h18
-rw-r--r--content/public/common/screen_orientation_values_list.h19
-rw-r--r--content/public/test/android/javatests/src/org/chromium/content/browser/test/util/MockOrientationObserver.java22
-rw-r--r--content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java43
21 files changed, 514 insertions, 58 deletions
diff --git a/android_webview/Android.mk b/android_webview/Android.mk
index 6248352..6b99a33 100644
--- a/android_webview/Android.mk
+++ b/android_webview/Android.mk
@@ -61,6 +61,7 @@ $(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/browser/
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/browser/SpeechRecognitionError.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/browser/input/PopupItemType.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/common/ResultCodes.java \
+$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/common/ScreenOrientationValues.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/media/ImageFormat.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/CertificateMimeType.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/CertVerifyStatusAndroid.java \
diff --git a/android_webview/all_webview.gyp b/android_webview/all_webview.gyp
index 66255cb..a630cf2 100644
--- a/android_webview/all_webview.gyp
+++ b/android_webview/all_webview.gyp
@@ -15,12 +15,14 @@
'android_webview.gyp:libwebviewchromium',
# Needed by android_webview_java
+ # Generated java files from templates should then be listed in android_webview/Android.mk
'../base/base.gyp:base_java_application_state',
'../base/base.gyp:base_java_memory_pressure_level_list',
'../content/content.gyp:gesture_event_type_java',
'../content/content.gyp:page_transition_types_java',
'../content/content.gyp:popup_item_type_java',
'../content/content.gyp:result_codes_java',
+ '../content/content.gyp:screen_orientation_values_java',
'../content/content.gyp:speech_recognition_error_java',
'../media/media.gyp:media_android_imageformat_list',
'../net/net.gyp:certificate_mime_types_java',
diff --git a/content/browser/android/browser_jni_registrar.cc b/content/browser/android/browser_jni_registrar.cc
index 93463c4..bf4540e 100644
--- a/content/browser/android/browser_jni_registrar.cc
+++ b/content/browser/android/browser_jni_registrar.cc
@@ -32,6 +32,7 @@
#include "content/browser/renderer_host/input/motion_event_android.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
#include "content/browser/renderer_host/java/java_bound_object.h"
+#include "content/browser/screen_orientation/screen_orientation_provider_android.h"
#include "content/browser/speech/speech_recognizer_impl_android.h"
#include "content/browser/vibration/vibration_provider_android.h"
#include "content/browser/web_contents/web_contents_android.h"
@@ -68,6 +69,8 @@ base::android::RegistrationMethod kContentRegisteredMethods[] = {
content::NavigationControllerAndroid::Register},
{"PowerSaveBlock", content::RegisterPowerSaveBlocker},
{"RegisterImeAdapter", content::RegisterImeAdapter},
+ {"ScreenOrientationProvider",
+ content::ScreenOrientationProviderAndroid::Register},
{"SensorManagerAndroid", content::SensorManagerAndroid::Register},
{"SpeechRecognizerImplAndroid",
content::SpeechRecognizerImplAndroid::RegisterSpeechRecognizer},
diff --git a/content/browser/screen_orientation/screen_orientation_dispatcher_host.cc b/content/browser/screen_orientation/screen_orientation_dispatcher_host.cc
index 7472000..5127c78 100644
--- a/content/browser/screen_orientation/screen_orientation_dispatcher_host.cc
+++ b/content/browser/screen_orientation/screen_orientation_dispatcher_host.cc
@@ -58,9 +58,11 @@ void ScreenOrientationDispatcherHost::OnUnlockRequest() {
provider_->UnlockOrientation();
}
+#if !defined(OS_ANDROID)
// static
ScreenOrientationProvider* ScreenOrientationDispatcherHost::CreateProvider() {
return NULL;
}
+#endif
} // namespace content
diff --git a/content/browser/screen_orientation/screen_orientation_provider.h b/content/browser/screen_orientation/screen_orientation_provider.h
index 6a4abb3..28d52c9 100644
--- a/content/browser/screen_orientation/screen_orientation_provider.h
+++ b/content/browser/screen_orientation/screen_orientation_provider.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_SCREEN_ORIENTATION_PROVIDER_H_
#define CONTENT_BROWSER_SCREEN_ORIENTATION_PROVIDER_H_
+#include "third_party/WebKit/public/platform/WebScreenOrientation.h"
+
namespace content {
// Interface that needs to be implemented by any backend that wants to handle
diff --git a/content/browser/screen_orientation/screen_orientation_provider_android.cc b/content/browser/screen_orientation/screen_orientation_provider_android.cc
new file mode 100644
index 0000000..a95d69a
--- /dev/null
+++ b/content/browser/screen_orientation/screen_orientation_provider_android.cc
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screen_orientation/screen_orientation_provider_android.h"
+
+#include "content/browser/screen_orientation/screen_orientation_dispatcher_host.h"
+#include "jni/ScreenOrientationProvider_jni.h"
+
+namespace content {
+
+ScreenOrientationProviderAndroid::ScreenOrientationProviderAndroid() {
+}
+
+ScreenOrientationProviderAndroid::~ScreenOrientationProviderAndroid() {
+}
+
+// static
+bool ScreenOrientationProviderAndroid::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+void ScreenOrientationProviderAndroid::LockOrientation(
+ blink::WebScreenOrientations orientations) {
+ if (j_screen_orientation_provider_.is_null()) {
+ j_screen_orientation_provider_.Reset(Java_ScreenOrientationProvider_create(
+ base::android::AttachCurrentThread()));
+ }
+
+ Java_ScreenOrientationProvider_lockOrientation(
+ base::android::AttachCurrentThread(),
+ j_screen_orientation_provider_.obj(), orientations);
+}
+
+void ScreenOrientationProviderAndroid::UnlockOrientation() {
+ // j_screen_orientation_provider_ is set when locking. If the screen
+ // orientation was not locked, unlocking should be a no-op.
+ if (j_screen_orientation_provider_.is_null())
+ return;
+
+ Java_ScreenOrientationProvider_unlockOrientation(
+ base::android::AttachCurrentThread(),
+ j_screen_orientation_provider_.obj());
+}
+
+// static
+ScreenOrientationProvider* ScreenOrientationDispatcherHost::CreateProvider() {
+ return new ScreenOrientationProviderAndroid();
+}
+
+} // namespace content
diff --git a/content/browser/screen_orientation/screen_orientation_provider_android.h b/content/browser/screen_orientation/screen_orientation_provider_android.h
new file mode 100644
index 0000000..12d1c8e4
--- /dev/null
+++ b/content/browser/screen_orientation/screen_orientation_provider_android.h
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SCREEN_ORIENTATION_PROVIDER_ANDROID_H_
+#define CONTENT_BROWSER_SCREEN_ORIENTATION_PROVIDER_ANDROID_H_
+
+#include "base/android/jni_android.h"
+#include "base/compiler_specific.h"
+#include "content/browser/screen_orientation/screen_orientation_provider.h"
+
+namespace content {
+
+class ScreenOrientationProviderAndroid : public ScreenOrientationProvider {
+ public:
+ ScreenOrientationProviderAndroid();
+
+ static bool Register(JNIEnv* env);
+
+ // ScreenOrientationProvider
+ virtual void LockOrientation(blink::WebScreenOrientations) OVERRIDE;
+ virtual void UnlockOrientation() OVERRIDE;
+
+ private:
+ virtual ~ScreenOrientationProviderAndroid();
+
+ base::android::ScopedJavaGlobalRef<jobject> j_screen_orientation_provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenOrientationProviderAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SCREEN_ORIENTATION_PROVIDER_ANDROID_H_
diff --git a/content/content.gyp b/content/content.gyp
index 7da2b29..6098fe1 100644
--- a/content/content.gyp
+++ b/content/content.gyp
@@ -419,6 +419,7 @@
'result_codes_java',
'speech_recognition_error_java',
'top_controls_state_java',
+ 'screen_orientation_values_java',
],
'variables': {
'java_in_dir': '../content/public/android/java',
@@ -510,6 +511,18 @@
'includes': [ '../build/android/java_cpp_template.gypi' ],
},
{
+ 'target_name': 'screen_orientation_values_java',
+ 'type': 'none',
+ 'sources': [
+ 'public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template',
+ ],
+ 'variables': {
+ 'package_name': 'org/chromium/content/common',
+ 'template_deps': ['public/common/screen_orientation_values_list.h'],
+ },
+ 'includes': [ '../build/android/java_cpp_template.gypi' ],
+ },
+ {
'target_name': 'java_set_jni_headers',
'type': 'none',
'variables': {
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 590ba27..0ca5776 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1130,6 +1130,8 @@
'browser/screen_orientation/screen_orientation_dispatcher_host.cc',
'browser/screen_orientation/screen_orientation_dispatcher_host.h',
'browser/screen_orientation/screen_orientation_provider.h',
+ 'browser/screen_orientation/screen_orientation_provider_android.h',
+ 'browser/screen_orientation/screen_orientation_provider_android.cc',
'browser/service_worker/embedded_worker_instance.cc',
'browser/service_worker/embedded_worker_instance.h',
'browser/service_worker/embedded_worker_registry.cc',
diff --git a/content/content_common.gypi b/content/content_common.gypi
index a7fe268..8e46bb5 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -24,6 +24,7 @@
'../base/base.gyp:base',
],
'sources': [
+ 'public/common/assert_matching_enums.cc',
'public/common/bindings_policy.h',
'public/common/child_process_host.h',
'public/common/child_process_host_delegate.cc',
diff --git a/content/content_jni.gypi b/content/content_jni.gypi
index 8c02b52..ef9bb62 100644
--- a/content/content_jni.gypi
+++ b/content/content_jni.gypi
@@ -28,6 +28,7 @@
'public/android/java/src/org/chromium/content/browser/MediaDrmCredentialManager.java',
'public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java',
'public/android/java/src/org/chromium/content/browser/PowerSaveBlocker.java',
+ 'public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java',
'public/android/java/src/org/chromium/content/browser/SpeechRecognition.java',
'public/android/java/src/org/chromium/content/browser/TouchEventSynthesizer.java',
'public/android/java/src/org/chromium/content/browser/TracingControllerAndroid.java',
diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
index b5068aa..a14d76b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
@@ -24,7 +24,8 @@ import org.chromium.base.ThreadUtils;
* ScreenOrientationListener is a class that informs its observers when the
* screen orientation changes.
*/
-class ScreenOrientationListener {
+@VisibleForTesting
+public class ScreenOrientationListener {
/**
* Observes changes in screen orientation.
diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java
new file mode 100644
index 0000000..89913ed
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java
@@ -0,0 +1,85 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.app.Activity;
+import android.content.pm.ActivityInfo;
+import android.util.Log;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.content.common.ScreenOrientationValues;
+
+/**
+ * This is the implementation of the C++ counterpart ScreenOrientationProvider.
+ */
+@JNINamespace("content")
+class ScreenOrientationProvider {
+ private static final String TAG = "ScreenOrientationProvider";
+
+ private int getOrientationFromWebScreenOrientations(byte orientations) {
+ switch (orientations) {
+ case ScreenOrientationValues.PORTRAIT_PRIMARY:
+ return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+ case ScreenOrientationValues.PORTRAIT_SECONDARY:
+ return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+ case ScreenOrientationValues.LANDSCAPE_PRIMARY:
+ return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ case ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+ case ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY:
+ return ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+ case ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ return ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+ case ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY |
+ ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ return ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
+ default:
+ Log.w(TAG, "Trying to lock to unsupported orientation!");
+ return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+ }
+
+ @VisibleForTesting
+ @CalledByNative
+ static ScreenOrientationProvider create() {
+ return new ScreenOrientationProvider();
+ }
+
+ @CalledByNative
+ void lockOrientation(byte orientations) {
+ Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
+ if (activity == null) {
+ return;
+ }
+
+ int orientation = getOrientationFromWebScreenOrientations(orientations);
+ if (orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
+ return;
+ }
+
+ activity.setRequestedOrientation(orientation);
+ }
+
+ @CalledByNative
+ void unlockOrientation() {
+ Activity activity = ApplicationStatus.getLastTrackedFocusedActivity();
+ if (activity == null) {
+ return;
+ }
+
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+ }
+
+ private ScreenOrientationProvider() {
+ }
+}
diff --git a/content/public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template b/content/public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template
new file mode 100644
index 0000000..162abd2
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/common/ScreenOrientationValues.template
@@ -0,0 +1,11 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.common;
+
+public class ScreenOrientationValues {
+#define DEFINE_SCREEN_ORIENTATION_VALUE(name, value) public static final int name = value;
+#include "content/public/common/screen_orientation_values_list.h"
+#undef DEFINE_SCREEN_ORIENTATION_VALUE
+}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
index 2b3bfdc..f75203e 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationListenerTest.java
@@ -11,9 +11,9 @@ import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
-import org.chromium.content.browser.ScreenOrientationListener.ScreenOrientationObserver;
-import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.MockOrientationObserver;
+import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
import org.chromium.content_shell_apk.ContentShellActivity;
import org.chromium.content_shell_apk.ContentShellTestBase;
@@ -29,60 +29,7 @@ public class ScreenOrientationListenerTest extends ContentShellTestBase {
private static final String DEFAULT_URL =
UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
- private static class OrientationObserver
- implements ScreenOrientationObserver {
-
- public int mOrientation = -1;
- public boolean mHasChanged = false;
-
- @Override
- public void onScreenOrientationChanged(int orientation) {
- mOrientation = orientation;
- mHasChanged = true;
- }
- }
-
- /**
- * Criteria used to know when an orientation change happens.
- */
- private static class OrientationChangeObserverCriteria implements Criteria {
-
- private final OrientationObserver mObserver;
- private final int mTarget;
- private final boolean mCheckTarget;
-
- // Constructor to be used when the criteria is that there is an
- // orientation change but the new orientation value does not matter.
- private OrientationChangeObserverCriteria(
- OrientationObserver observer) {
- mObserver = observer;
- mObserver.mHasChanged = false;
-
- mCheckTarget = false;
- mTarget = -1;
- }
-
- // Constructor to be used when the criteria cares about a change
- // happening to a specific orientation value.
- private OrientationChangeObserverCriteria(
- OrientationObserver observer, int target) {
- mObserver = observer;
- mObserver.mHasChanged = false;
-
- mTarget = target;
- mCheckTarget = true;
- }
-
- @Override
- public boolean isSatisfied() {
- if (!mObserver.mHasChanged)
- return false;
-
- return !mCheckTarget || mObserver.mOrientation == mTarget;
- }
- }
-
- private OrientationObserver mObserver;
+ private MockOrientationObserver mObserver;
/**
* Returns the expected orientation angle based on the orientation type.
@@ -136,7 +83,7 @@ public class ScreenOrientationListenerTest extends ContentShellTestBase {
public void setUp() throws Exception {
super.setUp();
- mObserver = new OrientationObserver();
+ mObserver = new MockOrientationObserver();
}
@Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java
new file mode 100644
index 0000000..4ff0e84
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ScreenOrientationProviderTest.java
@@ -0,0 +1,172 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.MockOrientationObserver;
+import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
+import org.chromium.content.common.ScreenOrientationValues;
+import org.chromium.content_shell_apk.ContentShellActivity;
+import org.chromium.content_shell_apk.ContentShellTestBase;
+
+/**
+ * Tests for ScreenOrientationListener and its implementations.
+ */
+public class ScreenOrientationProviderTest extends ContentShellTestBase {
+
+ // For some reasons build bots are not able to lock to 180 degrees. This
+ // boolean is here to make the false negative go away in that situation.
+ private static final boolean ALLOW_0_FOR_180 = true;
+
+ private static final String DEFAULT_URL =
+ UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
+
+ private MockOrientationObserver mObserver;
+ private final ScreenOrientationProvider mProvider = ScreenOrientationProvider.create();
+
+ private boolean checkOrientationForLock(int orientations) {
+ switch (orientations) {
+ case ScreenOrientationValues.PORTRAIT_PRIMARY:
+ return mObserver.mOrientation == 0;
+ case ScreenOrientationValues.PORTRAIT_SECONDARY:
+ return mObserver.mOrientation == 180 ||
+ (ALLOW_0_FOR_180 && mObserver.mOrientation == 0);
+ case ScreenOrientationValues.LANDSCAPE_PRIMARY:
+ return mObserver.mOrientation == 90;
+ case ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ return mObserver.mOrientation == -90;
+ case ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY:
+ return mObserver.mOrientation == 0 || mObserver.mOrientation == 180;
+ case ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ return mObserver.mOrientation == 90 || mObserver.mOrientation == -90;
+ case ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY |
+ ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY:
+ // The orientation should not change but might and the value could be anything.
+ return true;
+ default:
+ return mObserver.mHasChanged == false;
+ }
+ }
+
+ /**
+ * Locks the screen orientation to |orientations| using ScreenOrientationProvider.
+ */
+ private void lockOrientation(int orientations) {
+ mProvider.lockOrientation((byte)orientations);
+ }
+
+ /**
+ * Call |lockOrientation| and wait for an orientation change.
+ */
+ private boolean lockOrientationAndWait(int orientations)
+ throws InterruptedException {
+ OrientationChangeObserverCriteria criteria =
+ new OrientationChangeObserverCriteria(mObserver);
+
+ lockOrientation(orientations);
+
+ return CriteriaHelper.pollForCriteria(criteria);
+ }
+
+ /**
+ * Unlock the screen orientation using |ScreenOrientationProvider|.
+ */
+ private void unlockOrientation() {
+ mProvider.unlockOrientation();
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
+ waitForActiveShellToBeDoneLoading();
+
+ mObserver = new MockOrientationObserver();
+ ScreenOrientationListener.getInstance().addObserver(
+ mObserver, getInstrumentation().getTargetContext());
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ unlockOrientation();
+
+ mObserver = null;
+ super.tearDown();
+ }
+
+ @SmallTest
+ @Feature({"ScreenOrientation"})
+ public void testBasicValues() throws Exception {
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
+ }
+
+ @MediumTest
+ @Feature({"ScreenOrientation"})
+ public void testPortrait() throws Exception {
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
+ ScreenOrientationValues.PORTRAIT_SECONDARY));
+ }
+
+ @MediumTest
+ @Feature({"ScreenOrientation"})
+ public void testLandscape() throws Exception {
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
+
+ lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY);
+ assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
+ ScreenOrientationValues.LANDSCAPE_SECONDARY));
+ }
+
+ // There is no point in testing the case where we try to lock to
+ // PORTRAIT_PRIMARY | PORTRAIT_SECONDARY | LANDSCAPE_PRIMARY | LANDSCAPE_SECONDARY
+ // because with the device being likely flat during the test, locking to that
+ // will be a no-op.
+
+ // We can't test unlock because the device is likely flat during the test
+ // and in that situation unlocking is a no-op.
+}
diff --git a/content/public/common/assert_matching_enums.cc b/content/public/common/assert_matching_enums.cc
new file mode 100644
index 0000000..88a1b4a
--- /dev/null
+++ b/content/public/common/assert_matching_enums.cc
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Use this file to assert that *_list.h enums that are meant to do the bridge
+// from Blink are valid.
+
+#include "base/macros.h"
+#include "content/public/common/screen_orientation_values.h"
+#include "third_party/WebKit/public/platform/WebScreenOrientation.h"
+
+namespace content {
+
+#define COMPILE_ASSERT_MATCHING_ENUM(expected, actual) \
+ COMPILE_ASSERT(int(expected) == int(actual), mismatching_enums)
+
+COMPILE_ASSERT_MATCHING_ENUM(blink::WebScreenOrientationPortraitPrimary,
+ PORTRAIT_PRIMARY);
+COMPILE_ASSERT_MATCHING_ENUM(blink::WebScreenOrientationLandscapePrimary,
+ LANDSCAPE_PRIMARY);
+COMPILE_ASSERT_MATCHING_ENUM(blink::WebScreenOrientationPortraitSecondary,
+ PORTRAIT_SECONDARY);
+COMPILE_ASSERT_MATCHING_ENUM(blink::WebScreenOrientationLandscapeSecondary,
+ LANDSCAPE_SECONDARY);
+
+} // namespace content
diff --git a/content/public/common/screen_orientation_values.h b/content/public/common/screen_orientation_values.h
new file mode 100644
index 0000000..fe421a2
--- /dev/null
+++ b/content/public/common/screen_orientation_values.h
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_H_
+#define CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_H_
+
+namespace content {
+
+enum ScreenOrientationValues {
+#define DEFINE_SCREEN_ORIENTATION_VALUE(name, value) name = value,
+#include "content/public/common/screen_orientation_values_list.h"
+#undef DEFINE_SCREEN_ORIENTATION_VALUE
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_H_
diff --git a/content/public/common/screen_orientation_values_list.h b/content/public/common/screen_orientation_values_list.h
new file mode 100644
index 0000000..64c27e9
--- /dev/null
+++ b/content/public/common/screen_orientation_values_list.h
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_LIST_H_
+#define CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_LIST_H_
+
+#ifndef DEFINE_SCREEN_ORIENTATION_VALUE
+#error "DEFINE_SCREEN_ORIENTATION_VALUE should be defined before including this"
+#endif
+
+// These values are defined with macros so that a Java class can be generated
+// for them.
+DEFINE_SCREEN_ORIENTATION_VALUE(PORTRAIT_PRIMARY, 1 << 0)
+DEFINE_SCREEN_ORIENTATION_VALUE(LANDSCAPE_PRIMARY, 1 << 1)
+DEFINE_SCREEN_ORIENTATION_VALUE(PORTRAIT_SECONDARY, 1 << 2)
+DEFINE_SCREEN_ORIENTATION_VALUE(LANDSCAPE_SECONDARY, 1 << 3)
+
+#endif // CONTENT_PUBLIC_COMMON_SCREEN_ORIENTATION_VALUES_LIST_H_
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/MockOrientationObserver.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/MockOrientationObserver.java
new file mode 100644
index 0000000..eaaa3e6
--- /dev/null
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/MockOrientationObserver.java
@@ -0,0 +1,22 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.test.util;
+
+import org.chromium.content.browser.ScreenOrientationListener.ScreenOrientationObserver;
+
+/**
+ * Mock of an OrientationObserver for tests that need to observe ScreenOrientation changes.
+ */
+public class MockOrientationObserver implements ScreenOrientationObserver {
+
+ public int mOrientation = -1;
+ public boolean mHasChanged = false;
+
+ @Override
+ public void onScreenOrientationChanged(int orientation) {
+ mOrientation = orientation;
+ mHasChanged = true;
+ }
+}
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java
new file mode 100644
index 0000000..5132c80
--- /dev/null
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/OrientationChangeObserverCriteria.java
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.test.util;
+
+/**
+ * Criteria used to know when an orientation change happens.
+ */
+public class OrientationChangeObserverCriteria implements Criteria {
+
+ private final MockOrientationObserver mObserver;
+ private final int mTarget;
+ private final boolean mCheckTarget;
+
+ // Constructor to be used when the criteria is that there is an
+ // orientation change but the new orientation value does not matter.
+ public OrientationChangeObserverCriteria(MockOrientationObserver observer) {
+ mObserver = observer;
+ mObserver.mHasChanged = false;
+
+ mCheckTarget = false;
+ mTarget = -1;
+ }
+
+ // Constructor to be used when the criteria cares about a change
+ // happening to a specific orientation value.
+ public OrientationChangeObserverCriteria(MockOrientationObserver observer, int target) {
+ mObserver = observer;
+ mObserver.mHasChanged = false;
+
+ mTarget = target;
+ mCheckTarget = true;
+ }
+
+ @Override
+ public boolean isSatisfied() {
+ if (!mObserver.mHasChanged)
+ return false;
+
+ return !mCheckTarget || mObserver.mOrientation == mTarget;
+ }
+}