Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +11 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package androidx.window.extensions.layout; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED; Loading @@ -41,6 +42,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiContext; import androidx.annotation.VisibleForTesting; import androidx.window.common.CommonFoldingFeature; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; Loading Loading @@ -138,6 +140,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { throw new IllegalArgumentException("Context must be a UI Context, which should be" + " an Activity, WindowContext or InputMethodService"); } if (context.getAssociatedDisplayId() == INVALID_DISPLAY) { Log.w(TAG, "The registered Context is a UI Context but not associated with any" + " display. This Context may not receive any WindowLayoutInfo update"); } mFoldingFeatureProducer.getData((features) -> { WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features); consumer.accept(newWindowLayout); Loading Loading @@ -257,7 +263,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } } private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { @VisibleForTesting void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { synchronized (mLock) { mLastReportedFoldingFeatures.clear(); mLastReportedFoldingFeatures.addAll(storedFeatures); Loading Loading @@ -409,9 +416,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { * @return true if the display features should be reported for the UI Context, false otherwise. */ private boolean shouldReportDisplayFeatures(@NonNull @UiContext Context context) { int displayId = context.getDisplay().getDisplayId(); int displayId = context.getAssociatedDisplayId(); if (displayId != DEFAULT_DISPLAY) { // Display features are not supported on secondary displays. // Display features are not supported on secondary displays or the context is not // associated with any display. return false; } Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/layout/WindowLayoutComponentImplTest.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 * * http://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 androidx.window.extensions.layout; import static org.mockito.Mockito.mock; import android.content.Context; import android.content.ContextWrapper; import android.platform.test.annotations.Presubmit; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Collections; /** * Test class for {@link WindowLayoutComponentImpl}. * * Build/Install/Run: * atest WMJetpackUnitTests:WindowLayoutComponentImplTest */ @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class WindowLayoutComponentImplTest { private WindowLayoutComponentImpl mWindowLayoutComponent; @Before public void setUp() { mWindowLayoutComponent = new WindowLayoutComponentImpl( ApplicationProvider.getApplicationContext(), mock(DeviceStateManagerFoldingFeatureProducer.class)); } @Test public void testAddWindowLayoutListenerOnFakeUiContext_noCrash() { final Context fakeUiContext = createTestContext(); mWindowLayoutComponent.addWindowLayoutInfoListener(fakeUiContext, info -> {}); mWindowLayoutComponent.onDisplayFeaturesChanged(Collections.emptyList()); } private static Context createTestContext() { return new FakeUiContext(ApplicationProvider.getApplicationContext()); } /** * A {@link android.content.Context} overrides {@link android.content.Context#isUiContext} to * {@code true}. */ private static class FakeUiContext extends ContextWrapper { FakeUiContext(Context base) { super(base); } @Override public boolean isUiContext() { return true; } } } Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +11 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package androidx.window.extensions.layout; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED; Loading @@ -41,6 +42,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiContext; import androidx.annotation.VisibleForTesting; import androidx.window.common.CommonFoldingFeature; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.EmptyLifecycleCallbacksAdapter; Loading Loading @@ -138,6 +140,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { throw new IllegalArgumentException("Context must be a UI Context, which should be" + " an Activity, WindowContext or InputMethodService"); } if (context.getAssociatedDisplayId() == INVALID_DISPLAY) { Log.w(TAG, "The registered Context is a UI Context but not associated with any" + " display. This Context may not receive any WindowLayoutInfo update"); } mFoldingFeatureProducer.getData((features) -> { WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features); consumer.accept(newWindowLayout); Loading Loading @@ -257,7 +263,8 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { } } private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { @VisibleForTesting void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) { synchronized (mLock) { mLastReportedFoldingFeatures.clear(); mLastReportedFoldingFeatures.addAll(storedFeatures); Loading Loading @@ -409,9 +416,10 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { * @return true if the display features should be reported for the UI Context, false otherwise. */ private boolean shouldReportDisplayFeatures(@NonNull @UiContext Context context) { int displayId = context.getDisplay().getDisplayId(); int displayId = context.getAssociatedDisplayId(); if (displayId != DEFAULT_DISPLAY) { // Display features are not supported on secondary displays. // Display features are not supported on secondary displays or the context is not // associated with any display. return false; } Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/layout/WindowLayoutComponentImplTest.java 0 → 100644 +84 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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 * * http://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 androidx.window.extensions.layout; import static org.mockito.Mockito.mock; import android.content.Context; import android.content.ContextWrapper; import android.platform.test.annotations.Presubmit; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Collections; /** * Test class for {@link WindowLayoutComponentImpl}. * * Build/Install/Run: * atest WMJetpackUnitTests:WindowLayoutComponentImplTest */ @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class WindowLayoutComponentImplTest { private WindowLayoutComponentImpl mWindowLayoutComponent; @Before public void setUp() { mWindowLayoutComponent = new WindowLayoutComponentImpl( ApplicationProvider.getApplicationContext(), mock(DeviceStateManagerFoldingFeatureProducer.class)); } @Test public void testAddWindowLayoutListenerOnFakeUiContext_noCrash() { final Context fakeUiContext = createTestContext(); mWindowLayoutComponent.addWindowLayoutInfoListener(fakeUiContext, info -> {}); mWindowLayoutComponent.onDisplayFeaturesChanged(Collections.emptyList()); } private static Context createTestContext() { return new FakeUiContext(ApplicationProvider.getApplicationContext()); } /** * A {@link android.content.Context} overrides {@link android.content.Context#isUiContext} to * {@code true}. */ private static class FakeUiContext extends ContextWrapper { FakeUiContext(Context base) { super(base); } @Override public boolean isUiContext() { return true; } } }