Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update WindowManager sample and tests to v1.0.0-alpha10 #267

Merged
merged 1 commit into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions WindowManager/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ android {

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha02'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha03'

def window_version = '1.0.0-alpha09'
implementation "androidx.window:window:$window_version"
implementation "androidx.window:window-java:$window_version"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withSubstring
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.window.FoldingFeature.Orientation.Companion.HORIZONTAL
import androidx.window.FoldingFeature.Orientation.Companion.VERTICAL
import androidx.window.FoldingFeature.State.Companion.FLAT
import androidx.window.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.WindowLayoutInfo
import androidx.window.testing.FoldingFeature
import androidx.window.testing.WindowLayoutInfoPublisherRule
import androidx.window.windowInfoRepository
import androidx.window.layout.FoldingFeature.Orientation.Companion.HORIZONTAL
import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL
import androidx.window.layout.FoldingFeature.State.Companion.FLAT
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository
import androidx.window.layout.WindowLayoutInfo
import androidx.window.testing.layout.FoldingFeature
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.take
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,24 @@ package com.example.windowmanagersample

import android.graphics.Rect
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.assertion.PositionAssertions.isBottomAlignedWith
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyAbove
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyLeftOf
import androidx.test.espresso.assertion.PositionAssertions.isLeftAlignedWith
import androidx.test.espresso.assertion.PositionAssertions.isRightAlignedWith
import androidx.test.espresso.assertion.PositionAssertions.isTopAlignedWith
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.window.FoldingFeature
import androidx.window.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.FoldingFeature.Type.Companion.FOLD
import androidx.window.WindowLayoutInfo
import androidx.window.testing.WindowLayoutInfoPublisherRule
import androidx.window.windowInfoRepository
import androidx.window.layout.FoldingFeature
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.layout.FoldingFeature.Type.Companion.FOLD
import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.WindowMetricsCalculator
import androidx.window.testing.layout.WindowLayoutInfoPublisherRule
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toCollection
import kotlinx.coroutines.test.TestCoroutineScope
Expand All @@ -58,21 +62,50 @@ class SplitLayoutActivityTest {
testRule = RuleChain.outerRule(publisherRule).around(activityRule)
}

@Test
fun testDeviceOpen_Flat(): Unit = testScope.runBlockingTest {
activityRule.scenario.onActivity { activity ->
val expected = WindowLayoutInfo.Builder().setDisplayFeatures(listOf()).build()

val values = mutableListOf<WindowLayoutInfo>()
val value = testScope.async {
activity.windowInfoRepository().windowLayoutInfo.take(1).toCollection(values)
}
publisherRule.overrideWindowLayoutInfo(expected)
runBlockingTest {
val newValues = value.await().toList()
Assert.assertEquals(
listOf(expected),
newValues
)
}
}

// Checks that the two views are overlapped if there's no FoldingFeature.
onView(withId(R.id.start_layout)).check(isBottomAlignedWith(withId(R.id.end_layout)))
onView(withId(R.id.start_layout)).check(isTopAlignedWith(withId(R.id.end_layout)))
onView(withId(R.id.start_layout)).check(isLeftAlignedWith(withId(R.id.end_layout)))
onView(withId(R.id.start_layout)).check(isRightAlignedWith(withId(R.id.end_layout)))
}

@Test
fun testDeviceOpen_Vertical(): Unit = testScope.runBlockingTest {
activityRule.scenario.onActivity { activity ->
val bounds = activity.windowInfoRepository().currentWindowMetrics.bounds
val center = bounds.centerX()
val windowMetrics =
WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
val center = windowMetrics.bounds.centerX()
val feature = FoldingFeature(
Rect(center, 0, center, bounds.height()),
Rect(center, 0, center, windowMetrics.bounds.height()),
FOLD,
HALF_OPENED
)
val expected = WindowLayoutInfo.Builder().setDisplayFeatures(listOf(feature)).build()
val expected =
WindowLayoutInfo.Builder().setDisplayFeatures(listOf(feature)).build()

val values = mutableListOf<WindowLayoutInfo>()
val value = testScope.async {
activity.windowInfoRepository().windowLayoutInfo.take(1).toCollection(values)
activity.windowInfoRepository().windowLayoutInfo.take(1)
.toCollection(values)
}
publisherRule.overrideWindowLayoutInfo(expected)
runBlockingTest {
Expand All @@ -81,28 +114,32 @@ class SplitLayoutActivityTest {
listOf(expected),
newValues
)
delay(5000)
}
}
onView(withId(R.id.start_layout)).check(matches(isDisplayed()))
onView(withId(R.id.end_layout)).check(matches(isDisplayed()))

// Checks that start_layout is on the left of end_layout with a vertical folding feature.
// This requires to run the test on a big enough screen to fit both views on screen
onView(withId(R.id.start_layout)).check(isCompletelyLeftOf(withId(R.id.end_layout)))
}

@Test
fun testDeviceOpen_Horizontal(): Unit = testScope.runBlockingTest {
activityRule.scenario.onActivity { activity ->
val bounds = activity.windowInfoRepository().currentWindowMetrics.bounds
val center = bounds.centerY()
val windowMetrics =
WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(activity)
val center = windowMetrics.bounds.centerY()
val feature = FoldingFeature(
Rect(0, center, bounds.height(), center),
Rect(0, center, windowMetrics.bounds.height(), center),
FOLD,
HALF_OPENED
)
val expected = WindowLayoutInfo.Builder().setDisplayFeatures(listOf(feature)).build()
val expected =
WindowLayoutInfo.Builder().setDisplayFeatures(listOf(feature)).build()

val values = mutableListOf<WindowLayoutInfo>()
val value = testScope.async {
activity.windowInfoRepository().windowLayoutInfo.take(1).toCollection(values)
activity.windowInfoRepository().windowLayoutInfo.take(1)
.toCollection(values)
}
publisherRule.overrideWindowLayoutInfo(expected)
runBlockingTest {
Expand All @@ -111,10 +148,11 @@ class SplitLayoutActivityTest {
listOf(expected),
newValues
)
delay(5000)
}
}
onView(withId(R.id.start_layout)).check(matches(isDisplayed()))
onView(withId(R.id.end_layout)).check(matches(isDisplayed()))

// Checks that start_layout is above of end_layout with a horizontal folding feature.
// This requires to run the test on a big enough screen to fit both views on screen
onView(withId(R.id.start_layout)).check(isCompletelyAbove(withId(R.id.end_layout)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.window.FoldingFeature
import androidx.window.WindowInfoRepo
import androidx.window.WindowLayoutInfo
import androidx.window.windowInfoRepository
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoRepository
import androidx.window.layout.WindowInfoRepository.Companion.windowInfoRepository
import androidx.window.layout.WindowLayoutInfo
import com.example.windowmanagersample.databinding.ActivityDisplayFeaturesBinding
import java.text.SimpleDateFormat
import java.util.Date
Expand All @@ -44,7 +44,7 @@ class DisplayFeaturesActivity : AppCompatActivity() {
private val displayFeatureViews = ArrayList<View>()

private lateinit var binding: ActivityDisplayFeaturesBinding
private lateinit var windowInfoRepo: WindowInfoRepo
private lateinit var windowInfoRepo: WindowInfoRepository

@ExperimentalCoroutinesApi
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package com.example.windowmanagersample
import android.graphics.Rect
import android.view.View
import android.widget.FrameLayout
import androidx.window.DisplayFeature
import androidx.window.layout.DisplayFeature

/**
* Gets the bounds of the display feature translated to the View's coordinate space and current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import android.view.View
import android.view.View.MeasureSpec.AT_MOST
import android.view.View.MeasureSpec.EXACTLY
import android.widget.FrameLayout
import androidx.window.DisplayFeature
import androidx.window.FoldingFeature
import androidx.window.WindowLayoutInfo
import androidx.window.layout.DisplayFeature
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowLayoutInfo

/**
* An example of split-layout for two views, separated by a display feature that goes across the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.util.Consumer;
import androidx.window.WindowInfoRepo;
import androidx.window.WindowLayoutInfo;
import androidx.window.java.WindowInfoRepoJavaAdapter;
import androidx.window.java.layout.WindowInfoRepositoryCallbackAdapter;
import androidx.window.layout.WindowInfoRepository;
import androidx.window.layout.WindowLayoutInfo;
import com.example.windowmanagersample.databinding.ActivitySplitLayoutBinding;

public class SplitLayoutActivity extends AppCompatActivity {

private WindowInfoRepoJavaAdapter windowInfoRepo;
private WindowInfoRepositoryCallbackAdapter windowInfoRepository;
private ActivitySplitLayoutBinding binding;
private final LayoutStateChangeCallback layoutStateChangeCallback =
new LayoutStateChangeCallback();
Expand All @@ -39,19 +39,20 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

windowInfoRepo = new WindowInfoRepoJavaAdapter(WindowInfoRepo.create(this));
windowInfoRepository =
new WindowInfoRepositoryCallbackAdapter(WindowInfoRepository.getOrCreate(this));
}

@Override
protected void onStart() {
super.onStart();
windowInfoRepo.addWindowLayoutInfoListener(Runnable::run, layoutStateChangeCallback);
windowInfoRepository.addWindowLayoutInfoListener(Runnable::run, layoutStateChangeCallback);
}

@Override
protected void onStop() {
super.onStop();
windowInfoRepo.removeWindowLayoutInfoListener(layoutStateChangeCallback);
windowInfoRepository.removeWindowLayoutInfoListener(layoutStateChangeCallback);
}

class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
Expand Down
5 changes: 3 additions & 2 deletions WindowManager/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
*/

buildscript {
ext.kotlin_version = '1.5.20'
ext.kotlin_version = '1.5.21'
ext.coroutines_version = '1.5.0'
ext.ktlint_version = '0.40.0'
ext.window_version = '1.0.0-alpha10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.android.tools.build:gradle:7.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
2 changes: 1 addition & 1 deletion WindowManager/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists