ICU-20484 Narrow currency symbol should fall back to short symbol, C and J.

- Includes fixes to tests.
diff --git a/icu4c/source/common/ucurr.cpp b/icu4c/source/common/ucurr.cpp
index 7871601..802eafb 100644
--- a/icu4c/source/common/ucurr.cpp
+++ b/icu4c/source/common/ucurr.cpp
@@ -690,7 +690,13 @@
         key.append("/", ec2);
         key.append(buf, ec2);
         s = ures_getStringByKeyWithFallback(rb.getAlias(), key.data(), len, &ec2);
-    } else {
+        if (ec2 == U_MISSING_RESOURCE_ERROR) {
+            *ec = U_USING_FALLBACK_WARNING;
+            ec2 = U_ZERO_ERROR;
+            choice = UCURR_SYMBOL_NAME;
+        }
+    }
+    if (s == NULL) {
         ures_getByKey(rb.getAlias(), CURRENCIES, rb.getAlias(), &ec2);
         ures_getByKeyWithFallback(rb.getAlias(), buf, rb.getAlias(), &ec2);
         s = ures_getStringByIndex(rb.getAlias(), choice, len, &ec2);
diff --git a/icu4c/source/test/intltest/numbertest_api.cpp b/icu4c/source/test/intltest/numbertest_api.cpp
index 2d925ee..f27292f 100644
--- a/icu4c/source/test/intltest/numbertest_api.cpp
+++ b/icu4c/source/test/intltest/numbertest_api.cpp
@@ -779,7 +779,7 @@
             NumberFormatter::with().unit(PTE).unitWidth(UNUM_UNIT_WIDTH_NARROW),
             Locale("pt-PT"),
             444444.55,
-            u"444,444$55 PTE");
+            u"444,444$55 \u200B");
 
     assertFormatSingle(
             u"Currency-dependent symbols (Test ISO Code)",
diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp
index 26ae404..4625b13 100644
--- a/icu4c/source/test/intltest/numfmtst.cpp
+++ b/icu4c/source/test/intltest/numfmtst.cpp
@@ -123,6 +123,7 @@
   TESTCASE_AUTO(TestCases);
 
   TESTCASE_AUTO(TestCurrencyNames);
+  TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
   TESTCASE_AUTO(TestCurrencyAmount);
   TESTCASE_AUTO(TestCurrencyUnit);
   TESTCASE_AUTO(TestCoverage);
@@ -2097,6 +2098,50 @@
     // TODO add more tests later
 }
 
+void NumberFormatTest::Test20484_NarrowSymbolFallback(){
+    IcuTestErrorCode status(*this, "Test20484_NarrowSymbolFallback");
+
+    struct TestCase {
+        const char* locale;
+        const char16_t* isoCode;
+        const char16_t* expectedShort;
+        const char16_t* expectedNarrow;
+        UErrorCode expectedNarrowError;
+    } cases[] = {
+        {"en-US", u"CAD", u"CA$", u"$", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
+        {"en-US", u"CDF", u"CDF", u"CDF", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
+        {"sw-CD", u"CDF", u"FC", u"FC", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
+        {"en-US", u"GEL", u"GEL", u"₾", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
+        {"ka-GE", u"GEL", u"₾", u"₾", U_USING_FALLBACK_WARNING}, // narrow: fallback to ka
+        {"ka", u"GEL", u"₾", u"₾", U_ZERO_ERROR}, // no fallback on narrow
+    };
+    for (const auto& cas : cases) {
+        status.setScope(cas.isoCode);
+        UBool choiceFormatIgnored;
+        int32_t lengthIgnored;
+        const UChar* actualShort = ucurr_getName(
+            cas.isoCode,
+            cas.locale,
+            UCURR_SYMBOL_NAME,
+            &choiceFormatIgnored,
+            &lengthIgnored,
+            status);
+        status.errIfFailureAndReset();
+        const UChar* actualNarrow = ucurr_getName(
+            cas.isoCode,
+            cas.locale,
+            UCURR_NARROW_SYMBOL_NAME,
+            &choiceFormatIgnored,
+            &lengthIgnored,
+            status);
+        status.expectErrorAndReset(cas.expectedNarrowError);
+        assertEquals(UnicodeString("Short symbol: ") + cas.locale + u": " + cas.isoCode,
+                cas.expectedShort, actualShort);
+        assertEquals(UnicodeString("Narrow symbol: ") + cas.locale + ": " + cas.isoCode,
+                cas.expectedNarrow, actualNarrow);
+    }
+}
+
 void NumberFormatTest::TestCurrencyUnit(void){
     UErrorCode ec = U_ZERO_ERROR;
     static const UChar USD[]  = u"USD";
diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h
index 0451067..b62cde5 100644
--- a/icu4c/source/test/intltest/numfmtst.h
+++ b/icu4c/source/test/intltest/numfmtst.h
@@ -153,6 +153,8 @@
 
     void TestCurrencyNames(void);
 
+    void Test20484_NarrowSymbolFallback(void);
+
     void TestCurrencyAmount(void);
 
     void TestCurrencyUnit(void);
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/CurrencyDisplayNames.java b/icu4j/main/classes/core/src/com/ibm/icu/text/CurrencyDisplayNames.java
index 9bdd00d..21297aa 100644
--- a/icu4j/main/classes/core/src/com/ibm/icu/text/CurrencyDisplayNames.java
+++ b/icu4j/main/classes/core/src/com/ibm/icu/text/CurrencyDisplayNames.java
@@ -122,8 +122,8 @@
 
     /**
      * Returns the narrow symbol for the currency with the provided ISO code.
-     * If there is no data for narrow symbol, substitutes isoCode, or returns
-     * null if noSubstitute was set in the factory method.
+     * If there is no data for narrow symbol, substitutes the default symbol,
+     * or returns null if noSubstitute was set in the factory method.
      *
      * @param isoCode the three-letter ISO code.
      * @return the narrow symbol.
diff --git a/icu4j/main/classes/currdata/src/com/ibm/icu/impl/ICUCurrencyDisplayInfoProvider.java b/icu4j/main/classes/currdata/src/com/ibm/icu/impl/ICUCurrencyDisplayInfoProvider.java
index b0fe8de..9fb70c5 100644
--- a/icu4j/main/classes/currdata/src/com/ibm/icu/impl/ICUCurrencyDisplayInfoProvider.java
+++ b/icu4j/main/classes/currdata/src/com/ibm/icu/impl/ICUCurrencyDisplayInfoProvider.java
@@ -95,7 +95,7 @@
         /**
          * Cache for symbolMap() and nameMap().
          */
-        private volatile SoftReference<ParsingData> parsingDataCache = new SoftReference<ParsingData>(null);
+        private volatile SoftReference<ParsingData> parsingDataCache = new SoftReference<>(null);
 
         /**
          * Cache for getUnitPatterns().
@@ -124,8 +124,8 @@
         }
 
         static class ParsingData {
-            Map<String, String> symbolToIsoCode = new HashMap<String, String>();
-            Map<String, String> nameToIsoCode = new HashMap<String, String>();
+            Map<String, String> symbolToIsoCode = new HashMap<>();
+            Map<String, String> nameToIsoCode = new HashMap<>();
         }
 
         ////////////////////////
@@ -170,9 +170,8 @@
             NarrowSymbol narrowSymbol = fetchNarrowSymbol(isoCode);
 
             // Fall back to ISO Code
-            // TODO: Should this fall back to the regular symbol instead of the ISO code?
             if (narrowSymbol.narrowSymbol == null && fallback) {
-                return isoCode;
+                return getSymbol(isoCode);
             }
             return narrowSymbol.narrowSymbol;
         }
@@ -289,7 +288,7 @@
                 CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.TOP);
                 sink.parsingData = result;
                 rb.getAllItemsWithFallback("", sink);
-                parsingDataCache = new SoftReference<ParsingData>(result);
+                parsingDataCache = new SoftReference<>(result);
             }
             return result;
         }
@@ -297,7 +296,7 @@
         Map<String, String> fetchUnitPatterns() {
             Map<String, String> result = unitPatternsCache;
             if (result == null) {
-                result = new HashMap<String, String>();
+                result = new HashMap<>();
                 CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_UNIT_PATTERNS);
                 sink.unitPatterns = result;
                 rb.getAllItemsWithFallback("CurrencyUnitPatterns", sink);
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
index 69f3e6b..3d655af 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
@@ -741,7 +741,7 @@
                 NumberFormatter.with().unit(PTE).unitWidth(UnitWidth.NARROW),
                 ULocale.forLanguageTag("pt-PT"),
                 444444.55,
-                "444,444$55 PTE");
+                "444,444$55 \u200B");
 
         assertFormatSingle(
                 "Currency-dependent symbols (Test)",
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
index 0e8de68..7c8a3cc 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/CurrencyTest.java
@@ -239,6 +239,30 @@
     }
 
     @Test
+    public void test20484_NarrowSymbolFallback() {
+        Object[][] cases = new Object[][] {
+            {"en-US", "CAD", "CA$", "$"},
+            {"en-US", "CDF", "CDF", "CDF"},
+            {"sw-CD", "CDF", "FC", "FC"},
+            {"en-US", "GEL", "GEL", "₾"},
+            {"ka-GE", "GEL", "₾", "₾"},
+            {"ka", "GEL", "₾", "₾"},
+        };
+        for (Object[] cas : cases) {
+            ULocale locale = new ULocale((String) cas[0]);
+            String isoCode = (String) cas[1];
+            String expectedShort = (String) cas[2];
+            String expectedNarrow = (String) cas[3];
+
+            CurrencyDisplayNames cdn = CurrencyDisplayNames.getInstance(locale);
+            assertEquals("Short symbol: " + locale + ": " + isoCode,
+                    expectedShort, cdn.getSymbol(isoCode));
+            assertEquals("Narrow symbol: " + locale + ": " + isoCode,
+                    expectedNarrow, cdn.getNarrowSymbol(isoCode));
+        }
+    }
+
+    @Test
     public void testGetName_Locale_Int_String_BooleanArray() {
         Currency currency = Currency.getInstance(ULocale.CHINA);
         boolean[] isChoiceFormat = new boolean[1];