Starting in Android 15, variable fonts are rendered at
runtime with better efficiency and granularity. With this update, vendors must
add new variable font configurations to
font_fallback.xml
instead of fonts.xml
, as fonts.xml
is being deprecated.
See Support for variable fonts for more information.
In Android 11 and lower, updating device-installed font files in AOSP (in the
/system/fonts
partition) or the vendor partitions (in the /product/fonts
or
/system/fonts
partitions) requires a system update from the OEM. This
requirement has a significant impact on emoji compatibility. In
Android 12 you can use the FontManager
system
service to manage installed font files and update device-installed font files
without a system update.
Android 12 features three process interactions;
FontManagerService
, Font Updater
, and Application
.
The FontManagerService
is the central management system in the system server.
FontManagerService
stores the latest per-user system font settings.
The FontUpdater
is a pluggable font updater that’s trusted by a
signature|privileged
permission check. The FontUpdater
communicates with the
FontManagerService
to get, install, remove, or update current system font
settings. The FontUpdater
can pass new font file contents by inter-process
communications (IPC) mechanisms. The FontManagerService
saves the contents to
a world-readable storage location, such as in the /data/fonts
files. This
storage is guarded. It can be written by the FontManagerService
only, by
SELinux policy.
When the Application
class launches, it passes the system font settings as
arguments of the bindApplication
method; then it initializes the font settings
for use by the app process.
Support for variable fonts
Starting in Android 15, variable font configurations are
specified in
font_fallback.xml
using the following format:
<family lang="und-Ethi" supportedAxes="wght,ital">
<font>NotoSansEthiopic-VF.ttf</font>
</family>
In this format, a variable font has all of the attributes of a static font with
an additional supportedAxes
attribute. A supportedAxes
attribute is a
comma-separated list of supported axis tags. With
Android 15, only the wght
and ital
axes can be
specified.
If the supportedAxes
attribute isn't specified, the font
node works as a
static font of a single instance of a variable font specified with axis
children.
If the supportedAxes
attribute is specified, the system dynamically creates a
font instance for the given weight and style value at runtime.
Developers can use the android.graphics.fonts.SystemFonts#getAvailableFonts
Java API or the ASystemFontIterator_open
NDK API to get a list of system-installed font files. For information on
developer APIs that support this update, see
Improved OpenType Variable Font API
and buildVariableFamily
.
Customize fonts
Some OEMs install or replace font files in AOSP to show their brands. Android 12 supports this functionality, but adds requirements to keep emoji fonts updated in devices. OEMs that don’t modify or update emoji font files don't need to use this feature.
Google updates the font files, especially the NotoColorEmoji
files through GMS
Core, so don’t modify or remove the NotoColorEmoji.ttf
file from the
/system
partition, and don't remove it from
/frameworks/base/data/fonts/fonts.xml
.
Note the following three ways that you can customize your fonts:
- Replace the
NotoColorEmoji.ttf
file with an OEM-branded emoji font. - Modify the
NotoColorEmoji.ttf
file for your local market needs. - Replace or modify other font files.
If you aren't modifying emoji fonts in AOSP, you don't need to take action. If you want to customize emoji fonts, use the instructions in the following sections.
Replace NotoColorEmoji.ttf with OEM-branded emoji fonts
To replace the NotoColorEmoji.ttf
file with your OEM-branded emoji fonts file,
put the emoji font just before the font fallback chain:
- Place your own font, called
OEMCustomEmoji.ttf
, in the/system
partition. Modify
/frameworks/base/data/fonts/fonts.xml
(and/frameworks/base/data/fonts/font-fallback.xml
in Android 15 and higher) as in the following code:<family lang="ko"> <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font> </family> <!-- ADD FOLLOWING LINE --> <family lang="und-Zsye"> <font weight="400" style="normal">OEMCustomEmoji.ttf</font> </family> <!-- END OF MODIFICATION --> <family lang="und-Zsye"> <font weight="400" style="normal">NotoColorEmoji.ttf</font> </family> <family lang="und-Zsym"> <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted2.ttf</font> </family>
Modify NotoColorEmoji.ttf for local market needs
Follow these steps to customize for your local market needs:
- Create your own
NotoColorEmoji
file with a different name; for example, name itModified\_NotoColorEmoji.ttf
. - Place it before the original
NotoColorEmoji.ttf
file.
After you perform step 2, the modified glyph supported by
Modified\NotoColorEmoji.ttf
shows instead of the original NotoColorEmoji.ttf
.
Google recommends the following:
- Only have the necessary glyph in this font.
- Delegate unmodified glyphs to the original
NotoColorEmoji.ttf
file so that your devices receive any design fixes made in future emoji releases.
Remove glyphs: To remove glyphs from the NotoColorEmoji.ttf
file, follow
steps 1 and 2, and specify glyph ID = 0
in your cmap.
Use a regional flag: If the target glyph is a regional flag, specify the
glyph ID as an unknown country code. (Use country code = "ZZ"
.)
Make a tofu glyph: You can explicitly specify a tofu glyph ID if you want
to use one. When you specify glyphID = 0
, the related app interprets that as
“glyph is not available”. For example, when you use this attribute, the
Paint#hasGlyph
app returns false
.
Replace or modify other font files
To replace or modify other fonts, the customization is similar to that for modifying the TTF files for local market needs. Unknown font files that are updated in the AOSP at runtime are ignored, and aren't updated. Google ignores unknown fonts in your device. This includes font files that were modified from the original fonts in AOSP.
Although font updates are done by Google in GMS Core, the general font update mechanism is open to all OEMs. OEMs can install additional font updaters using the steps in Meeting prerequisites, Signing font files, and Making runtime font updates.
Meet prerequisites
The font update mechanism uses the fs-verity
Linux kernel feature. Verify that
your device is fs-verity
compliant and include the certificate in your device.
Sign font files
Since font files are risky resources, they must be verified with trusted keys.
Carefully review all font files that are to be updated, and sign with your
private key. The signature must befs-verity
compatible.
Make runtime font updates
The FontManager
system app performs font updates. The FontManager
app
provides the latest installed system font status and the ability to update font
files with signatures. To call update apps, add the
UPDATE_FONT signature|privileged
permission to your
app allowlist,
and to your manifest.
Provide the UPDATE_FONT signature|privileged
permission to your app’s updater
function.