Fix empty value problem in the TextEntry

Now, the value in TextEntry would be a zero length byte array if
the text record response doesn't contain the value. The problem
is that the value could either be an empty string ("key="), or
there can be no value ("key"), as per rfc6763 6.4 "If there is
no '=' in a DNS-SD TXT record string, then it is a boolean
attribute, simply identified as being present, with no value.".

Bug: 254166302
Test: atest FramworksNetTests
Change-Id: I4eaa5e593ce9ddaa6b6cb2f069c1aef977910796
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
index f1b2def..9683bc9 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
@@ -270,7 +270,8 @@
     public Map<String, String> getAttributes() {
         Map<String, String> map = new HashMap<>(attributes.size());
         for (Map.Entry<String, byte[]> kv : attributes.entrySet()) {
-            map.put(kv.getKey(), new String(kv.getValue(), UTF_8));
+            final byte[] value = kv.getValue();
+            map.put(kv.getKey(), value == null ? null : new String(value, UTF_8));
         }
         return Collections.unmodifiableMap(map);
     }
@@ -342,7 +343,7 @@
             // 2. If there is no '=' in a DNS-SD TXT record string, then it is a
             // boolean attribute, simply identified as being present, with no value.
             if (delimitPos < 0) {
-                return new TextEntry(new String(textBytes, US_ASCII), "");
+                return new TextEntry(new String(textBytes, US_ASCII), (byte[]) null);
             } else if (delimitPos == 0) {
                 return null;
             }
@@ -353,13 +354,13 @@
 
         /** Creates a new {@link TextEntry} with given key and value of a UTF-8 string. */
         public TextEntry(String key, String value) {
-            this(key, value.getBytes(UTF_8));
+            this(key, value == null ? null : value.getBytes(UTF_8));
         }
 
         /** Creates a new {@link TextEntry} with given key and value of a byte array. */
         public TextEntry(String key, byte[] value) {
             this.key = key;
-            this.value = value.clone();
+            this.value = value == null ? null : value.clone();
         }
 
         private TextEntry(Parcel in) {
@@ -372,17 +373,24 @@
         }
 
         public byte[] getValue() {
-            return value.clone();
+            return value == null ? null : value.clone();
         }
 
         /** Converts this {@link TextEntry} instance to '=' separated byte array. */
         public byte[] toBytes() {
-            return ByteUtils.concat(key.getBytes(US_ASCII), new byte[]{'='}, value);
+            final byte[] keyBytes = key.getBytes(US_ASCII);
+            if (value == null) {
+                return keyBytes;
+            }
+            return ByteUtils.concat(keyBytes, new byte[]{'='}, value);
         }
 
         /** Converts this {@link TextEntry} instance to '=' separated string. */
         @Override
         public String toString() {
+            if (value == null) {
+                return key;
+            }
             return key + "=" + new String(value, UTF_8);
         }
 
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
index d3934c2..ebdb73f 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
@@ -164,7 +164,8 @@
                         List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
                         List.of(
                                 MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
-                                MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max")));
+                                MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max"),
+                                MdnsServiceInfo.TextEntry.fromString("test=")));
 
         beforeParcel.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
@@ -208,11 +209,11 @@
     }
 
     @Test
-    public void textEntry_fromStringWithoutAssignPunc_valueisEmpty() {
+    public void textEntry_fromStringWithoutAssignPunc_noValue() {
         TextEntry entry = TextEntry.fromString("AA");
 
         assertEquals("AA", entry.getKey());
-        assertArrayEquals(new byte[] {}, entry.getValue());
+        assertNull(entry.getValue());
     }
 
     @Test
@@ -241,11 +242,11 @@
     }
 
     @Test
-    public void textEntry_fromBytesWithoutAssignPunc_valueisEmpty() {
+    public void textEntry_fromBytesWithoutAssignPunc_noValue() {
         TextEntry entry = TextEntry.fromBytes(new byte[] {'A', 'A'});
 
         assertEquals("AA", entry.getKey());
-        assertArrayEquals(new byte[] {}, entry.getValue());
+        assertNull(entry.getValue());
     }
 
     @Test
@@ -270,4 +271,12 @@
         assertEquals(new TextEntry("BB", "xxyyzz"), new TextEntry("BB", "xxyyzz"));
         assertEquals(new TextEntry("AA", "XXYYZZ"), new TextEntry("AA", "XXYYZZ"));
     }
+
+    @Test
+    public void textEntry_fromString_valueIsEmpty() {
+        TextEntry entry = TextEntry.fromString("AA=");
+
+        assertEquals("AA", entry.getKey());
+        assertArrayEquals(new byte[] {}, entry.getValue());
+    }
 }