feat(non linear font scaling): add test activity for end-to-end tests

Fix: 256929929
Test: atest FrameworksCoreTests:android.content.res.FontScaleConverterActivityTest

Change-Id: I260b939a568ee47ac9d5c8620b93f16c756339eb
This commit is contained in:
Tyler Freeman
2023-01-10 12:13:35 -08:00
parent 3356162939
commit 079a5d2137
3 changed files with 234 additions and 1 deletions

View File

@@ -1685,12 +1685,16 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
</intent-filter>
</activity>
</activity>
<activity android:name="android.window.WindowMetricsHelperTest$TestActivity"
android:resizeableActivity="true"
android:exported="true">
</activity>
<activity android:name="android.content.res.FontScaleConverterActivityTest$TestActivity"
android:exported="true">
</activity>
<service android:name="android.view.stylus.HandwritingImeService"
android:label="Handwriting IME"
android:permission="android.permission.BIND_INPUT_METHOD"

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:id="@+id/text8sp"
android:text="@string/view"
android:textSize="8sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView android:id="@+id/text18sp"
android:text="@string/view"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView android:id="@+id/text35sp"
android:text="@string/view"
android:textSize="35sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2023 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 android.content.res;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.view.View;
import android.widget.TextView;
import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.frameworks.coretests.R;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import java.util.concurrent.atomic.AtomicReference;
/**
* Test for verifying non-linear font scaling behavior.
* Build/Install/Run:
* atest FrameworksCoreTests:android.content.res.FontScaleConverterActivityTest
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
@Presubmit
public class FontScaleConverterActivityTest {
@Rule
public ActivityScenarioRule<TestActivity> rule = new ActivityScenarioRule<>(TestActivity.class);
@Rule
public TestRule compatChangeRule = new PlatformCompatChangeRule();
private float mOriginalFontScale = Float.MIN_VALUE;
@Before
public void setup() {
mOriginalFontScale = Settings.System.getFloat(
InstrumentationRegistry.getInstrumentation().getContext().getContentResolver(),
Settings.System.FONT_SCALE,
Float.MIN_VALUE
);
}
@After
public void teardown() {
if (mOriginalFontScale != Float.MIN_VALUE) {
setSystemFontScale(mOriginalFontScale);
}
}
@Test
public void testFontsScaleNonLinearly() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
setSystemFontScale(2f);
var densityRef = new AtomicReference<Float>();
scenario.onActivity(activity -> {
densityRef.compareAndSet(null, activity.getResources().getDisplayMetrics().density);
});
var density = densityRef.get();
assertThat(density).isNotNull();
onView(withId(R.id.text8sp)).check(matches(withTextSizeInRange(
15f * density,
16f * density
)));
onView(withId(R.id.text18sp)).check(matches(withTextSizeInRange(
20f * density,
36f * density
)));
onView(withId(R.id.text35sp)).check(matches(withTextSizeInRange(
35 * density,
60 * density
)));
}
@Test
public void testOnConfigurationChanged_doesNotCrash() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
scenario.onActivity(activity -> {
var config = new Configuration(activity.getResources().getConfiguration());
config.fontScale = 1.2f;
activity.onConfigurationChanged(config);
activity.finish();
});
}
@Test
public void testUpdateConfiguration_doesNotCrash() {
final ActivityScenario<TestActivity> scenario = rule.getScenario();
scenario.onActivity(activity -> {
activity.updateConfiguration();
activity.finish();
});
}
private static void setSystemFontScale(float fontScale) {
ShellIdentityUtils.invokeWithShellPermissions(() -> {
Settings.System.putFloat(
InstrumentationRegistry.getInstrumentation().getContext().getContentResolver(),
Settings.System.FONT_SCALE,
fontScale
);
});
}
private Matcher<View> withTextSizeInRange(float sizeStartPx, float sizeEndPx) {
return new BoundedMatcher<>(TextView.class) {
private static final float TOLERANCE = 0.05f;
@Override
public void describeMismatch(Object item, Description description) {
super.describeMismatch(item, description);
description.appendText("was ").appendValue(((TextView) item).getTextSize());
}
@Override
public void describeTo(Description description) {
description.appendText("withTextSize between " + sizeStartPx + " and " + sizeEndPx);
}
@Override
protected boolean matchesSafely(TextView textView) {
var textSize = textView.getTextSize();
return sizeStartPx - TOLERANCE < textSize && textSize < sizeEndPx + TOLERANCE;
}
};
}
/** Test Activity */
public static class TestActivity extends Activity {
final Configuration mConfig = new Configuration();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().getDecorView().setKeepScreenOn(true);
setShowWhenLocked(true);
setTurnScreenOn(true);
setContentView(R.layout.font_scale_converter_activity);
}
public Configuration updateConfiguration() {
Settings.System.getConfiguration(getContentResolver(), mConfig);
return mConfig;
}
}
}