Commit bd3b0ee6 authored by Anna Malova's avatar Anna Malova Committed by Commit Bot

[aw] Allow to set Network in AwPacProcessor.

Bug: 1085115
Change-Id: I8846261a0f21ecb48692b70ab778f68996843760
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2414173Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Commit-Queue: Anna Malova <amalova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812494}
parent d8e22e81
...@@ -108,9 +108,6 @@ proxy_resolver::ProxyResolverV8TracingFactory* GetProxyResolverFactory() { ...@@ -108,9 +108,6 @@ proxy_resolver::ProxyResolverV8TracingFactory* GetProxyResolverFactory() {
// blocking DNS queries, to get better performance. // blocking DNS queries, to get better performance.
class HostResolver : public proxy_resolver::ProxyHostResolver { class HostResolver : public proxy_resolver::ProxyHostResolver {
public: public:
HostResolver(net_handle_t net_handle) : net_handle_(net_handle) {}
~HostResolver() override {}
std::unique_ptr<proxy_resolver::ProxyHostResolver::Request> CreateRequest( std::unique_ptr<proxy_resolver::ProxyHostResolver::Request> CreateRequest(
const std::string& hostname, const std::string& hostname,
net::ProxyResolveDnsOperation operation, net::ProxyResolveDnsOperation operation,
...@@ -119,9 +116,11 @@ class HostResolver : public proxy_resolver::ProxyHostResolver { ...@@ -119,9 +116,11 @@ class HostResolver : public proxy_resolver::ProxyHostResolver {
link_addresses_); link_addresses_);
} }
void SetNetworkLinkAddresses( void SetNetworkAndLinkAddresses(
const net_handle_t net_handle,
const std::vector<net::IPAddress>& link_addresses) { const std::vector<net::IPAddress>& link_addresses) {
link_addresses_ = link_addresses; link_addresses_ = link_addresses;
net_handle_ = net_handle;
} }
private: private:
...@@ -169,7 +168,7 @@ class HostResolver : public proxy_resolver::ProxyHostResolver { ...@@ -169,7 +168,7 @@ class HostResolver : public proxy_resolver::ProxyHostResolver {
bool MyIpAddressImpl() { bool MyIpAddressImpl() {
// For network-aware queries the results are set from Java on // For network-aware queries the results are set from Java on
// NetworkCallback#onLinkPropertiesChanged. // NetworkCallback#onLinkPropertiesChanged.
// See SetNetworkLinkAddresses. // See SetNetworkAndLinkAddresses.
if (IsNetworkSpecified()) { if (IsNetworkSpecified()) {
results_.push_back(link_addresses_.front()); results_.push_back(link_addresses_.front());
return true; return true;
...@@ -380,9 +379,8 @@ class MakeProxyRequestJob : public Job { ...@@ -380,9 +379,8 @@ class MakeProxyRequestJob : public Job {
std::unique_ptr<net::ProxyResolver::Request> request_; std::unique_ptr<net::ProxyResolver::Request> request_;
}; };
AwPacProcessor::AwPacProcessor(net_handle_t net_handle) AwPacProcessor::AwPacProcessor() {
: net_handle_(net_handle) { host_resolver_ = std::make_unique<HostResolver>();
host_resolver_ = std::make_unique<HostResolver>(net_handle_);
} }
AwPacProcessor::~AwPacProcessor() { AwPacProcessor::~AwPacProcessor() {
...@@ -467,30 +465,26 @@ ScopedJavaLocalRef<jstring> AwPacProcessor::MakeProxyRequest( ...@@ -467,30 +465,26 @@ ScopedJavaLocalRef<jstring> AwPacProcessor::MakeProxyRequest(
return ConvertUTF8ToJavaString(env, MakeProxyRequest(url)); return ConvertUTF8ToJavaString(env, MakeProxyRequest(url));
} }
// ProxyResolverV8Tracing posts DNS resolution queries back to the thread void AwPacProcessor::SetNetworkAndLinkAddresses(
// it is called from. Post update of link addresses to the same thread to
// prevent concurrent access and modification of the same vector.
void AwPacProcessor::SetNetworkLinkAddresses(
JNIEnv* env, JNIEnv* env,
net_handle_t net_handle,
const base::android::JavaParamRef<jobjectArray>& jlink_addresses) { const base::android::JavaParamRef<jobjectArray>& jlink_addresses) {
std::vector<std::string> string_link_addresses; std::vector<std::string> string_link_addresses;
base::android::AppendJavaStringArrayToStringVector(env, jlink_addresses, base::android::AppendJavaStringArrayToStringVector(env, jlink_addresses,
&string_link_addresses); &string_link_addresses);
std::vector<net::IPAddress> link_addresses; std::vector<net::IPAddress> link_addresses;
for (std::string const& address : string_link_addresses) { for (std::string const& address : string_link_addresses) {
link_addresses.push_back(StringToIPAddress(address)); link_addresses.push_back(StringToIPAddress(address));
} }
GetTaskRunner()->PostTask( GetTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&HostResolver::SetNetworkLinkAddresses, FROM_HERE, base::BindOnce(&HostResolver::SetNetworkAndLinkAddresses,
base::Unretained(host_resolver_.get()), base::Unretained(host_resolver_.get()),
std::move(link_addresses))); net_handle, std::move(link_addresses)));
} }
static jlong JNI_AwPacProcessor_CreateNativePacProcessor(JNIEnv* env, static jlong JNI_AwPacProcessor_CreateNativePacProcessor(JNIEnv* env) {
jlong net_handle) { AwPacProcessor* processor = new AwPacProcessor();
AwPacProcessor* processor = new AwPacProcessor(net_handle);
return reinterpret_cast<intptr_t>(processor); return reinterpret_cast<intptr_t>(processor);
} }
......
...@@ -22,7 +22,7 @@ class HostResolver; ...@@ -22,7 +22,7 @@ class HostResolver;
class AwPacProcessor { class AwPacProcessor {
public: public:
AwPacProcessor(net_handle_t net_handle); AwPacProcessor();
AwPacProcessor(const AwPacProcessor&) = delete; AwPacProcessor(const AwPacProcessor&) = delete;
AwPacProcessor& operator=(const AwPacProcessor&) = delete; AwPacProcessor& operator=(const AwPacProcessor&) = delete;
...@@ -39,8 +39,9 @@ class AwPacProcessor { ...@@ -39,8 +39,9 @@ class AwPacProcessor {
const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jstring>& jurl); const base::android::JavaParamRef<jstring>& jurl);
std::string MakeProxyRequest(std::string url); std::string MakeProxyRequest(std::string url);
void SetNetworkLinkAddresses( void SetNetworkAndLinkAddresses(
JNIEnv* env, JNIEnv* env,
net_handle_t net_handle,
const base::android::JavaParamRef<jobjectArray>& addresses); const base::android::JavaParamRef<jobjectArray>& addresses);
private: private:
...@@ -63,7 +64,6 @@ class AwPacProcessor { ...@@ -63,7 +64,6 @@ class AwPacProcessor {
std::unique_ptr<HostResolver> host_resolver_; std::unique_ptr<HostResolver> host_resolver_;
std::set<Job*> jobs_; std::set<Job*> jobs_;
net_handle_t net_handle_;
}; };
} // namespace android_webview } // namespace android_webview
......
...@@ -33,7 +33,7 @@ class AwPacProcessorTest : public testing::Test { ...@@ -33,7 +33,7 @@ class AwPacProcessorTest : public testing::Test {
protected: protected:
base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME}; base::test::TaskEnvironment::TimeSource::MOCK_TIME};
AwPacProcessor* pac_processor_ = new AwPacProcessor(NETWORK_UNSPECIFIED); AwPacProcessor* pac_processor_ = new AwPacProcessor();
}; };
TEST_F(AwPacProcessorTest, MakeProxyRequest) { TEST_F(AwPacProcessorTest, MakeProxyRequest) {
...@@ -49,8 +49,7 @@ TEST_F(AwPacProcessorTest, MakeProxyRequestDnsResolve) { ...@@ -49,8 +49,7 @@ TEST_F(AwPacProcessorTest, MakeProxyRequestDnsResolve) {
} }
TEST_F(AwPacProcessorTest, MultipleProxyRequest) { TEST_F(AwPacProcessorTest, MultipleProxyRequest) {
AwPacProcessor* other_pac_processor_ = AwPacProcessor* other_pac_processor_ = new AwPacProcessor();
new AwPacProcessor(NETWORK_UNSPECIFIED);
pac_processor_->SetProxyScript(kScript); pac_processor_->SetProxyScript(kScript);
other_pac_processor_->SetProxyScript(kScriptDnsResolve); other_pac_processor_->SetProxyScript(kScriptDnsResolve);
......
...@@ -24,57 +24,62 @@ import org.chromium.base.annotations.NativeMethods; ...@@ -24,57 +24,62 @@ import org.chromium.base.annotations.NativeMethods;
public class AwPacProcessor { public class AwPacProcessor {
private long mNativePacProcessor; private long mNativePacProcessor;
private Network mNetwork; private Network mNetwork;
private ConnectivityManager.NetworkCallback mNetworkCallback;
public static final long NETWORK_UNSPECIFIED = 0; public static final long NETWORK_UNSPECIFIED = 0;
private static class LazyHolder { private static class LazyHolder {
static final AwPacProcessor sInstance = new AwPacProcessor(null); static final AwPacProcessor sInstance = new AwPacProcessor();
} }
public static AwPacProcessor getInstance() { public static AwPacProcessor getInstance() {
return LazyHolder.sInstance; return LazyHolder.sInstance;
} }
public AwPacProcessor(Network network) { public AwPacProcessor() {
if (network == null) { mNativePacProcessor = AwPacProcessorJni.get().createNativePacProcessor();
mNativePacProcessor = registerNetworkCallback();
AwPacProcessorJni.get().createNativePacProcessor(NETWORK_UNSPECIFIED);
return;
} }
mNetwork = network; private static ConnectivityManager getConnectivityManager() {
mNativePacProcessor =
AwPacProcessorJni.get().createNativePacProcessor(mNetwork.getNetworkHandle());
Context context = ContextUtils.getApplicationContext(); Context context = ContextUtils.getApplicationContext();
ConnectivityManager connectivityManager = return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
connectivityManager.registerNetworkCallback(
builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onLinkPropertiesChanged(
Network network, LinkProperties linkProperties) {
if (network.equals(mNetwork)) {
updateNetworkLinkAddress(linkProperties);
}
}
});
updateNetworkLinkAddress(connectivityManager.getLinkProperties(mNetwork));
} }
private void updateNetworkLinkAddress(LinkProperties linkProperties) { private void updateNetworkLinkAddress(Network network, LinkProperties linkProperties) {
if (network == null || linkProperties == null) {
setNetworkAndLinkAddresses(NETWORK_UNSPECIFIED, new String[0]);
} else {
String[] addresses = linkProperties.getLinkAddresses() String[] addresses = linkProperties.getLinkAddresses()
.stream() .stream()
.map(LinkAddress::toString) .map(LinkAddress::toString)
.toArray(String[] ::new); .toArray(String[] ::new);
AwPacProcessorJni.get().setNetworkLinkAddresses(mNativePacProcessor, addresses); setNetworkAndLinkAddresses(network.getNetworkHandle(), addresses);
}
}
public void setNetworkAndLinkAddresses(long networkHandle, String[] addresses) {
AwPacProcessorJni.get().setNetworkAndLinkAddresses(
mNativePacProcessor, networkHandle, addresses);
}
private void registerNetworkCallback() {
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
if (network.equals(mNetwork)) {
updateNetworkLinkAddress(network, linkProperties);
}
}
};
NetworkRequest.Builder builder = new NetworkRequest.Builder();
getConnectivityManager().registerNetworkCallback(builder.build(), mNetworkCallback);
} }
// The calling code must not call any methods after it called destroy(). // The calling code must not call any methods after it called destroy().
public void destroy() { public void destroy() {
getConnectivityManager().unregisterNetworkCallback(mNetworkCallback);
AwPacProcessorJni.get().destroyNative(mNativePacProcessor, this); AwPacProcessorJni.get().destroyNative(mNativePacProcessor, this);
} }
...@@ -86,6 +91,11 @@ public class AwPacProcessor { ...@@ -86,6 +91,11 @@ public class AwPacProcessor {
return AwPacProcessorJni.get().makeProxyRequest(mNativePacProcessor, this, url); return AwPacProcessorJni.get().makeProxyRequest(mNativePacProcessor, this, url);
} }
public void setNetwork(Network network) {
updateNetworkLinkAddress(network, getConnectivityManager().getLinkProperties(network));
mNetwork = network;
}
public Network getNetwork() { public Network getNetwork() {
return mNetwork; return mNetwork;
} }
...@@ -97,10 +107,11 @@ public class AwPacProcessor { ...@@ -97,10 +107,11 @@ public class AwPacProcessor {
@NativeMethods @NativeMethods
interface Natives { interface Natives {
void initializeEnvironment(); void initializeEnvironment();
long createNativePacProcessor(long netHandle); long createNativePacProcessor();
boolean setProxyScript(long nativeAwPacProcessor, AwPacProcessor caller, String script); boolean setProxyScript(long nativeAwPacProcessor, AwPacProcessor caller, String script);
String makeProxyRequest(long nativeAwPacProcessor, AwPacProcessor caller, String url); String makeProxyRequest(long nativeAwPacProcessor, AwPacProcessor caller, String url);
void destroyNative(long nativeAwPacProcessor, AwPacProcessor caller); void destroyNative(long nativeAwPacProcessor, AwPacProcessor caller);
void setNetworkLinkAddresses(long nativeAwPacProcessor, String[] adresses); void setNetworkAndLinkAddresses(
long nativeAwPacProcessor, long networkHandle, String[] adresses);
} }
} }
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.test;
import androidx.test.filters.SmallTest;
import com.android.webview.chromium.WebViewChromiumFactoryProvider;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.android_webview.AwPacProcessor;
import org.chromium.base.JNIUtils;
import org.chromium.base.library_loader.LibraryLoader;
/**
* Tests for AwPacProcessor class.
*/
@RunWith(AwJUnit4ClassRunner.class)
public class AwPacProcessorTest {
private AwPacProcessor mProcessor;
private final String mPacScript = "function FindProxyForURL(url, host) {\n"
+ "var x = myIpAddress();"
+ "\treturn \"PROXY \" + x + \":80\";\n"
+ "}";
private final String mTestUrl = "http://testurl.test";
@Rule
public AwActivityTestRule mRule = new AwActivityTestRule();
@Before
public void setUp() {
JNIUtils.setClassLoader(WebViewChromiumFactoryProvider.class.getClassLoader());
LibraryLoader.getInstance().ensureInitialized();
mProcessor = AwPacProcessor.getInstance();
}
@Test
@SmallTest
public void testUpdateNetworkAndLinkAddresses() throws Throwable {
// PAC script returns result of myIpAddress call
mProcessor.setProxyScript(mPacScript);
// Save the proxy request result when network is not set
String proxyResultNetworkIsNotSet = mProcessor.makeProxyRequest(mTestUrl);
// Set network and IP addresses, check they are correctly propagated.
mProcessor.setNetworkAndLinkAddresses(42, new String[] {"1.2.3.4"});
String proxyResultNetworkIsSet = mProcessor.makeProxyRequest(mTestUrl);
Assert.assertEquals("PROXY 1.2.3.4:80", proxyResultNetworkIsSet);
// Unset network, the returned proxy string must be equal previously saved value
mProcessor.setNetwork(null);
Assert.assertEquals(proxyResultNetworkIsNotSet, mProcessor.makeProxyRequest(mTestUrl));
}
}
\ No newline at end of file
...@@ -255,6 +255,7 @@ instrumentation_test_apk("webview_instrumentation_test_apk") { ...@@ -255,6 +255,7 @@ instrumentation_test_apk("webview_instrumentation_test_apk") {
"../javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java", "../javatests/src/org/chromium/android_webview/test/AwLegacyQuirksTest.java",
"../javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java", "../javatests/src/org/chromium/android_webview/test/AwMetricsIntegrationTest.java",
"../javatests/src/org/chromium/android_webview/test/AwNetworkConfigurationTest.java", "../javatests/src/org/chromium/android_webview/test/AwNetworkConfigurationTest.java",
"../javatests/src/org/chromium/android_webview/test/AwPacProcessorTest.java",
"../javatests/src/org/chromium/android_webview/test/AwPageLoadMetricsTest.java", "../javatests/src/org/chromium/android_webview/test/AwPageLoadMetricsTest.java",
"../javatests/src/org/chromium/android_webview/test/AwPermissionManagerTest.java", "../javatests/src/org/chromium/android_webview/test/AwPermissionManagerTest.java",
"../javatests/src/org/chromium/android_webview/test/AwProxyControllerTest.java", "../javatests/src/org/chromium/android_webview/test/AwProxyControllerTest.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment