From f8d4a6684c321e0d2b564df6600c739c9bcd5863 Mon Sep 17 00:00:00 2001 From: Derek Sollenberger Date: Fri, 21 Feb 2020 16:38:43 -0500 Subject: Fix mmap errors when reading font files via the AssetManager. Previous attempts to do this ignored the offset that the AssetFileDescriptor may have. Bug: 149927583 Test: CtsTextTestCases and androidx.appcompat.widget.AppCompatTextViewTest Change-Id: Idcc8cb83a7f265cfa12707b7ce643b35f7f72352 --- graphics/java/android/graphics/fonts/Font.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'graphics') diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index 853165d4cf3f..b09082e65ca4 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -19,6 +19,7 @@ package android.graphics.fonts; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.LocaleList; @@ -219,6 +220,27 @@ public final class Font { Preconditions.checkNotNull(am, "assetManager can not be null"); Preconditions.checkNotNull(path, "path can not be null"); + // Attempt to open as FD, which should work unless the asset is compressed + AssetFileDescriptor assetFD; + try { + if (isAsset) { + assetFD = am.openFd(path); + } else if (cookie > 0) { + assetFD = am.openNonAssetFd(cookie, path); + } else { + assetFD = am.openNonAssetFd(path); + } + + try (FileInputStream fis = assetFD.createInputStream()) { + final FileChannel fc = fis.getChannel(); + long startOffset = assetFD.getStartOffset(); + long declaredLength = assetFD.getDeclaredLength(); + return fc.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); + } + } catch (IOException e) { + // failed to open as FD so now we will attempt to open as an input stream + } + try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER) : am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) { -- cgit v1.2.3