tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsAndroidNetworkLinkService.cpp (7451B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsAndroidNetworkLinkService.h"
      8 #include "nsServiceManagerUtils.h"
      9 
     10 #include "nsIObserverService.h"
     11 #include "mozilla/StaticPrefs_network.h"
     12 #include "mozilla/IntegerPrintfMacros.h"
     13 #include "mozilla/Services.h"
     14 #include "mozilla/Logging.h"
     15 
     16 #include "AndroidBridge.h"
     17 #include "mozilla/java/GeckoAppShellWrappers.h"
     18 #include "mozilla/jni/Utils.h"
     19 
     20 namespace java = mozilla::java;
     21 namespace jni = mozilla::jni;
     22 
     23 static mozilla::LazyLogModule gNotifyAddrLog("nsAndroidNetworkLinkService");
     24 #define LOG(args) MOZ_LOG(gNotifyAddrLog, mozilla::LogLevel::Debug, args)
     25 
     26 NS_IMPL_ISUPPORTS(nsAndroidNetworkLinkService, nsINetworkLinkService,
     27                  nsIObserver)
     28 
     29 nsAndroidNetworkLinkService::nsAndroidNetworkLinkService()
     30    : mStatusIsKnown(false) {}
     31 
     32 nsresult nsAndroidNetworkLinkService::Init() {
     33  nsCOMPtr<nsIObserverService> observerService =
     34      mozilla::services::GetObserverService();
     35  if (!observerService) {
     36    return NS_ERROR_FAILURE;
     37  }
     38 
     39  nsresult rv;
     40  rv = observerService->AddObserver(this, "xpcom-shutdown-threads", false);
     41  NS_ENSURE_SUCCESS(rv, rv);
     42 
     43  mNetlinkSvc = new mozilla::net::NetlinkService();
     44  rv = mNetlinkSvc->Init(this);
     45  if (NS_FAILED(rv)) {
     46    mNetlinkSvc = nullptr;
     47    LOG(("Cannot initialize NetlinkService [rv=0x%08" PRIx32 "]",
     48         static_cast<uint32_t>(rv)));
     49    return rv;
     50  }
     51  NS_ENSURE_SUCCESS(rv, rv);
     52 
     53  return NS_OK;
     54 }
     55 
     56 nsresult nsAndroidNetworkLinkService::Shutdown() {
     57  // remove xpcom shutdown observer
     58  nsCOMPtr<nsIObserverService> observerService =
     59      mozilla::services::GetObserverService();
     60  if (observerService)
     61    observerService->RemoveObserver(this, "xpcom-shutdown-threads");
     62 
     63  if (mNetlinkSvc) {
     64    mNetlinkSvc->Shutdown();
     65    mNetlinkSvc = nullptr;
     66  }
     67 
     68  return NS_OK;
     69 }
     70 
     71 NS_IMETHODIMP
     72 nsAndroidNetworkLinkService::Observe(nsISupports* subject, const char* topic,
     73                                     const char16_t* data) {
     74  if (!strcmp("xpcom-shutdown-threads", topic)) {
     75    Shutdown();
     76  }
     77 
     78  return NS_OK;
     79 }
     80 
     81 NS_IMETHODIMP
     82 nsAndroidNetworkLinkService::GetIsLinkUp(bool* aIsUp) {
     83  if (mNetlinkSvc && mStatusIsKnown) {
     84    mNetlinkSvc->GetIsLinkUp(aIsUp);
     85    return NS_OK;
     86  }
     87 
     88  if (!mozilla::AndroidBridge::Bridge()) {
     89    // Fail soft here and assume a connection exists
     90    NS_WARNING("GetIsLinkUp is not supported without a bridge connection");
     91    *aIsUp = true;
     92    return NS_OK;
     93  }
     94 
     95  *aIsUp = java::GeckoAppShell::IsNetworkLinkUp();
     96  return NS_OK;
     97 }
     98 
     99 NS_IMETHODIMP
    100 nsAndroidNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown) {
    101  if (mStatusIsKnown) {
    102    *aIsKnown = true;
    103    return NS_OK;
    104  }
    105 
    106  NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_NOT_IMPLEMENTED);
    107 
    108  *aIsKnown = java::GeckoAppShell::IsNetworkLinkKnown();
    109  return NS_OK;
    110 }
    111 
    112 NS_IMETHODIMP
    113 nsAndroidNetworkLinkService::GetLinkType(uint32_t* aLinkType) {
    114  NS_ENSURE_ARG_POINTER(aLinkType);
    115 
    116  if (!mozilla::AndroidBridge::Bridge()) {
    117    // Fail soft here and assume a connection exists
    118    NS_WARNING("GetLinkType is not supported without a bridge connection");
    119    *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
    120    return NS_OK;
    121  }
    122 
    123  *aLinkType = java::GeckoAppShell::GetNetworkLinkType();
    124  return NS_OK;
    125 }
    126 
    127 NS_IMETHODIMP
    128 nsAndroidNetworkLinkService::GetNetworkID(nsACString& aNetworkID) {
    129 #ifdef BASE_BROWSER_VERSION
    130  aNetworkID.Truncate();
    131 #else
    132  if (!mNetlinkSvc) {
    133    return NS_ERROR_NOT_AVAILABLE;
    134  }
    135 
    136  mNetlinkSvc->GetNetworkID(aNetworkID);
    137 #endif
    138  return NS_OK;
    139 }
    140 
    141 NS_IMETHODIMP
    142 nsAndroidNetworkLinkService::GetDnsSuffixList(
    143    nsTArray<nsCString>& aDnsSuffixList) {
    144  aDnsSuffixList.Clear();
    145  if (!jni::IsAvailable()) {
    146    NS_WARNING("GetDnsSuffixList is not supported without JNI");
    147    return NS_ERROR_NOT_AVAILABLE;
    148  }
    149 
    150  jni::String::LocalRef suffixList;
    151  nsresult rv = java::GeckoAppShell::GetDNSDomains(&suffixList);
    152  if (NS_FAILED(rv)) {
    153    return rv;
    154  }
    155 
    156  if (!suffixList || !suffixList->Length()) {
    157    return NS_OK;
    158  }
    159 
    160  nsAutoCString list(suffixList->ToCString());
    161  for (const nsACString& suffix : list.Split(',')) {
    162    aDnsSuffixList.AppendElement(suffix);
    163  }
    164  return NS_OK;
    165 }
    166 
    167 NS_IMETHODIMP
    168 nsAndroidNetworkLinkService::GetResolvers(
    169    nsTArray<RefPtr<nsINetAddr>>& aResolvers) {
    170  return NS_ERROR_NOT_IMPLEMENTED;
    171 }
    172 
    173 NS_IMETHODIMP
    174 nsAndroidNetworkLinkService::GetNativeResolvers(
    175    nsTArray<mozilla::net::NetAddr>& aResolvers) {
    176  return NS_ERROR_NOT_IMPLEMENTED;
    177 }
    178 
    179 NS_IMETHODIMP
    180 nsAndroidNetworkLinkService::GetPlatformDNSIndications(
    181    uint32_t* aPlatformDNSIndications) {
    182  return NS_ERROR_NOT_IMPLEMENTED;
    183 }
    184 
    185 void nsAndroidNetworkLinkService::OnNetworkChanged() {
    186  if (mozilla::StaticPrefs::network_notify_changed()) {
    187    RefPtr<nsAndroidNetworkLinkService> self = this;
    188    NS_DispatchToMainThread(NS_NewRunnableFunction(
    189        "nsAndroidNetworkLinkService::OnNetworkChanged", [self]() {
    190          self->NotifyObservers(NS_NETWORK_LINK_TOPIC,
    191                                NS_NETWORK_LINK_DATA_CHANGED);
    192        }));
    193  }
    194 }
    195 
    196 void nsAndroidNetworkLinkService::OnNetworkIDChanged() {
    197  RefPtr<nsAndroidNetworkLinkService> self = this;
    198  NS_DispatchToMainThread(NS_NewRunnableFunction(
    199      "nsAndroidNetworkLinkService::OnNetworkIDChanged", [self]() {
    200        self->NotifyObservers(NS_NETWORK_ID_CHANGED_TOPIC, nullptr);
    201      }));
    202 }
    203 
    204 void nsAndroidNetworkLinkService::OnLinkUp() {
    205  RefPtr<nsAndroidNetworkLinkService> self = this;
    206  NS_DispatchToMainThread(
    207      NS_NewRunnableFunction("nsAndroidNetworkLinkService::OnLinkUp", [self]() {
    208        self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_UP);
    209      }));
    210 }
    211 
    212 void nsAndroidNetworkLinkService::OnLinkDown() {
    213  RefPtr<nsAndroidNetworkLinkService> self = this;
    214  NS_DispatchToMainThread(NS_NewRunnableFunction(
    215      "nsAndroidNetworkLinkService::OnLinkDown", [self]() {
    216        self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_DOWN);
    217      }));
    218 }
    219 
    220 void nsAndroidNetworkLinkService::OnLinkStatusKnown() { mStatusIsKnown = true; }
    221 
    222 void nsAndroidNetworkLinkService::OnDnsSuffixListUpdated() {
    223  RefPtr<nsAndroidNetworkLinkService> self = this;
    224  NS_DispatchToMainThread(NS_NewRunnableFunction(
    225      "nsAndroidNetworkLinkService::OnDnsSuffixListUpdated", [self]() {
    226        self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr);
    227      }));
    228 }
    229 
    230 /* Sends the given event. Assumes aTopic/aData never goes out of scope (static
    231 * strings are ideal).
    232 */
    233 void nsAndroidNetworkLinkService::NotifyObservers(const char* aTopic,
    234                                                  const char* aData) {
    235  MOZ_ASSERT(NS_IsMainThread());
    236 
    237  LOG(("nsAndroidNetworkLinkService::NotifyObservers: topic:%s data:%s\n",
    238       aTopic, aData ? aData : ""));
    239 
    240  nsCOMPtr<nsIObserverService> observerService =
    241      mozilla::services::GetObserverService();
    242 
    243  if (observerService) {
    244    observerService->NotifyObservers(
    245        static_cast<nsINetworkLinkService*>(this), aTopic,
    246        aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr);
    247  }
    248 }
    249 
    250 // static
    251 bool nsINetworkLinkService::HasNonLocalIPv6Address() {
    252  return mozilla::net::NetlinkService::HasNonLocalIPv6Address();
    253 }