Merge "Don't show warnings for fonts not bundled." into lmp-dev
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
index 154851b..a4a3b7d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
@@ -80,6 +80,10 @@
         mText = text;
         mFonts = new ArrayList<Font>(paint.getFonts().size());
         for (FontInfo fontInfo : paint.getFonts()) {
+            if (fontInfo == null) {
+                mFonts.add(null);
+                continue;
+            }
             mFonts.add(fontInfo.mFont);
         }
         mBounds = new RectF();
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index de3307f..bf4e288 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -27,7 +27,11 @@
 import java.awt.FontFormatException;
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
 
@@ -51,6 +55,14 @@
     private static final String FONT_SUFFIX_BOLD = "Bold.ttf";
     private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
 
+    private static final Set<String> MISSING_FONTS =
+            Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
+                    "NotoSansHans-Regular.otf",
+                    "NotoSansHant-Regular.otf",
+                    "NotoSansJP-Regular.otf",
+                    "NotoSansKR-Regular.otf"
+            )));
+
     /**
      * A class associating {@link Font} with its metadata.
      */
@@ -82,6 +94,8 @@
     private FontVariant mVariant;
     // Path of fonts that haven't been created since sFontLoader hasn't been initialized.
     private List<String> mPath = new ArrayList<String>();
+    /** @see #isValid() */
+    private boolean mValid = false;
 
 
     // ---- Public helper class ----
@@ -132,6 +146,16 @@
         return mVariant;
     }
 
+    /**
+     * Returns if the FontFamily should contain any fonts. If this returns true and
+     * {@link #getFont(int)} returns an empty list, it means that an error occurred while loading
+     * the fonts. However, some fonts are deliberately skipped, for example they are not bundled
+     * with the SDK. In such a case, this method returns false.
+     */
+    public boolean isValid() {
+        return mValid;
+    }
+
     /*package*/ static int getFontStyle(String path) {
         int style = Font.PLAIN;
         String fontName = path.substring(path.lastIndexOf('/'));
@@ -201,6 +225,13 @@
     /*package*/ static boolean nAddFont(long nativeFamily, String path) {
         FontFamily_Delegate delegate = getDelegate(nativeFamily);
         if (delegate != null) {
+            // If the font to be added is known to be missing from the SDK, don't try to load it and
+            // mark the FontFamily to be not valid.
+            if (path.startsWith(SYSTEM_FONTS) &&
+                    MISSING_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
+                return delegate.mValid = false;
+            }
+            delegate.mValid = true;
             if (sFontLocation == null) {
                 delegate.mPath.add(path);
                 return true;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 73d67a7..7b07404 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -65,6 +65,8 @@
             new DelegateManager<Paint_Delegate>(Paint_Delegate.class);
 
     // ---- delegate helper data ----
+
+    // This list can contain null elements.
     private List<FontInfo> mFonts;
 
     // ---- delegate data ----
@@ -1171,6 +1173,12 @@
             // and skew info.
             ArrayList<FontInfo> infoList = new ArrayList<FontInfo>(fonts.size());
             for (Font font : fonts) {
+                if (font == null) {
+                    // If the font is null, add null to infoList. When rendering the text, if this
+                    // null is reached, a warning will be logged.
+                    infoList.add(null);
+                    continue;
+                }
                 FontInfo info = new FontInfo();
                 info.mFont = font.deriveFont(mTextSize);
                 if (mTextScaleX != 1.0 || mTextSkewX != 0) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index f044def..72fe61c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -74,6 +74,10 @@
      * Return a list of fonts that match the style and variant. The list is ordered according to
      * preference of fonts.
      *
+     * The list may contain null when the font failed to load. If null is reached when trying to
+     * render with this list of fonts, then a warning should be logged letting the user know that
+     * some font failed to load.
+     *
      * @param variant The variant preferred. Can only be {@link FontVariant#COMPACT} or
      *                {@link FontVariant#ELEGANT}
      */
@@ -83,7 +87,7 @@
         List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
         for (int i = 0; i < mFontFamilies.length; i++) {
             FontFamily_Delegate ffd = mFontFamilies[i];
-            if (ffd != null) {
+            if (ffd != null && ffd.isValid()) {
                 Font font = ffd.getFont(mStyle);
                 if (font != null) {
                     FontVariant ffdVariant = ffd.getVariant();
@@ -107,6 +111,12 @@
                     } else {
                         fonts.add(font2);
                     }
+                } else {
+                    // The FontFamily is valid but doesn't contain any matching font. This means
+                    // that the font failed to load. We add null to the list of fonts. Don't throw
+                    // the warning just yet. If this is a non-english font, we don't want to warn
+                    // users who are trying to render only english text.
+                    fonts.add(null);
                 }
             }
         }