Merge changes If92be663,I377f3409,I7bb22856,I98d484b3,I945f2c7c, ...

* changes:
  gn2bp: Remove unused builtin_deps
  gn2bp: Allow pclmul and ssse3 cflag
  gn2bp: Use list for cflag_allowlist
  gn2bp: Fix to bubble up proto static_lib deps
  gn2bp: Use chromium protoc to generate .c/.h files
  gn2bp: create modules for protoc
  gn2bp: Remove third_party protobuf from local_include_dirs_denylist
  gn2bp: Remove third_party protobuf from builtin_deps
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java
new file mode 100644
index 0000000..fcfe9f7
--- /dev/null
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsAnyRecord.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.connectivity.mdns;
+
+import android.net.DnsResolver;
+
+import java.io.IOException;
+
+/**
+ * A mDNS "ANY" record, used in mDNS questions to query for any record type.
+ */
+public class MdnsAnyRecord extends MdnsRecord {
+
+    protected MdnsAnyRecord(String[] name, MdnsPacketReader reader) throws IOException {
+        super(name, TYPE_ANY, reader, true /* isQuestion */);
+    }
+
+    protected MdnsAnyRecord(String[] name, boolean unicast) {
+        super(name, TYPE_ANY, DnsResolver.CLASS_IN /* cls */,
+                0L /* receiptTimeMillis */, unicast /* cacheFlush */, 0L /* ttlMillis */);
+    }
+
+    @Override
+    protected void readData(MdnsPacketReader reader) throws IOException {
+        // No data to read
+    }
+
+    @Override
+    protected void writeData(MdnsPacketWriter writer) throws IOException {
+        // No data to write
+    }
+}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
index 47ac20e..dd8a526 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsInetAddressRecord.java
@@ -43,7 +43,32 @@
      */
     public MdnsInetAddressRecord(String[] name, int type, MdnsPacketReader reader)
             throws IOException {
-        super(name, type, reader);
+        this(name, type, reader, false);
+    }
+
+    /**
+     * Constructs the {@link MdnsRecord}
+     *
+     * @param name       the service host name
+     * @param type       the type of record (either Type 'AAAA' or Type 'A')
+     * @param reader     the reader to read the record from.
+     * @param isQuestion whether the record is in the question section
+     */
+    public MdnsInetAddressRecord(String[] name, int type, MdnsPacketReader reader,
+            boolean isQuestion)
+            throws IOException {
+        super(name, type, reader, isQuestion);
+    }
+
+    public MdnsInetAddressRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+                    long ttlMillis, InetAddress address) {
+        super(name, address instanceof Inet4Address ? TYPE_A : TYPE_AAAA,
+                MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush, ttlMillis);
+        if (address instanceof Inet4Address) {
+            inet4Address = (Inet4Address) address;
+        } else {
+            inet6Address = (Inet6Address) address;
+        }
     }
 
     /** Returns the IPv6 address. */
@@ -127,4 +152,4 @@
                 && Objects.equals(inet4Address, ((MdnsInetAddressRecord) other).inet4Address)
                 && Objects.equals(inet6Address, ((MdnsInetAddressRecord) other).inet6Address);
     }
-}
\ No newline at end of file
+}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
index 9641a40..2c7b26b 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPointerRecord.java
@@ -29,7 +29,19 @@
     private String[] pointer;
 
     public MdnsPointerRecord(String[] name, MdnsPacketReader reader) throws IOException {
-        super(name, TYPE_PTR, reader);
+        this(name, reader, false);
+    }
+
+    public MdnsPointerRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+            throws IOException {
+        super(name, TYPE_PTR, reader, isQuestion);
+    }
+
+    public MdnsPointerRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+                    long ttlMillis, String[] pointer) {
+        super(name, TYPE_PTR, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+                ttlMillis);
+        this.pointer = pointer;
     }
 
     /** Returns the pointer as an array of labels. */
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
index 35f6da1..c0481a4 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsRecord.java
@@ -39,6 +39,11 @@
     public static final int TYPE_PTR = 0x000C;
     public static final int TYPE_SRV = 0x0021;
     public static final int TYPE_TXT = 0x0010;
+    public static final int TYPE_ANY = 0x00ff;
+
+    private static final int FLAG_CACHE_FLUSH = 0x8000;
+
+    public static final long RECEIPT_TIME_NOT_SENT = 0L;
 
     /** Status indicating that the record is current. */
     public static final int STATUS_OK = 0;
@@ -58,23 +63,52 @@
      * Constructs a new record with the given name and type.
      *
      * @param reader The reader to read the record from.
+     * @param isQuestion Whether the record was included in the questions part of the message.
+     * @throws IOException If an error occurs while reading the packet.
+     */
+    protected MdnsRecord(String[] name, int type, MdnsPacketReader reader, boolean isQuestion)
+            throws IOException {
+        this.name = name;
+        this.type = type;
+        cls = reader.readUInt16();
+        receiptTimeMillis = SystemClock.elapsedRealtime();
+
+        if (isQuestion) {
+            // Questions do not have TTL or data
+            ttlMillis = 0L;
+        } else {
+            ttlMillis = SECONDS.toMillis(reader.readUInt32());
+            int dataLength = reader.readUInt16();
+
+            reader.setLimit(dataLength);
+            readData(reader);
+            reader.clearLimit();
+        }
+    }
+
+    /**
+     * Constructs a new record with the given name and type.
+     *
+     * @param reader The reader to read the record from.
      * @throws IOException If an error occurs while reading the packet.
      */
     // call to readData(com.android.server.connectivity.mdns.MdnsPacketReader) not allowed on given
     // receiver.
     @SuppressWarnings("nullness:method.invocation.invalid")
     protected MdnsRecord(String[] name, int type, MdnsPacketReader reader) throws IOException {
+        this(name, type, reader, false);
+    }
+
+    /**
+     * Constructs a new record with the given properties.
+     */
+    protected MdnsRecord(String[] name, int type, int cls, long receiptTimeMillis,
+            boolean cacheFlush, long ttlMillis) {
         this.name = name;
         this.type = type;
-        cls = reader.readUInt16();
-        ttlMillis = SECONDS.toMillis(reader.readUInt32());
-        int dataLength = reader.readUInt16();
-
-        receiptTimeMillis = SystemClock.elapsedRealtime();
-
-        reader.setLimit(dataLength);
-        readData(reader);
-        reader.clearLimit();
+        this.cls = cls | (cacheFlush ? FLAG_CACHE_FLUSH : 0);
+        this.receiptTimeMillis = receiptTimeMillis;
+        this.ttlMillis = ttlMillis;
     }
 
     /**
@@ -126,13 +160,29 @@
         return type;
     }
 
+    /** Return the record's class. */
+    public final int getRecordClass() {
+        return cls & ~FLAG_CACHE_FLUSH;
+    }
+
+    /** Return whether the cache flush flag is set. */
+    public final boolean getCacheFlush() {
+        return (cls & FLAG_CACHE_FLUSH) != 0;
+    }
+
     /**
      * Returns the record's remaining TTL.
      *
+     * If the record was not sent yet (receipt time {@link #RECEIPT_TIME_NOT_SENT}), this is the
+     * original TTL of the record.
      * @param now The current system time.
      * @return The remaning TTL, in milliseconds.
      */
     public long getRemainingTTL(final long now) {
+        if (receiptTimeMillis == RECEIPT_TIME_NOT_SENT) {
+            return ttlMillis;
+        }
+
         long age = now - receiptTimeMillis;
         if (age > ttlMillis) {
             return 0;
@@ -187,6 +237,9 @@
 
     /** Gets the status of the record. */
     public int getStatus(final long now) {
+        if (receiptTimeMillis == RECEIPT_TIME_NOT_SENT) {
+            return STATUS_OK;
+        }
         final long age = now - receiptTimeMillis;
         if (age > ttlMillis) {
             return STATUS_EXPIRED;
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
index c52d25e..ebd8b77 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceRecord.java
@@ -39,7 +39,23 @@
     private String[] serviceHost;
 
     public MdnsServiceRecord(String[] name, MdnsPacketReader reader) throws IOException {
-        super(name, TYPE_SRV, reader);
+        this(name, reader, false);
+    }
+
+    public MdnsServiceRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+            throws IOException {
+        super(name, TYPE_SRV, reader, isQuestion);
+    }
+
+    public MdnsServiceRecord(String[] name, long receiptTimeMillis, boolean cacheFlush,
+                    long ttlMillis, int servicePriority, int serviceWeight, int servicePort,
+                    String[] serviceHost) {
+        super(name, TYPE_SRV, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+                ttlMillis);
+        this.servicePriority = servicePriority;
+        this.serviceWeight = serviceWeight;
+        this.servicePort = servicePort;
+        this.serviceHost = serviceHost;
     }
 
     /** Returns the service's port number. */
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
index 1e66589..4149dbe 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
@@ -33,7 +33,19 @@
     private List<TextEntry> entries;
 
     public MdnsTextRecord(String[] name, MdnsPacketReader reader) throws IOException {
-        super(name, TYPE_TXT, reader);
+        this(name, reader, false);
+    }
+
+    public MdnsTextRecord(String[] name, MdnsPacketReader reader, boolean isQuestion)
+            throws IOException {
+        super(name, TYPE_TXT, reader, isQuestion);
+    }
+
+    public MdnsTextRecord(String[] name, long receiptTimeMillis, boolean cacheFlush, long ttlMillis,
+            List<TextEntry> entries) {
+        super(name, TYPE_TXT, MdnsConstants.QCLASS_INTERNET, receiptTimeMillis, cacheFlush,
+                ttlMillis);
+        this.entries = entries;
     }
 
     /** Returns the list of strings. */
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
index 9fc4674..9746a35 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
@@ -79,14 +79,7 @@
         Inet4Address addr = record.getInet4Address();
         assertEquals("/10.1.2.3", addr.toString());
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
-
-        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
-        byte[] dataOut = packet.getData();
-
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         assertEquals(dataInText, dataOutText);
@@ -123,14 +116,7 @@
         Inet6Address addr = record.getInet6Address();
         assertEquals("/aabb:ccdd:1122:3344:a0b0:c0d0:1020:3040", addr.toString());
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
-
-        packet = writer.getPacket(MULTICAST_IPV6_ADDRESS);
-        byte[] dataOut = packet.getData();
-
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         assertEquals(dataInText, dataOutText);
@@ -167,14 +153,7 @@
         Inet4Address addr = record.getInet4Address();
         assertEquals("/16.32.48.64", addr.toString());
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
-
-        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
-        byte[] dataOut = packet.getData();
-
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         final byte[] expectedDataIn =
@@ -215,14 +194,7 @@
         assertFalse(record.hasSubtype());
         assertNull(record.getSubtype());
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
-
-        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
-        byte[] dataOut = packet.getData();
-
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         assertEquals(dataInText, dataOutText);
@@ -263,14 +235,35 @@
         assertEquals(1, record.getServicePriority());
         assertEquals(255, record.getServiceWeight());
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
+        String dataOutText = toHex(record);
+        Log.d(TAG, dataOutText);
 
-        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
-        byte[] dataOut = packet.getData();
+        assertEquals(dataInText, dataOutText);
+    }
 
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+    @Test
+    public void testAnyRecord() throws IOException {
+        final byte[] dataIn = HexDump.hexStringToByteArray(
+                "047465737407616E64726F696403636F6D0000FF0001000000000000");
+        assertNotNull(dataIn);
+        String dataInText = HexDump.dumpHexString(dataIn, 0, dataIn.length);
+
+        // Decode
+        DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+        MdnsPacketReader reader = new MdnsPacketReader(packet);
+
+        String[] name = reader.readLabels();
+        assertNotNull(name);
+        assertEquals(3, name.length);
+        String fqdn = MdnsRecord.labelsToString(name);
+        assertEquals("test.android.com", fqdn);
+
+        int type = reader.readUInt16();
+        assertEquals(MdnsRecord.TYPE_ANY, type);
+
+        MdnsAnyRecord record = new MdnsAnyRecord(name, reader);
+
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         assertEquals(dataInText, dataOutText);
@@ -320,19 +313,23 @@
         assertEquals(new TextEntry("b", "1234567890"), entries.get(1));
         assertEquals(new TextEntry("xyz", "!@#$"), entries.get(2));
 
-        // Encode
-        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
-        record.write(writer, record.getReceiptTime());
-
-        packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
-        byte[] dataOut = packet.getData();
-
-        String dataOutText = HexDump.dumpHexString(dataOut, 0, packet.getLength());
+        String dataOutText = toHex(record);
         Log.d(TAG, dataOutText);
 
         assertEquals(dataInText, dataOutText);
     }
 
+    private static String toHex(MdnsRecord record) throws IOException {
+        MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
+        record.write(writer, record.getReceiptTime());
+
+        // The address does not matter as only the data is used
+        final DatagramPacket packet = writer.getPacket(MULTICAST_IPV4_ADDRESS);
+        final byte[] dataOut = packet.getData();
+
+        return HexDump.dumpHexString(dataOut, 0, packet.getLength());
+    }
+
     @Test
     public void textRecord_recordDoesNotHaveDataOfGivenLength_throwsEOFException()
             throws Exception {