Bug 778235 - Add support for Gonk to NetworkGeolocationProvider.js. r=jdm, a=blocking-basecamp
authorDoug Turner <dougt@dougt.org>
Tue, 09 Oct 2012 18:40:11 -0700
changeset 116044 34a039c14957d4a2a0f87e355df7c754b0c06709
parent 116043 c0b49817915dfc5f65f40f43b83bc55a6d066d1d
child 116045 43dd673647ae47e1dfe9f2bb0be6f7bbcc000345
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm, blocking-basecamp
bugs778235
milestone18.0a2
Bug 778235 - Add support for Gonk to NetworkGeolocationProvider.js. r=jdm, a=blocking-basecamp
configure.in
dom/system/Makefile.in
netwerk/wifi/Makefile.in
netwerk/wifi/nsWifiAccessPoint.h
netwerk/wifi/nsWifiMonitor.h
netwerk/wifi/nsWifiMonitorGonk.cpp
--- a/configure.in
+++ b/configure.in
@@ -4316,17 +4316,21 @@ esac
 
 case "${target}" in
     *-android*|*-linuxandroid*)
         if test "$CPU_ARCH" = "arm" ; then
           USE_ARM_KUSER=1
         fi
 
         NSS_DISABLE_DBM=1
-        NECKO_WIFI=
+        if test -z "$gonkdir"; then
+          NECKO_WIFI=
+        else
+          NECKO_WIFI=1
+        fi
         MOZ_THEME_FASTSTRIPE=1
         MOZ_TREE_FREETYPE=1
         MOZ_MEMORY=1
         MOZ_RAW=1
         ;;
 
 esac
 
--- a/dom/system/Makefile.in
+++ b/dom/system/Makefile.in
@@ -55,16 +55,23 @@ ifneq (Android,$(OS_TARGET))
 EXTRA_COMPONENTS = \
   NetworkGeolocationProvider.js \
   NetworkGeolocationProvider.manifest \
   GPSDGeolocationProvider.js \
   GPSDGeolocationProvider.manifest \
   $(NULL)
 endif
 
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+EXTRA_COMPONENTS = \
+  NetworkGeolocationProvider.js \
+  NetworkGeolocationProvider.manifest \
+  $(NULL)
+endif
+
 EXPORTS_NAMESPACES = mozilla
 
 EXPORTS     = \
   nsDeviceSensors.h \
   $(NULL)
 
 EXPORTS_mozilla = \
   OSFileConstants.h \
--- a/netwerk/wifi/Makefile.in
+++ b/netwerk/wifi/Makefile.in
@@ -23,20 +23,23 @@ FAIL_ON_WARNINGS := 1
 endif
 
 XPIDLSRCS = \
   nsIWifiAccessPoint.idl \
   nsIWifiListener.idl \
   nsIWifiMonitor.idl \
   $(NULL)
 
-CPPSRCS = \
-  nsWifiMonitor.cpp \
-  nsWifiAccessPoint.cpp \
-  $(NULL)
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+CPPSRCS += nsWifiMonitorGonk.cpp
+else
+CPPSRCS += nsWifiMonitor.cpp
+endif
+
+CPPSRCS += nsWifiAccessPoint.cpp
 
 ifeq ($(OS_ARCH),Darwin)
 CPPSRCS += nsWifiScannerMac.cpp
 CMMSRCS = osx_corewlan.mm
 else
 ifneq (,$(filter WINNT,$(OS_ARCH)))
 CPPSRCS += nsWifiScannerWin.cpp
 else
--- a/netwerk/wifi/nsWifiAccessPoint.h
+++ b/netwerk/wifi/nsWifiAccessPoint.h
@@ -26,16 +26,21 @@ public:
   char mSsid[33];
   int  mSsidLen;
 
   void setSignal(int signal)
   {
     mSignal = signal;
   }
 
+  void setMacRaw(const char* aString)
+  {
+    memcpy(mMac, aString, mozilla::ArrayLength(mMac));
+  }
+
   void setMac(const unsigned char mac_as_int[6])
   {
     // mac_as_int is big-endian. Write in byte chunks.
     // Format is XX-XX-XX-XX-XX-XX.
 
     const unsigned char holder[6] = {0};
     if (!mac_as_int) {
       mac_as_int = holder;
@@ -45,16 +50,21 @@ public:
 
     sprintf(mMac, kMacFormatString,
             mac_as_int[0], mac_as_int[1], mac_as_int[2],
             mac_as_int[3], mac_as_int[4], mac_as_int[5]);
 
     mMac[17] = 0;
   }
 
+  void setSSIDRaw(const char* aSSID, unsigned long len) {
+    memcpy(mSsid, aSSID, mozilla::ArrayLength(mSsid));
+    mSsidLen = PR_MIN(len, mozilla::ArrayLength(mSsid));
+  }
+
   void setSSID(const char* aSSID, unsigned long len) {
     if (aSSID && (len < sizeof(mSsid))) {
         strncpy(mSsid, aSSID, len);
         mSsid[len] = 0;
         mSsidLen = len;
     }
     else
     {
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -1,27 +1,29 @@
 /* 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/. */
 
+#ifndef __nsWifiMonitor__
+#define __nsWifiMonitor__
+
 #include "nsIWifiMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIThread.h"
 #include "nsIRunnable.h"
 #include "nsCOMArray.h"
 #include "nsIWifiMonitor.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "prlog.h"
 #include "nsIObserver.h"
 #include "nsTArray.h"
+#include "nsITimer.h"
 #include "mozilla/Attributes.h"
-
-#ifndef __nsWifiMonitor__
-#define __nsWifiMonitor__
+#include "nsIInterfaceRequestor.h"
 
 #if defined(PR_LOGGING)
 extern PRLogModuleInfo *gWifiMonitorLog;
 #endif
 #define LOG(args)     PR_LOG(gWifiMonitorLog, PR_LOG_DEBUG, args)
 
 class nsWifiAccessPoint;
 
@@ -35,16 +37,17 @@ class nsWifiListener
     mHasSentData = false;
   }
   ~nsWifiListener() {}
 
   nsCOMPtr<nsIWifiListener> mListener;
   bool mHasSentData;
 };
 
+#ifndef MOZ_WIDGET_GONK
 class nsWifiMonitor MOZ_FINAL : nsIRunnable, nsIWifiMonitor, nsIObserver
 {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIWIFIMONITOR
   NS_DECL_NSIRUNNABLE
   NS_DECL_NSIOBSERVER
 
@@ -66,10 +69,36 @@ class nsWifiMonitor MOZ_FINAL : nsIRunna
   bool mKeepGoing;
   nsCOMPtr<nsIThread> mThread;
 
   nsTArray<nsWifiListener> mListeners;
 
   mozilla::ReentrantMonitor mReentrantMonitor;
 
 };
+#else
+#include "nsIWifi.h"
+class nsWifiMonitor MOZ_FINAL : nsIWifiMonitor, nsIWifiScanResultsReady, nsIObserver
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIWIFIMONITOR
+  NS_DECL_NSIOBSERVER
+  NS_DECL_NSIWIFISCANRESULTSREADY
+
+  nsWifiMonitor();
+
+ private:
+  ~nsWifiMonitor();
+
+  void ClearTimer() {
+    if (mTimer) {
+      mTimer->Cancel();
+      mTimer = nullptr;
+    }
+  }
+  nsCOMArray<nsWifiAccessPoint> mLastAccessPoints;
+  nsTArray<nsWifiListener> mListeners;
+  nsCOMPtr<nsITimer> mTimer;
+};
+#endif
 
 #endif
new file mode 100644
--- /dev/null
+++ b/netwerk/wifi/nsWifiMonitorGonk.cpp
@@ -0,0 +1,182 @@
+/* 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 "nsCOMPtr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "nsXPCOM.h"
+#include "nsXPCOMCID.h"
+#include "nsIObserver.h"
+#include "nsIObserverService.h"
+#include "nsWifiMonitor.h"
+#include "nsWifiAccessPoint.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "mozilla/Services.h"
+
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+
+using namespace mozilla;
+
+#if defined(PR_LOGGING)
+PRLogModuleInfo *gWifiMonitorLog;
+#endif
+
+NS_IMPL_ISUPPORTS3(nsWifiMonitor,
+                   nsIWifiMonitor,
+                   nsIObserver,
+                   nsIWifiScanResultsReady)
+
+nsWifiMonitor::nsWifiMonitor()
+{
+#if defined(PR_LOGGING)
+  gWifiMonitorLog = PR_NewLogModule("WifiMonitor");
+#endif
+
+  nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
+  if (obsSvc) {
+    obsSvc->AddObserver(this, "xpcom-shutdown", false);
+  }
+  LOG(("@@@@@ wifimonitor created\n"));
+}
+
+nsWifiMonitor::~nsWifiMonitor()
+{
+}
+
+NS_IMETHODIMP
+nsWifiMonitor::StartWatching(nsIWifiListener *aListener)
+{
+  LOG(("@@@@@ nsWifiMonitor::StartWatching\n"));
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  if (!aListener) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  mListeners.AppendElement(nsWifiListener(aListener));
+
+  if (!mTimer) {
+    mTimer = do_CreateInstance("@mozilla.org/timer;1");
+    mTimer->Init(this, 5000, nsITimer::TYPE_REPEATING_SLACK);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWifiMonitor::StopWatching(nsIWifiListener *aListener)
+{
+  LOG(("@@@@@ nsWifiMonitor::StopWatching\n"));
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  if (!aListener) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  for (uint32_t i = 0; i < mListeners.Length(); i++) {
+    if (mListeners[i].mListener == aListener) {
+      mListeners.RemoveElementAt(i);
+      break;
+    }
+  }
+
+  if (mListeners.Length() == 0) {
+    ClearTimer();
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWifiMonitor::Observe(nsISupports *subject, const char *topic,
+                       const PRUnichar *data)
+{
+  if (!strcmp(topic, "timer-callback")) {
+    LOG(("timer callback\n"));
+
+    nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
+    nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
+    if (!wifi) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    wifi->GetWifiScanResults(this);
+    return NS_OK;
+  }
+
+  if (!strcmp(topic, "xpcom-shutdown")) {
+    LOG(("Shutting down\n"));
+    ClearTimer();
+    return NS_OK;
+  }
+
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsWifiMonitor::Onready(uint32_t count, nsIWifiScanResult **results)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  LOG(("@@@@@ About to send data to the wifi listeners\n"));
+
+  nsCOMArray<nsWifiAccessPoint> accessPoints;
+
+  for (uint32_t i = 0; i < count; i++) {
+    nsRefPtr<nsWifiAccessPoint> ap = new nsWifiAccessPoint();
+
+    nsString temp;
+    results[i]->GetBssid(temp);
+    //   00:00:00:00:00:00 --> 00-00-00-00-00-00
+    for (int32_t x=0; x<6; x++) {
+      temp.ReplaceSubstring(NS_LITERAL_STRING(":"), NS_LITERAL_STRING("-")); // would it be too much to ask for a ReplaceAll()?
+    }
+
+    nsCString mac;
+    mac.AssignWithConversion(temp);
+
+    results[i]->GetSsid(temp);
+
+    nsCString ssid;
+    ssid.AssignWithConversion(temp);
+
+    uint32_t signal;
+    results[i]->GetSignalStrength(&signal);
+
+    ap->setSignal(signal);
+    ap->setMacRaw(mac.get());
+    ap->setSSIDRaw(ssid.get(), ssid.Length());
+
+    accessPoints.AppendObject(ap);
+  }
+
+  bool accessPointsChanged = !AccessPointsEqual(accessPoints, mLastAccessPoints);
+  ReplaceArray(mLastAccessPoints, accessPoints);
+
+  nsTArray<nsIWifiAccessPoint*> ac;
+  uint32_t resultCount = accessPoints.Count();
+  for (uint32_t i = 0; i < resultCount; i++) {
+    ac.AppendElement(accessPoints[i]);
+  }
+
+  for (uint32_t i = 0; i < mListeners.Length(); i++) {
+    if (!mListeners[i].mHasSentData || accessPointsChanged) {
+      mListeners[i].mHasSentData = true;
+      mListeners[i].mListener->OnChange(ac.Elements(), ac.Length());
+    }
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsWifiMonitor::Onfailure()
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  LOG(("@@@@@ About to send error to the wifi listeners\n"));
+  for (uint32_t i = 0; i < mListeners.Length(); i++) {
+    mListeners[i].mListener->OnError(NS_ERROR_UNEXPECTED);
+  }
+
+  ClearTimer();
+  return NS_OK;
+}