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
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 853165d..b09082e 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -19,6 +19,7 @@
 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 @@
             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)) {