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:
Seigo Nonaka
2017-03-27 19:46:51 -07:00
parent 2388f0c81c
commit 455f1bfc05
7 changed files with 32 additions and 95 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.
*/

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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;
}
}