LCOV - code coverage report
Current view: top level - netwerk/wifi - nsWifiMonitor.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 119 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       4             : 
       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"
      16             : 
      17             : #include "nsServiceManagerUtils.h"
      18             : #include "nsComponentManagerUtils.h"
      19             : #include "mozilla/IntegerPrintfMacros.h"
      20             : #include "mozilla/Services.h"
      21             : 
      22             : using namespace mozilla;
      23             : 
      24             : LazyLogModule gWifiMonitorLog("WifiMonitor");
      25             : 
      26           0 : NS_IMPL_ISUPPORTS(nsWifiMonitor,
      27             :                   nsIRunnable,
      28             :                   nsIObserver,
      29             :                   nsIWifiMonitor)
      30             : 
      31           0 : nsWifiMonitor::nsWifiMonitor()
      32             : : mKeepGoing(true)
      33             : , mThreadComplete(false)
      34           0 : , mReentrantMonitor("nsWifiMonitor.mReentrantMonitor")
      35             : {
      36           0 :   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
      37           0 :   if (obsSvc)
      38           0 :     obsSvc->AddObserver(this, "xpcom-shutdown", false);
      39             : 
      40           0 :   LOG(("@@@@@ wifimonitor created\n"));
      41           0 : }
      42             : 
      43           0 : nsWifiMonitor::~nsWifiMonitor()
      44             : {
      45           0 : }
      46             : 
      47             : NS_IMETHODIMP
      48           0 : nsWifiMonitor::Observe(nsISupports *subject, const char *topic,
      49             :                      const char16_t *data)
      50             : {
      51           0 :   if (!strcmp(topic, "xpcom-shutdown")) {
      52           0 :     LOG(("Shutting down\n"));
      53             : 
      54           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      55           0 :     mKeepGoing = false;
      56           0 :     mon.Notify();
      57           0 :     mThread = nullptr;
      58             :   }
      59           0 :   return NS_OK;
      60             : }
      61             : 
      62             : 
      63           0 : NS_IMETHODIMP nsWifiMonitor::StartWatching(nsIWifiListener *aListener)
      64             : {
      65           0 :   LOG(("nsWifiMonitor::StartWatching %p thread %p listener %p\n",
      66             :        this, mThread.get(), aListener));
      67           0 :   MOZ_ASSERT(NS_IsMainThread());
      68             : 
      69           0 :   if (!aListener)
      70           0 :     return NS_ERROR_NULL_POINTER;
      71           0 :   if (!mKeepGoing) {
      72           0 :       return NS_ERROR_NOT_AVAILABLE;
      73             :   }
      74             : 
      75           0 :   nsresult rv = NS_OK;
      76             : 
      77           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      78           0 :   if (mThreadComplete) {
      79             :       // generally there is just one thread for the lifetime of the service,
      80             :       // but if DoScan returns with an error before shutdown (i.e. !mKeepGoing)
      81             :       // then we will respawn the thread.
      82           0 :       LOG(("nsWifiMonitor::StartWatching %p restarting thread\n", this));
      83           0 :       mThreadComplete = false;
      84           0 :       mThread = nullptr;
      85             :   }
      86             : 
      87           0 :   if (!mThread) {
      88           0 :     rv = NS_NewNamedThread("Wifi Monitor", getter_AddRefs(mThread), this);
      89           0 :     if (NS_FAILED(rv))
      90           0 :       return rv;
      91             :   }
      92             : 
      93             : 
      94           0 :   mListeners.AppendElement(
      95           0 :     nsWifiListener(new nsMainThreadPtrHolder<nsIWifiListener>(
      96           0 :       "nsIWifiListener", aListener)));
      97             : 
      98             :   // tell ourselves that we have a new watcher.
      99           0 :   mon.Notify();
     100           0 :   return NS_OK;
     101             : }
     102             : 
     103           0 : NS_IMETHODIMP nsWifiMonitor::StopWatching(nsIWifiListener *aListener)
     104             : {
     105           0 :   LOG(("nsWifiMonitor::StopWatching %p thread %p listener %p\n",
     106             :        this, mThread.get(), aListener));
     107           0 :   MOZ_ASSERT(NS_IsMainThread());
     108             : 
     109           0 :   if (!aListener)
     110           0 :     return NS_ERROR_NULL_POINTER;
     111             : 
     112           0 :   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     113             : 
     114           0 :   for (uint32_t i = 0; i < mListeners.Length(); i++) {
     115             : 
     116           0 :     if (mListeners[i].mListener == aListener) {
     117           0 :       mListeners.RemoveElementAt(i);
     118           0 :       break;
     119             :     }
     120             :   }
     121             : 
     122           0 :   return NS_OK;
     123             : }
     124             : 
     125             : typedef nsTArray<nsMainThreadPtrHandle<nsIWifiListener> > WifiListenerArray;
     126             : 
     127             : class nsPassErrorToWifiListeners final : public nsIRunnable
     128             : {
     129             :  public:
     130             :   NS_DECL_THREADSAFE_ISUPPORTS
     131             :   NS_DECL_NSIRUNNABLE
     132             : 
     133           0 :   nsPassErrorToWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
     134             :                              nsresult aResult)
     135           0 :   : mListeners(aListeners),
     136           0 :     mResult(aResult)
     137           0 :   {}
     138             : 
     139             :  private:
     140           0 :   ~nsPassErrorToWifiListeners() {}
     141             :   nsAutoPtr<WifiListenerArray> mListeners;
     142             :   nsresult mResult;
     143             : };
     144             : 
     145           0 : NS_IMPL_ISUPPORTS(nsPassErrorToWifiListeners,
     146             :                   nsIRunnable)
     147             : 
     148           0 : NS_IMETHODIMP nsPassErrorToWifiListeners::Run()
     149             : {
     150           0 :   LOG(("About to send error to the wifi listeners\n"));
     151           0 :   for (size_t i = 0; i < mListeners->Length(); i++) {
     152           0 :     (*mListeners)[i]->OnError(mResult);
     153             :   }
     154           0 :   return NS_OK;
     155             : }
     156             : 
     157           0 : NS_IMETHODIMP nsWifiMonitor::Run()
     158             : {
     159           0 :   LOG(("@@@@@ wifi monitor run called\n"));
     160             : 
     161           0 :   nsresult rv = DoScan();
     162           0 :   LOG(("@@@@@ wifi monitor run::doscan complete %" PRIx32 "\n", static_cast<uint32_t>(rv)));
     163             : 
     164           0 :   nsAutoPtr<WifiListenerArray> currentListeners;
     165           0 :   bool doError = false;
     166             : 
     167             :   {
     168           0 :       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     169           0 :       if (mKeepGoing && NS_FAILED(rv)) {
     170           0 :           doError = true;
     171           0 :           currentListeners = new WifiListenerArray(mListeners.Length());
     172           0 :           for (uint32_t i = 0; i < mListeners.Length(); i++)
     173           0 :               currentListeners->AppendElement(mListeners[i].mListener);
     174             :       }
     175           0 :       mThreadComplete = true;
     176             :   }
     177             : 
     178           0 :   if (doError) {
     179           0 :     nsCOMPtr<nsIEventTarget> target = GetMainThreadEventTarget();
     180           0 :     if (!target)
     181           0 :       return NS_ERROR_UNEXPECTED;
     182             : 
     183           0 :     nsCOMPtr<nsIRunnable> runnable(new nsPassErrorToWifiListeners(currentListeners, rv));
     184           0 :     if (!runnable)
     185           0 :       return NS_ERROR_OUT_OF_MEMORY;
     186             : 
     187           0 :     target->Dispatch(runnable, NS_DISPATCH_SYNC);
     188             :   }
     189             : 
     190           0 :   LOG(("@@@@@ wifi monitor run complete\n"));
     191           0 :   return NS_OK;
     192             : }
     193             : 
     194             : class nsCallWifiListeners final : public nsIRunnable
     195             : {
     196             :  public:
     197             :   NS_DECL_THREADSAFE_ISUPPORTS
     198             :   NS_DECL_NSIRUNNABLE
     199             : 
     200           0 :   nsCallWifiListeners(nsAutoPtr<WifiListenerArray> aListeners,
     201             :                       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > aAccessPoints)
     202           0 :   : mListeners(aListeners),
     203           0 :     mAccessPoints(aAccessPoints)
     204           0 :   {}
     205             : 
     206             :  private:
     207           0 :   ~nsCallWifiListeners() {}
     208             :   nsAutoPtr<WifiListenerArray> mListeners;
     209             :   nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > mAccessPoints;
     210             : };
     211             : 
     212           0 : NS_IMPL_ISUPPORTS(nsCallWifiListeners,
     213             :                   nsIRunnable)
     214             : 
     215           0 : NS_IMETHODIMP nsCallWifiListeners::Run()
     216             : {
     217           0 :   LOG(("About to send data to the wifi listeners\n"));
     218           0 :   for (size_t i = 0; i < mListeners->Length(); i++) {
     219           0 :     (*mListeners)[i]->OnChange(mAccessPoints->Elements(), mAccessPoints->Length());
     220             :   }
     221           0 :   return NS_OK;
     222             : }
     223             : 
     224             : nsresult
     225           0 : nsWifiMonitor::CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
     226             :                                  bool aAccessPointsChanged)
     227             : {
     228           0 :     nsAutoPtr<WifiListenerArray> currentListeners;
     229             :     {
     230           0 :       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     231             : 
     232           0 :       currentListeners = new WifiListenerArray(mListeners.Length());
     233             : 
     234           0 :       for (uint32_t i = 0; i < mListeners.Length(); i++) {
     235           0 :         if (!mListeners[i].mHasSentData || aAccessPointsChanged) {
     236           0 :           mListeners[i].mHasSentData = true;
     237           0 :           currentListeners->AppendElement(mListeners[i].mListener);
     238             :         }
     239             :       }
     240             :     }
     241             : 
     242           0 :     if (currentListeners->Length() > 0)
     243             :     {
     244           0 :       uint32_t resultCount = aAccessPoints.Count();
     245             :       nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > accessPoints(
     246           0 :                                new nsTArray<nsIWifiAccessPoint *>(resultCount));
     247           0 :       if (!accessPoints)
     248           0 :         return NS_ERROR_OUT_OF_MEMORY;
     249             : 
     250           0 :       for (uint32_t i = 0; i < resultCount; i++)
     251           0 :         accessPoints->AppendElement(aAccessPoints[i]);
     252             : 
     253           0 :       nsCOMPtr<nsIThread> thread = do_GetMainThread();
     254           0 :       if (!thread)
     255           0 :         return NS_ERROR_UNEXPECTED;
     256             : 
     257             :       nsCOMPtr<nsIRunnable> runnable(
     258           0 :                       new nsCallWifiListeners(currentListeners, accessPoints));
     259           0 :       if (!runnable)
     260           0 :         return NS_ERROR_OUT_OF_MEMORY;
     261             : 
     262           0 :       thread->Dispatch(runnable, NS_DISPATCH_SYNC);
     263             :     }
     264             : 
     265           0 :     return NS_OK;
     266             : }

Generated by: LCOV version 1.13