Snap for 11530953 from ad2b1e14e56e382e0f3adce76ca9599aa56d8b64 to mainline-documentsui-release

Change-Id: If9065174c0455d4d383229787ef5dbe6c24e7d07
diff --git a/Android.bp b/Android.bp
index 4aa2138..ae31237 100644
--- a/Android.bp
+++ b/Android.bp
@@ -139,8 +139,9 @@
         // Used for bypassing the macro check. In fact mdnssd is not used because we don't compile
         // the related source files.
         "-DOTBR_ENABLE_MDNS_MDNSSD=1",
-        "-DOTBR_ENABLE_SRP_ADVERTISING_PROXY=0",
+        "-DOTBR_ENABLE_SRP_ADVERTISING_PROXY=1",
         "-DOTBR_ENABLE_DNSSD_DISCOVERY_PROXY=0",
+        "-DOTBR_ENABLE_SRP_SERVER_AUTO_ENABLE_MODE=1",
         "-DOTBR_PACKAGE_NAME=\"OTBR_AGENT\"",
     ],
 
diff --git a/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl b/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
index 11ba51c..17f6295 100644
--- a/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
+++ b/src/android/aidl/com/android/server/thread/openthread/INsdPublisher.aidl
@@ -51,7 +51,8 @@
      * @param port the port number of the service
      * @param txt the entries of the TXT record
      * @param receiver the receiver of the register callback
-     * @param listenerId the listener ID of the 'unregister' opreation
+     * @param listenerId the ID of the NsdManager.RegistrationListener which is used to
+     *                             identify the registration
      */
     void registerService(in @nullable String hostname,
                         in String name,
@@ -63,13 +64,31 @@
                         int listenerId);
 
     /**
+     * Registers an mDNS host.
+     *
+     * <p>The listenerId is an integer ID generated by the caller. It's used by the caller and
+     * the NsdPublisher service to uniquely identify a registration.
+     *
+     * @param name the hostname like "my-host"
+     * @param addresses the IPv6 addresses of the host. Each String represents an address.
+     * @param receiver the receiver of the register callback
+     * @param listenerId the ID of the NsdManager.RegistrationListener which is used to
+     *                             identify the registration
+     */
+    void registerHost(in String name,
+                      in List<String> addresses,
+                      in INsdStatusReceiver receiver,
+                      int listenerId);
+
+    /**
      * Unregisters an mDNS service.
      *
      * <p>To unregister a previously registered service/host/key, the caller must pass in the same
      * listener which was used when registering the service/host/key.
      *
      * @param receiver the receiver of the unregister callback
-     * @param listenerId the listenerId of the 'unregister' operation
+     * @param listenerId the ID of the NsdManager.RegistrationListener which is used to
+     *                             identify the registration
      */
     void unregister(in INsdStatusReceiver receiver, int listenerId);
 }
diff --git a/src/android/mdns_publisher.cpp b/src/android/mdns_publisher.cpp
index 9ed68eb..4bd26ae 100644
--- a/src/android/mdns_publisher.cpp
+++ b/src/android/mdns_publisher.cpp
@@ -26,6 +26,8 @@
  *    POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define OTBR_LOG_TAG "MDNS"
+
 #include "android/mdns_publisher.hpp"
 
 namespace otbr {
@@ -149,7 +151,7 @@
         static_cast<NsdServiceRegistration *>(FindServiceRegistration(aName, aType));
 
     VerifyOrExit(IsStarted(), std::move(aCallback)(OTBR_ERROR_MDNS));
-    if (mNsdPublisher != nullptr)
+    if (mNsdPublisher == nullptr)
     {
         otbrLogWarning("No platform mDNS implementation registered!");
         ExitNow(std::move(aCallback)(OTBR_ERROR_MDNS));
@@ -167,13 +169,45 @@
                                          const AddressList &aAddresses,
                                          ResultCallback   &&aCallback)
 {
-    OTBR_UNUSED_VARIABLE(aName);
-    OTBR_UNUSED_VARIABLE(aAddresses);
-    OTBR_UNUSED_VARIABLE(aCallback);
+    int32_t   listenerId = AllocateListenerId();
+    TxtList   txtList;
+    otbrError error = OTBR_ERROR_NONE;
 
-    DieForNotImplemented(__func__);
+    std::vector<std::string> addressStrings;
 
-    return OTBR_ERROR_MDNS;
+    VerifyOrExit(IsStarted(), error = OTBR_ERROR_MDNS);
+    if (mNsdPublisher == nullptr)
+    {
+        otbrLogWarning("No platform mDNS implementation registered!");
+        ExitNow(error = OTBR_ERROR_MDNS);
+    }
+
+    aCallback = HandleDuplicateHostRegistration(aName, aAddresses, std::move(aCallback));
+    VerifyOrExit(!aCallback.IsNull(), error = OTBR_ERROR_INVALID_STATE);
+
+    AddHostRegistration(
+        MakeUnique<NsdHostRegistration>(aName, aAddresses, /* aCallback= */ nullptr, this, listenerId, mNsdPublisher));
+
+    otbrLogInfo("Publishing host %s listener ID = %d", aName.c_str(), listenerId);
+
+    addressStrings.reserve(aAddresses.size());
+    for (const Ip6Address &address : aAddresses)
+    {
+        addressStrings.push_back(address.ToString());
+    }
+
+    if (aAddresses.size())
+    {
+        mNsdPublisher->registerHost(aName, addressStrings, CreateReceiver(std::move(aCallback)), listenerId);
+    }
+    else
+    {
+        // No addresses to register.
+        std::move(aCallback)(OTBR_ERROR_NONE);
+    }
+
+exit:
+    return error;
 }
 
 otbrError MdnsPublisher::PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback)
@@ -189,11 +223,20 @@
 
 void MdnsPublisher::UnpublishHost(const std::string &aName, ResultCallback &&aCallback)
 {
-    OTBR_UNUSED_VARIABLE(aName);
-    OTBR_UNUSED_VARIABLE(aCallback);
+    NsdHostRegistration *hostRegistration = static_cast<NsdHostRegistration *>(FindHostRegistration(aName));
 
-    DieForNotImplemented(__func__);
+    VerifyOrExit(IsStarted(), std::move(aCallback)(OTBR_ERROR_MDNS));
+    if (mNsdPublisher == nullptr)
+    {
+        otbrLogWarning("No platform mDNS implementation registered!");
+        ExitNow(std::move(aCallback)(OTBR_ERROR_MDNS));
+    }
+    VerifyOrExit(hostRegistration != nullptr, std::move(aCallback)(OTBR_ERROR_NONE));
 
+    hostRegistration->mUnregisterReceiver = CreateReceiver(std::move(aCallback));
+    RemoveHostRegistration(aName, OTBR_ERROR_NONE);
+
+exit:
     return;
 }
 
@@ -280,5 +323,22 @@
     return;
 }
 
+MdnsPublisher::NsdHostRegistration::~NsdHostRegistration(void)
+{
+    VerifyOrExit(mPublisher->IsStarted() && mNsdPublisher != nullptr);
+
+    otbrLogInfo("Unpublishing host %s listener ID = %d", mName.c_str(), mListenerId);
+
+    if (!mUnregisterReceiver)
+    {
+        mUnregisterReceiver = CreateReceiver([](int) {});
+    }
+
+    mNsdPublisher->unregister(mUnregisterReceiver, mListenerId);
+
+exit:
+    return;
+}
+
 } // namespace Android
 } // namespace otbr
diff --git a/src/android/mdns_publisher.hpp b/src/android/mdns_publisher.hpp
index f55b944..a547d4f 100644
--- a/src/android/mdns_publisher.hpp
+++ b/src/android/mdns_publisher.hpp
@@ -56,7 +56,7 @@
     // want to ensure ot-daemon won't do any mDNS operations when Thread is disabled.
     void SetINsdPublisher(std::shared_ptr<INsdPublisher> aINsdPublisher);
 
-    otbrError Start(void) override { return OTBR_ERROR_MDNS; }
+    otbrError Start(void) override { return OTBR_ERROR_NONE; }
 
     void Stop(void) override
     {
@@ -153,6 +153,30 @@
         std::shared_ptr<INsdPublisher> mNsdPublisher;
     };
 
+    class NsdHostRegistration : public HostRegistration
+    {
+    public:
+        NsdHostRegistration(const std::string             &aName,
+                            const AddressList             &aAddresses,
+                            ResultCallback               &&aCallback,
+                            MdnsPublisher                 *aPublisher,
+                            int32_t                        aListenerId,
+                            std::shared_ptr<INsdPublisher> aINsdPublisher)
+            : HostRegistration(aName, aAddresses, std::move(aCallback), aPublisher)
+            , mListenerId(aListenerId)
+            , mNsdPublisher(aINsdPublisher)
+        {
+        }
+
+        ~NsdHostRegistration(void) override;
+
+        const int32_t                      mListenerId;
+        std::shared_ptr<NsdStatusReceiver> mUnregisterReceiver;
+
+    private:
+        std::shared_ptr<INsdPublisher> mNsdPublisher;
+    };
+
     int32_t AllocateListenerId(void);
 
     StateCallback                  mStateCallback;