diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index 8e078e16360d..ae6d3204cf89 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -97,6 +97,9 @@ import java.util.NoSuchElementException; import java.util.StringTokenizer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.SynchronousQueue; +import java.net.ProxySelector; +import java.net.Proxy; +import java.net.URI; public class GeckoAppShell { @@ -2233,4 +2236,44 @@ public class GeckoAppShell } return false; } + + public static String getProxyForURI(String spec, String scheme, String host, int port) { + URI uri = null; + try { + uri = new URI(spec); + } catch(java.net.URISyntaxException uriEx) { + try { + uri = new URI(scheme, null, host, port, null, null, null); + } catch(java.net.URISyntaxException uriEx2) { + Log.d("GeckoProxy", "Failed to create uri from spec", uriEx); + Log.d("GeckoProxy", "Failed to create uri from parts", uriEx2); + } + } + if (uri != null) { + ProxySelector ps = ProxySelector.getDefault(); + if (ps != null) { + List proxies = ps.select(uri); + if (proxies != null && !proxies.isEmpty()) { + Proxy proxy = proxies.get(0); + if (!Proxy.NO_PROXY.equals(proxy)) { + final String proxyStr; + switch (proxy.type()) { + case HTTP: + proxyStr = "PROXY " + proxy.address().toString(); + break; + case SOCKS: + proxyStr = "SOCKS " + proxy.address().toString(); + break; + case DIRECT: + default: + proxyStr = "DIRECT"; + break; + } + return proxyStr; + } + } + } + } + return "DIRECT"; + } } diff --git a/toolkit/Makefile.in b/toolkit/Makefile.in index 3e95f4ba6468..f7f5ce2de6b8 100644 --- a/toolkit/Makefile.in +++ b/toolkit/Makefile.in @@ -51,6 +51,10 @@ ifneq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT))) PARALLEL_DIRS += system/windowsproxy endif +ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT))) +PARALLEL_DIRS += system/androidproxy +endif + ifdef MOZ_CRASHREPORTER PARALLEL_DIRS += crashreporter endif diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in index 677f45408064..e4e8ca4acbc2 100644 --- a/toolkit/library/Makefile.in +++ b/toolkit/library/Makefile.in @@ -215,6 +215,12 @@ COMPONENT_LIBS += \ $(NULL) endif +ifneq (,$(filter android,$(MOZ_WIDGET_TOOLKIT))) +COMPONENT_LIBS += \ + androidproxy \ + $(NULL) +endif + ifdef MOZ_JSDEBUGGER DEFINES += -DMOZ_JSDEBUGGER COMPONENT_LIBS += \ diff --git a/toolkit/library/nsStaticXULComponents.cpp b/toolkit/library/nsStaticXULComponents.cpp index 85b21a2875b1..af05e57b194f 100644 --- a/toolkit/library/nsStaticXULComponents.cpp +++ b/toolkit/library/nsStaticXULComponents.cpp @@ -143,6 +143,12 @@ #define WINDOWSPROXY_MODULE #endif +#if defined(MOZ_WIDGET_ANDROID) +#define ANDROIDPROXY_MODULE MODULE(nsAndroidProxyModule) +#else +#define ANDROIDPROXY_MODULE +#endif + #if defined(BUILD_CTYPES) #define JSCTYPES_MODULE MODULE(jsctypes) #else @@ -224,6 +230,7 @@ UNIXPROXY_MODULE \ OSXPROXY_MODULE \ WINDOWSPROXY_MODULE \ + ANDROIDPROXY_MODULE \ JSCTYPES_MODULE \ MODULE(jsreflect) \ MODULE(jsperf) \ diff --git a/toolkit/system/androidproxy/Makefile.in b/toolkit/system/androidproxy/Makefile.in new file mode 100644 index 000000000000..5bda806347f5 --- /dev/null +++ b/toolkit/system/androidproxy/Makefile.in @@ -0,0 +1,26 @@ +# 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/. + +DEPTH = @DEPTH@ +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = androidproxy +LIBRARY_NAME = androidproxy + +EXPORT_LIBRARY = 1 +IS_COMPONENT = 1 +MODULE_NAME = nsAndroidProxyModule +GRE_MODULE = 1 +LIBXUL_LIBRARY = 1 + + +CPPSRCS = \ + nsAndroidSystemProxySettings.cpp \ + $(NULL) + +include $(topsrcdir)/config/rules.mk diff --git a/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp b/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp new file mode 100644 index 000000000000..d97bac4c4b89 --- /dev/null +++ b/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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 "nsNetUtil.h" +#include "nsIURI.h" + +#include "mozilla/Util.h" +#include "nsISystemProxySettings.h" +#include "nsIServiceManager.h" +#include "mozilla/ModuleUtils.h" +#include "nsPrintfCString.h" +#include "nsNetUtil.h" +#include "nsISupportsPrimitives.h" +#include "nsIURI.h" + +#include "AndroidBridge.h" + +class nsAndroidSystemProxySettings : public nsISystemProxySettings +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISYSTEMPROXYSETTINGS + + nsAndroidSystemProxySettings() {}; + nsresult Init(); + +private: + ~nsAndroidSystemProxySettings() {}; +}; + +NS_IMPL_THREADSAFE_ISUPPORTS1(nsAndroidSystemProxySettings, nsISystemProxySettings) + +NS_IMETHODIMP +nsAndroidSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + *aMainThreadOnly = true; + return NS_OK; +} + + +nsresult +nsAndroidSystemProxySettings::Init() +{ + return NS_OK; +} + +nsresult +nsAndroidSystemProxySettings::GetPACURI(nsACString& aResult) +{ + return NS_OK; +} + +nsresult +nsAndroidSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) +{ + return mozilla::AndroidBridge::Bridge()->GetProxyForURI(aSpec, aScheme, aHost, aPort, aResult); +} + +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAndroidSystemProxySettings, Init) + +#define NS_ANDROIDSYSTEMPROXYSERVICE_CID \ + {0xf01f0060, 0x3708, 0x478e, \ + {0xb9, 0x35, 0x3e, 0xce, 0x8b, 0xe2, 0x94, 0xb8}} + +NS_DEFINE_NAMED_CID(NS_ANDROIDSYSTEMPROXYSERVICE_CID); + +void test() {}; + +static const mozilla::Module::CIDEntry kSysProxyCIDs[] = { + { &kNS_ANDROIDSYSTEMPROXYSERVICE_CID, false, NULL, nsAndroidSystemProxySettingsConstructor }, + { NULL } +}; + +static const mozilla::Module::ContractIDEntry kSysProxyContracts[] = { + { NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_ANDROIDSYSTEMPROXYSERVICE_CID }, + { NULL } +}; + +static const mozilla::Module kSysProxyModule = { + mozilla::Module::kVersion, + kSysProxyCIDs, + kSysProxyContracts +}; + +NSMODULE_DEFN(nsAndroidProxyModule) = &kSysProxyModule; diff --git a/toolkit/toolkit-makefiles.sh b/toolkit/toolkit-makefiles.sh index 5ae3a99c9d97..b8d6e1325112 100644 --- a/toolkit/toolkit-makefiles.sh +++ b/toolkit/toolkit-makefiles.sh @@ -632,6 +632,7 @@ elif [ "$MOZ_WIDGET_TOOLKIT" = "android" ]; then image/decoders/icon/android/Makefile netwerk/system/android/Makefile widget/android/Makefile + toolkit/system/androidproxy/Makefile " if [ "$MOZ_BUILD_APP" = "mobile/xul" -o "$MOZ_BUILD_APP" = "b2g" ]; then add_makefiles " diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index 695ffdb7d988..22749d11f371 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -202,6 +202,7 @@ AndroidBridge::Init(JNIEnv *jEnv, jNotifyWakeLockChanged = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V"); jGetGfxInfoData = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getGfxInfoData", "()Ljava/lang/String;"); + jGetProxyForURI = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getProxyForURI", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;"); jRegisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "registerSurfaceTextureFrameListener", "(Ljava/lang/Object;I)V"); jUnregisterSurfaceTextureFrameListener = jEnv->GetStaticMethodID(jGeckoAppShellClass, "unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V"); @@ -2399,6 +2400,36 @@ AndroidBridge::GetGfxInfoData(nsACString& aRet) CopyUTF16toUTF8(jniStr, aRet); } +#define CREATE_JAVA_STRING(name) jstring j##name = NewJavaStringUTF(&jniFrame, nsPromiseFlatCString(a##name).get()) + +nsresult +AndroidBridge::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) +{ + JNIEnv* env = GetJNIEnv(); + if (!env) + return NS_ERROR_FAILURE; + + AutoLocalJNIFrame jniFrame(env); + + CREATE_JAVA_STRING(Spec); + CREATE_JAVA_STRING(Scheme); + CREATE_JAVA_STRING(Host); + jstring jstrRet = static_cast + (env->CallStaticObjectMethod(mGeckoAppShellClass, jGetProxyForURI, jSpec, jScheme, jHost, aPort)); + + if (jniFrame.CheckForException()) + return NS_ERROR_FAILURE; + + nsJNIString jniStr(jstrRet, env); + CopyUTF16toUTF8(jniStr, aResult); + return NS_OK; +} + + /* attribute nsIAndroidBrowserApp browserApp; */ NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp) { diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 7cecd541f84d..b09955f8b9e0 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -366,7 +366,11 @@ public: void UnregisterSurfaceTextureFrameListener(jobject surfaceTexture); void GetGfxInfoData(nsACString& aRet); - + nsresult GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult); protected: static AndroidBridge *sBridge; static StaticAutoPtr > > sSmsRequests; @@ -466,6 +470,7 @@ protected: jmethodID jShowSurface; jmethodID jHideSurface; jmethodID jDestroySurface; + jmethodID jGetProxyForURI; jmethodID jNumberOfMessages; jmethodID jSendMessage;