Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c0b7827

Browse files
authored
Remove usages of WindowManager's getDefaultDisplay (#55002)
Removed deprecated usages of WindowManager's `getDefaultDisplay()` and replaced them with DisplayManager's `getDisplay()`. Note: Decided to keep a usage of `getDefaultDisplay()`, which can be found in FlutterView.java because it is expected to be deleted as a part of V1 embedding removal. No changes were made to that file. path to FlutterView.java: shell/platform/android/io/flutter/embedding/android/FlutterView.java Fixes [#99421](flutter/flutter#99421) ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent d143ca8 commit c0b7827

File tree

5 files changed

+86
-20
lines changed

5 files changed

+86
-20
lines changed

shell/platform/android/io/flutter/Build.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
package io.flutter;
66

7+
import androidx.annotation.VisibleForTesting;
8+
79
/** A replacement of utilities from android.os.Build. */
810
public class Build {
911
/** For use in place of the Android Build.VERSION_CODES class. */
1012
public static class API_LEVELS {
13+
@VisibleForTesting public static final int FLUTTER_MIN = 21;
1114
public static final int API_21 = 21;
1215
public static final int API_22 = 22;
1316
public static final int API_23 = 23;

shell/platform/android/io/flutter/embedding/android/FlutterView.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
import android.database.ContentObserver;
1515
import android.graphics.Insets;
1616
import android.graphics.Rect;
17+
import android.hardware.display.DisplayManager;
1718
import android.os.Build;
1819
import android.os.Handler;
1920
import android.os.Looper;
2021
import android.provider.Settings;
2122
import android.text.format.DateFormat;
2223
import android.util.AttributeSet;
2324
import android.util.SparseArray;
25+
import android.view.Display;
2426
import android.view.DisplayCutout;
2527
import android.view.KeyEvent;
2628
import android.view.MotionEvent;
@@ -31,7 +33,6 @@
3133
import android.view.ViewGroup;
3234
import android.view.ViewStructure;
3335
import android.view.WindowInsets;
34-
import android.view.WindowManager;
3536
import android.view.accessibility.AccessibilityManager;
3637
import android.view.accessibility.AccessibilityNodeProvider;
3738
import android.view.autofill.AutofillValue;
@@ -597,26 +598,35 @@ protected void setWindowInfoListenerDisplayFeatures(WindowLayoutInfo layoutInfo)
597598
// android may decide to place the software navigation bars on the side. When the nav
598599
// bar is hidden, the reported insets should be removed to prevent extra useless space
599600
// on the sides.
600-
private enum ZeroSides {
601+
@VisibleForTesting
602+
public enum ZeroSides {
601603
NONE,
602604
LEFT,
603605
RIGHT,
604606
BOTH
605607
}
606608

607-
private ZeroSides calculateShouldZeroSides() {
609+
/**
610+
* This method can be run on APIs 30 and above but its intended use is for 30 and below.
611+
*
612+
* @return some ZeroSides enum
613+
*/
614+
@androidx.annotation.DeprecatedSinceApi(api = API_LEVELS.API_30)
615+
@VisibleForTesting
616+
public ZeroSides calculateShouldZeroSides() {
608617
// We get both orientation and rotation because rotation is all 4
609618
// rotations relative to default rotation while orientation is portrait
610619
// or landscape. By combining both, we can obtain a more precise measure
611620
// of the rotation.
612621
Context context = getContext();
613622
int orientation = context.getResources().getConfiguration().orientation;
614-
int rotation =
615-
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
616-
.getDefaultDisplay()
617-
.getRotation();
618623

619624
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
625+
int rotation =
626+
((DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE))
627+
.getDisplay(Display.DEFAULT_DISPLAY)
628+
.getRotation();
629+
620630
if (rotation == Surface.ROTATION_90) {
621631
return ZeroSides.RIGHT;
622632
} else if (rotation == Surface.ROTATION_270) {

shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.graphics.Rect;
3030
import android.graphics.Region;
3131
import android.hardware.HardwareBuffer;
32+
import android.hardware.display.DisplayManager;
3233
import android.media.Image;
3334
import android.media.Image.Plane;
3435
import android.media.ImageReader;
@@ -39,13 +40,13 @@
3940
import android.view.Surface;
4041
import android.view.View;
4142
import android.view.WindowInsets;
42-
import android.view.WindowManager;
4343
import android.widget.FrameLayout;
4444
import androidx.core.util.Consumer;
4545
import androidx.test.core.app.ApplicationProvider;
4646
import androidx.test.ext.junit.runners.AndroidJUnit4;
4747
import androidx.window.layout.FoldingFeature;
4848
import androidx.window.layout.WindowLayoutInfo;
49+
import io.flutter.Build.API_LEVELS;
4950
import io.flutter.embedding.engine.FlutterEngine;
5051
import io.flutter.embedding.engine.FlutterJNI;
5152
import io.flutter.embedding.engine.loader.FlutterLoader;
@@ -438,6 +439,48 @@ public void systemInsetHandlesFullscreenNavbarRightBelowSDK23() {
438439
validateViewportMetricPadding(viewportMetricsCaptor, 100, 0, 0, 0);
439440
}
440441

442+
@Test
443+
@Config(minSdk = API_LEVELS.FLUTTER_MIN, maxSdk = API_LEVELS.API_29, qualifiers = "port")
444+
public void calculateShouldZeroSidesInPortrait() {
445+
FlutterView flutterView = spy(new FlutterView(ctx));
446+
assertEquals(FlutterView.ZeroSides.NONE, flutterView.calculateShouldZeroSides());
447+
}
448+
449+
@Test
450+
@Config(minSdk = API_LEVELS.FLUTTER_MIN, maxSdk = API_LEVELS.API_29, qualifiers = "land")
451+
public void calculateShouldZeroSidesInLandscapeNeutralRotation() {
452+
FlutterView flutterView = spy(new FlutterView(ctx));
453+
setExpectedDisplayRotation(Surface.ROTATION_0);
454+
assertEquals(FlutterView.ZeroSides.BOTH, flutterView.calculateShouldZeroSides());
455+
456+
setExpectedDisplayRotation(Surface.ROTATION_180);
457+
assertEquals(FlutterView.ZeroSides.BOTH, flutterView.calculateShouldZeroSides());
458+
}
459+
460+
@Test
461+
@Config(minSdk = API_LEVELS.FLUTTER_MIN, maxSdk = API_LEVELS.API_29, qualifiers = "land")
462+
public void calculateShouldZeroSidesInLandscapeRotation90() {
463+
FlutterView flutterView = spy(new FlutterView(ctx));
464+
setExpectedDisplayRotation(Surface.ROTATION_90);
465+
assertEquals(FlutterView.ZeroSides.RIGHT, flutterView.calculateShouldZeroSides());
466+
}
467+
468+
@Test
469+
@Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_22, qualifiers = "land")
470+
public void calculateShouldZeroSidesInLandscapeRotation270API22() {
471+
FlutterView flutterView = spy(new FlutterView(ctx));
472+
setExpectedDisplayRotation(Surface.ROTATION_270);
473+
assertEquals(FlutterView.ZeroSides.RIGHT, flutterView.calculateShouldZeroSides());
474+
}
475+
476+
@Test
477+
@Config(minSdk = API_LEVELS.API_23, maxSdk = API_LEVELS.API_29, qualifiers = "land")
478+
public void calculateShouldZeroSidesInLandscapeRotation270API23Plus() {
479+
FlutterView flutterView = spy(new FlutterView(ctx));
480+
setExpectedDisplayRotation(Surface.ROTATION_270);
481+
assertEquals(FlutterView.ZeroSides.LEFT, flutterView.calculateShouldZeroSides());
482+
}
483+
441484
@SuppressWarnings("deprecation")
442485
// getSystemUiVisibility, getWindowSystemUiVisibility required to test pre api 30 behavior.
443486
@Test
@@ -615,9 +658,6 @@ public void systemInsetDisplayCutoutSimple() {
615658
public void itRegistersAndUnregistersToWindowManager() {
616659
Context context = Robolectric.setupActivity(Activity.class);
617660
FlutterView flutterView = spy(new FlutterView(context));
618-
ShadowDisplay display =
619-
Shadows.shadowOf(
620-
((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay());
621661
WindowInfoRepositoryCallbackAdapterWrapper windowInfoRepo =
622662
mock(WindowInfoRepositoryCallbackAdapterWrapper.class);
623663
// For reasoning behing using doReturn instead of when, read "Important gotcha" at
@@ -646,9 +686,6 @@ public void itRegistersAndUnregistersToWindowManager() {
646686
public void itSendsHingeDisplayFeatureToFlutter() {
647687
Context context = Robolectric.setupActivity(Activity.class);
648688
FlutterView flutterView = spy(new FlutterView(context));
649-
ShadowDisplay display =
650-
Shadows.shadowOf(
651-
((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay());
652689
when(flutterView.getContext()).thenReturn(context);
653690
WindowInfoRepositoryCallbackAdapterWrapper windowInfoRepo =
654691
mock(WindowInfoRepositoryCallbackAdapterWrapper.class);
@@ -1102,10 +1139,10 @@ public SettingsChannel.MessageBuilder answer(InvocationOnMock invocation)
11021139

11031140
@SuppressWarnings("deprecation")
11041141
private void setExpectedDisplayRotation(int rotation) {
1105-
ShadowDisplay display =
1142+
ShadowDisplay myDisplay =
11061143
Shadows.shadowOf(
1107-
((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay());
1108-
display.setRotation(rotation);
1144+
((DisplayManager) ctx.getSystemService(Context.DISPLAY_SERVICE)).getDisplay(0));
1145+
myDisplay.setRotation(rotation);
11091146
}
11101147

11111148
private void validateViewportMetricPadding(

shell/platform/android/test/io/flutter/plugin/platform/WindowManagerHandlerTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public void windowManagerHandler_forwardsAllOtherCallsToDelegate() {
109109
@SuppressWarnings("Unchecked cast")
110110
Consumer<Boolean> mockListener = (Consumer<Boolean>) mock(Consumer.class);
111111

112+
// Windowmanager's getDefaultDisplay() function is deprecated in API 30 level 30.
113+
// See Android docs here:
114+
// https://developer.android.com/reference/android/view/WindowManager#getDefaultDisplay()
115+
// We expect this behavior because this unit test expects a blind forward that includes
116+
// deprecated function calls. See comment above for more details.
112117
windowManagerHandler.getDefaultDisplay();
113118
verify(mockWindowManager).getDefaultDisplay();
114119

tools/android_lint/baseline.xml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<issues format="6" by="lint 8.1.0 [10406996] " type="baseline" client="" dependencies="true" name="" variant="all" version="8.1.0 [10406996] ">
2+
<issues format="6" by="lint 8.3.0 [11479570] " type="baseline" client="" dependencies="true" name="" variant="all" version="8.3.0 [11479570] ">
3+
4+
<issue
5+
id="DeprecatedSinceApi"
6+
message="This method is deprecated as of API level 30"
7+
errorLine1=" zeroSides = calculateShouldZeroSides();"
8+
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
9+
<location
10+
file="../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java"
11+
line="759"
12+
column="21"/>
13+
</issue>
314

415
<issue
516
id="HardcodedDebugMode"
@@ -19,7 +30,7 @@
1930
errorLine2=" ~~~~~~~~~~~~">
2031
<location
2132
file="../../../flutter/shell/platform/android/io/flutter/view/FlutterView.java"
22-
line="445"
33+
line="474"
2334
column="18"/>
2435
</issue>
2536

@@ -30,7 +41,7 @@
3041
errorLine2=" ~~~~~~~~~~~~">
3142
<location
3243
file="../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterView.java"
33-
line="928"
44+
line="896"
3445
column="18"/>
3546
</issue>
3647

0 commit comments

Comments
 (0)