summaryrefslogtreecommitdiff
path: root/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java')
-rw-r--r--tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java125
1 files changed, 90 insertions, 35 deletions
diff --git a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
index e68455612c7e..74f6bca4d7a0 100644
--- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
+++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
@@ -19,6 +19,8 @@ package com.android.updatablesystemfont;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import android.platform.test.annotations.RootPermissionTest;
import com.android.fsverity.AddFsVerityCertRule;
@@ -35,8 +37,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -47,6 +47,9 @@ import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
+ private static final String SYSTEM_FONTS_DIR = "/system/fonts/";
+ private static final String DATA_FONTS_DIR = "/data/fonts/files/";
+
private static final String CERT_PATH = "/data/local/tmp/UpdatableSystemFontTestCert.der";
private static final Pattern PATTERN_FONT = Pattern.compile("path = ([^, \n]*)");
@@ -72,6 +75,15 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
private static final String TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG =
"/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig";
+ private static final String EMOJI_RENDERING_TEST_APP_ID = "com.android.emojirenderingtestapp";
+ private static final String EMOJI_RENDERING_TEST_ACTIVITY =
+ EMOJI_RENDERING_TEST_APP_ID + "/.EmojiRenderingTestActivity";
+ private static final long ACTIVITY_TIMEOUT_MILLIS = SECONDS.toMillis(10);
+
+ private interface ThrowingSupplier<T> {
+ T get() throws Exception;
+ }
+
@Rule
public final AddFsVerityCertRule mAddFsverityCertRule =
new AddFsVerityCertRule(this, CERT_PATH);
@@ -91,7 +103,10 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath).startsWith("/data/fonts/files/");
+ assertThat(fontPath).startsWith(DATA_FONTS_DIR);
+ // The updated font should be readable and unmodifiable.
+ expectRemoteCommandToSucceed("cat " + fontPath + " > /dev/null");
+ expectRemoteCommandToFail("echo -n '' >> " + fontPath);
}
@Test
@@ -102,8 +117,12 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG));
String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath2).startsWith("/data/fonts/files/");
+ assertThat(fontPath2).startsWith(DATA_FONTS_DIR);
assertThat(fontPath2).isNotEqualTo(fontPath);
+ // The new file should be readable.
+ expectRemoteCommandToSucceed("cat " + fontPath2 + " > /dev/null");
+ // The old file should be still readable.
+ expectRemoteCommandToSucceed("cat " + fontPath + " > /dev/null");
}
@Test
@@ -119,25 +138,14 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
String fontPath3 = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath).startsWith("/data/fonts/files/");
+ assertThat(fontPath).startsWith(DATA_FONTS_DIR);
assertThat(fontPath2).isNotEqualTo(fontPath);
- assertThat(fontPath2).startsWith("/data/fonts/files/");
- assertThat(fontPath3).startsWith("/data/fonts/files/");
+ assertThat(fontPath2).startsWith(DATA_FONTS_DIR);
+ assertThat(fontPath3).startsWith(DATA_FONTS_DIR);
assertThat(fontPath3).isNotEqualTo(fontPath);
}
@Test
- public void updatedFont_dataFileIsImmutableAndReadable() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath).startsWith("/data");
-
- expectRemoteCommandToFail("echo -n '' >> " + fontPath);
- expectRemoteCommandToSucceed("cat " + fontPath + " > /dev/null");
- }
-
- @Test
public void updateFont_invalidCert() throws Exception {
expectRemoteCommandToFail(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG));
@@ -158,15 +166,38 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
}
@Test
+ public void launchApp() throws Exception {
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(fontPath).startsWith(SYSTEM_FONTS_DIR);
+ startActivity(EMOJI_RENDERING_TEST_APP_ID, EMOJI_RENDERING_TEST_ACTIVITY);
+ waitUntil(ACTIVITY_TIMEOUT_MILLIS, () ->
+ isFileOpenedBy(fontPath, EMOJI_RENDERING_TEST_APP_ID));
+ }
+
+ @Test
+ public void launchApp_afterUpdateFont() throws Exception {
+ String originalFontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(originalFontPath).startsWith(SYSTEM_FONTS_DIR);
+ expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
+ String updatedFontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updatedFontPath).startsWith(DATA_FONTS_DIR);
+ startActivity(EMOJI_RENDERING_TEST_APP_ID, EMOJI_RENDERING_TEST_ACTIVITY);
+ // The original font should NOT be opened by the app.
+ waitUntil(ACTIVITY_TIMEOUT_MILLIS, () ->
+ isFileOpenedBy(updatedFontPath, EMOJI_RENDERING_TEST_APP_ID)
+ && !isFileOpenedBy(originalFontPath, EMOJI_RENDERING_TEST_APP_ID));
+ }
+
+ @Test
public void reboot() throws Exception {
expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath).startsWith("/data/fonts/files/");
+ assertThat(fontPath).startsWith(DATA_FONTS_DIR);
- expectRemoteCommandToSucceed("stop");
- expectRemoteCommandToSucceed("start");
- waitUntilFontCommandIsReady();
+ // Emulate reboot by 'cmd font restart'.
+ expectRemoteCommandToSucceed("cmd font restart");
String fontPathAfterReboot = getFontPath(NOTO_COLOR_EMOJI_TTF);
assertThat(fontPathAfterReboot).isEqualTo(fontPath);
}
@@ -184,6 +215,17 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
return null;
}
+ private void startActivity(String appId, String activityId) throws Exception {
+ // Make sure that the app is installed and enabled.
+ waitUntil(ACTIVITY_TIMEOUT_MILLIS, () -> {
+ String packageInfo = expectRemoteCommandToSucceed(
+ "pm list packages -e " + EMOJI_RENDERING_TEST_APP_ID);
+ return !packageInfo.isEmpty();
+ });
+ expectRemoteCommandToSucceed("am force-stop " + EMOJI_RENDERING_TEST_APP_ID);
+ expectRemoteCommandToSucceed("am start-activity -n " + EMOJI_RENDERING_TEST_ACTIVITY);
+ }
+
private String expectRemoteCommandToSucceed(String cmd) throws Exception {
CommandResult result = getDevice().executeShellV2Command(cmd);
assertWithMessage("`" + cmd + "` failed: " + result.getStderr())
@@ -199,27 +241,40 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
.isNotEqualTo(CommandStatus.SUCCESS);
}
- private void waitUntilFontCommandIsReady() {
- waitUntil(TimeUnit.SECONDS.toMillis(30), () -> {
- try {
- return getDevice().executeShellV2Command("cmd font status").getStatus()
- == CommandStatus.SUCCESS;
- } catch (DeviceNotAvailableException e) {
- return false;
- }
- });
- }
-
- private void waitUntil(long timeoutMillis, Supplier<Boolean> func) {
+ private void waitUntil(long timeoutMillis, ThrowingSupplier<Boolean> func) {
long untilMillis = System.currentTimeMillis() + timeoutMillis;
do {
- if (func.get()) return;
try {
+ if (func.get()) return;
Thread.sleep(100);
} catch (InterruptedException e) {
throw new AssertionError("Interrupted", e);
+ } catch (Exception e) {
+ throw new AssertionError("Unexpected exception", e);
}
} while (System.currentTimeMillis() < untilMillis);
throw new AssertionError("Timed out");
}
+
+ private boolean isFileOpenedBy(String path, String appId) throws DeviceNotAvailableException {
+ String pid = pidOf(appId);
+ if (pid.isEmpty()) {
+ return false;
+ }
+ CommandResult result = getDevice().executeShellV2Command(
+ String.format("lsof -t -p %s '%s'", pid, path));
+ if (result.getStatus() != CommandStatus.SUCCESS) {
+ return false;
+ }
+ // The file is open if the output of lsof is non-empty.
+ return !result.getStdout().trim().isEmpty();
+ }
+
+ private String pidOf(String appId) throws DeviceNotAvailableException {
+ CommandResult result = getDevice().executeShellV2Command("pidof " + appId);
+ if (result.getStatus() != CommandStatus.SUCCESS) {
+ return "";
+ }
+ return result.getStdout().trim();
+ }
}