Bug 1205237 - Part 3: get self Wi-Fi IP address; r=seanlin
☠☠ backed out by 64ea72607527 ☠ ☠
authorLiang-Heng Chen <xeonchen@mozilla.com>
Tue, 20 Oct 2015 02:32:00 +0200
changeset 303915 b47029d8d4197a07c34ecf03ef1493621875ee8e
parent 303914 2c0b212a28796bc43f7177ec46015b1547ced329
child 303916 9336ec74d12fef26221395196ccb81a028e956e6
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseanlin
bugs1205237
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1205237 - Part 3: get self Wi-Fi IP address; r=seanlin
dom/presentation/PresentationSessionInfo.cpp
dom/presentation/PresentationSessionInfo.h
--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -2,53 +2,145 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/HTMLIFrameElementBinding.h"
 #include "mozilla/dom/TabParent.h"
+#include "mozilla/Function.h"
+#include "mozilla/Logging.h"
+#include "mozilla/Move.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsIDocShell.h"
 #include "nsIFrameLoader.h"
 #include "nsIMutableArray.h"
 #include "nsINetAddr.h"
 #include "nsISocketTransport.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "PresentationService.h"
 #include "PresentationSessionInfo.h"
 
+#ifdef MOZ_WIDGET_ANDROID
+#include "nsIPresentationNetworkHelper.h"
+#endif // MOZ_WIDGET_ANDROID
+
 #ifdef MOZ_WIDGET_GONK
 #include "nsINetworkInterface.h"
 #include "nsINetworkManager.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::services;
 
+inline static PRLogModuleInfo*
+GetPresentationSessionInfoLog()
+{
+  static PRLogModuleInfo* log = PR_NewLogModule("PresentationSessionInfo");
+  return log;
+}
+#undef LOG
+#define LOG(...) MOZ_LOG(GetPresentationSessionInfoLog(), mozilla::LogLevel::Error, (__VA_ARGS__))
+
+
 /*
  * Implementation of PresentationChannelDescription
  */
 
 namespace mozilla {
 namespace dom {
 
+#ifdef MOZ_WIDGET_ANDROID
+
+namespace {
+
+class PresentationNetworkHelper final : public nsIPresentationNetworkHelperListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPRESENTATIONNETWORKHELPERLISTENER
+
+  using Function = nsresult(PresentationControllingInfo::*)(const nsACString&);
+
+  explicit PresentationNetworkHelper(PresentationControllingInfo* aInfo,
+                                     const Function& aFunc);
+
+  nsresult GetWifiIPAddress();
+
+private:
+  ~PresentationNetworkHelper() = default;
+
+  RefPtr<PresentationControllingInfo> mInfo;
+  Function mFunc;
+};
+
+NS_IMPL_ISUPPORTS(PresentationNetworkHelper,
+                  nsIPresentationNetworkHelperListener)
+
+PresentationNetworkHelper::PresentationNetworkHelper(PresentationControllingInfo* aInfo,
+                                                     const Function& aFunc)
+  : mInfo(aInfo)
+  , mFunc(aFunc)
+{
+  MOZ_ASSERT(aInfo);
+  MOZ_ASSERT(aFunc);
+}
+
+nsresult
+PresentationNetworkHelper::GetWifiIPAddress()
+{
+  nsresult rv;
+
+  nsCOMPtr<nsIPresentationNetworkHelper> networkHelper =
+    do_GetService(PRESENTATION_NETWORK_HELPER_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  return networkHelper->GetWifiIPAddress(this);
+}
+
+NS_IMETHODIMP
+PresentationNetworkHelper::OnError(const nsACString & aReason)
+{
+  LOG("PresentationNetworkHelper::OnError: %s",
+    nsPromiseFlatCString(aReason).get());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationNetworkHelper::OnGetWifiIPAddress(const nsACString& aIPAddress)
+{
+  MOZ_ASSERT(mInfo);
+  MOZ_ASSERT(mFunc);
+
+  NS_DispatchToMainThread(
+    NS_NewRunnableMethodWithArg<nsCString>(mInfo,
+                                           mFunc,
+                                           aIPAddress));
+  return NS_OK;
+}
+
+} // anonymous namespace
+
+#endif // MOZ_WIDGET_ANDROID
+
 class PresentationChannelDescription final : public nsIPresentationChannelDescription
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPRESENTATIONCHANNELDESCRIPTION
 
-  PresentationChannelDescription(nsACString& aAddress,
+  PresentationChannelDescription(const nsACString& aAddress,
                                  uint16_t aPort)
     : mAddress(aAddress)
     , mPort(aPort)
   {
   }
 
 private:
   ~PresentationChannelDescription() {}
@@ -382,19 +474,19 @@ PresentationControllingInfo::Shutdown(ns
   // Close the server socket if any.
   if (mServerSocket) {
     NS_WARN_IF(NS_FAILED(mServerSocket->Close()));
     mServerSocket = nullptr;
   }
 }
 
 nsresult
-PresentationControllingInfo::GetAddress(nsACString& aAddress)
+PresentationControllingInfo::GetAddress()
 {
-#ifdef MOZ_WIDGET_GONK
+#if defined(MOZ_WIDGET_GONK)
   nsCOMPtr<nsINetworkManager> networkManager =
     do_GetService("@mozilla.org/network/manager;1");
   if (NS_WARN_IF(!networkManager)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsCOMPtr<nsINetworkInfo> activeNetworkInfo;
   networkManager->GetActiveNetworkInfo(getter_AddRefs(activeNetworkInfo));
@@ -414,28 +506,62 @@ PresentationControllingInfo::GetAddress(
 
   // TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
   // Ultimately we may use all the available addresses. DataChannel appears
   // more robust upon handling ICE. And at the first stage Presentation API is
   // only exposed on Firefox OS where the first IP appears enough for most
   // scenarios.
   nsAutoString ip;
   ip.Assign(ips[0]);
-  aAddress = NS_ConvertUTF16toUTF8(ip);
+
+  // On Android platform, the IP address is retrieved from a callback function.
+  // To make consistent code sequence, following function call is dispatched
+  // into main thread instead of calling it directly.
+  NS_DispatchToMainThread(
+    NS_NewRunnableMethodWithArg<nsCString>(
+      this,
+      &PresentationControllingInfo::OnGetAddress,
+      NS_ConvertUTF16toUTF8(ip)));
 
   NS_Free(prefixes);
   NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, ips);
+
+#elif defined(MOZ_WIDGET_ANDROID)
+  RefPtr<PresentationNetworkHelper> networkHelper =
+    new PresentationNetworkHelper(this,
+                                  &PresentationControllingInfo::OnGetAddress);
+  nsresult rv = networkHelper->GetWifiIPAddress();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
 #else
   // TODO Get host IP via other platforms.
-  aAddress.Truncate();
 #endif
 
   return NS_OK;
 }
 
+nsresult
+PresentationControllingInfo::OnGetAddress(const nsACString& aAddress)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Prepare and send the offer.
+  int32_t port;
+  nsresult rv = mServerSocket->GetPort(&port);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  RefPtr<PresentationChannelDescription> description =
+    new PresentationChannelDescription(aAddress, static_cast<uint16_t>(port));
+  return mControlChannel->SendOffer(description);
+}
+
 // nsIPresentationControlChannelListener
 NS_IMETHODIMP
 PresentationControllingInfo::OnOffer(nsIPresentationChannelDescription* aDescription)
 {
   MOZ_ASSERT(false, "Sender side should not receive offer.");
   return NS_ERROR_FAILURE;
 }
 
@@ -457,32 +583,18 @@ PresentationControllingInfo::OnAnswer(ns
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::NotifyOpened()
 {
-  // Prepare and send the offer.
-  int32_t port;
-  nsresult rv = mServerSocket->GetPort(&port);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCString address;
-  rv = GetAddress(address);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  RefPtr<PresentationChannelDescription> description =
-    new PresentationChannelDescription(address, static_cast<uint16_t>(port));
-  return mControlChannel->SendOffer(description);
+  MOZ_ASSERT(NS_IsMainThread());
+  return GetAddress();
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::NotifyClosed(nsresult aReason)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Unset control channel here so it won't try to re-close it in potential
--- a/dom/presentation/PresentationSessionInfo.h
+++ b/dom/presentation/PresentationSessionInfo.h
@@ -163,17 +163,19 @@ public:
 private:
   ~PresentationControllingInfo()
   {
     Shutdown(NS_OK);
   }
 
   void Shutdown(nsresult aReason) override;
 
-  nsresult GetAddress(nsACString& aAddress);
+  nsresult GetAddress();
+
+  nsresult OnGetAddress(const nsACString& aAddress);
 
   nsCOMPtr<nsIServerSocket> mServerSocket;
 };
 
 // Session info with presenting browsing context (receiver side) behaviors.
 class PresentationPresentingInfo final : public PresentationSessionInfo
                                        , public PromiseNativeHandler
                                        , public nsITimerCallback