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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1003,21 +1003,22 @@ public class Typeface {
|
||||
Map<String, ByteBuffer> 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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user