Repository navigation
DisplayFeature.bounds not being updated if the device is rotated #155658
Copy link
Copy link
Closed
flutter-team-archive/engine
#55992Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listengineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.found in release: 3.24Found to occur in 3.24Found to occur in 3.24found in release: 3.26Found to occur in 3.26Found to occur in 3.26has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamOwned by Android platform teamtriaged-androidTriaged by Android platform teamTriaged by Android platform team
Description
Steps to reproduce
- Run example on an Android device with a
DisplayFeatureType.cutoutdisplay feature i.e. camera covering part of the screenn. - Rotate device
Expected results
The green box indicating where display features are should move with the new orientation.
Actual results
The green box stays in the same place.
Code sample
Code sample
import 'dart:ui';
import 'package:flutter/material.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MediaFeaturesDisplayPage(),
);
}
}
class MediaFeaturesDisplayPage extends StatelessWidget {
const MediaFeaturesDisplayPage({super.key});
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: DisplayFeaturesPainter(MediaQuery.of(context).displayFeatures),
size: Size.infinite,
);
}
}
class DisplayFeaturesPainter extends CustomPainter {
final List<DisplayFeature> displayFeatures;
DisplayFeaturesPainter(this.displayFeatures);
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = const Color(0xFF00FF00);
for (var feature in displayFeatures) {
canvas.drawRect(feature.bounds, paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
Screenshots or Video
No response
Logs
No response
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.24.3, on macOS 14.7 23H124 darwin-arm64, locale en)
• Flutter version 3.24.3 on channel stable at /Users/User/Development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 2663184aa7 (13 days ago), 2024-09-11 16:27:48 -0500
• Engine revision 36335019a8
• Dart version 3.5.3
• DevTools version 2.37.3
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/User/Library/Android/sdk
• Platform android-35, build-tools 34.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15F31d
• CocoaPods version 1.15.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2024.1)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
[✓] VS Code (version 1.94.0-insider)
• VS Code at /Applications/Visual Studio Code - Insiders.app/Contents
• Flutter extension version 3.96.0
[✓] Connected device (5 available)
• Pixel (mobile) • FA76R0301797 • android-arm64 • Android 10 (API 29)
• SM A256B (mobile) • R5CX806EZNE • android-arm64 • Android 14 (API 34)
• macOS (desktop) • macos • darwin-arm64 • macOS 14.7 23H124 darwin-arm64
• Mac Designed for iPad (desktop) • mac-designed-for-ipad • darwin • macOS 14.7 23H124 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 129.0.6668.59
[✓] Network resources
• All expected network resources are available.
• No issues found!Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listengineflutter/engine related. See also e: labels.flutter/engine related. See also e: labels.found in release: 3.24Found to occur in 3.24Found to occur in 3.24found in release: 3.26Found to occur in 3.26Found to occur in 3.26has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onplatform-androidAndroid applications specificallyAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamOwned by Android platform teamtriaged-androidTriaged by Android platform teamTriaged by Android platform team
Activity
jellynoone commentedon Sep 25, 2024
After further testing, it also seems the display features aren't properly reported when the device enters full screen (Using SystemChrome.setEnabledSystemUIMode). Again the reported dimensions stay the same even though the device might shrink the screen to completely cover the display feature.
The device I'm observing this behaviour on is a Samsung Galaxy A25 5G.
danagbemava-nc commentedon Sep 25, 2024
Reproducible using the code sample provided above. I tested on a Pixel 7 running android 14
screen-20240925-093540.mp4
flutter doctor -v
gmackall commentedon Oct 8, 2024
Interesting, I believe this is because we are conflating Android's notion of
WindowLayoutInfo.displayFeaturesandDisplayCutouts, and handling in the same method, but that method is only set as a listener to changes to the former.We could probably fix this by disentangling the handling, and invoking the handling for
DisplayCutoutchanges fromonSizeChanged(or somewhere else more fitting for rotation).yaakovschectman commentedon Oct 16, 2024
@jellynoone I'd like to check with you, did you observe this bug on an emulator, physical device, or both? And in any case, what was the device(s) you found this bug on? I have experienced some Android emulators on which cutouts simulated through developer settings don't behave as expected at all
jellynoone commentedon Oct 16, 2024
@yaakovschectman The device I'm observing this behaviour on is a Samsung Galaxy A25 5G. I didn't check out any emulators.
yaakovschectman commentedon Oct 16, 2024
I'm observing very inconsistent behavior across a couple emulators. After rotating, sometimes the box will be in the position where the cutout used to be, sometimes where it is, and sometimes there will be no box at all (and debugging shows that no cutout was found in the engine).
@gmackall Our listener where we update the display features is called on orientation changes, but do you think it might be possible that an orientation change triggers both the window info layout listener and updates the cutouts, but the order/timing of doing so is not well defined, causing these discrepancies?
gmackall commentedon Oct 16, 2024
Ok, it seems that this behavior isn't consistent between emulators and devices (or perhaps, it is device specific). Adding logs to see when each of
setWindowInfoListenerDisplayFeaturesandonApplyWindowInsetsget invoked, and then rotating a couple times:On my (api 34) pixel 7 pro:
Versus on an (api 34) pixel 6 pro emulator:
Testing on a Samsung Galaxy s23 w/ api 34 shows the same behavior as the physical pixel 7 pro, i.e. we don't invoke the display feature handling. Perhaps this is just a difference between emulators and physical devices? Maybe we should follow up with the Android emulator team?
But regardless, I still think we can probably fix the issue by making it so that we also send updates to the
viewportMetrics.displayFeatureswhen window insets get applied, as we countandroid.view.DisplayCutouts as an element of that list, and listening to changes to window insets will ensure we catch all updates to that subsetFlutterRenderer.DisplayFeatures.yaakovschectman commentedon Oct 17, 2024
Earlier I had tried moving the logic to
onSizeChanged, which also resulted in inconsistent behavior, at least on an emulator. Sometimes it would detect the old cutouts, sometimes the new one, sometimes none at all. I will still have to test if the behavior is any different when it's called while updating window insets, but I still wonder if the order of updates/triggers might be inconsistentyaakovschectman commentedon Oct 17, 2024
Update: Using the windows insets listener seems to resolve the issue from my testing so far, since the callback receives the new insets as an argument. Emulators still seem to behave a bit inconsistent but I think I agree that this is the right approach.
Move detection of cutouts in Android engine to `onApplyWindowInsets` (#…
Move detection of cutouts in Android engine to `onApplyWindowInsets` (f…
github-actions commentedon Nov 25, 2024
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.Move detection of cutouts in Android engine to `onApplyWindowInsets` (f…