summaryrefslogtreecommitdiffstats
path: root/packages/services/PacProcessor
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2013-07-03 17:04:33 -0400
committerJason Monk <jmonk@google.com>2013-08-07 21:01:39 -0400
commit602b232a06ede86999aa362a12eb28cbc782dc1d (patch)
tree07a2168ba91425f81bd7ac9c9311adb78114cc13 /packages/services/PacProcessor
parent55db1e1218971105e68ba9d451b2e0b1e9e5f9fb (diff)
downloadframeworks_base-602b232a06ede86999aa362a12eb28cbc782dc1d.zip
frameworks_base-602b232a06ede86999aa362a12eb28cbc782dc1d.tar.gz
frameworks_base-602b232a06ede86999aa362a12eb28cbc782dc1d.tar.bz2
Add PAC File support for proxy configuration
PAC (Proxy auto-config) files contain a single javascript function, FindProxyForURL(url, host). It gets called to determine what proxy should be used for a specific request. This adds PAC support to the system. The ProxyProperties has been modified to hold the PAC file when one is present. The Proxy method setHttpProxySystemProperty has been modified to insert a PacProxySelector as the default ProxySelector when it is required. This new ProxySelector makes calls to the ConnectivityService to parse the PAC file. The ConnectivityService and the WifiConfigStore have been modified to support saving the extra PAC file data. The ConnectivityService now has a class attached (PacProxyNative) that interfaces to the native calls for PAC files. The parsing of the PAC file is handled by libpac (which is being added to external/) which utilizes libv8 to parse the javascript. As a fallback to applications that don't use the java ProxySelector, the proxy is setup to point to a local proxy server that will handle the pac parsing. bug:10182711 Change-Id: I5eb8df893c632fd3e1b732385cb7720ad646f401
Diffstat (limited to 'packages/services/PacProcessor')
-rw-r--r--packages/services/PacProcessor/Android.mk41
-rw-r--r--packages/services/PacProcessor/IProxyService.cpp97
-rw-r--r--packages/services/PacProcessor/IProxyService.h59
-rw-r--r--packages/services/PacProcessor/ProxyService.cpp96
-rw-r--r--packages/services/PacProcessor/ProxyService.h33
-rw-r--r--packages/services/PacProcessor/main_pacserver.cpp43
6 files changed, 369 insertions, 0 deletions
diff --git a/packages/services/PacProcessor/Android.mk b/packages/services/PacProcessor/Android.mk
new file mode 100644
index 0000000..e4afde6
--- /dev/null
+++ b/packages/services/PacProcessor/Android.mk
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ main_pacserver.cpp \
+ ProxyService.cpp \
+ IProxyService.cpp
+
+LOCAL_C_INCLUDES += \
+ external/chromium-libpac/src
+
+LOCAL_SHARED_LIBRARIES := \
+ libutils \
+ liblog \
+ libpac \
+ libbinder \
+ libstlport
+
+LOCAL_MODULE := pacserver
+LOCAL_MODULE_TAGS := optional
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_EXECUTABLE)
diff --git a/packages/services/PacProcessor/IProxyService.cpp b/packages/services/PacProcessor/IProxyService.cpp
new file mode 100644
index 0000000..3707d85
--- /dev/null
+++ b/packages/services/PacProcessor/IProxyService.cpp
@@ -0,0 +1,97 @@
+#define LOG_TAG "ProxyTesting"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <utils/Errors.h>
+#include "IProxyService.h"
+
+#include <utils/Log.h>
+
+#include <private/android_filesystem_config.h>
+
+using namespace android;
+
+String16 BpProxyService::resolveProxies(String16 host, String16 url) {
+ String16 ret;
+ return ret;
+}
+
+void BpProxyService::setPacFile(String16& scriptContents) {
+
+}
+
+void BpProxyService::startPacSystem() {
+
+}
+void BpProxyService::stopPacSystem() {
+
+}
+
+IMPLEMENT_META_INTERFACE(ProxyService, "com.android.net.IProxyService");
+
+status_t BnProxyService::onTransact(
+ uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags) {
+ int returnInt = 0;
+ switch (code) {
+ case RESOLVE_PROXIES:
+ {
+ CHECK_INTERFACE(IProxyService, data, reply);
+ String16 host = data.readString16();
+ String16 url = data.readString16();
+ String16 response = resolveProxies(host, url);
+ reply->writeNoException();
+ reply->writeString16(response);
+ return NO_ERROR;
+ } break;
+ case SET_PAC:
+ {
+ CHECK_INTERFACE(IProxyService, data, reply);
+ if (notSystemUid()) {
+ returnInt = 1;
+ } else {
+ String16 pacFile = data.readString16();
+ setPacFile(pacFile);
+ }
+ reply->writeNoException();
+ reply->writeInt32(returnInt);
+ return NO_ERROR;
+ } break;
+ case START_PAC:
+ {
+ CHECK_INTERFACE(IProxyService, data, reply);
+ if (notSystemUid()) {
+ returnInt = 1;
+ } else {
+ startPacSystem();
+ }
+ reply->writeNoException();
+ reply->writeInt32(returnInt);
+ return NO_ERROR;
+ } break;
+ case STOP_PAC:
+ {
+ CHECK_INTERFACE(IProxyService, data, reply);
+ if (notSystemUid()) {
+ returnInt = 1;
+ } else {
+ stopPacSystem();
+ }
+ reply->writeNoException();
+ reply->writeInt32(returnInt);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+int BnProxyService::getCallingUid() {
+ return IPCThreadState::self()->getCallingUid();
+}
+
+bool BnProxyService::notSystemUid() {
+ return getCallingUid() != AID_SYSTEM;
+}
diff --git a/packages/services/PacProcessor/IProxyService.h b/packages/services/PacProcessor/IProxyService.h
new file mode 100644
index 0000000..57c527b
--- /dev/null
+++ b/packages/services/PacProcessor/IProxyService.h
@@ -0,0 +1,59 @@
+#ifndef IPROXY_SERVICE_H
+#define IPROXY_SERVICE_H
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+
+namespace android {
+class IProxyService : public IInterface {
+public:
+ /**
+ * Keep up-to-date with
+ * frameworks/base/packages/services/Proxy/com/android/net/IProxyService.aidl
+ */
+ enum {
+ RESOLVE_PROXIES = IBinder::FIRST_CALL_TRANSACTION,
+ SET_PAC,
+ START_PAC,
+ STOP_PAC,
+ };
+public:
+ DECLARE_META_INTERFACE(ProxyService);
+
+public:
+
+ virtual String16 resolveProxies(String16 host, String16 url) = 0;
+
+ virtual void setPacFile(String16& scriptContents) = 0;
+
+ virtual void startPacSystem() = 0;
+ virtual void stopPacSystem() = 0;
+private:
+};
+
+class BpProxyService : public BpInterface<IProxyService> {
+public:
+ BpProxyService(const sp<IBinder>& impl) : BpInterface<IProxyService>(impl) {}
+
+ virtual String16 resolveProxies(String16 host, String16 url);
+
+ virtual void setPacFile(String16& scriptContents);
+
+ virtual void startPacSystem();
+ virtual void stopPacSystem();
+};
+
+class BnProxyService : public BnInterface<IProxyService> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
+
+private:
+ int getCallingUid();
+
+ bool notSystemUid();
+};
+}
+
+
+#endif //IPROXY_SERVICE_H
diff --git a/packages/services/PacProcessor/ProxyService.cpp b/packages/services/PacProcessor/ProxyService.cpp
new file mode 100644
index 0000000..7084a47
--- /dev/null
+++ b/packages/services/PacProcessor/ProxyService.cpp
@@ -0,0 +1,96 @@
+#define LOG_TAG "ProxyService"
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <utils/threads.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <sys/stat.h>
+#include <proxy_resolver_v8.h>
+#include <sstream>
+
+#include "ProxyService.h"
+
+using namespace net;
+
+using namespace android;
+
+class ProxyErrorLogger : public ProxyErrorListener {
+protected:
+ ~ProxyErrorLogger() {
+
+ }
+public:
+ void AlertMessage(String16 message) {
+ String8 str(message);
+ ALOGD("Alert: %s", str.string());
+ }
+ void ErrorMessage(String16 message) {
+ String8 str(message);
+ ALOGE("Error: %s", str.string());
+ }
+};
+
+void ProxyService::instantiate() {
+ ALOGV("instantiate");
+ defaultServiceManager()->addService(String16("com.android.net.IProxyService"),
+ new ProxyService());
+}
+
+ProxyService::ProxyService() {
+ hasSetScript = false;
+}
+
+ProxyService::~ProxyService() {
+ stopPacSystem();
+}
+
+String16 ProxyService::resolveProxies(String16 host, String16 url) {
+ ALOGV("resolve");
+ String16 blankRet;
+ if (proxyResolver != NULL) {
+ if (hasSetScript) {
+ String16 ret;
+ if (proxyResolver->GetProxyForURL(url, host, &ret) != OK) {
+ return blankRet;
+ }
+ return ret;
+ } else {
+ ALOGD("Unable to resolve PAC when no script is set!");
+ }
+ } else {
+ ALOGE("Cannot parse while resolver not initialized!");
+ }
+ return blankRet;
+}
+
+void ProxyService::setPacFile(String16& scriptContents) {
+ ALOGV("set");
+ if (proxyResolver != NULL) {
+ if (proxyResolver->SetPacScript(scriptContents) != OK) {
+ ALOGD("Unable to initialize PAC - Resolving will not work");
+ } else {
+ hasSetScript = true;
+ }
+ } else {
+ ALOGE("PAC script set while resolver not initialized!");
+ }
+}
+
+void ProxyService::startPacSystem() {
+ ALOGV("start");
+ // Stop in case redundant start call
+ stopPacSystem();
+
+ proxyResolver = new ProxyResolverV8(ProxyResolverJSBindings::CreateDefault(),
+ new ProxyErrorLogger());
+ hasSetScript = false;
+}
+
+void ProxyService::stopPacSystem() {
+ ALOGV("stop");
+ if (proxyResolver != NULL) {
+ delete proxyResolver;
+ proxyResolver = NULL;
+ }
+}
diff --git a/packages/services/PacProcessor/ProxyService.h b/packages/services/PacProcessor/ProxyService.h
new file mode 100644
index 0000000..a0861b2
--- /dev/null
+++ b/packages/services/PacProcessor/ProxyService.h
@@ -0,0 +1,33 @@
+#ifndef PROXY_SERVICE_H
+#define PROXY_SERVICE_H
+
+#include <binder/IInterface.h>
+#include "IProxyService.h"
+#include "proxy_resolver_v8.h"
+
+namespace android {
+
+class ProxyService : public BnProxyService {
+public:
+ static void instantiate();
+
+private:
+ ProxyService();
+ virtual ~ProxyService();
+
+public:
+ String16 resolveProxies(String16 host, String16 url);
+
+ void setPacFile(String16& scriptContents);
+
+ void startPacSystem();
+ void stopPacSystem();
+
+private:
+ net::ProxyResolverV8* proxyResolver;
+ bool hasSetScript;
+};
+
+}
+
+#endif //PROXY_SERVICE_H
diff --git a/packages/services/PacProcessor/main_pacserver.cpp b/packages/services/PacProcessor/main_pacserver.cpp
new file mode 100644
index 0000000..19588b5
--- /dev/null
+++ b/packages/services/PacProcessor/main_pacserver.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "pacserver"
+//#define LOG_NDEBUG 0
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+#include "ProxyService.h"
+#include "proxy_resolver_v8.h"
+#include <stdio.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+ sp<ProcessState> proc(ProcessState::self());
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ printf("1\n");
+ ALOGV("ServiceManager: %p", sm.get());
+ ProxyService::instantiate();
+ printf("1\n");
+
+ ProcessState::self()->startThreadPool();
+ printf("1\n");
+ IPCThreadState::self()->joinThreadPool();
+}