<lambda>null1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
2 * Any copyright is dedicated to the Public Domain.
3 http://creativecommons.org/publicdomain/zero/1.0/ */
4
5 package org.mozilla.geckoview.test
6
7 import android.content.pm.ActivityInfo
8 import android.content.res.Configuration
9 import androidx.test.ext.junit.rules.ActivityScenarioRule
10 import androidx.test.filters.MediumTest
11 import androidx.test.ext.junit.runners.AndroidJUnit4
12
13 import org.hamcrest.Matchers.*
14 import org.junit.Rule
15
16 import org.junit.Test
17 import org.junit.rules.RuleChain
18 import org.junit.runner.RunWith
19
20 import org.mozilla.geckoview.*
21 import org.mozilla.geckoview.GeckoSession.ContentDelegate
22 import org.mozilla.geckoview.OrientationController
23 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
24 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
25
26 @RunWith(AndroidJUnit4::class)
27 @MediumTest
28 class OrientationDelegateTest : BaseSessionTest() {
29 val activityRule = ActivityScenarioRule(GeckoViewTestActivity::class.java)
30
31 @get:Rule
32 override val rules: RuleChain = RuleChain.outerRule(activityRule).around(sessionRule)
33
34 private fun goFullscreen() {
35 sessionRule.setPrefsUntilTestEnd(mapOf("full-screen-api.allow-trusted-requests-only" to false))
36 mainSession.loadTestPath(FULLSCREEN_PATH)
37 mainSession.waitForPageStop()
38 val promise = mainSession.evaluatePromiseJS("document.querySelector('#fullscreen').requestFullscreen()")
39 sessionRule.waitUntilCalled(object : ContentDelegate {
40 @AssertCalled(count = 1)
41 override fun onFullScreen(session: GeckoSession, fullScreen: Boolean) {
42 assertThat("Div went fullscreen", fullScreen, equalTo(true))
43 }
44 })
45 promise.value
46 }
47
48 private fun lockPortrait() {
49 val promise = mainSession.evaluatePromiseJS("screen.orientation.lock('portrait-primary')")
50 sessionRule.delegateDuringNextWait(object : OrientationController.OrientationDelegate {
51 @AssertCalled(count = 1)
52 override fun onOrientationLock(aOrientation: Int): GeckoResult<AllowOrDeny> {
53 assertThat(
54 "The orientation should be portrait",
55 aOrientation,
56 equalTo(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
57 )
58 activityRule.scenario.onActivity { activity ->
59 activity.requestedOrientation = aOrientation
60 }
61 return GeckoResult.allow()
62 }
63 })
64 sessionRule.runtime.orientationChanged(Configuration.ORIENTATION_PORTRAIT)
65 promise.value
66 // Remove previous delegate
67 mainSession.waitForRoundTrip()
68 }
69
70 private fun lockLandscape() {
71 val promise = mainSession.evaluatePromiseJS("screen.orientation.lock('landscape-primary')")
72 sessionRule.delegateDuringNextWait(object : OrientationController.OrientationDelegate {
73 @AssertCalled(count = 1)
74 override fun onOrientationLock(aOrientation: Int): GeckoResult<AllowOrDeny> {
75 assertThat(
76 "The orientation should be landscape",
77 aOrientation,
78 equalTo(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
79 )
80 activityRule.scenario.onActivity { activity ->
81 activity.requestedOrientation = aOrientation
82 }
83 return GeckoResult.allow()
84 }
85 })
86 sessionRule.runtime.orientationChanged(Configuration.ORIENTATION_LANDSCAPE)
87 promise.value
88 // Remove previous delegate
89 mainSession.waitForRoundTrip()
90 }
91
92 @Test fun orientationLock() {
93 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
94 goFullscreen()
95 activityRule.scenario.onActivity { activity ->
96 // If the orientation is landscape, lock to portrait and wait for delegate. If portrait, lock to landscape instead.
97 if (activity.resources.configuration.orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
98 lockPortrait()
99 } else if (activity.resources.configuration.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
100 lockLandscape()
101 }
102 }
103 }
104
105 @Test fun orientationUnlock() {
106 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
107 goFullscreen()
108 mainSession.evaluateJS("screen.orientation.unlock()")
109 sessionRule.waitUntilCalled(object : OrientationController.OrientationDelegate {
110 @AssertCalled(count = 1)
111 override fun onOrientationUnlock() {
112 activityRule.scenario.onActivity { activity ->
113 activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
114 }
115 }
116 })
117 }
118
119 @Test fun orientationLockedAlready() {
120 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
121 goFullscreen()
122 // Lock to landscape twice to verify successful locking with existing lock
123 lockLandscape()
124 lockLandscape()
125 }
126
127 @Test fun orientationLockedExistingOrientation() {
128 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
129 goFullscreen()
130 // Lock to landscape twice to verify successful locking to existing orientation
131 activityRule.scenario.onActivity { activity ->
132 activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
133 }
134 lockLandscape()
135 }
136
137 @Test(expected = GeckoSessionTestRule.RejectedPromiseException::class)
138 fun orientationLockNoFullscreen() {
139 // Verify if fullscreen pre-lock conditions are not met, a rejected promise is returned.
140 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
141 mainSession.loadTestPath(FULLSCREEN_PATH)
142 mainSession.waitForPageStop()
143 mainSession.evaluateJS("screen.orientation.lock('landscape-primary')")
144 }
145
146 @Test fun orientationLockUnlock() {
147 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
148 goFullscreen()
149
150 val promise = mainSession.evaluatePromiseJS("screen.orientation.lock('landscape-primary')")
151 sessionRule.delegateDuringNextWait(object : OrientationController.OrientationDelegate {
152 @AssertCalled(count = 1)
153 override fun onOrientationLock(aOrientation: Int): GeckoResult<AllowOrDeny> {
154 assertThat(
155 "The orientation value is as expected",
156 aOrientation,
157 equalTo(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
158 )
159 activityRule.scenario.onActivity { activity ->
160 activity.requestedOrientation = aOrientation
161 }
162 return GeckoResult.allow()
163 }
164 })
165 sessionRule.runtime.orientationChanged(Configuration.ORIENTATION_LANDSCAPE)
166 promise.value
167 // Remove previous delegate
168 mainSession.waitForRoundTrip()
169
170 // after locking to orientation landscape, unlock to default
171 mainSession.evaluateJS("screen.orientation.unlock()")
172 sessionRule.waitUntilCalled(object : OrientationController.OrientationDelegate {
173 @AssertCalled(count = 1)
174 override fun onOrientationUnlock() {
175 activityRule.scenario.onActivity { activity ->
176 activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
177 }
178 }
179 })
180 }
181
182 @Test fun orientationLockUnsupported() {
183 // If no delegate, orientation.lock must throws NotSupportedError
184 sessionRule.setPrefsUntilTestEnd(mapOf("dom.screenorientation.allow-lock" to true))
185 goFullscreen()
186
187 val promise = mainSession.evaluatePromiseJS("""
188 new Promise(r => {
189 screen.orientation.lock('landscape-primary')
190 .then(() => r("successful"))
191 .catch(e => r(e.name))
192 })
193 """.trimIndent())
194
195 assertThat("The operation must throw NotSupportedError",
196 promise.value,
197 equalTo("NotSupportedError"))
198
199 val promise2 = mainSession.evaluatePromiseJS("""
200 new Promise(r => {
201 screen.orientation.lock(screen.orientation.type)
202 .then(() => r("successful"))
203 .catch(e => r(e.name))
204 })
205 """.trimIndent())
206
207 assertThat("The operation must throw NotSupportedError even if same orientation",
208 promise2.value,
209 equalTo("NotSupportedError"))
210 }
211 }
212