diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2df0a1941..e1eeb5421 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,6 +21,7 @@ androidx-paging = "3.3.6" androidx-startup-runtime = "1.2.0" androidx-test = "1.6.1" androidx-test-espresso = "3.6.1" +androidx-test-junit = "1.2.1" androidx-window = "1.4.0-rc01" androidx-window-core = "1.4.0-beta02" androidx-window-java = "1.3.0" @@ -130,6 +131,7 @@ androidx-startup-runtime = {module = "androidx.startup:startup-runtime", version androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test" } androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-test-espresso" } androidx-test-runner = "androidx.test:runner:1.6.2" +androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-junit" } androidx-tiles = { module = "androidx.wear.tiles:tiles", version.ref = "tiles" } androidx-tiles-renderer = { module = "androidx.wear.tiles:tiles-renderer", version.ref = "tiles" } androidx-tiles-testing = { module = "androidx.wear.tiles:tiles-testing", version.ref = "tiles" } diff --git a/misc/build.gradle.kts b/misc/build.gradle.kts index b2619b9e6..e5cc3cc1d 100644 --- a/misc/build.gradle.kts +++ b/misc/build.gradle.kts @@ -70,6 +70,8 @@ dependencies { implementation(libs.androidx.window.java) implementation(libs.appcompat) testImplementation(libs.junit) + testImplementation(kotlin("test")) + androidTestImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.junit) androidTestImplementation(libs.androidx.test.core) androidTestImplementation(libs.androidx.test.runner) diff --git a/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java b/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java new file mode 100644 index 000000000..46ebe69df --- /dev/null +++ b/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets; + +import androidx.appcompat.app.AppCompatActivity +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import org.junit.Rule; +import org.junit.Test; +import static org.junit.Assert.assertFalse; + +public class DeviceCompatibilityModeTestJavaSnippets { + + // [START android_device_compatibility_mode_assert_isLetterboxed_java] + @Rule + public ActivityScenarioRule rule = new ActivityScenarioRule<>(MainActivity.class); + + @Test + public void activity_launched_notLetterBoxed() { + try (ActivityScenario scenario = + ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity( activity -> { + assertFalse(isLetterboxed(activity)); + }); + } + } + // [END android_device_compatibility_mode_assert_isLetterboxed_java] + + + // Method used by snippets. + public boolean isLetterboxed(AppCompatActivity activity) { + return true; + } + +} diff --git a/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt b/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt new file mode 100644 index 000000000..7b392c612 --- /dev/null +++ b/misc/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets + +import androidx.appcompat.app.AppCompatActivity +import androidx.test.ext.junit.rules.ActivityScenarioRule +import org.junit.Assert.assertFalse +import org.junit.Rule +import org.junit.Test + +class DeviceCompatibilityModeTestKotlinSnippets { + + // [START android_device_compatibility_mode_assert_isLetterboxed_kotlin] + @get:Rule + val activityRule = ActivityScenarioRule(MainActivity::class.java) + + @Test + fun activity_launched_notLetterBoxed() { + activityRule.scenario.onActivity { + assertFalse(it.isLetterboxed()) + } + } + // [END android_device_compatibility_mode_assert_isLetterboxed_kotlin] + + // Classes used by snippets. + + class MainActivity : AppCompatActivity() { + + fun isLetterboxed(): Boolean { + return true + } + } +} diff --git a/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeJavaSnippets.java b/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeJavaSnippets.java new file mode 100644 index 000000000..d5e3a3622 --- /dev/null +++ b/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeJavaSnippets.java @@ -0,0 +1,46 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets; + +import android.graphics.Rect; +import android.os.Build.VERSION_CODES; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AppCompatActivity; +import androidx.window.layout.WindowMetricsCalculator; + +public class DeviceCompatibilityModeJavaSnippets { + + @RequiresApi(api=VERSION_CODES.N) + // [START android_device_compatibility_mode_isLetterboxed_java] + public boolean isLetterboxed(AppCompatActivity activity) { + if (activity.isInMultiWindowMode()) { + return false; + } + + WindowMetricsCalculator wmc = WindowMetricsCalculator.getOrCreate(); + Rect currentBounds = wmc.computeCurrentWindowMetrics(activity).getBounds(); + Rect maxBounds = wmc.computeMaximumWindowMetrics(activity).getBounds(); + + boolean isScreenPortrait = maxBounds.height() > maxBounds.width(); + + return (isScreenPortrait) + ? currentBounds.height() < maxBounds.height() + : currentBounds.width() < maxBounds.width(); + } + // [END android_device_compatibility_mode_isLetterboxed_java] + +} diff --git a/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeKotlinSnippets.kt b/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeKotlinSnippets.kt new file mode 100644 index 000000000..7bc6a1971 --- /dev/null +++ b/misc/src/main/java/com/example/snippets/DeviceCompatibilityModeKotlinSnippets.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets + +import android.os.Build +import android.os.Bundle +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import androidx.window.layout.WindowMetricsCalculator + +class DeviceCompatibilityModeKotlinSnippets : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + @RequiresApi(Build.VERSION_CODES.N) + // [START android_device_compatibility_mode_isLetterboxed_kotlin] + fun isLetterboxed(activity: AppCompatActivity): Boolean { + if (isInMultiWindowMode) return false + + val wmc = WindowMetricsCalculator.getOrCreate() + val currentBounds = wmc.computeCurrentWindowMetrics(this).bounds + val maxBounds = wmc.computeMaximumWindowMetrics(this).bounds + + val isScreenPortrait = maxBounds.height() > maxBounds.width() + + return if (isScreenPortrait) { + currentBounds.height() < maxBounds.height() + } else { + currentBounds.width() < maxBounds.width() + } + } + // [END android_device_compatibility_mode_isLetterboxed_kotlin] +}