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

@Config(fontScale=...) does not get applied to the default display #8851

Open
hoisie opened this issue Feb 18, 2024 · 4 comments
Open

@Config(fontScale=...) does not get applied to the default display #8851

hoisie opened this issue Feb 18, 2024 · 4 comments

Comments

@hoisie
Copy link
Contributor

hoisie commented Feb 18, 2024

For instance, add this to AndroidTestEnvironmentTest:

 @Test
  @Config(fontScale = 1.3f)
  public void setFontScale_updateDefaultDisplayScaledDensity() {
    Context context = ApplicationProvider.getApplicationContext();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display defaultDisplay = wm.getDefaultDisplay();
    DisplayMetrics defaultDisplayMetrics = new DisplayMetrics();
    defaultDisplay.getMetrics(defaultDisplayMetrics);
    assertThat(defaultDisplayMetrics.scaledDensity).isEqualTo(defaultDisplayMetrics.density * 1.3f);
  }

@utzcoz and @MGaetan89, this is related to the ShadowDisplay.setScaledDensity that was recently removed:: https://github.com/robolectric/robolectric/pull/8840/files#diff-ef2dfc7df64dc5c3c361a801fdcbaa9696e5749de52872debdba1c06f0fdf2e1L201-L203

I assumed that it was possible to set the scaled density using a combination of e.g. @Config(qualifiers="xhdpi", fontScale=1.3"), but there is a bug in Robolectric and that doesn't seem to apply to WindowManager.getDefaultDisplay().

I took a quick look and it may be related to the call to 'displayInfo.getAppMetrics' in ShadowDisplayManager.createDisplayInfo
https://github.com/robolectric/robolectric/blob/master/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManager.java#L154-L156, but I was not able to do a quick fix.

We could investigate a bit more, but if there is not an easy solution we may need to restore the ShadowDisplay.setScaledDensity until this issue is fixed, and then we can remove it again. There are a few tests inside of Google that look at the value of scaledDensity from the default display.

@hoisie
Copy link
Contributor Author

hoisie commented Feb 18, 2024

Just a bit more findings:

Display.getMetric(DisplayMetrics outMetrics) is this code:

    public void getMetrics(DisplayMetrics outMetrics) {
        synchronized (mLock) {
            updateDisplayInfoLocked();
            mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments());
        }
    }

I think in real Android, getDisplayAdjustments(), which returns a DisplayAdjustments class, is where the scaled density gets set. In DisplayAdjustments there is a member CompatibilityInfo which encapsulates the font scale value that the user overrides.

There is currently no logic in Robolectric that has logic to set the display adjustments.

Unfortunately the initial implementation of font scale never took into consideration DisplayAdjustments or Displays.

@hoisie
Copy link
Contributor Author

hoisie commented Feb 18, 2024

This method may also play a role: CompatibilityInfo.setOverrideInvertedScale.

hoisie added a commit to hoisie/robolectric that referenced this issue Feb 18, 2024
There is a bug in the `@Config(fontScale=...)` annotation that causes it
to not be applied to the result of Display.getMetrics. Until that bug is
fixed, there needs to be a way for tests to override the value of
Display.scaledDensity.

RE robolectric#8851
utzcoz pushed a commit that referenced this issue Feb 19, 2024
There is a bug in the `@Config(fontScale=...)` annotation that causes it
to not be applied to the result of Display.getMetrics. Until that bug is
fixed, there needs to be a way for tests to override the value of
Display.scaledDensity.

RE #8851
@MGaetan89
Copy link
Contributor

I'll try to look into this issue. Thanks for providing all these info @hoisie

@MGaetan89
Copy link
Contributor

@hoisie just to be sure, the test case you shared in the issue detail should also call bootstrapWrapper.callSetUpApplicationState();, right? Otherwise the default display doesn't get created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants