netwerk/wifi/nsWifiMonitor.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsCOMPtr.h"
     6 #include "nsProxyRelease.h"
     7 #include "nsComponentManagerUtils.h"
     8 #include "nsServiceManagerUtils.h"
     9 #include "nsThreadUtils.h"
    10 #include "nsXPCOM.h"
    11 #include "nsXPCOMCID.h"
    12 #include "nsIObserver.h"
    13 #include "nsIObserverService.h"
    14 #include "nsWifiMonitor.h"
    15 #include "nsWifiAccessPoint.h"
    17 #include "nsServiceManagerUtils.h"
    18 #include "nsComponentManagerUtils.h"
    19 #include "mozilla/Services.h"
    21 using namespace mozilla;
    23 #if defined(PR_LOGGING)
    24 PRLogModuleInfo *gWifiMonitorLog;
    25 #endif
    27 NS_IMPL_ISUPPORTS(nsWifiMonitor,
    28                   nsIRunnable,
    29                   nsIObserver,
    30                   nsIWifiMonitor)
    32 nsWifiMonitor::nsWifiMonitor()
    33 : mKeepGoing(true)
    34 , mReentrantMonitor("nsWifiMonitor.mReentrantMonitor")
    35 {
    36 #if defined(PR_LOGGING)
    37   gWifiMonitorLog = PR_NewLogModule("WifiMonitor");
    38 #endif
    40   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
    41   if (obsSvc)
    42     obsSvc->AddObserver(this, "xpcom-shutdown", false);
    44   LOG(("@@@@@ wifimonitor created\n"));
    45 }
    47 nsWifiMonitor::~nsWifiMonitor()
    48 {
    49 }
    51 NS_IMETHODIMP
    52 nsWifiMonitor::Observe(nsISupports *subject, const char *topic,
    53                      const char16_t *data)
    54 {
    55   if (!strcmp(topic, "xpcom-shutdown")) {
    56     LOG(("Shutting down\n"));
    57     mKeepGoing = false;
    59     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    60     mon.Notify();
    61   }
    62   return NS_OK;
    63 }
    66 NS_IMETHODIMP nsWifiMonitor::StartWatching(nsIWifiListener *aListener)
    67 {
    68   if (!aListener)
    69     return NS_ERROR_NULL_POINTER;
    71   nsresult rv = NS_OK;
    72   if (!mThread) {
    73     rv = NS_NewThread(getter_AddRefs(mThread), this);
    74     if (NS_FAILED(rv))
    75       return rv;
    76   }
    78   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    80   mKeepGoing = true;
    82   mListeners.AppendElement(nsWifiListener(new nsMainThreadPtrHolder<nsIWifiListener>(aListener)));
    84   // tell ourselves that we have a new watcher.
    85   mon.Notify();
    86   return NS_OK;
    87 }
    89 NS_IMETHODIMP nsWifiMonitor::StopWatching(nsIWifiListener *aListener)
    90 {
    91   if (!aListener)
    92     return NS_ERROR_NULL_POINTER;
    94   LOG(("removing listener\n"));
    96   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    98   for (uint32_t i = 0; i < mListeners.Length(); i++) {
   100     if (mListeners[i].mListener == aListener) {
   101       mListeners.RemoveElementAt(i);
   102       break;
   103     }
   104   }
   106   if (mListeners.Length() == 0) {
   107     mKeepGoing = false;
   108     mon.Notify();
   109     mThread = nullptr;
   110   }
   112   return NS_OK;
   113 }
   115 typedef nsTArray<nsMainThreadPtrHandle<nsIWifiListener> > WifiListenerArray;
   117 class nsPassErrorToWifiListeners MOZ_FINAL : public nsIRunnable
   118 {
   119  public:
   120   NS_DECL_THREADSAFE_ISUPPORTS
   121   NS_DECL_NSIRUNNABLE
   123   nsPassErrorToWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
   124                              nsresult aResult)
   125   : mListeners(aListeners),
   126     mResult(aResult)
   127   {}
   129  private:
   130   nsAutoPtr<WifiListenerArray> mListeners;
   131   nsresult mResult;
   132 };
   134 NS_IMPL_ISUPPORTS(nsPassErrorToWifiListeners,
   135                   nsIRunnable)
   137 NS_IMETHODIMP nsPassErrorToWifiListeners::Run()
   138 {
   139   LOG(("About to send error to the wifi listeners\n"));
   140   for (size_t i = 0; i < mListeners->Length(); i++) {
   141     (*mListeners)[i]->OnError(mResult);
   142   }
   143   return NS_OK;
   144 }
   146 NS_IMETHODIMP nsWifiMonitor::Run()
   147 {
   148   LOG(("@@@@@ wifi monitor run called\n"));
   150   PR_SetCurrentThreadName("Wifi Monitor");
   152   nsresult rv = DoScan();
   154   if (mKeepGoing && NS_FAILED(rv)) {
   155     nsAutoPtr<WifiListenerArray> currentListeners(
   156                            new WifiListenerArray(mListeners.Length()));
   157     if (!currentListeners)
   158       return NS_ERROR_OUT_OF_MEMORY;
   160     for (uint32_t i = 0; i < mListeners.Length(); i++)
   161       currentListeners->AppendElement(mListeners[i].mListener);
   163     nsCOMPtr<nsIThread> thread = do_GetMainThread();
   164     if (!thread)
   165       return NS_ERROR_UNEXPECTED;
   167     nsCOMPtr<nsIRunnable> runnable(new nsPassErrorToWifiListeners(currentListeners, rv));
   168     if (!runnable)
   169       return NS_ERROR_OUT_OF_MEMORY;
   171     thread->Dispatch(runnable, NS_DISPATCH_SYNC);
   172   }
   174   return NS_OK;
   175 }
   177 class nsCallWifiListeners MOZ_FINAL : public nsIRunnable
   178 {
   179  public:
   180   NS_DECL_THREADSAFE_ISUPPORTS
   181   NS_DECL_NSIRUNNABLE
   183   nsCallWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
   184                       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > aAccessPoints)
   185   : mListeners(aListeners),
   186     mAccessPoints(aAccessPoints)
   187   {}
   189  private:
   190   nsAutoPtr<WifiListenerArray> mListeners;
   191   nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > mAccessPoints;
   192 };
   194 NS_IMPL_ISUPPORTS(nsCallWifiListeners,
   195                   nsIRunnable)
   197 NS_IMETHODIMP nsCallWifiListeners::Run()
   198 {
   199   LOG(("About to send data to the wifi listeners\n"));
   200   for (size_t i = 0; i < mListeners->Length(); i++) {
   201     (*mListeners)[i]->OnChange(mAccessPoints->Elements(), mAccessPoints->Length());
   202   }
   203   return NS_OK;
   204 }
   206 nsresult
   207 nsWifiMonitor::CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
   208                                  bool aAccessPointsChanged)
   209 {
   210     nsAutoPtr<WifiListenerArray> currentListeners(
   211                            new WifiListenerArray(mListeners.Length()));
   212     if (!currentListeners)
   213       return NS_ERROR_OUT_OF_MEMORY;
   215     {
   216       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   218       for (uint32_t i = 0; i < mListeners.Length(); i++) {
   219         if (!mListeners[i].mHasSentData || aAccessPointsChanged) {
   220           mListeners[i].mHasSentData = true;
   221           currentListeners->AppendElement(mListeners[i].mListener);
   222         }
   223       }
   224     }
   226     if (currentListeners->Length() > 0)
   227     {
   228       uint32_t resultCount = aAccessPoints.Count();
   229       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > accessPoints(
   230                                new nsTArray<nsIWifiAccessPoint *>(resultCount));
   231       if (!accessPoints)
   232         return NS_ERROR_OUT_OF_MEMORY;
   234       for (uint32_t i = 0; i < resultCount; i++)
   235         accessPoints->AppendElement(aAccessPoints[i]);
   237       nsCOMPtr<nsIThread> thread = do_GetMainThread();
   238       if (!thread)
   239         return NS_ERROR_UNEXPECTED;
   241       nsCOMPtr<nsIRunnable> runnable(
   242                       new nsCallWifiListeners(currentListeners, accessPoints));
   243       if (!runnable)
   244         return NS_ERROR_OUT_OF_MEMORY;
   246       thread->Dispatch(runnable, NS_DISPATCH_SYNC);
   247     }
   249     return NS_OK;
   250 }

mercurial