From 455f1bfc05bf972ee4fe8cd5fa135ed232126bb7 Mon Sep 17 00:00:00 2001 From: Seigo Nonaka Date: Mon, 27 Mar 2017 19:46:51 -0700 Subject: [PATCH] Do not use many FDs in FontManagerService. Currently there are over 170 font files are installed in system directory. Opening 170+ files and keep them is not unacceptable. Pass URI instead. At the same time, this CL hides full font path from FontConfig since /system/fonts directory will be deprecated in future. Bug: 36660849 Test: android.text.cts.FontManagerTest passed Change-Id: I1d216dc9c6dec702a4ce3b946bfda6dcbe12b7fe --- api/current.txt | 2 +- api/system-current.txt | 2 +- api/test-current.txt | 2 +- core/java/android/text/FontConfig.java | 83 +++---------------- .../java/android/graphics/FontListParser.java | 5 +- graphics/java/android/graphics/Typeface.java | 11 +-- .../android/server/FontManagerService.java | 22 ++--- 7 files changed, 32 insertions(+), 95 deletions(-) diff --git a/api/current.txt b/api/current.txt index 369e571225232..a06dc71e3a0f3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -41073,9 +41073,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); diff --git a/api/system-current.txt b/api/system-current.txt index 95d6897aaa598..ae15af1f7237d 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -44528,9 +44528,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); diff --git a/api/test-current.txt b/api/test-current.txt index a436d1f42d78d..4f7b72e6a213b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -41278,9 +41278,9 @@ package android.text { public static final class FontConfig.Font implements android.os.Parcelable { method public int describeContents(); method public android.text.FontConfig.Axis[] getAxes(); - method public android.os.ParcelFileDescriptor getFd(); method public java.lang.String getFontName(); method public int getTtcIndex(); + method public android.net.Uri getUri(); method public int getWeight(); method public boolean isItalic(); method public void writeToParcel(android.os.Parcel, int); diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 70f9bdd9193ba..14d3ad790b1d4 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -22,13 +22,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.FontListParser; +import android.net.Uri; import android.os.Parcel; -import android.os.ParcelFileDescriptor; import android.os.Parcelable; -import java.io.IOException; import java.lang.annotation.Retention; -import java.util.Arrays; /** @@ -43,20 +41,6 @@ public final class FontConfig implements Parcelable { mAliases = aliases; } - /** - * For duplicating file descriptors. - * - * Note that this copy constructor can not be usable for deep copy. - * @hide - */ - public FontConfig(@NonNull FontConfig config) { - mFamilies = new Family[config.mFamilies.length]; - for (int i = 0; i < config.mFamilies.length; ++i) { - mFamilies[i] = new Family(config.mFamilies[i]); - } - mAliases = Arrays.copyOf(config.mAliases, config.mAliases.length); - } - /** * Returns the ordered list of families included in the system fonts. */ @@ -174,7 +158,7 @@ public final class FontConfig implements Parcelable { private final @NonNull Axis[] mAxes; private final int mWeight; private final boolean mIsItalic; - private @Nullable ParcelFileDescriptor mFd; + private Uri mUri; /** * @hide @@ -186,29 +170,6 @@ public final class FontConfig implements Parcelable { mAxes = axes; mWeight = weight; mIsItalic = isItalic; - mFd = null; - } - - /** - * This is for duplicating FileDescriptors. - * - * Note that this copy ctor doesn't deep copy the members. - * - * @hide - */ - public Font(Font origin) { - mFontName = origin.mFontName; - mTtcIndex = origin.mTtcIndex; - mAxes = origin.mAxes; - mWeight = origin.mWeight; - mIsItalic = origin.mIsItalic; - if (origin.mFd != null) { - try { - mFd = origin.mFd.dup(); - } catch (IOException e) { - e.printStackTrace(); - } - } } /** @@ -247,17 +208,20 @@ public final class FontConfig implements Parcelable { } /** - * Returns a file descriptor to access the specified font. This should be closed after use. + * Returns the content uri associated to this font. + * + * You can reach to the font contents by calling {@link + * android.content.ContentResolver#openInputStream}. */ - public @Nullable ParcelFileDescriptor getFd() { - return mFd; + public @Nullable Uri getUri() { + return mUri; } /** * @hide */ - public void setFd(@NonNull ParcelFileDescriptor fd) { - mFd = fd; + public void setUri(@NonNull Uri uri) { + mUri = uri; } /** @@ -269,11 +233,7 @@ public final class FontConfig implements Parcelable { mAxes = in.createTypedArray(Axis.CREATOR); mWeight = in.readInt(); mIsItalic = in.readInt() == 1; - if (in.readInt() == 1) { /* has FD */ - mFd = ParcelFileDescriptor.CREATOR.createFromParcel(in); - } else { - mFd = null; - } + mUri = in.readTypedObject(Uri.CREATOR); } @Override @@ -283,10 +243,7 @@ public final class FontConfig implements Parcelable { out.writeTypedArray(mAxes, flag); out.writeInt(mWeight); out.writeInt(mIsItalic ? 1 : 0); - out.writeInt(mFd == null ? 0 : 1); - if (mFd != null) { - mFd.writeToParcel(out, flag); - } + out.writeTypedObject(mUri, flag); } @Override @@ -424,22 +381,6 @@ public final class FontConfig implements Parcelable { mVariant = variant; } - /** - * For duplicating file descriptor underlying Font object. - * - * This copy constructor is not for deep copying. - * @hide - */ - public Family(Family origin) { - mName = origin.mName; - mLanguage = origin.mLanguage; - mVariant = origin.mVariant; - mFonts = new Font[origin.mFonts.length]; - for (int i = 0; i < origin.mFonts.length; ++i) { - mFonts[i] = new Font(origin.mFonts[i]); - } - } - /** * Returns the name given by the system to this font family. */ diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java index b78df34f5c3ec..ff9f11dae4dcb 100644 --- a/graphics/java/android/graphics/FontListParser.java +++ b/graphics/java/android/graphics/FontListParser.java @@ -189,9 +189,8 @@ public class FontListParser { skip(parser); } } - String fullFilename = "/system/fonts/" + - FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); - return new FontConfig.Font(fullFilename, index, + String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); + return new FontConfig.Font(sanitizedName, index, axes.toArray(new FontConfig.Axis[axes.size()]), weight, isItalic); } diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 228d9500180a3..8c3a2e8068ca2 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -1003,21 +1003,22 @@ public class Typeface { Map bufferForPath) { FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant()); for (FontConfig.Font font : family.getFonts()) { - ByteBuffer fontBuffer = bufferForPath.get(font.getFontName()); + String fullPathName = "/system/fonts/" + font.getFontName(); + ByteBuffer fontBuffer = bufferForPath.get(fullPathName); if (fontBuffer == null) { - try (FileInputStream file = new FileInputStream(font.getFontName())) { + try (FileInputStream file = new FileInputStream(fullPathName)) { FileChannel fileChannel = file.getChannel(); long fontSize = fileChannel.size(); fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize); - bufferForPath.put(font.getFontName(), fontBuffer); + bufferForPath.put(fullPathName, fontBuffer); } catch (IOException e) { - Log.e(TAG, "Error mapping font file " + font.getFontName()); + Log.e(TAG, "Error mapping font file " + fullPathName); continue; } } if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(), font.getWeight(), font.isItalic() ? Builder.ITALIC : Builder.NORMAL)) { - Log.e(TAG, "Error creating font " + font.getFontName() + "#" + font.getTtcIndex()); + Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex()); } } fontFamily.freeze(); diff --git a/services/core/java/com/android/server/FontManagerService.java b/services/core/java/com/android/server/FontManagerService.java index 55a945a6fce1f..f1726473c5912 100644 --- a/services/core/java/com/android/server/FontManagerService.java +++ b/services/core/java/com/android/server/FontManagerService.java @@ -18,6 +18,7 @@ package com.android.server; import android.content.Context; import android.graphics.FontListParser; +import android.net.Uri; import android.os.ParcelFileDescriptor; import android.text.FontConfig; import android.util.Slog; @@ -34,6 +35,7 @@ import java.io.IOException; public class FontManagerService extends IFontManager.Stub { private static final String TAG = "FontManagerService"; private static final String FONTS_CONFIG = "/system/etc/fonts.xml"; + private static final String SYSTEM_FONT_DIR = "/system/fonts/"; @GuardedBy("mLock") private FontConfig mConfig; @@ -63,28 +65,22 @@ public class FontManagerService extends IFontManager.Stub { public FontConfig getSystemFonts() { synchronized (mLock) { if (mConfig != null) { - return new FontConfig(mConfig); + return mConfig; } - FontConfig config = loadFromSystem(); - if (config == null) { + mConfig = loadFromSystem(); + if (mConfig == null) { return null; } - for (FontConfig.Family family : config.getFamilies()) { + for (FontConfig.Family family : mConfig.getFamilies()) { for (FontConfig.Font font : family.getFonts()) { - File fontFile = new File(font.getFontName()); - try { - font.setFd(ParcelFileDescriptor.open( - fontFile, ParcelFileDescriptor.MODE_READ_ONLY)); - } catch (IOException e) { - Slog.e(TAG, "Error opening font file " + font.getFontName(), e); - } + File fontFile = new File(SYSTEM_FONT_DIR, font.getFontName()); + font.setUri(Uri.fromFile(fontFile)); } } - mConfig = config; - return new FontConfig(mConfig); + return mConfig; } }