зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1539819 - P2: Introduce PProxyConfigLookup.ipdl for get proxy config in TRRServiceChannel r=dragana
Differential Revision: https://phabricator.services.mozilla.com/D68398
This commit is contained in:
Родитель
bdbecde447
Коммит
2cbb8cd25e
|
@ -0,0 +1,21 @@
|
|||
/* 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 protocol PSocketProcess;
|
||||
|
||||
include NeckoChannelParams;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
async refcounted protocol PProxyConfigLookup
|
||||
{
|
||||
manager PSocketProcess;
|
||||
|
||||
child:
|
||||
async __delete__(ProxyInfoCloneArgs[] aProxyInfo, nsresult aResult);
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -17,6 +17,7 @@ include protocol PBackground;
|
|||
include protocol PAltService;
|
||||
include protocol PAltSvcTransaction;
|
||||
include protocol PTRRService;
|
||||
include protocol PProxyConfigLookup;
|
||||
|
||||
include MemoryReportTypes;
|
||||
include NeckoChannelParams;
|
||||
|
@ -34,6 +35,7 @@ using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
|
|||
using base::ProcessId from "base/process.h";
|
||||
using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
|
||||
using PRTime from "prtime.h";
|
||||
using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -51,6 +53,7 @@ sync protocol PSocketProcess
|
|||
manages PAltService;
|
||||
manages PAltSvcTransaction;
|
||||
manages PTRRService;
|
||||
manages PProxyConfigLookup;
|
||||
|
||||
parent:
|
||||
async InitCrashReporter(NativeThreadId threadId);
|
||||
|
@ -84,6 +87,7 @@ parent:
|
|||
ByteArray? aClientCert,
|
||||
ByteArray[] aCollectedCANames)
|
||||
returns (bool aSucceeded, ByteArray aOutCert, ByteArray aOutKey, ByteArray[] aBuiltChain);
|
||||
async PProxyConfigLookup(nsIURI aUri, uint32_t aFlags);
|
||||
|
||||
child:
|
||||
async PreferenceUpdate(Pref pref);
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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 "ProxyConfigLookup.h"
|
||||
#include "ProxyConfigLookupChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nsIProtocolProxyService.h"
|
||||
#include "nsIProtocolProxyService2.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// static
|
||||
nsresult ProxyConfigLookup::Create(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback, nsIURI* aURI,
|
||||
uint32_t aProxyResolveFlags) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<ProxyConfigLookup> lookUp =
|
||||
new ProxyConfigLookup(std::move(aCallback), aURI, aProxyResolveFlags);
|
||||
return lookUp->DoProxyResolve();
|
||||
}
|
||||
|
||||
ProxyConfigLookup::ProxyConfigLookup(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback, nsIURI* aURI,
|
||||
uint32_t aProxyResolveFlags)
|
||||
: mCallback(std::move(aCallback)),
|
||||
mURI(aURI),
|
||||
mProxyResolveFlags(aProxyResolveFlags) {}
|
||||
|
||||
ProxyConfigLookup::~ProxyConfigLookup() = default;
|
||||
|
||||
nsresult ProxyConfigLookup::DoProxyResolve() {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
RefPtr<ProxyConfigLookup> self = this;
|
||||
bool result = ProxyConfigLookupChild::Create(
|
||||
mURI, mProxyResolveFlags,
|
||||
[self](nsIProxyInfo* aProxyinfo, nsresult aResult) {
|
||||
self->OnProxyAvailable(nullptr, nullptr, aProxyinfo, aResult);
|
||||
});
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel), mURI,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProtocolProxyService> pps =
|
||||
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// using the nsIProtocolProxyService2 allows a minor performance
|
||||
// optimization, but if an add-on has only provided the original interface
|
||||
// then it is ok to use that version.
|
||||
nsCOMPtr<nsICancelable> proxyRequest;
|
||||
nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
|
||||
if (pps2) {
|
||||
rv = pps2->AsyncResolve2(channel, mProxyResolveFlags, this, nullptr,
|
||||
getter_AddRefs(proxyRequest));
|
||||
} else {
|
||||
rv = pps->AsyncResolve(channel, mProxyResolveFlags, this, nullptr,
|
||||
getter_AddRefs(proxyRequest));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ProxyConfigLookup::OnProxyAvailable(nsICancelable* aRequest,
|
||||
nsIChannel* aChannel,
|
||||
nsIProxyInfo* aProxyinfo,
|
||||
nsresult aResult) {
|
||||
mCallback(aProxyinfo, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ProxyConfigLookup, nsIProtocolProxyCallback)
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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_net_ProxyConfigLookup_h
|
||||
#define mozilla_net_ProxyConfigLookup_h
|
||||
|
||||
#include <functional>
|
||||
#include "nsIProtocolProxyCallback.h"
|
||||
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class ProxyConfigLookup final : public nsIProtocolProxyCallback {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLPROXYCALLBACK
|
||||
|
||||
static nsresult Create(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback, nsIURI* aURI,
|
||||
uint32_t aProxyResolveFlags);
|
||||
|
||||
private:
|
||||
explicit ProxyConfigLookup(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback, nsIURI* aURI,
|
||||
uint32_t aProxyResolveFlags);
|
||||
virtual ~ProxyConfigLookup();
|
||||
nsresult DoProxyResolve();
|
||||
|
||||
std::function<void(nsIProxyInfo*, nsresult)> mCallback;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
uint32_t mProxyResolveFlags;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_ProxyConfigLookup_h
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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 "ProxyConfigLookupChild.h"
|
||||
|
||||
#include "mozilla/net/SocketProcessChild.h"
|
||||
#include "nsProxyInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// static
|
||||
bool ProxyConfigLookupChild::Create(
|
||||
nsIURI* aURI, uint32_t aProxyResolveFlags,
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback) {
|
||||
SocketProcessChild* socketChild = SocketProcessChild::GetSingleton();
|
||||
if (!socketChild) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ProxyConfigLookupChild> child =
|
||||
new ProxyConfigLookupChild(std::move(aCallback));
|
||||
return socketChild->SendPProxyConfigLookupConstructor(child, aURI,
|
||||
aProxyResolveFlags);
|
||||
}
|
||||
|
||||
ProxyConfigLookupChild::ProxyConfigLookupChild(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback)
|
||||
: mCallback(std::move(aCallback)) {}
|
||||
|
||||
mozilla::ipc::IPCResult ProxyConfigLookupChild::Recv__delete__(
|
||||
nsTArray<ProxyInfoCloneArgs>&& aProxyInfo, const nsresult& aResult) {
|
||||
nsCOMPtr<nsIProxyInfo> proxyInfo =
|
||||
nsProxyInfo::DeserializeProxyInfo(aProxyInfo);
|
||||
mCallback(proxyInfo, aResult);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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_net_ProxyConfigLookupChild_h
|
||||
#define mozilla_net_ProxyConfigLookupChild_h
|
||||
|
||||
#include "mozilla/net/PProxyConfigLookupChild.h"
|
||||
#include <functional>
|
||||
|
||||
class nsIProxyInfo;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class ProxyConfigLookupChild final : public PProxyConfigLookupChild {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ProxyConfigLookupChild, override)
|
||||
|
||||
static bool Create(nsIURI* aURI, uint32_t aProxyResolveFlags,
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback);
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__(
|
||||
nsTArray<ProxyInfoCloneArgs>&& aProxyInfo, const nsresult& aResult);
|
||||
|
||||
private:
|
||||
explicit ProxyConfigLookupChild(
|
||||
std::function<void(nsIProxyInfo*, nsresult)>&& aCallback);
|
||||
virtual ~ProxyConfigLookupChild() = default;
|
||||
|
||||
std::function<void(nsIProxyInfo*, nsresult)> mCallback;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_ProxyConfigLookupChild_h
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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 "ProxyConfigLookupParent.h"
|
||||
#include "ProxyConfigLookup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsProxyInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
ProxyConfigLookupParent::ProxyConfigLookupParent(nsIURI* aURI,
|
||||
uint32_t aProxyResolveFlags)
|
||||
: mURI(aURI), mProxyResolveFlags(aProxyResolveFlags) {}
|
||||
|
||||
ProxyConfigLookupParent::~ProxyConfigLookupParent() = default;
|
||||
|
||||
void ProxyConfigLookupParent::DoProxyLookup() {
|
||||
RefPtr<ProxyConfigLookupParent> self = this;
|
||||
nsresult rv = ProxyConfigLookup::Create(
|
||||
[self](nsIProxyInfo* aProxyInfo, nsresult aStatus) {
|
||||
if (self->CanSend()) {
|
||||
nsTArray<ProxyInfoCloneArgs> proxyInfoArray;
|
||||
if (aProxyInfo && NS_SUCCEEDED(aStatus)) {
|
||||
nsProxyInfo::SerializeProxyInfo(
|
||||
static_cast<nsProxyInfo*>(aProxyInfo), proxyInfoArray);
|
||||
}
|
||||
Unused << Send__delete__(self, proxyInfoArray, aStatus);
|
||||
}
|
||||
},
|
||||
mURI, mProxyResolveFlags);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
nsTArray<ProxyInfoCloneArgs> emptyArray;
|
||||
Unused << Send__delete__(self, emptyArray, rv);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=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_net_ProxyConfigLookupParent_h
|
||||
#define mozilla_net_ProxyConfigLookupParent_h
|
||||
|
||||
#include "mozilla/net/PProxyConfigLookupParent.h"
|
||||
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class ProxyConfigLookupParent final : public PProxyConfigLookupParent {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ProxyConfigLookupParent, override)
|
||||
|
||||
explicit ProxyConfigLookupParent(nsIURI* aURI, uint32_t aProxyResolveFlags);
|
||||
|
||||
void DoProxyLookup();
|
||||
|
||||
private:
|
||||
virtual ~ProxyConfigLookupParent();
|
||||
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
uint32_t mProxyResolveFlags;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_ProxyConfigLookupParent_h
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/ipc/PChildToParentStreamParent.h"
|
||||
#include "mozilla/ipc/PParentToChildStreamParent.h"
|
||||
#include "mozilla/net/DNSRequestParent.h"
|
||||
#include "mozilla/net/ProxyConfigLookupParent.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TelemetryIPC.h"
|
||||
#include "nsIHttpActivityObserver.h"
|
||||
|
@ -328,6 +329,21 @@ mozilla::ipc::IPCResult SocketProcessParent::RecvGetTLSClientCert(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<PProxyConfigLookupParent>
|
||||
SocketProcessParent::AllocPProxyConfigLookupParent(
|
||||
nsIURI* aURI, const uint32_t& aProxyResolveFlags) {
|
||||
RefPtr<ProxyConfigLookupParent> actor =
|
||||
new ProxyConfigLookupParent(aURI, aProxyResolveFlags);
|
||||
return actor.forget();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult SocketProcessParent::RecvPProxyConfigLookupConstructor(
|
||||
PProxyConfigLookupParent* aActor, nsIURI* aURI,
|
||||
const uint32_t& aProxyResolveFlags) {
|
||||
static_cast<ProxyConfigLookupParent*>(aActor)->DoProxyLookup();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// To ensure that IPDL is finished before SocketParent gets deleted.
|
||||
class DeferredDeleteSocketProcessParent : public Runnable {
|
||||
public:
|
||||
|
|
|
@ -103,6 +103,12 @@ class SocketProcessParent final
|
|||
bool* aSucceeded, ByteArray* aOutCert, ByteArray* aOutKey,
|
||||
nsTArray<ByteArray>* aBuiltChain);
|
||||
|
||||
already_AddRefed<PProxyConfigLookupParent> AllocPProxyConfigLookupParent(
|
||||
nsIURI* aURI, const uint32_t& aProxyResolveFlags);
|
||||
mozilla::ipc::IPCResult RecvPProxyConfigLookupConstructor(
|
||||
PProxyConfigLookupParent* aActor, nsIURI* aURI,
|
||||
const uint32_t& aProxyResolveFlags) override;
|
||||
|
||||
private:
|
||||
SocketProcessHost* mHost;
|
||||
UniquePtr<dom::MemoryReportRequestHost> mMemoryReportRequest;
|
||||
|
|
|
@ -19,6 +19,9 @@ EXPORTS.mozilla.net += [
|
|||
'NeckoParent.h',
|
||||
'NeckoTargetHolder.h',
|
||||
'ParentProcessDocumentChannel.h',
|
||||
'ProxyConfigLookup.h',
|
||||
'ProxyConfigLookupChild.h',
|
||||
'ProxyConfigLookupParent.h',
|
||||
'SocketProcessBridgeChild.h',
|
||||
'SocketProcessBridgeParent.h',
|
||||
'SocketProcessChild.h',
|
||||
|
@ -39,6 +42,9 @@ UNIFIED_SOURCES += [
|
|||
'NeckoParent.cpp',
|
||||
'NeckoTargetHolder.cpp',
|
||||
'ParentProcessDocumentChannel.cpp',
|
||||
'ProxyConfigLookup.cpp',
|
||||
'ProxyConfigLookupChild.cpp',
|
||||
'ProxyConfigLookupParent.cpp',
|
||||
'SocketProcessBridgeChild.cpp',
|
||||
'SocketProcessBridgeParent.cpp',
|
||||
'SocketProcessChild.cpp',
|
||||
|
@ -55,6 +61,7 @@ IPDL_SOURCES = [
|
|||
'PFileChannel.ipdl',
|
||||
'PInputChannelThrottleQueue.ipdl',
|
||||
'PNecko.ipdl',
|
||||
'PProxyConfigLookup.ipdl',
|
||||
'PSimpleChannel.ipdl',
|
||||
'PSocketProcess.ipdl',
|
||||
'PSocketProcessBridge.ipdl'
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "nsIOService.h"
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "ProxyConfigLookup.h"
|
||||
#include "TRRLoadInfo.h"
|
||||
#include "ReferrerInfo.h"
|
||||
#include "TRR.h"
|
||||
|
@ -207,29 +208,13 @@ nsresult TRRServiceChannel::ResolveProxy() {
|
|||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel), mURI,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIProtocolProxyService> pps =
|
||||
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// using the nsIProtocolProxyService2 allows a minor performance
|
||||
// optimization, but if an add-on has only provided the original interface
|
||||
// then it is ok to use that version.
|
||||
nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
|
||||
if (pps2) {
|
||||
rv = pps2->AsyncResolve2(channel, mProxyResolveFlags, this, nullptr,
|
||||
getter_AddRefs(mProxyRequest));
|
||||
} else {
|
||||
rv = pps->AsyncResolve(channel, mProxyResolveFlags, this, nullptr,
|
||||
getter_AddRefs(mProxyRequest));
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: bug 1625171. Consider moving proxy resolution to socket process.
|
||||
RefPtr<TRRServiceChannel> self = this;
|
||||
nsresult rv = ProxyConfigLookup::Create(
|
||||
[self](nsIProxyInfo* aProxyInfo, nsresult aStatus) {
|
||||
self->OnProxyAvailable(nullptr, nullptr, aProxyInfo, aStatus);
|
||||
},
|
||||
mURI, mProxyResolveFlags);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (!mCurrentEventTarget->IsOnCurrentThread()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче