diff options
Diffstat (limited to 'dom/system/gonk/mozstumbler')
-rw-r--r-- | dom/system/gonk/mozstumbler/MozStumbler.cpp | 426 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/MozStumbler.h | 47 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/StumblerLogging.cpp | 13 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/StumblerLogging.h | 18 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp | 151 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/UploadStumbleRunnable.h | 46 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp | 321 | ||||
-rw-r--r-- | dom/system/gonk/mozstumbler/WriteStumbleOnThread.h | 91 |
8 files changed, 0 insertions, 1113 deletions
diff --git a/dom/system/gonk/mozstumbler/MozStumbler.cpp b/dom/system/gonk/mozstumbler/MozStumbler.cpp deleted file mode 100644 index 61e09e705..000000000 --- a/dom/system/gonk/mozstumbler/MozStumbler.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 "MozStumbler.h" -#include "nsDataHashtable.h" -#include "nsGeoPosition.h" -#include "nsNetCID.h" -#include "nsPrintfCString.h" -#include "StumblerLogging.h" -#include "WriteStumbleOnThread.h" -#include "../GeolocationUtil.h" - -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIMobileConnectionInfo.h" -#include "nsIMobileConnectionService.h" -#include "nsIMobileCellInfo.h" -#include "nsIMobileNetworkInfo.h" -#include "nsINetworkInterface.h" -#include "nsIRadioInterfaceLayer.h" - -using namespace mozilla; -using namespace mozilla::dom; - - -NS_IMPL_ISUPPORTS(StumblerInfo, nsICellInfoListCallback, nsIWifiScanResultsReady) - -class RequestCellInfoEvent : public Runnable { -public: - RequestCellInfoEvent(StumblerInfo *callback) - : mRequestCallback(callback) - {} - - NS_IMETHOD Run() override { - MOZ_ASSERT(NS_IsMainThread()); - // Get Cell Info - nsCOMPtr<nsIMobileConnectionService> service = - do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); - - if (!service) { - STUMBLER_ERR("Stumbler-can not get nsIMobileConnectionService \n"); - return NS_OK; - } - nsCOMPtr<nsIMobileConnection> connection; - uint32_t numberOfRilServices = 1, cellInfoNum = 0; - - service->GetNumItems(&numberOfRilServices); - for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) { - service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection)); - if (!connection) { - STUMBLER_ERR("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum); - } else { - cellInfoNum++; - connection->GetCellInfoList(mRequestCallback); - } - } - mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum); - - // Get Wifi AP Info - nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1"); - nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir); - if (!wifi) { - mRequestCallback->SetWifiInfoResponseReceived(); - STUMBLER_ERR("Stumbler-can not get nsIWifi interface\n"); - return NS_OK; - } - wifi->GetWifiScanResults(mRequestCallback); - return NS_OK; - } -private: - RefPtr<StumblerInfo> mRequestCallback; -}; - -void -MozStumble(nsGeoPosition* position) -{ - if (WriteStumbleOnThread::IsFileWaitingForUpload()) { - nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); - MOZ_ASSERT(target); - // Knowing that file is waiting to upload, and no collection will take place, - // just trigger the thread with an empty string. - nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(EmptyCString()); - target->Dispatch(event, NS_DISPATCH_NORMAL); - return; - } - - nsCOMPtr<nsIDOMGeoPositionCoords> coords; - position->GetCoords(getter_AddRefs(coords)); - if (!coords) { - return; - } - - double latitude, longitude; - coords->GetLatitude(&latitude); - coords->GetLongitude(&longitude); - - const double kMinChangeInMeters = 30; - static int64_t lastTime_ms = 0; - static double sLastLat = 0; - static double sLastLon = 0; - double delta = -1.0; - int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms; - - if (0 != sLastLon || 0 != sLastLat) { - delta = CalculateDeltaInMeter(latitude, longitude, sLastLat, sLastLon); - } - STUMBLER_DBG("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n", - longitude, latitude, timediff, delta); - - // Consecutive GPS locations must be 30 meters and 3 seconds apart - if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){ - lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC); - sLastLat = latitude; - sLastLon = longitude; - RefPtr<StumblerInfo> requestCallback = new StumblerInfo(position); - RefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback); - NS_DispatchToMainThread(runnable); - } else { - STUMBLER_DBG("Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n"); - } -} - -void -StumblerInfo::SetWifiInfoResponseReceived() -{ - mIsWifiInfoResponseReceived = true; - - if (mIsWifiInfoResponseReceived && mCellInfoResponsesReceived == mCellInfoResponsesExpected) { - STUMBLER_DBG("Call DumpStumblerInfo from SetWifiInfoResponseReceived\n"); - DumpStumblerInfo(); - } -} - -void -StumblerInfo::SetCellInfoResponsesExpected(uint8_t count) -{ - mCellInfoResponsesExpected = count; - STUMBLER_DBG("SetCellInfoNum (%d)\n", count); - - if (mIsWifiInfoResponseReceived && mCellInfoResponsesReceived == mCellInfoResponsesExpected) { - STUMBLER_DBG("Call DumpStumblerInfo from SetCellInfoResponsesExpected\n"); - DumpStumblerInfo(); - } -} - - -#define TEXT_LAT NS_LITERAL_CSTRING("latitude") -#define TEXT_LON NS_LITERAL_CSTRING("longitude") -#define TEXT_ACC NS_LITERAL_CSTRING("accuracy") -#define TEXT_ALT NS_LITERAL_CSTRING("altitude") -#define TEXT_ALTACC NS_LITERAL_CSTRING("altitudeAccuracy") -#define TEXT_HEAD NS_LITERAL_CSTRING("heading") -#define TEXT_SPD NS_LITERAL_CSTRING("speed") - -nsresult -StumblerInfo::LocationInfoToString(nsACString& aLocDesc) -{ - nsCOMPtr<nsIDOMGeoPositionCoords> coords; - mPosition->GetCoords(getter_AddRefs(coords)); - if (!coords) { - return NS_ERROR_FAILURE; - } - - nsDataHashtable<nsCStringHashKey, double> info; - - double val; - coords->GetLatitude(&val); - info.Put(TEXT_LAT, val); - coords->GetLongitude(&val); - info.Put(TEXT_LON, val); - coords->GetAccuracy(&val); - info.Put(TEXT_ACC, val); - coords->GetAltitude(&val); - info.Put(TEXT_ALT, val); - coords->GetAltitudeAccuracy(&val); - info.Put(TEXT_ALTACC, val); - coords->GetHeading(&val); - info.Put(TEXT_HEAD, val); - coords->GetSpeed(&val); - info.Put(TEXT_SPD, val); - - for (auto it = info.Iter(); !it.Done(); it.Next()) { - const nsACString& key = it.Key(); - val = it.UserData(); - if (!IsNaN(val)) { - aLocDesc += nsPrintfCString("\"%s\":%f,", key.BeginReading(), val); - } - } - - aLocDesc += nsPrintfCString("\"timestamp\":%lld,", PR_Now() / PR_USEC_PER_MSEC).get(); - return NS_OK; -} - -#define TEXT_RADIOTYPE NS_LITERAL_CSTRING("radioType") -#define TEXT_MCC NS_LITERAL_CSTRING("mobileCountryCode") -#define TEXT_MNC NS_LITERAL_CSTRING("mobileNetworkCode") -#define TEXT_LAC NS_LITERAL_CSTRING("locationAreaCode") -#define TEXT_CID NS_LITERAL_CSTRING("cellId") -#define TEXT_PSC NS_LITERAL_CSTRING("psc") -#define TEXT_STRENGTH_ASU NS_LITERAL_CSTRING("asu") -#define TEXT_STRENGTH_DBM NS_LITERAL_CSTRING("signalStrength") -#define TEXT_REGISTERED NS_LITERAL_CSTRING("serving") -#define TEXT_TIMEING_ADVANCE NS_LITERAL_CSTRING("timingAdvance") - -template <class T> void -ExtractCommonNonCDMACellInfoItems(nsCOMPtr<T>& cell, nsDataHashtable<nsCStringHashKey, int32_t>& info) -{ - int32_t mcc, mnc, cid, sig; - - cell->GetMcc(&mcc); - cell->GetMnc(&mnc); - cell->GetCid(&cid); - cell->GetSignalStrength(&sig); - - info.Put(TEXT_MCC, mcc); - info.Put(TEXT_MNC, mnc); - info.Put(TEXT_CID, cid); - info.Put(TEXT_STRENGTH_ASU, sig); -} - -void -StumblerInfo::CellNetworkInfoToString(nsACString& aCellDesc) -{ - aCellDesc += "\"cellTowers\": ["; - - for (uint32_t idx = 0; idx < mCellInfo.Length() ; idx++) { - const char* radioType = 0; - int32_t type; - mCellInfo[idx]->GetType(&type); - bool registered; - mCellInfo[idx]->GetRegistered(®istered); - if (idx) { - aCellDesc += ",{"; - } else { - aCellDesc += "{"; - } - - STUMBLER_DBG("type=%d\n", type); - - nsDataHashtable<nsCStringHashKey, int32_t> info; - info.Put(TEXT_REGISTERED, registered); - - if(type == nsICellInfo::CELL_INFO_TYPE_GSM) { - radioType = "gsm"; - nsCOMPtr<nsIGsmCellInfo> gsmCellInfo = do_QueryInterface(mCellInfo[idx]); - ExtractCommonNonCDMACellInfoItems(gsmCellInfo, info); - int32_t lac; - gsmCellInfo->GetLac(&lac); - info.Put(TEXT_LAC, lac); - } else if (type == nsICellInfo::CELL_INFO_TYPE_WCDMA) { - radioType = "wcdma"; - nsCOMPtr<nsIWcdmaCellInfo> wcdmaCellInfo = do_QueryInterface(mCellInfo[idx]); - ExtractCommonNonCDMACellInfoItems(wcdmaCellInfo, info); - int32_t lac, psc; - wcdmaCellInfo->GetLac(&lac); - wcdmaCellInfo->GetPsc(&psc); - info.Put(TEXT_LAC, lac); - info.Put(TEXT_PSC, psc); - } else if (type == nsICellInfo::CELL_INFO_TYPE_CDMA) { - radioType = "cdma"; - nsCOMPtr<nsICdmaCellInfo> cdmaCellInfo = do_QueryInterface(mCellInfo[idx]); - int32_t mnc, lac, cid, sig; - cdmaCellInfo->GetSystemId(&mnc); - cdmaCellInfo->GetNetworkId(&lac); - cdmaCellInfo->GetBaseStationId(&cid); - info.Put(TEXT_MNC, mnc); - info.Put(TEXT_LAC, lac); - info.Put(TEXT_CID, cid); - - cdmaCellInfo->GetEvdoDbm(&sig); - if (sig < 0 || sig == nsICellInfo::UNKNOWN_VALUE) { - cdmaCellInfo->GetCdmaDbm(&sig); - } - if (sig > -1 && sig != nsICellInfo::UNKNOWN_VALUE) { - sig *= -1; - info.Put(TEXT_STRENGTH_DBM, sig); - } - } else if (type == nsICellInfo::CELL_INFO_TYPE_LTE) { - radioType = "lte"; - nsCOMPtr<nsILteCellInfo> lteCellInfo = do_QueryInterface(mCellInfo[idx]); - ExtractCommonNonCDMACellInfoItems(lteCellInfo, info); - int32_t lac, timingAdvance, pcid, rsrp; - lteCellInfo->GetTac(&lac); - lteCellInfo->GetTimingAdvance(&timingAdvance); - lteCellInfo->GetPcid(&pcid); - lteCellInfo->GetRsrp(&rsrp); - info.Put(TEXT_LAC, lac); - info.Put(TEXT_TIMEING_ADVANCE, timingAdvance); - info.Put(TEXT_PSC, pcid); - if (rsrp != nsICellInfo::UNKNOWN_VALUE) { - info.Put(TEXT_STRENGTH_DBM, rsrp * -1); - } - } - - aCellDesc += nsPrintfCString("\"%s\":\"%s\"", TEXT_RADIOTYPE.get(), radioType); - for (auto it = info.Iter(); !it.Done(); it.Next()) { - const nsACString& key = it.Key(); - int32_t value = it.UserData(); - if (value != nsICellInfo::UNKNOWN_VALUE) { - aCellDesc += nsPrintfCString(",\"%s\":%d", key.BeginReading(), value); - } - } - - aCellDesc += "}"; - } - aCellDesc += "]"; -} - -void -StumblerInfo::DumpStumblerInfo() -{ - if (!mIsWifiInfoResponseReceived || mCellInfoResponsesReceived != mCellInfoResponsesExpected) { - STUMBLER_DBG("CellInfoReceived=%d (Expected=%d), WifiInfoResponseReceived=%d\n", - mCellInfoResponsesReceived, mCellInfoResponsesExpected, mIsWifiInfoResponseReceived); - return; - } - mIsWifiInfoResponseReceived = false; - mCellInfoResponsesReceived = 0; - - nsAutoCString desc; - nsresult rv = LocationInfoToString(desc); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("LocationInfoToString failed, skip this dump"); - return; - } - - CellNetworkInfoToString(desc); - desc += mWifiDesc; - - STUMBLER_DBG("dispatch write event to thread\n"); - nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); - MOZ_ASSERT(target); - - nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(desc); - target->Dispatch(event, NS_DISPATCH_NORMAL); -} - -NS_IMETHODIMP -StumblerInfo::NotifyGetCellInfoList(uint32_t count, nsICellInfo** aCellInfos) -{ - MOZ_ASSERT(NS_IsMainThread()); - STUMBLER_DBG("There are %d cellinfo in the result\n", count); - - for (uint32_t i = 0; i < count; i++) { - mCellInfo.AppendElement(aCellInfos[i]); - } - mCellInfoResponsesReceived++; - DumpStumblerInfo(); - return NS_OK; -} - -NS_IMETHODIMP StumblerInfo::NotifyGetCellInfoListFailed(const nsAString& error) -{ - MOZ_ASSERT(NS_IsMainThread()); - mCellInfoResponsesReceived++; - STUMBLER_ERR("NotifyGetCellInfoListFailedm CellInfoReadyNum=%d, mCellInfoResponsesExpected=%d, mIsWifiInfoResponseReceived=%d", - mCellInfoResponsesReceived, mCellInfoResponsesExpected, mIsWifiInfoResponseReceived); - DumpStumblerInfo(); - return NS_OK; -} - -NS_IMETHODIMP -StumblerInfo::Onready(uint32_t count, nsIWifiScanResult** results) -{ - MOZ_ASSERT(NS_IsMainThread()); - STUMBLER_DBG("There are %d wifiAPinfo in the result\n",count); - - mWifiDesc += ",\"wifiAccessPoints\": ["; - bool firstItem = true; - for (uint32_t i = 0 ; i < count ; i++) { - nsString ssid; - results[i]->GetSsid(ssid); - if (ssid.IsEmpty()) { - STUMBLER_DBG("no ssid, skip this AP\n"); - continue; - } - - if (ssid.Length() >= 6) { - if (StringEndsWith(ssid, NS_LITERAL_STRING("_nomap"))) { - STUMBLER_DBG("end with _nomap. skip this AP(ssid :%s)\n", ssid.get()); - continue; - } - } - - if (firstItem) { - mWifiDesc += "{"; - firstItem = false; - } else { - mWifiDesc += ",{"; - } - - // mac address - nsString bssid; - results[i]->GetBssid(bssid); - // 00:00:00:00:00:00 --> 000000000000 - bssid.StripChars(":"); - mWifiDesc += "\"macAddress\":\""; - mWifiDesc += NS_ConvertUTF16toUTF8(bssid); - - uint32_t signal; - results[i]->GetSignalStrength(&signal); - mWifiDesc += "\",\"signalStrength\":"; - mWifiDesc.AppendInt(signal); - - mWifiDesc += "}"; - } - mWifiDesc += "]"; - - mIsWifiInfoResponseReceived = true; - DumpStumblerInfo(); - return NS_OK; -} - -NS_IMETHODIMP -StumblerInfo::Onfailure() -{ - MOZ_ASSERT(NS_IsMainThread()); - STUMBLER_ERR("GetWifiScanResults Onfailure\n"); - mIsWifiInfoResponseReceived = true; - DumpStumblerInfo(); - return NS_OK; -} - diff --git a/dom/system/gonk/mozstumbler/MozStumbler.h b/dom/system/gonk/mozstumbler/MozStumbler.h deleted file mode 100644 index 41ee4e5e1..000000000 --- a/dom/system/gonk/mozstumbler/MozStumbler.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 mozilla_system_mozstumbler_h__ -#define mozilla_system_mozstumbler_h__ - -#include "nsIDOMEventTarget.h" -#include "nsICellInfo.h" -#include "nsIWifi.h" - -#define STUMBLE_INTERVAL_MS 3000 - -class nsGeoPosition; - -void MozStumble(nsGeoPosition* position); - -class StumblerInfo final : public nsICellInfoListCallback, - public nsIWifiScanResultsReady -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSICELLINFOLISTCALLBACK - NS_DECL_NSIWIFISCANRESULTSREADY - - explicit StumblerInfo(nsGeoPosition* position) - : mPosition(position), mCellInfoResponsesExpected(0), mCellInfoResponsesReceived(0), mIsWifiInfoResponseReceived(0) - {} - void SetWifiInfoResponseReceived(); - void SetCellInfoResponsesExpected(uint8_t count); - -private: - ~StumblerInfo() {} - void DumpStumblerInfo(); - nsresult LocationInfoToString(nsACString& aLocDesc); - void CellNetworkInfoToString(nsACString& aCellDesc); - nsTArray<RefPtr<nsICellInfo>> mCellInfo; - nsCString mWifiDesc; - RefPtr<nsGeoPosition> mPosition; - int mCellInfoResponsesExpected; - int mCellInfoResponsesReceived; - bool mIsWifiInfoResponseReceived; -}; -#endif // mozilla_system_mozstumbler_h__ - diff --git a/dom/system/gonk/mozstumbler/StumblerLogging.cpp b/dom/system/gonk/mozstumbler/StumblerLogging.cpp deleted file mode 100644 index acf23b3b1..000000000 --- a/dom/system/gonk/mozstumbler/StumblerLogging.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 "StumblerLogging.h" - -mozilla::LogModule* GetLog() -{ - static mozilla::LazyLogModule log("mozstumbler"); - return log; -} diff --git a/dom/system/gonk/mozstumbler/StumblerLogging.h b/dom/system/gonk/mozstumbler/StumblerLogging.h deleted file mode 100644 index 038f44f8f..000000000 --- a/dom/system/gonk/mozstumbler/StumblerLogging.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 STUMBLERLOGGING_H -#define STUMBLERLOGGING_H - -#include "mozilla/Logging.h" - -mozilla::LogModule* GetLog(); - -#define STUMBLER_DBG(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Debug, ("STUMBLER - %s: " arg, __func__, ##__VA_ARGS__)) -#define STUMBLER_LOG(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Info, ("STUMBLER - %s: " arg, __func__, ##__VA_ARGS__)) -#define STUMBLER_ERR(arg, ...) MOZ_LOG(GetLog(), mozilla::LogLevel::Error, ("STUMBLER -%s: " arg, __func__, ##__VA_ARGS__)) - -#endif diff --git a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp deleted file mode 100644 index d97aa9712..000000000 --- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 "UploadStumbleRunnable.h" -#include "StumblerLogging.h" -#include "mozilla/dom/Event.h" -#include "nsIInputStream.h" -#include "nsIScriptSecurityManager.h" -#include "nsIURLFormatter.h" -#include "nsIXMLHttpRequest.h" -#include "nsNetUtil.h" -#include "nsVariant.h" - -UploadStumbleRunnable::UploadStumbleRunnable(nsIInputStream* aUploadData) -: mUploadInputStream(aUploadData) -{ -} - -NS_IMETHODIMP -UploadStumbleRunnable::Run() -{ - MOZ_ASSERT(NS_IsMainThread()); - nsresult rv = Upload(); - if (NS_FAILED(rv)) { - WriteStumbleOnThread::UploadEnded(false); - } - return NS_OK; -} - -nsresult -UploadStumbleRunnable::Upload() -{ - nsresult rv; - RefPtr<nsVariant> variant = new nsVariant(); - - rv = variant->SetAsISupports(mUploadInputStream); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIXMLHttpRequest> xhr = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIScriptSecurityManager> secman = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIPrincipal> systemPrincipal; - rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIURLFormatter> formatter = - do_CreateInstance("@mozilla.org/toolkit/URLFormatterService;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsString url; - rv = formatter->FormatURLPref(NS_LITERAL_STRING("geo.stumbler.url"), url); - NS_ENSURE_SUCCESS(rv, rv); - - rv = xhr->Open(NS_LITERAL_CSTRING("POST"), NS_ConvertUTF16toUTF8(url), false, EmptyString(), EmptyString()); - NS_ENSURE_SUCCESS(rv, rv); - - xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("gzip")); - xhr->SetMozBackgroundRequest(true); - // 60s timeout - xhr->SetTimeout(60 * 1000); - - nsCOMPtr<EventTarget> target(do_QueryInterface(xhr)); - RefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr); - - const char* const sEventStrings[] = { - // nsIXMLHttpRequestEventTarget event types - "abort", - "error", - "load", - "timeout" - }; - - for (uint32_t index = 0; index < MOZ_ARRAY_LENGTH(sEventStrings); index++) { - nsAutoString eventType = NS_ConvertASCIItoUTF16(sEventStrings[index]); - rv = target->AddEventListener(eventType, listener, false); - NS_ENSURE_SUCCESS(rv, rv); - } - - rv = xhr->Send(variant); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener) - -UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR) -: mXHR(aXHR) -{ -} - -NS_IMETHODIMP -UploadEventListener::HandleEvent(nsIDOMEvent* aEvent) -{ - nsString type; - if (NS_FAILED(aEvent->GetType(type))) { - STUMBLER_ERR("Failed to get event type"); - WriteStumbleOnThread::UploadEnded(false); - return NS_ERROR_FAILURE; - } - - if (type.EqualsLiteral("load")) { - STUMBLER_DBG("Got load Event\n"); - } else if (type.EqualsLiteral("error") && mXHR) { - STUMBLER_ERR("Upload Error"); - } else { - STUMBLER_DBG("Receive %s Event", NS_ConvertUTF16toUTF8(type).get()); - } - - uint32_t statusCode = 0; - bool doDelete = false; - if (!mXHR) { - return NS_OK; - } - nsresult rv = mXHR->GetStatus(&statusCode); - if (NS_SUCCEEDED(rv)) { - STUMBLER_DBG("statuscode %d \n", statusCode); - } - - if (200 == statusCode || 400 == statusCode) { - doDelete = true; - } - - WriteStumbleOnThread::UploadEnded(doDelete); - nsCOMPtr<EventTarget> target(do_QueryInterface(mXHR)); - - const char* const sEventStrings[] = { - // nsIXMLHttpRequestEventTarget event types - "abort", - "error", - "load", - "timeout" - }; - - for (uint32_t index = 0; index < MOZ_ARRAY_LENGTH(sEventStrings); index++) { - nsAutoString eventType = NS_ConvertASCIItoUTF16(sEventStrings[index]); - rv = target->RemoveEventListener(eventType, this, false); - } - - mXHR = nullptr; - return NS_OK; -} diff --git a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h b/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h deleted file mode 100644 index 462665a86..000000000 --- a/dom/system/gonk/mozstumbler/UploadStumbleRunnable.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 UPLOADSTUMBLERUNNABLE_H -#define UPLOADSTUMBLERUNNABLE_H - -#include "nsIDOMEventListener.h" - -class nsIXMLHttpRequest; -class nsIInputStream; - -/* - This runnable is managed by WriteStumbleOnThread only, see that class - for how this is scheduled. - */ -class UploadStumbleRunnable final : public Runnable -{ -public: - explicit UploadStumbleRunnable(nsIInputStream* aUploadInputStream); - - NS_IMETHOD Run() override; -private: - virtual ~UploadStumbleRunnable() {} - nsCOMPtr<nsIInputStream> mUploadInputStream; - nsresult Upload(); -}; - - -class UploadEventListener : public nsIDOMEventListener -{ -public: - UploadEventListener(nsIXMLHttpRequest* aXHR); - - NS_DECL_ISUPPORTS - NS_DECL_NSIDOMEVENTLISTENER - -protected: - virtual ~UploadEventListener() {} - nsCOMPtr<nsIXMLHttpRequest> mXHR; -}; - -#endif diff --git a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp deleted file mode 100644 index e58e771c4..000000000 --- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 "WriteStumbleOnThread.h" -#include "StumblerLogging.h" -#include "UploadStumbleRunnable.h" -#include "nsDumpUtils.h" -#include "nsGZFileWriter.h" -#include "nsIFileStreams.h" -#include "nsIInputStream.h" -#include "nsPrintfCString.h" - -#define MAXFILESIZE_KB (15 * 1024) -#define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000) -#define MAX_UPLOAD_ATTEMPTS 20 - -mozilla::Atomic<bool> WriteStumbleOnThread::sIsFileWaitingForUpload(false); -mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false); -WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0}; - -#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json.gz") -#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json.gz") -#define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler") - -class DeleteRunnable : public Runnable -{ - public: - DeleteRunnable() {} - - NS_IMETHOD - Run() override - { - nsCOMPtr<nsIFile> tmpFile; - nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, - getter_AddRefs(tmpFile), - OUTPUT_DIR, - nsDumpUtils::CREATE); - if (NS_SUCCEEDED(rv)) { - tmpFile->Remove(true); - } - // critically, this sets this flag to false so writing can happen again - WriteStumbleOnThread::sIsAlreadyRunning = false; - WriteStumbleOnThread::sIsFileWaitingForUpload = false; - return NS_OK; - } - - private: - ~DeleteRunnable() {} -}; - -bool -WriteStumbleOnThread::IsFileWaitingForUpload() -{ - return sIsFileWaitingForUpload; -} - -void -WriteStumbleOnThread::UploadEnded(bool deleteUploadFile) -{ - if (!deleteUploadFile) { - sIsAlreadyRunning = false; - return; - } - - nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); - MOZ_ASSERT(target); - nsCOMPtr<nsIRunnable> event = new DeleteRunnable(); - target->Dispatch(event, NS_DISPATCH_NORMAL); -} - -void -WriteStumbleOnThread::WriteJSON(Partition aPart) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - nsCOMPtr<nsIFile> tmpFile; - nsresult rv; - rv = nsDumpUtils::OpenTempFile(FILENAME_INPROGRESS, getter_AddRefs(tmpFile), - OUTPUT_DIR, nsDumpUtils::CREATE); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("Open a file for stumble failed"); - return; - } - - RefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(nsGZFileWriter::Append); - rv = gzWriter->Init(tmpFile); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("gzWriter init failed"); - return; - } - - /* - The json format is like below. - {items:[ - {item}, - {item}, - {item} - ]} - */ - - // Need to add "]}" after the last item - if (aPart == Partition::End) { - rv = gzWriter->Write("]}"); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("gzWriter Write failed"); - } - - rv = gzWriter->Finish(); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream finish failed"); - } - - nsCOMPtr<nsIFile> targetFile; - nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(targetFile), - OUTPUT_DIR, nsDumpUtils::CREATE); - nsAutoString targetFilename; - rv = targetFile->GetLeafName(targetFilename); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("Get Filename failed"); - return; - } - rv = targetFile->Remove(true); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("Remove File failed"); - return; - } - // Rename tmpfile - rv = tmpFile->MoveTo(/* directory */ nullptr, targetFilename); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("Rename File failed"); - return; - } - return; - } - - // Need to add "{items:[" before the first item - if (aPart == Partition::Begining) { - rv = gzWriter->Write("{\"items\":[{"); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream write begining failed"); - } - } else if (aPart == Partition::Middle) { - rv = gzWriter->Write(",{"); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream write middle failed"); - } - } - rv = gzWriter->Write(mDesc.get()); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream write mDesc failed"); - } - // one item is ended with '}' (e.g. {item}) - rv = gzWriter->Write("}"); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream write end failed"); - } - - rv = gzWriter->Finish(); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("ostream finish failed"); - } - - // check if it is the end of this file - int64_t fileSize = 0; - rv = tmpFile->GetFileSize(&fileSize); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("GetFileSize failed"); - return; - } - if (fileSize >= MAXFILESIZE_KB) { - WriteJSON(Partition::End); - return; - } -} - -WriteStumbleOnThread::Partition -WriteStumbleOnThread::GetWritePosition() -{ - MOZ_ASSERT(!NS_IsMainThread()); - - nsCOMPtr<nsIFile> tmpFile; - nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_INPROGRESS, getter_AddRefs(tmpFile), - OUTPUT_DIR, nsDumpUtils::CREATE); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("Open a file for stumble failed"); - return Partition::Unknown; - } - - int64_t fileSize = 0; - rv = tmpFile->GetFileSize(&fileSize); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("GetFileSize failed"); - return Partition::Unknown; - } - - if (fileSize == 0) { - return Partition::Begining; - } else if (fileSize >= MAXFILESIZE_KB) { - return Partition::End; - } else { - return Partition::Middle; - } -} - -NS_IMETHODIMP -WriteStumbleOnThread::Run() -{ - MOZ_ASSERT(!NS_IsMainThread()); - - bool b = sIsAlreadyRunning.exchange(true); - if (b) { - return NS_OK; - } - - UploadFileStatus status = GetUploadFileStatus(); - - if (UploadFileStatus::NoFile != status) { - if (UploadFileStatus::ExistsAndReadyToUpload == status) { - sIsFileWaitingForUpload = true; - Upload(); - return NS_OK; - } - } else { - Partition partition = GetWritePosition(); - if (partition == Partition::Unknown) { - STUMBLER_ERR("GetWritePosition failed, skip once"); - } else { - WriteJSON(partition); - } - } - - sIsFileWaitingForUpload = false; - sIsAlreadyRunning = false; - return NS_OK; -} - - -/* - If the upload file exists, then check if it is one day old. - • if it is a day old -> ExistsAndReadyToUpload - • if it is less than the current day old -> Exists - • otherwise -> NoFile - - The Exists case means that the upload and the stumbling is rate limited - per-day to the size of the one file. - */ -WriteStumbleOnThread::UploadFileStatus -WriteStumbleOnThread::GetUploadFileStatus() -{ - nsCOMPtr<nsIFile> tmpFile; - nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(tmpFile), - OUTPUT_DIR, nsDumpUtils::CREATE); - int64_t fileSize; - rv = tmpFile->GetFileSize(&fileSize); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("GetFileSize failed"); - return UploadFileStatus::NoFile; - } - if (fileSize <= 0) { - tmpFile->Remove(true); - return UploadFileStatus::NoFile; - } - - PRTime lastModifiedTime; - tmpFile->GetLastModifiedTime(&lastModifiedTime); - if ((PR_Now() / PR_USEC_PER_MSEC) - lastModifiedTime >= ONEDAY_IN_MSEC) { - return UploadFileStatus::ExistsAndReadyToUpload; - } - return UploadFileStatus::Exists; -} - -void -WriteStumbleOnThread::Upload() -{ - MOZ_ASSERT(!NS_IsMainThread()); - - time_t seconds = time(0); - int day = seconds / (60 * 60 * 24); - - if (sUploadFreqGuard.daySinceEpoch < day) { - sUploadFreqGuard.daySinceEpoch = day; - sUploadFreqGuard.attempts = 0; - } - - sUploadFreqGuard.attempts++; - if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) { - STUMBLER_ERR("Too many upload attempts today"); - sIsAlreadyRunning = false; - return; - } - - nsCOMPtr<nsIFile> tmpFile; - nsresult rv = nsDumpUtils::OpenTempFile(FILENAME_COMPLETED, getter_AddRefs(tmpFile), - OUTPUT_DIR, nsDumpUtils::CREATE); - int64_t fileSize; - rv = tmpFile->GetFileSize(&fileSize); - if (NS_WARN_IF(NS_FAILED(rv))) { - STUMBLER_ERR("GetFileSize failed"); - sIsAlreadyRunning = false; - return; - } - - if (fileSize <= 0) { - sIsAlreadyRunning = false; - return; - } - - // prepare json into nsIInputStream - nsCOMPtr<nsIInputStream> inStream; - rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile); - if (NS_FAILED(rv)) { - sIsAlreadyRunning = false; - return; - } - - RefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(inStream); - NS_DispatchToMainThread(uploader); -} diff --git a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h b/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h deleted file mode 100644 index 104cf9bdd..000000000 --- a/dom/system/gonk/mozstumbler/WriteStumbleOnThread.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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 WriteStumbleOnThread_H -#define WriteStumbleOnThread_H - -#include "mozilla/Atomics.h" - -class DeleteRunnable; - -/* - This class is the entry point to stumbling, in that it - receives the location+cell+wifi string and writes it - to disk, or instead, it calls UploadStumbleRunnable - to upload the data. - - Writes will happen until the file is a max size, then stop. - Uploads will happen only when the file is one day old. - The purpose of these decisions is to have very simple rate-limiting - on the writes, as well as the uploads. - - There is only one file active; it is either being used for writing, - or for uploading. If the file is ready for uploading, no further - writes will take place until this file has been uploaded. - This can mean writing might not take place for days until the uploaded - file is processed. This is correct by-design. - - A notable limitation is that the upload is triggered by a location event, - this is used as an arbitrary and simple trigger. In future, there are - better events that can be used, such as detecting network activity. - - This thread is guarded so that only one instance is active (see the - mozilla::Atomics used for this). - */ -class WriteStumbleOnThread : public mozilla::Runnable -{ -public: - explicit WriteStumbleOnThread(const nsCString& aDesc) - : mDesc(aDesc) - {} - - NS_IMETHOD Run() override; - - static void UploadEnded(bool deleteUploadFile); - - // Used externally to determine if cell+wifi scans should happen - // (returns false for that case). - static bool IsFileWaitingForUpload(); - -private: - friend class DeleteRunnable; - - enum class Partition { - Begining, - Middle, - End, - Unknown - }; - - enum class UploadFileStatus { - NoFile, Exists, ExistsAndReadyToUpload - }; - - ~WriteStumbleOnThread() {} - - Partition GetWritePosition(); - UploadFileStatus GetUploadFileStatus(); - void WriteJSON(Partition aPart); - void Upload(); - - nsCString mDesc; - - // Only run one instance of this - static mozilla::Atomic<bool> sIsAlreadyRunning; - - static mozilla::Atomic<bool> sIsFileWaitingForUpload; - - // Limit the upload attempts per day. If the device is rebooted - // this resets the allowed attempts, which is acceptable. - struct UploadFreqGuard { - int attempts; - int daySinceEpoch; - }; - static UploadFreqGuard sUploadFreqGuard; - -}; - -#endif |