319 lines
12 KiB
Java
319 lines
12 KiB
Java
/*
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.graphics.fonts;
|
|
|
|
import android.Manifest;
|
|
import android.annotation.IntDef;
|
|
import android.annotation.IntRange;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.RequiresPermission;
|
|
import android.annotation.SystemApi;
|
|
import android.annotation.SystemService;
|
|
import android.annotation.TestApi;
|
|
import android.content.Context;
|
|
import android.os.RemoteException;
|
|
import android.text.FontConfig;
|
|
|
|
import com.android.internal.graphics.fonts.IFontManager;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
@SystemApi
|
|
@TestApi
|
|
@SystemService(Context.FONT_SERVICE)
|
|
public class FontManager {
|
|
private static final String TAG = "FontManager";
|
|
private final @NonNull IFontManager mIFontManager;
|
|
|
|
/** @hide */
|
|
@IntDef(prefix = "RESULT_",
|
|
value = { RESULT_SUCCESS, RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE,
|
|
RESULT_ERROR_VERIFICATION_FAILURE, RESULT_ERROR_VERSION_MISMATCH,
|
|
RESULT_ERROR_INVALID_FONT_FILE, RESULT_ERROR_INVALID_FONT_NAME,
|
|
RESULT_ERROR_DOWNGRADING, RESULT_ERROR_FAILED_UPDATE_CONFIG,
|
|
RESULT_ERROR_FONT_UPDATER_DISABLED, RESULT_ERROR_FONT_NOT_FOUND })
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface ResultCode {}
|
|
|
|
/**
|
|
* Indicates that the request has been processed successfully.
|
|
*/
|
|
public static final int RESULT_SUCCESS = 0;
|
|
|
|
/**
|
|
* Indicates that a failure occurred while writing the font file to disk.
|
|
*
|
|
* This is an internal error that the system cannot place the font file for being used by
|
|
* application.
|
|
*/
|
|
public static final int RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE = -1;
|
|
|
|
/**
|
|
* Indicates that a failure occurred during the verification of the font file.
|
|
*
|
|
* The system failed to verify given font file contents and signature with system installed
|
|
* certificate.
|
|
*/
|
|
public static final int RESULT_ERROR_VERIFICATION_FAILURE = -2;
|
|
|
|
/**
|
|
* Indicates that a failure occurred as a result of invalid font format or content.
|
|
*
|
|
* Android only accepts OpenType compliant font files.
|
|
*/
|
|
public static final int RESULT_ERROR_INVALID_FONT_FILE = -3;
|
|
|
|
/**
|
|
* Indicates a failure due to missing PostScript name in font's name table.
|
|
*
|
|
* 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 RESULT_ERROR_INVALID_FONT_NAME = -4;
|
|
|
|
/**
|
|
* Indicates that a failure occurred due to downgrading the font version.
|
|
*
|
|
* The font must have equal or newer revision in its head table.
|
|
*/
|
|
public static final int RESULT_ERROR_DOWNGRADING = -5;
|
|
|
|
/**
|
|
* Indicates that a failure occurred while updating system font configuration.
|
|
*
|
|
* This is an internal error that the system couldn't update the {@link FontConfig}.
|
|
*/
|
|
public static final int RESULT_ERROR_FAILED_UPDATE_CONFIG = -6;
|
|
|
|
/**
|
|
* Indicates a failure due to disabled font updater.
|
|
*
|
|
* 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 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 occurred because a font with the specified PostScript name could not be
|
|
* found.
|
|
*/
|
|
public static final int RESULT_ERROR_FONT_NOT_FOUND = -9;
|
|
|
|
/**
|
|
* Indicates a failure of opening font file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_FAILED_TO_OPEN_FONT_FILE = -10001;
|
|
|
|
/**
|
|
* Indicates a failure of opening signature file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_FAILED_TO_OPEN_SIGNATURE_FILE = -10002;
|
|
|
|
/**
|
|
* Indicates a failure of invalid shell command arguments.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_INVALID_SHELL_ARGUMENT = -10003;
|
|
|
|
/**
|
|
* Indicates a failure of reading signature file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_INVALID_SIGNATURE_FILE = -10004;
|
|
|
|
/**
|
|
* Indicates a failure due to exceeding allowed signature file size (8kb).
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_SIGNATURE_TOO_LARGE = -10005;
|
|
|
|
/**
|
|
* Indicates a failure of opening XML file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_FAILED_TO_OPEN_XML_FILE = -10006;
|
|
|
|
/**
|
|
* Indicates a failure due to invalid XML file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_INVALID_XML = -10007;
|
|
|
|
/**
|
|
* Indicates a failure due to invalid debug certificate file.
|
|
*
|
|
* This error code is only used with the shell command interaction.
|
|
*
|
|
* @hide
|
|
*/
|
|
public static final int RESULT_ERROR_INVALID_DEBUG_CERTIFICATE = -10008;
|
|
|
|
private FontManager(@NonNull IFontManager iFontManager) {
|
|
mIFontManager = iFontManager;
|
|
}
|
|
|
|
/**
|
|
* Returns the system font configuration.
|
|
*
|
|
* This information is expected to be used by system font updater. If you are looking for APIs
|
|
* about drawing text and/or high-level system font information, use
|
|
* {@link android.graphics.Typeface} or {@link SystemFonts} instead.
|
|
*
|
|
* @return The current font configuration. null if failed to fetch information from the system
|
|
* service.
|
|
*/
|
|
@RequiresPermission(Manifest.permission.UPDATE_FONTS)
|
|
public @NonNull FontConfig getFontConfig() {
|
|
try {
|
|
return mIFontManager.getFontConfig();
|
|
} catch (RemoteException e) {
|
|
throw e.rethrowAsRuntimeException();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update or add system font families.
|
|
*
|
|
* <p>This method will update existing font families or add new font families. The updated
|
|
* font family definitions will be used when creating {@link android.graphics.Typeface} objects
|
|
* with using {@link android.graphics.Typeface#create(String, int)} specifying the family name,
|
|
* or through XML resources.
|
|
*
|
|
* To protect devices, system font updater relies on a Linux Kernel feature called fs-verity.
|
|
* If the device does not support fs-verity, {@link #RESULT_ERROR_FONT_UPDATER_DISABLED} will be
|
|
* returned.
|
|
*
|
|
* <p>Android only accepts OpenType compliant font files. If other font files are provided,
|
|
* {@link #RESULT_ERROR_INVALID_FONT_FILE} will be returned.
|
|
*
|
|
* <p>The font file to be updated is identified by PostScript name stored in the name table. If
|
|
* the font file doesn't have PostScript name entry, {@link #RESULT_ERROR_INVALID_FONT_NAME}
|
|
* will be returned.
|
|
*
|
|
* <p>The entire font file is verified with the given signature using system installed
|
|
* certificates. If the system cannot verify the font file contents,
|
|
* {@link #RESULT_ERROR_VERIFICATION_FAILURE} will be returned.
|
|
*
|
|
* <p>The font file must have a newer revision number in the head table. In other words, it is
|
|
* not allowed to downgrade a font file. If an older font file is provided,
|
|
* {@link #RESULT_ERROR_DOWNGRADING} will be returned.
|
|
*
|
|
* <p>The caller must specify the base config version for keeping the font configuration
|
|
* consistent. If the font configuration is updated for some reason between the time you get
|
|
* a configuration with {@link #getFontConfig()} and the time when you call this method,
|
|
* {@link #RESULT_ERROR_VERSION_MISMATCH} will be returned. Get the latest font configuration by
|
|
* calling {@link #getFontConfig()} and call this method again with the latest config version.
|
|
*
|
|
* @param request A {@link FontFamilyUpdateRequest} to execute.
|
|
* @param baseVersion A base config version to be updated. You can get the latest config version
|
|
* by {@link FontConfig#getConfigVersion()} via {@link #getFontConfig()}. If
|
|
* the system has a newer config version, the update will fail with
|
|
* {@link #RESULT_ERROR_VERSION_MISMATCH}.
|
|
* @return A 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_FONT_NOT_FOUND
|
|
*/
|
|
@RequiresPermission(Manifest.permission.UPDATE_FONTS) public @ResultCode int updateFontFamily(
|
|
@NonNull FontFamilyUpdateRequest request, @IntRange(from = 0) int baseVersion) {
|
|
List<FontUpdateRequest> requests = new ArrayList<>();
|
|
List<FontFileUpdateRequest> fontFileUpdateRequests = request.getFontFileUpdateRequests();
|
|
for (int i = 0; i < fontFileUpdateRequests.size(); i++) {
|
|
FontFileUpdateRequest fontFile = fontFileUpdateRequests.get(i);
|
|
requests.add(new FontUpdateRequest(fontFile.getParcelFileDescriptor(),
|
|
fontFile.getSignature()));
|
|
}
|
|
List<FontFamilyUpdateRequest.FontFamily> fontFamilies = request.getFontFamilies();
|
|
for (int i = 0; i < fontFamilies.size(); i++) {
|
|
FontFamilyUpdateRequest.FontFamily fontFamily = fontFamilies.get(i);
|
|
requests.add(new FontUpdateRequest(fontFamily.getName(), fontFamily.getFonts()));
|
|
}
|
|
try {
|
|
return mIFontManager.updateFontFamily(requests, baseVersion);
|
|
} catch (RemoteException e) {
|
|
throw e.rethrowFromSystemServer();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Factory method of the FontManager.
|
|
*
|
|
* Do not use this method directly. Use getSystemService(Context.FONT_SERVICE) instead.
|
|
*
|
|
* @return A new instance of FontManager
|
|
* @hide
|
|
*/
|
|
public static FontManager create(@NonNull IFontManager iFontManager) {
|
|
Objects.requireNonNull(iFontManager);
|
|
return new FontManager(iFontManager);
|
|
}
|
|
}
|