Merge "Add FontManager#updateFont API" into sc-dev am: ad68508496
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13422366 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I2569e1d5b3b08e55eecfc5afd9b19ce5b11ea073
This commit is contained in:
@@ -2610,6 +2610,17 @@ package android.graphics.fonts {
|
|||||||
|
|
||||||
public class FontManager {
|
public class FontManager {
|
||||||
method @Nullable public android.text.FontConfig getFontConfig();
|
method @Nullable public android.text.FontConfig getFontConfig();
|
||||||
|
method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[], @IntRange(from=0) int);
|
||||||
|
field public static final int RESULT_ERROR_DOWNGRADING = -5; // 0xfffffffb
|
||||||
|
field public static final int RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE = -1; // 0xffffffff
|
||||||
|
field public static final int RESULT_ERROR_FAILED_UPDATE_CONFIG = -6; // 0xfffffffa
|
||||||
|
field public static final int RESULT_ERROR_FONT_UPDATER_DISABLED = -7; // 0xfffffff9
|
||||||
|
field public static final int RESULT_ERROR_INVALID_FONT_FILE = -3; // 0xfffffffd
|
||||||
|
field public static final int RESULT_ERROR_INVALID_FONT_NAME = -4; // 0xfffffffc
|
||||||
|
field public static final int RESULT_ERROR_REMOTE_EXCEPTION = -9; // 0xfffffff7
|
||||||
|
field public static final int RESULT_ERROR_VERIFICATION_FAILURE = -2; // 0xfffffffe
|
||||||
|
field public static final int RESULT_ERROR_VERSION_MISMATCH = -8; // 0xfffffff8
|
||||||
|
field public static final int RESULT_SUCCESS = 0; // 0x0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -13662,7 +13673,9 @@ package android.text {
|
|||||||
public final class FontConfig implements android.os.Parcelable {
|
public final class FontConfig implements android.os.Parcelable {
|
||||||
method public int describeContents();
|
method public int describeContents();
|
||||||
method @NonNull public java.util.List<android.text.FontConfig.Alias> getAliases();
|
method @NonNull public java.util.List<android.text.FontConfig.Alias> getAliases();
|
||||||
|
method @IntRange(from=0) public int getConfigVersion();
|
||||||
method @NonNull public java.util.List<android.text.FontConfig.FontFamily> getFontFamilies();
|
method @NonNull public java.util.List<android.text.FontConfig.FontFamily> getFontFamilies();
|
||||||
|
method public long getLastModifiedTimeMillis();
|
||||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -826,6 +826,17 @@ package android.graphics.fonts {
|
|||||||
|
|
||||||
public class FontManager {
|
public class FontManager {
|
||||||
method @Nullable public android.text.FontConfig getFontConfig();
|
method @Nullable public android.text.FontConfig getFontConfig();
|
||||||
|
method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[], @IntRange(from=0) int);
|
||||||
|
field public static final int RESULT_ERROR_DOWNGRADING = -5; // 0xfffffffb
|
||||||
|
field public static final int RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE = -1; // 0xffffffff
|
||||||
|
field public static final int RESULT_ERROR_FAILED_UPDATE_CONFIG = -6; // 0xfffffffa
|
||||||
|
field public static final int RESULT_ERROR_FONT_UPDATER_DISABLED = -7; // 0xfffffff9
|
||||||
|
field public static final int RESULT_ERROR_INVALID_FONT_FILE = -3; // 0xfffffffd
|
||||||
|
field public static final int RESULT_ERROR_INVALID_FONT_NAME = -4; // 0xfffffffc
|
||||||
|
field public static final int RESULT_ERROR_REMOTE_EXCEPTION = -9; // 0xfffffff7
|
||||||
|
field public static final int RESULT_ERROR_VERIFICATION_FAILURE = -2; // 0xfffffffe
|
||||||
|
field public static final int RESULT_ERROR_VERSION_MISMATCH = -8; // 0xfffffff8
|
||||||
|
field public static final int RESULT_SUCCESS = 0; // 0x0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2033,7 +2044,9 @@ package android.text {
|
|||||||
public final class FontConfig implements android.os.Parcelable {
|
public final class FontConfig implements android.os.Parcelable {
|
||||||
method public int describeContents();
|
method public int describeContents();
|
||||||
method @NonNull public java.util.List<android.text.FontConfig.Alias> getAliases();
|
method @NonNull public java.util.List<android.text.FontConfig.Alias> getAliases();
|
||||||
|
method @IntRange(from=0) public int getConfigVersion();
|
||||||
method @NonNull public java.util.List<android.text.FontConfig.FontFamily> getFontFamilies();
|
method @NonNull public java.util.List<android.text.FontConfig.FontFamily> getFontFamilies();
|
||||||
|
method public long getLastModifiedTimeMillis();
|
||||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,17 @@
|
|||||||
|
|
||||||
package android.graphics.fonts;
|
package android.graphics.fonts;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
|
import android.annotation.IntRange;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.annotation.SystemService;
|
import android.annotation.SystemService;
|
||||||
import android.annotation.TestApi;
|
import android.annotation.TestApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.FontConfig;
|
import android.text.FontConfig;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -35,6 +39,10 @@ import java.util.Objects;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class gives you control of system installed font files.
|
* This class gives you control of system installed font files.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This class gives you the information of system font configuration and ability of changing them.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
@@ -45,68 +53,87 @@ public class FontManager {
|
|||||||
private final @NonNull IFontManager mIFontManager;
|
private final @NonNull IFontManager mIFontManager;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@IntDef(prefix = "ERROR_CODE_",
|
@IntDef(prefix = "RESULT_",
|
||||||
value = { ERROR_CODE_OK, ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
value = { RESULT_SUCCESS, RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
ERROR_CODE_VERIFICATION_FAILURE, ERROR_CODE_FONT_NAME_MISMATCH,
|
RESULT_ERROR_VERIFICATION_FAILURE, RESULT_ERROR_VERSION_MISMATCH,
|
||||||
ERROR_CODE_INVALID_FONT_FILE, ERROR_CODE_MISSING_POST_SCRIPT_NAME,
|
RESULT_ERROR_INVALID_FONT_FILE, RESULT_ERROR_INVALID_FONT_NAME,
|
||||||
ERROR_CODE_DOWNGRADING, ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE,
|
RESULT_ERROR_DOWNGRADING, RESULT_ERROR_FAILED_UPDATE_CONFIG,
|
||||||
ERROR_CODE_FONT_UPDATER_DISABLED })
|
RESULT_ERROR_FONT_UPDATER_DISABLED, RESULT_ERROR_REMOTE_EXCEPTION })
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface ErrorCode {}
|
public @interface ResultCode {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates an operation has processed successfully.
|
* Indicates that the request has been processed successfully.
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_OK = 0;
|
public static final int RESULT_SUCCESS = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of writing font files.
|
* Indicates that a failure occurred while writing the font file to disk.
|
||||||
* @hide
|
*
|
||||||
|
* This is an internal error that the system cannot place the font file for being used by
|
||||||
|
* application.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_FAILED_TO_WRITE_FONT_FILE = -1;
|
public static final int RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of fs-verity setup.
|
* Indicates that a failure occurred during the verification of the font file.
|
||||||
* @hide
|
*
|
||||||
|
* The system failed to verify given font file contents and signature with system installed
|
||||||
|
* certificate.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_VERIFICATION_FAILURE = -2;
|
public static final int RESULT_ERROR_VERIFICATION_FAILURE = -2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of verifying the font name with PostScript name.
|
* Indicates that a failure occurred as a result of invalid font format or content.
|
||||||
* @hide
|
*
|
||||||
|
* Android only accepts OpenType compliant font files.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_FONT_NAME_MISMATCH = -3;
|
public static final int RESULT_ERROR_INVALID_FONT_FILE = -3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of placing fonts due to unexpected font contents.
|
* Indicates a failure due to missing PostScript name in font's name table.
|
||||||
* @hide
|
*
|
||||||
|
* Indicates that a failure occurred since PostScript name in the name table(ID=6) was missing.
|
||||||
|
* The font is expected to have a PostScript name.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_INVALID_FONT_FILE = -4;
|
public static final int RESULT_ERROR_INVALID_FONT_NAME = -4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure due to missing PostScript name in name table.
|
* Indicates that a failure occurred due to downgrading the font version.
|
||||||
* @hide
|
*
|
||||||
|
* The font must have equal or newer revision in its head table.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_MISSING_POST_SCRIPT_NAME = -5;
|
public static final int RESULT_ERROR_DOWNGRADING = -5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of placing fonts due to downgrading.
|
* Indicates that a failure occurred while updating system font configuration.
|
||||||
* @hide
|
*
|
||||||
|
* This is an internal error that the system couldn't update the {@link FontConfig}.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_DOWNGRADING = -6;
|
public static final int RESULT_ERROR_FAILED_UPDATE_CONFIG = -6;
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates a failure of writing system font configuration XML file.
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE = -7;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure due to disabled font updater.
|
* Indicates a failure due to disabled font updater.
|
||||||
* @hide
|
*
|
||||||
|
* This is typically returned due to missing Linux kernel feature.
|
||||||
|
* The font updater only works with the Linux kernel that has fs-verity feature. The fs-verity
|
||||||
|
* is required after the device shipped with Android 11. Thus the updated device may not have
|
||||||
|
* fs-verity feature and font updater is disabled.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_FONT_UPDATER_DISABLED = -8;
|
public static final int RESULT_ERROR_FONT_UPDATER_DISABLED = -7;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a failure occurred because provided {@code baseVersion} did not match.
|
||||||
|
*
|
||||||
|
* The {@code baseVersion} provided does not match to the current {@link FontConfig} version.
|
||||||
|
* Please get the latest configuration and update {@code baseVersion} accordingly.
|
||||||
|
*/
|
||||||
|
public static final int RESULT_ERROR_VERSION_MISMATCH = -8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a failure due to IPC communication.
|
||||||
|
*/
|
||||||
|
public static final int RESULT_ERROR_REMOTE_EXCEPTION = -9;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of opening font file.
|
* Indicates a failure of opening font file.
|
||||||
@@ -115,7 +142,7 @@ public class FontManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_FAILED_TO_OPEN_FONT_FILE = -10001;
|
public static final int RESULT_ERROR_FAILED_TO_OPEN_FONT_FILE = -10001;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of opening signature file.
|
* Indicates a failure of opening signature file.
|
||||||
@@ -124,7 +151,7 @@ public class FontManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_FAILED_TO_OPEN_SIGNATURE_FILE = -10002;
|
public static final int RESULT_ERROR_FAILED_TO_OPEN_SIGNATURE_FILE = -10002;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of invalid shell command arguments.
|
* Indicates a failure of invalid shell command arguments.
|
||||||
@@ -133,7 +160,7 @@ public class FontManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_INVALID_SHELL_ARGUMENT = -10003;
|
public static final int RESULT_ERROR_INVALID_SHELL_ARGUMENT = -10003;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure of reading signature file.
|
* Indicates a failure of reading signature file.
|
||||||
@@ -142,7 +169,7 @@ public class FontManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_INVALID_SIGNATURE_FILE = -10004;
|
public static final int RESULT_ERROR_INVALID_SIGNATURE_FILE = -10004;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates a failure due to exceeding allowed signature file size (8kb).
|
* Indicates a failure due to exceeding allowed signature file size (8kb).
|
||||||
@@ -151,7 +178,7 @@ public class FontManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_CODE_SIGNATURE_TOO_LARGE = -10005;
|
public static final int RESULT_ERROR_SIGNATURE_TOO_LARGE = -10005;
|
||||||
|
|
||||||
|
|
||||||
private FontManager(@NonNull IFontManager iFontManager) {
|
private FontManager(@NonNull IFontManager iFontManager) {
|
||||||
@@ -177,6 +204,70 @@ public class FontManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update system installed font file.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* To protect devices, system font updater relies on the Linux Kernel feature called fs-verity.
|
||||||
|
* If the device is not ready for fs-verity, {@link #RESULT_ERROR_FONT_UPDATER_DISABLED} will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* Android only accepts OpenType compliant font files. If other font files are provided,
|
||||||
|
* {@link #RESULT_ERROR_INVALID_FONT_FILE} will be returned.
|
||||||
|
*
|
||||||
|
* The font file to be updated is identified by PostScript name stored in name table. If the
|
||||||
|
* font file doesn't have PostScript name entry, {@link #RESULT_ERROR_INVALID_FONT_NAME} will be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* The entire font file is verified with the given signature for the system installed
|
||||||
|
* certificate. If the system cannot verify the font contents,
|
||||||
|
* {@link #RESULT_ERROR_VERIFICATION_FAILURE} will be returned.
|
||||||
|
*
|
||||||
|
* The font file must have newer or equal revision number in the head table. In other words, the
|
||||||
|
* downgrading font file is not allowed. If the older font file is provided,
|
||||||
|
* {@link #RESULT_ERROR_DOWNGRADING} will be returned.
|
||||||
|
*
|
||||||
|
* The caller must specify the base config version for keeping consist system configuration. If
|
||||||
|
* the system configuration is updated for some reason between you get config with
|
||||||
|
* {@link #getFontConfig()} and calling this method, {@link #RESULT_ERROR_VERSION_MISMATCH} will
|
||||||
|
* be returned. Get the latest font configuration by calling {@link #getFontConfig()} again and
|
||||||
|
* try with the latest config version again.
|
||||||
|
*
|
||||||
|
* @param pfd A file descriptor of the font file.
|
||||||
|
* @param signature A PKCS#7 detached signature for verifying entire font files.
|
||||||
|
* @param baseVersion A base config version to be updated. You can get latest config version by
|
||||||
|
* {@link FontConfig#getConfigVersion()} via {@link #getFontConfig()}. If the
|
||||||
|
* system has newer config version, the update will fail with
|
||||||
|
* {@link #RESULT_ERROR_VERSION_MISMATCH}. Try to get the latest config and
|
||||||
|
* try update again.
|
||||||
|
* @return result code.
|
||||||
|
*
|
||||||
|
* @see FontConfig#getConfigVersion()
|
||||||
|
* @see #getFontConfig()
|
||||||
|
* @see #RESULT_SUCCESS
|
||||||
|
* @see #RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE
|
||||||
|
* @see #RESULT_ERROR_VERIFICATION_FAILURE
|
||||||
|
* @see #RESULT_ERROR_VERSION_MISMATCH
|
||||||
|
* @see #RESULT_ERROR_INVALID_FONT_FILE
|
||||||
|
* @see #RESULT_ERROR_INVALID_FONT_NAME
|
||||||
|
* @see #RESULT_ERROR_DOWNGRADING
|
||||||
|
* @see #RESULT_ERROR_FAILED_UPDATE_CONFIG
|
||||||
|
* @see #RESULT_ERROR_FONT_UPDATER_DISABLED
|
||||||
|
* @see #RESULT_ERROR_REMOTE_EXCEPTION
|
||||||
|
*/
|
||||||
|
@RequiresPermission(Manifest.permission.UPDATE_FONTS) public @ResultCode int updateFontFile(
|
||||||
|
@NonNull ParcelFileDescriptor pfd,
|
||||||
|
@NonNull byte[] signature,
|
||||||
|
@IntRange(from = 0) int baseVersion
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
return mIFontManager.updateFont(pfd, signature, baseVersion);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Failed to call updateFont API", e);
|
||||||
|
return RESULT_ERROR_REMOTE_EXCEPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method of the FontManager.
|
* Factory method of the FontManager.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import java.util.List;
|
|||||||
public final class FontConfig implements Parcelable {
|
public final class FontConfig implements Parcelable {
|
||||||
private final @NonNull List<FontFamily> mFamilies;
|
private final @NonNull List<FontFamily> mFamilies;
|
||||||
private final @NonNull List<Alias> mAliases;
|
private final @NonNull List<Alias> mAliases;
|
||||||
private final long mLastModifiedDate;
|
private final long mLastModifiedTimeMillis;
|
||||||
private final int mConfigVersion;
|
private final int mConfigVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,10 +65,10 @@ public final class FontConfig implements Parcelable {
|
|||||||
* @hide Only system server can create this instance and passed via IPC.
|
* @hide Only system server can create this instance and passed via IPC.
|
||||||
*/
|
*/
|
||||||
public FontConfig(@NonNull List<FontFamily> families, @NonNull List<Alias> aliases,
|
public FontConfig(@NonNull List<FontFamily> families, @NonNull List<Alias> aliases,
|
||||||
long lastModifiedDate, @IntRange(from = 0) int configVersion) {
|
long lastModifiedTimeMillis, @IntRange(from = 0) int configVersion) {
|
||||||
mFamilies = families;
|
mFamilies = families;
|
||||||
mAliases = aliases;
|
mAliases = aliases;
|
||||||
mLastModifiedDate = lastModifiedDate;
|
mLastModifiedTimeMillis = lastModifiedTimeMillis;
|
||||||
mConfigVersion = configVersion;
|
mConfigVersion = configVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,20 +93,21 @@ public final class FontConfig implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last modified date as Java epoch seconds.
|
* Returns the last modified time in milliseconds.
|
||||||
|
*
|
||||||
|
* This is a value of {@link System#currentTimeMillis()} when the system font configuration was
|
||||||
|
* modified last time.
|
||||||
*
|
*
|
||||||
* If there is no update, this return 0.
|
* If there is no update, this return 0.
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
public long getLastModifiedDate() {
|
public long getLastModifiedTimeMillis() {
|
||||||
return mLastModifiedDate;
|
return mLastModifiedTimeMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the monotonically increasing config version value.
|
* Returns the monotonically increasing config version value.
|
||||||
*
|
*
|
||||||
* The config version is reset to 0 when the system is restarted.
|
* The config version is reset to 0 when the system is restarted.
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
public @IntRange(from = 0) int getConfigVersion() {
|
public @IntRange(from = 0) int getConfigVersion() {
|
||||||
return mConfigVersion;
|
return mConfigVersion;
|
||||||
@@ -132,7 +133,7 @@ public final class FontConfig implements Parcelable {
|
|||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
dest.writeParcelableList(mFamilies, flags);
|
dest.writeParcelableList(mFamilies, flags);
|
||||||
dest.writeParcelableList(mAliases, flags);
|
dest.writeParcelableList(mAliases, flags);
|
||||||
dest.writeLong(mLastModifiedDate);
|
dest.writeLong(mLastModifiedTimeMillis);
|
||||||
dest.writeInt(mConfigVersion);
|
dest.writeInt(mConfigVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.internal.graphics.fonts;
|
package com.android.internal.graphics.fonts;
|
||||||
|
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.text.FontConfig;
|
import android.text.FontConfig;
|
||||||
import android.graphics.fonts.SystemFontState;
|
import android.graphics.fonts.SystemFontState;
|
||||||
|
|
||||||
@@ -26,4 +27,6 @@ import android.graphics.fonts.SystemFontState;
|
|||||||
*/
|
*/
|
||||||
interface IFontManager {
|
interface IFontManager {
|
||||||
FontConfig getFontConfig();
|
FontConfig getFontConfig();
|
||||||
|
|
||||||
|
int updateFont(in ParcelFileDescriptor fd, in byte[] signature, int baseVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.graphics.fonts;
|
package com.android.server.graphics.fonts;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -24,6 +25,7 @@ import android.graphics.fonts.FontFamily;
|
|||||||
import android.graphics.fonts.FontFileUtil;
|
import android.graphics.fonts.FontFileUtil;
|
||||||
import android.graphics.fonts.FontManager;
|
import android.graphics.fonts.FontManager;
|
||||||
import android.graphics.fonts.SystemFonts;
|
import android.graphics.fonts.SystemFonts;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
import android.os.SharedMemory;
|
import android.os.SharedMemory;
|
||||||
@@ -37,6 +39,7 @@ import android.util.Slog;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.graphics.fonts.IFontManager;
|
import com.android.internal.graphics.fonts.IFontManager;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
import com.android.server.security.FileIntegrityService;
|
import com.android.server.security.FileIntegrityService;
|
||||||
@@ -53,6 +56,7 @@ import java.nio.channels.FileChannel;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/** A service for managing system fonts. */
|
/** A service for managing system fonts. */
|
||||||
// TODO(b/173619554): Add API to update fonts.
|
// TODO(b/173619554): Add API to update fonts.
|
||||||
@@ -66,10 +70,27 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
return getSystemFontConfig();
|
return getSystemFontConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int updateFont(ParcelFileDescriptor fd, byte[] signature, int baseVersion)
|
||||||
|
throws RemoteException {
|
||||||
|
Objects.requireNonNull(fd);
|
||||||
|
Objects.requireNonNull(signature);
|
||||||
|
Preconditions.checkArgumentNonnegative(baseVersion);
|
||||||
|
getContext().enforceCallingPermission(Manifest.permission.UPDATE_FONTS,
|
||||||
|
"UPDATE_FONTS permission required.");
|
||||||
|
try {
|
||||||
|
installFontFile(fd.getFileDescriptor(), signature, baseVersion);
|
||||||
|
return FontManager.RESULT_SUCCESS;
|
||||||
|
} catch (SystemFontException e) {
|
||||||
|
Slog.e(TAG, "Failed to update font file", e);
|
||||||
|
return e.getErrorCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* package */ static class SystemFontException extends AndroidException {
|
/* package */ static class SystemFontException extends AndroidException {
|
||||||
private final int mErrorCode;
|
private final int mErrorCode;
|
||||||
|
|
||||||
SystemFontException(@FontManager.ErrorCode int errorCode, String msg, Throwable cause) {
|
SystemFontException(@FontManager.ResultCode int errorCode, String msg, Throwable cause) {
|
||||||
super(msg, cause);
|
super(msg, cause);
|
||||||
mErrorCode = errorCode;
|
mErrorCode = errorCode;
|
||||||
}
|
}
|
||||||
@@ -79,7 +100,8 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
mErrorCode = errorCode;
|
mErrorCode = errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FontManager.ErrorCode int getErrorCode() {
|
@FontManager.ResultCode
|
||||||
|
int getErrorCode() {
|
||||||
return mErrorCode;
|
return mErrorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,14 +219,21 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void installFontFile(FileDescriptor fd, byte[] pkcs7Signature)
|
/* package */ void installFontFile(FileDescriptor fd, byte[] pkcs7Signature, int baseVersion)
|
||||||
throws SystemFontException {
|
throws SystemFontException {
|
||||||
if (mUpdatableFontDir == null) {
|
if (mUpdatableFontDir == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FONT_UPDATER_DISABLED,
|
FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED,
|
||||||
"The font updater is disabled.");
|
"The font updater is disabled.");
|
||||||
}
|
}
|
||||||
synchronized (FontManagerService.this) {
|
synchronized (FontManagerService.this) {
|
||||||
|
// baseVersion == -1 only happens from shell command. This is filtered and treated as
|
||||||
|
// error from SystemApi call.
|
||||||
|
if (baseVersion != -1 && mUpdatableFontDir.getConfigVersion() != baseVersion) {
|
||||||
|
throw new SystemFontException(
|
||||||
|
FontManager.RESULT_ERROR_VERSION_MISMATCH,
|
||||||
|
"The base config version is older than current.");
|
||||||
|
}
|
||||||
mUpdatableFontDir.installFontFile(fd, pkcs7Signature);
|
mUpdatableFontDir.installFontFile(fd, pkcs7Signature);
|
||||||
// Create updated font map in the next getSerializedSystemFontMap() call.
|
// Create updated font map in the next getSerializedSystemFontMap() call.
|
||||||
mSerializedFontMap = null;
|
mSerializedFontMap = null;
|
||||||
@@ -214,7 +243,7 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
/* package */ void clearUpdates() throws SystemFontException {
|
/* package */ void clearUpdates() throws SystemFontException {
|
||||||
if (mUpdatableFontDir == null) {
|
if (mUpdatableFontDir == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FONT_UPDATER_DISABLED,
|
FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED,
|
||||||
"The font updater is disabled.");
|
"The font updater is disabled.");
|
||||||
}
|
}
|
||||||
mUpdatableFontDir.clearUpdates();
|
mUpdatableFontDir.clearUpdates();
|
||||||
|
|||||||
@@ -304,27 +304,27 @@ public class FontManagerShellCommand extends ShellCommand {
|
|||||||
String fontPath = shell.getNextArg();
|
String fontPath = shell.getNextArg();
|
||||||
if (fontPath == null) {
|
if (fontPath == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_SHELL_ARGUMENT,
|
FontManager.RESULT_ERROR_INVALID_SHELL_ARGUMENT,
|
||||||
"Font file path argument is required.");
|
"Font file path argument is required.");
|
||||||
}
|
}
|
||||||
String signaturePath = shell.getNextArg();
|
String signaturePath = shell.getNextArg();
|
||||||
if (signaturePath == null) {
|
if (signaturePath == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_SHELL_ARGUMENT,
|
FontManager.RESULT_ERROR_INVALID_SHELL_ARGUMENT,
|
||||||
"Signature file argument is required.");
|
"Signature file argument is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ParcelFileDescriptor fontFd = shell.openFileForSystem(fontPath, "r");
|
ParcelFileDescriptor fontFd = shell.openFileForSystem(fontPath, "r");
|
||||||
if (fontFd == null) {
|
if (fontFd == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_OPEN_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_OPEN_FONT_FILE,
|
||||||
"Failed to open font file");
|
"Failed to open font file");
|
||||||
}
|
}
|
||||||
|
|
||||||
ParcelFileDescriptor sigFd = shell.openFileForSystem(signaturePath, "r");
|
ParcelFileDescriptor sigFd = shell.openFileForSystem(signaturePath, "r");
|
||||||
if (sigFd == null) {
|
if (sigFd == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_OPEN_SIGNATURE_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_OPEN_SIGNATURE_FILE,
|
||||||
"Failed to open signature file");
|
"Failed to open signature file");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,24 +333,24 @@ public class FontManagerShellCommand extends ShellCommand {
|
|||||||
int len = sigFis.available();
|
int len = sigFis.available();
|
||||||
if (len > MAX_SIGNATURE_FILE_SIZE_BYTES) {
|
if (len > MAX_SIGNATURE_FILE_SIZE_BYTES) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_SIGNATURE_TOO_LARGE,
|
FontManager.RESULT_ERROR_SIGNATURE_TOO_LARGE,
|
||||||
"Signature file is too large");
|
"Signature file is too large");
|
||||||
}
|
}
|
||||||
byte[] signature = new byte[len];
|
byte[] signature = new byte[len];
|
||||||
if (sigFis.read(signature, 0, len) != len) {
|
if (sigFis.read(signature, 0, len) != len) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_SIGNATURE_FILE,
|
FontManager.RESULT_ERROR_INVALID_SIGNATURE_FILE,
|
||||||
"Invalid read length");
|
"Invalid read length");
|
||||||
}
|
}
|
||||||
mService.installFontFile(fontFis.getFD(), signature);
|
mService.installFontFile(fontFis.getFD(), signature, -1);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_SIGNATURE_FILE,
|
FontManager.RESULT_ERROR_INVALID_SIGNATURE_FILE,
|
||||||
"Failed to read signature file.", e);
|
"Failed to read signature file.", e);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_FONT_FILE,
|
FontManager.RESULT_ERROR_INVALID_FONT_FILE,
|
||||||
"Failed to read font files.", e);
|
"Failed to read font files.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ public class FontManagerShellCommand extends ShellCommand {
|
|||||||
FontConfig config = mService.getSystemFontConfig();
|
FontConfig config = mService.getSystemFontConfig();
|
||||||
|
|
||||||
writer.println("Current Version: " + config.getConfigVersion());
|
writer.println("Current Version: " + config.getConfigVersion());
|
||||||
LocalDateTime dt = LocalDateTime.ofEpochSecond(config.getLastModifiedDate(), 0,
|
LocalDateTime dt = LocalDateTime.ofEpochSecond(config.getLastModifiedTimeMillis(), 0,
|
||||||
ZoneOffset.UTC);
|
ZoneOffset.UTC);
|
||||||
writer.println("Last Modified Date: " + dt.format(DateTimeFormatter.ISO_DATE_TIME));
|
writer.println("Last Modified Date: " + dt.format(DateTimeFormatter.ISO_DATE_TIME));
|
||||||
|
|
||||||
|
|||||||
@@ -130,13 +130,7 @@ final class UpdatableFontDir {
|
|||||||
|
|
||||||
UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser,
|
UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser,
|
||||||
FsverityUtil fsverityUtil) {
|
FsverityUtil fsverityUtil) {
|
||||||
mFilesDir = filesDir;
|
this(filesDir, preinstalledFontDirs, parser, fsverityUtil, new File(CONFIG_XML_FILE));
|
||||||
mPreinstalledFontDirs = preinstalledFontDirs;
|
|
||||||
mParser = parser;
|
|
||||||
mFsverityUtil = fsverityUtil;
|
|
||||||
mConfigFile = new File(CONFIG_XML_FILE);
|
|
||||||
mTmpConfigFile = new File(CONFIG_XML_FILE + ".tmp");
|
|
||||||
loadFontFileMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For unit testing
|
// For unit testing
|
||||||
@@ -199,7 +193,7 @@ final class UpdatableFontDir {
|
|||||||
PersistentSystemFontConfig.writeToXml(fos, mConfig);
|
PersistentSystemFontConfig.writeToXml(fos, mConfig);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE,
|
FontManager.RESULT_ERROR_FAILED_UPDATE_CONFIG,
|
||||||
"Failed to write config XML.", e);
|
"Failed to write config XML.", e);
|
||||||
}
|
}
|
||||||
mConfigVersion++;
|
mConfigVersion++;
|
||||||
@@ -222,7 +216,7 @@ final class UpdatableFontDir {
|
|||||||
File newDir = getRandomDir(mFilesDir);
|
File newDir = getRandomDir(mFilesDir);
|
||||||
if (!newDir.mkdir()) {
|
if (!newDir.mkdir()) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
"Failed to create font directory.");
|
"Failed to create font directory.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -230,7 +224,7 @@ final class UpdatableFontDir {
|
|||||||
Os.chmod(newDir.getAbsolutePath(), 0711);
|
Os.chmod(newDir.getAbsolutePath(), 0711);
|
||||||
} catch (ErrnoException e) {
|
} catch (ErrnoException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
"Failed to change mode to 711", e);
|
"Failed to change mode to 711", e);
|
||||||
}
|
}
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
@@ -240,7 +234,7 @@ final class UpdatableFontDir {
|
|||||||
FileUtils.copy(fd, out.getFD());
|
FileUtils.copy(fd, out.getFD());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
"Failed to write font file to storage.", e);
|
"Failed to write font file to storage.", e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -250,7 +244,7 @@ final class UpdatableFontDir {
|
|||||||
pkcs7Signature);
|
pkcs7Signature);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_VERIFICATION_FAILURE,
|
FontManager.RESULT_ERROR_VERIFICATION_FAILURE,
|
||||||
"Failed to setup fs-verity.", e);
|
"Failed to setup fs-verity.", e);
|
||||||
}
|
}
|
||||||
String postScriptName;
|
String postScriptName;
|
||||||
@@ -258,18 +252,18 @@ final class UpdatableFontDir {
|
|||||||
postScriptName = mParser.getPostScriptName(tempNewFontFile);
|
postScriptName = mParser.getPostScriptName(tempNewFontFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_FONT_FILE,
|
FontManager.RESULT_ERROR_INVALID_FONT_FILE,
|
||||||
"Failed to read PostScript name from font file", e);
|
"Failed to read PostScript name from font file", e);
|
||||||
}
|
}
|
||||||
if (postScriptName == null) {
|
if (postScriptName == null) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_MISSING_POST_SCRIPT_NAME,
|
FontManager.RESULT_ERROR_INVALID_FONT_NAME,
|
||||||
"Failed to read PostScript name from font file");
|
"Failed to read PostScript name from font file");
|
||||||
}
|
}
|
||||||
File newFontFile = new File(newDir, postScriptName + ALLOWED_EXTENSION);
|
File newFontFile = new File(newDir, postScriptName + ALLOWED_EXTENSION);
|
||||||
if (!mFsverityUtil.rename(tempNewFontFile, newFontFile)) {
|
if (!mFsverityUtil.rename(tempNewFontFile, newFontFile)) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
"Failed to move verified font file.");
|
"Failed to move verified font file.");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -277,7 +271,7 @@ final class UpdatableFontDir {
|
|||||||
Os.chmod(newFontFile.getAbsolutePath(), 0644);
|
Os.chmod(newFontFile.getAbsolutePath(), 0644);
|
||||||
} catch (ErrnoException e) {
|
} catch (ErrnoException e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE,
|
FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
||||||
"Failed to change mode to 711", e);
|
"Failed to change mode to 711", e);
|
||||||
}
|
}
|
||||||
FontFileInfo fontFileInfo = validateFontFile(newFontFile);
|
FontFileInfo fontFileInfo = validateFontFile(newFontFile);
|
||||||
@@ -291,7 +285,7 @@ final class UpdatableFontDir {
|
|||||||
PersistentSystemFontConfig.writeToXml(fos, copied);
|
PersistentSystemFontConfig.writeToXml(fos, copied);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE,
|
FontManager.RESULT_ERROR_FAILED_UPDATE_CONFIG,
|
||||||
"Failed to write config XML.", e);
|
"Failed to write config XML.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +293,7 @@ final class UpdatableFontDir {
|
|||||||
HashMap<String, FontFileInfo> backup = new HashMap<>(mFontFileInfoMap);
|
HashMap<String, FontFileInfo> backup = new HashMap<>(mFontFileInfoMap);
|
||||||
if (!addFileToMapIfNewerLocked(fontFileInfo, false)) {
|
if (!addFileToMapIfNewerLocked(fontFileInfo, false)) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_DOWNGRADING,
|
FontManager.RESULT_ERROR_DOWNGRADING,
|
||||||
"Downgrading font file is forbidden.");
|
"Downgrading font file is forbidden.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +302,7 @@ final class UpdatableFontDir {
|
|||||||
mFontFileInfoMap.clear();
|
mFontFileInfoMap.clear();
|
||||||
mFontFileInfoMap.putAll(backup);
|
mFontFileInfoMap.putAll(backup);
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE,
|
FontManager.RESULT_ERROR_FAILED_UPDATE_CONFIG,
|
||||||
"Failed to stage the config file.");
|
"Failed to stage the config file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,18 +394,18 @@ final class UpdatableFontDir {
|
|||||||
private FontFileInfo validateFontFile(File file) throws SystemFontException {
|
private FontFileInfo validateFontFile(File file) throws SystemFontException {
|
||||||
if (!mFsverityUtil.hasFsverity(file.getAbsolutePath())) {
|
if (!mFsverityUtil.hasFsverity(file.getAbsolutePath())) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_VERIFICATION_FAILURE,
|
FontManager.RESULT_ERROR_VERIFICATION_FAILURE,
|
||||||
"Font validation failed. Fs-verity is not enabled: " + file);
|
"Font validation failed. Fs-verity is not enabled: " + file);
|
||||||
}
|
}
|
||||||
if (!validateFontFileName(file)) {
|
if (!validateFontFileName(file)) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_FONT_NAME_MISMATCH,
|
FontManager.RESULT_ERROR_INVALID_FONT_NAME,
|
||||||
"Font validation failed. Could not validate font file name: " + file);
|
"Font validation failed. Could not validate font file name: " + file);
|
||||||
}
|
}
|
||||||
long revision = getFontRevision(file);
|
long revision = getFontRevision(file);
|
||||||
if (revision == -1) {
|
if (revision == -1) {
|
||||||
throw new SystemFontException(
|
throw new SystemFontException(
|
||||||
FontManager.ERROR_CODE_INVALID_FONT_FILE,
|
FontManager.RESULT_ERROR_INVALID_FONT_FILE,
|
||||||
"Font validation failed. Could not read font revision: " + file);
|
"Font validation failed. Could not read font revision: " + file);
|
||||||
}
|
}
|
||||||
return new FontFileInfo(file, revision);
|
return new FontFileInfo(file, revision);
|
||||||
@@ -472,4 +466,10 @@ final class UpdatableFontDir {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ int getConfigVersion() {
|
||||||
|
synchronized (UpdatableFontDir.this) {
|
||||||
|
return mConfigVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public final class UpdatableFontDirTest {
|
|||||||
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
|
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
|
||||||
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
|
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
|
||||||
mConfigFile);
|
mConfigFile);
|
||||||
assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedDate())
|
assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
|
||||||
.isEqualTo(expectedModifiedDate);
|
.isEqualTo(expectedModifiedDate);
|
||||||
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
|
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
|
||||||
installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
|
installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
|
||||||
@@ -156,7 +156,7 @@ public final class UpdatableFontDirTest {
|
|||||||
// Four font dirs are created.
|
// Four font dirs are created.
|
||||||
assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
|
assertThat(mUpdatableFontFilesDir.list()).hasLength(4);
|
||||||
//
|
//
|
||||||
assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedDate())
|
assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
|
||||||
.isNotEqualTo(expectedModifiedDate);
|
.isNotEqualTo(expectedModifiedDate);
|
||||||
|
|
||||||
UpdatableFontDir dir = new UpdatableFontDir(
|
UpdatableFontDir dir = new UpdatableFontDir(
|
||||||
@@ -319,7 +319,7 @@ public final class UpdatableFontDirTest {
|
|||||||
installFontFile(dir, "test,1", GOOD_SIGNATURE);
|
installFontFile(dir, "test,1", GOOD_SIGNATURE);
|
||||||
fail("Expect IllegalArgumentException");
|
fail("Expect IllegalArgumentException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode()).isEqualTo(FontManager.ERROR_CODE_DOWNGRADING);
|
assertThat(e.getErrorCode()).isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).containsKey("test.ttf");
|
assertThat(dir.getFontFileMap()).containsKey("test.ttf");
|
||||||
assertWithMessage("Font should not be downgraded to an older revision")
|
assertWithMessage("Font should not be downgraded to an older revision")
|
||||||
@@ -355,7 +355,7 @@ public final class UpdatableFontDirTest {
|
|||||||
fail("Expect SystemFontException");
|
fail("Expect SystemFontException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode())
|
assertThat(e.getErrorCode())
|
||||||
.isEqualTo(FontManager.ERROR_CODE_VERIFICATION_FAILURE);
|
.isEqualTo(FontManager.RESULT_ERROR_VERIFICATION_FAILURE);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -373,7 +373,7 @@ public final class UpdatableFontDirTest {
|
|||||||
installFontFile(dir, "test,1", GOOD_SIGNATURE);
|
installFontFile(dir, "test,1", GOOD_SIGNATURE);
|
||||||
fail("Expect IllegalArgumentException");
|
fail("Expect IllegalArgumentException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode()).isEqualTo(FontManager.ERROR_CODE_DOWNGRADING);
|
assertThat(e.getErrorCode()).isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -403,9 +403,9 @@ public final class UpdatableFontDirTest {
|
|||||||
installFontFile(dir, "test,2", GOOD_SIGNATURE);
|
installFontFile(dir, "test,2", GOOD_SIGNATURE);
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode())
|
assertThat(e.getErrorCode())
|
||||||
.isEqualTo(FontManager.ERROR_CODE_FAILED_TO_CREATE_CONFIG_FILE);
|
.isEqualTo(FontManager.RESULT_ERROR_FAILED_UPDATE_CONFIG);
|
||||||
}
|
}
|
||||||
assertThat(dir.getSystemFontConfig().getLastModifiedDate())
|
assertThat(dir.getSystemFontConfig().getLastModifiedTimeMillis())
|
||||||
.isEqualTo(expectedModifiedDate);
|
.isEqualTo(expectedModifiedDate);
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -435,7 +435,7 @@ public final class UpdatableFontDirTest {
|
|||||||
fail("Expect SystemFontException");
|
fail("Expect SystemFontException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode())
|
assertThat(e.getErrorCode())
|
||||||
.isEqualTo(FontManager.ERROR_CODE_MISSING_POST_SCRIPT_NAME);
|
.isEqualTo(FontManager.RESULT_ERROR_INVALID_FONT_NAME);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -462,7 +462,7 @@ public final class UpdatableFontDirTest {
|
|||||||
fail("Expect SystemFontException");
|
fail("Expect SystemFontException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode())
|
assertThat(e.getErrorCode())
|
||||||
.isEqualTo(FontManager.ERROR_CODE_INVALID_FONT_FILE);
|
.isEqualTo(FontManager.RESULT_ERROR_INVALID_FONT_FILE);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -497,7 +497,7 @@ public final class UpdatableFontDirTest {
|
|||||||
fail("Expect SystemFontException");
|
fail("Expect SystemFontException");
|
||||||
} catch (FontManagerService.SystemFontException e) {
|
} catch (FontManagerService.SystemFontException e) {
|
||||||
assertThat(e.getErrorCode())
|
assertThat(e.getErrorCode())
|
||||||
.isEqualTo(FontManager.ERROR_CODE_FAILED_TO_WRITE_FONT_FILE);
|
.isEqualTo(FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE);
|
||||||
}
|
}
|
||||||
assertThat(dir.getFontFileMap()).isEmpty();
|
assertThat(dir.getFontFileMap()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user