Fixed
Status Update
Comments
[Deleted User] <[Deleted User]> #2
I was just about to file a similar issue, in my case, getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK wrongly returns false right after flipping the orientation from landscape to reverseLandscape, or portrait to reversePortrait.
After some research I found out that this happens because these rotations trigger a relayout of the window in WindowManagerService, which is modifying the activity Configuration, but does not call onConfigurationChanged() on the visible activity.
Same thing when the activity is in PictureInPictureMode, rotating the device does not call onConfigurationChanged() in the activity.
This is an issue because AppCompatActivity relies on the onConfigurationChanged() callback to have the AppCompatDelegate update the Configuration object, as well as clearing the drawable cache and re-apply the theme via the applyDayNight() method.
You can reproduce this very easily by registering a OrientationEventListener, and printing the value of the uiMode. Something like :
mOrientationListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
boolean isNightMode = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
Log.v(TAG, "NIGHT MODE = " + isNightMode);
}
};
mOrientationListener.enable();
You can see that right when the orientation changes, and the app gets redrawn by the WindowManagerService, the value will be false, then will get back to true as soon as onConfigurationChanged() gets called (for a rotation from portrait to landscape). But when flipping orientation 180 degrees, typically from landscape to reverseLandscape, the value stays false until the next onConfigurationChanged, resulting in all resources calls returning the default resources instead of the -night ones.
The same code shows the original bug reported, simply put this activity in PictureInPicture mode, and rotate (any rotation will trigger the bug in this case), you will see the value turn from true to false.
*Important note* : This only happens on Android 8.x (Oreo), Android 7.x (Nougat) does *not* have the issue, even though it doesn't call onConfigurationChanged() either when reversing orientations. Which makes me think it might a bug resulting from the PictureInPicture implementation introduced in Oreo.
Could it be that the PictureInPicture implementation added a Configuration update somewhere that is not getting propagated to the activity via the onConfigurationChanged() callback?
After some research I found out that this happens because these rotations trigger a relayout of the window in WindowManagerService, which is modifying the activity Configuration, but does not call onConfigurationChanged() on the visible activity.
Same thing when the activity is in PictureInPictureMode, rotating the device does not call onConfigurationChanged() in the activity.
This is an issue because AppCompatActivity relies on the onConfigurationChanged() callback to have the AppCompatDelegate update the Configuration object, as well as clearing the drawable cache and re-apply the theme via the applyDayNight() method.
You can reproduce this very easily by registering a OrientationEventListener, and printing the value of the uiMode. Something like :
mOrientationListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
boolean isNightMode = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
Log.v(TAG, "NIGHT MODE = " + isNightMode);
}
};
mOrientationListener.enable();
You can see that right when the orientation changes, and the app gets redrawn by the WindowManagerService, the value will be false, then will get back to true as soon as onConfigurationChanged() gets called (for a rotation from portrait to landscape). But when flipping orientation 180 degrees, typically from landscape to reverseLandscape, the value stays false until the next onConfigurationChanged, resulting in all resources calls returning the default resources instead of the -night ones.
The same code shows the original bug reported, simply put this activity in PictureInPicture mode, and rotate (any rotation will trigger the bug in this case), you will see the value turn from true to false.
*Important note* : This only happens on Android 8.x (Oreo), Android 7.x (Nougat) does *not* have the issue, even though it doesn't call onConfigurationChanged() either when reversing orientations. Which makes me think it might a bug resulting from the PictureInPicture implementation introduced in Oreo.
Could it be that the PictureInPicture implementation added a Configuration update somewhere that is not getting propagated to the activity via the onConfigurationChanged() callback?
ad...@google.com <ad...@google.com> #3
Thank you for reporting this issue. For us to further investigate this issue, please provide the following additional information:
Please provide sample project or apk to reproduce the issue. Also mention the steps to be followed for reproducing the issue with the given sample project or apk.
Expected output
What do you expect to occur?
Current output
What do you see instead?
Screen Record of the Issue
Please capture screen record or video of the issue using following steps:
adb shell screenrecord /sdcard/video.mp4
Subsequently use following command to pull the recorded file:
adb pull /sdcard/video.mp4
Attach the file to this issue.
Please upload the files to Google Drive and share the folder to android-bugreport@google.com, then share the link here.
Please provide sample project or apk to reproduce the issue. Also mention the steps to be followed for reproducing the issue with the given sample project or apk.
Expected output
What do you expect to occur?
Current output
What do you see instead?
Screen Record of the Issue
Please capture screen record or video of the issue using following steps:
adb shell screenrecord /sdcard/video.mp4
Subsequently use following command to pull the recorded file:
adb pull /sdcard/video.mp4
Attach the file to this issue.
Please upload the files to Google Drive and share the folder to android-bugreport@google.com, then share the link here.
[Deleted User] <[Deleted User]> #4
Sorry, should have started with that, here it is:
Screen Record of the Issue
https://drive.google.com/file/d/10QqpoeT4NjIyg7yjyxOPIms1_7IGjjqu/view?usp=sharing
Sample project with APK included:
https://drive.google.com/file/d/1vQO4nS4TfjazwDqnu8FZ0oFX433IvaGV/view?usp=sharing
Steps to reproduce:
- launch the sample project
- rotate to lanscape
- rotate to reverse landscape
- rotate to landscape
Expected output
rotating back and forth between landscape and reverseLandscape preserves the default night mode value.
Current output
rotating back and forth between landscape and reverseLandscape resets the current night mode value.
Screen Record of the Issue
Sample project with APK included:
Steps to reproduce:
- launch the sample project
- rotate to lanscape
- rotate to reverse landscape
- rotate to landscape
Expected output
rotating back and forth between landscape and reverseLandscape preserves the default night mode value.
Current output
rotating back and forth between landscape and reverseLandscape resets the current night mode value.
[Deleted User] <[Deleted User]> #5
Side note: this happens whether or not the activity handles configuration changes (the sample project does not handle configuration changes)
pr...@gmail.com <pr...@gmail.com> #6
Thanks, Justin, for picking this up and running with it. I've just seen a request for screen record and sample project but from your submissions I think they now have all they need to identify and fix this issue.
SimonH
SimonH
ad...@google.com <ad...@google.com> #7
We have passed this to the development team and will update this issue with more information as it becomes available.
ad...@google.com <ad...@google.com> #8
da...@gmail.com <da...@gmail.com> #9
I hope this is the correct place to ask this question...
I have now switched to 1.1.0-alpha03+ and am seeing the following behavior: For an Activity that has `uiMode` declared as part of the the `configChanges` attribute in the AndroidManifest.xml the Night Mode is now never applied when the Activity is first created. So, even though I call `AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)` in my Application's onCreate(), the Activity will be rendered in light mode. Only when I remove the `uiMode` part from the AndroidManifest.xml do I get a dark Activity.
Is this how it is supposed to work? I thought the `configChanges` attribute applied only to changes coming in _after_ the initial creation of the Activity and the documentation also seems to imply as much: "When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted." Not a word about the Activity not receiving any configuration that differs from the default when it is first created... :-)
Thanks for any advice!
I have now switched to 1.1.0-alpha03+ and am seeing the following behavior: For an Activity that has `uiMode` declared as part of the the `configChanges` attribute in the AndroidManifest.xml the Night Mode is now never applied when the Activity is first created. So, even though I call `AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)` in my Application's onCreate(), the Activity will be rendered in light mode. Only when I remove the `uiMode` part from the AndroidManifest.xml do I get a dark Activity.
Is this how it is supposed to work? I thought the `configChanges` attribute applied only to changes coming in _after_ the initial creation of the Activity and the documentation also seems to imply as much: "When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted." Not a word about the Activity not receiving any configuration that differs from the default when it is first created... :-)
Thanks for any advice!
ja...@gmail.com <ja...@gmail.com> #10
I have the same issue as #9
Description
Version used: appcompat-v7:26.1.0
Theme used: apptheme_noactionbar
Devices/Android versions reproduced on: Nexus 5X running Android 8.1.0. Emulator
Issue is as follows :-
Set AppCompatDelegate.setDefaultNightMode to MODE_NIGHT_ON. (Bug also occurs when set to MODE_NIGHT_AUTO and it IS night)
Enter PIP mode : enterPictureInPictureMode(p);
On entering PIP , getting the uiMode will correctly return night mode
i.e. getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK is true
Rotate the device - i.e. change orientation
getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK now returns false.