summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--CleanSpec.mk1
-rw-r--r--core/java/android/net/PacProxySelector.java26
-rw-r--r--core/java/android/net/Proxy.java8
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--packages/services/PacProcessor/Android.mk27
-rw-r--r--packages/services/PacProcessor/AndroidManifest.xml16
-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/com/android/net/IProxyService.aidl27
-rw-r--r--packages/services/PacProcessor/jni/Android.mk41
-rw-r--r--packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp148
-rw-r--r--packages/services/PacProcessor/jni/jni_init.cpp38
-rw-r--r--packages/services/PacProcessor/main_pacserver.cpp43
-rw-r--r--packages/services/PacProcessor/res/values/strings.xml6
-rw-r--r--packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java86
-rw-r--r--packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java101
-rw-r--r--packages/services/Proxy/com/android/net/IProxyService.aidl16
-rw-r--r--services/java/com/android/server/connectivity/PacManager.java230
21 files changed, 634 insertions, 468 deletions
diff --git a/Android.mk b/Android.mk
index 656e40c2cba2..73f4048cd2d8 100644
--- a/Android.mk
+++ b/Android.mk
@@ -264,7 +264,7 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
- packages/services/Proxy/com/android/net/IProxyService.aidl \
+ packages/services/PacProcessor/com/android/net/IProxyService.aidl \
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 8fd5186c67e4..a94252d66ec2 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -170,6 +170,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoveryObserver.*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/printservice/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/packages/services/Proxy/)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java
index d3ce2e509e14..b674324197ed 100644
--- a/core/java/android/net/PacProxySelector.java
+++ b/core/java/android/net/PacProxySelector.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2013 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.
+ */
package android.net;
@@ -25,19 +40,25 @@ public class PacProxySelector extends ProxySelector {
private static final String TAG = "PacProxySelector";
public static final String PROXY_SERVICE = "com.android.net.IProxyService";
private IProxyService mProxyService;
+ private final List<Proxy> mDefaultList;
public PacProxySelector() {
mProxyService = IProxyService.Stub.asInterface(
ServiceManager.getService(PROXY_SERVICE));
if (mProxyService == null) {
// Added because of b10267814 where mako is restarting.
- Log.e(TAG, "PackManager: no proxy service");
+ Log.e(TAG, "PacManager: no proxy service");
}
+ mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY);
}
@Override
public List<Proxy> select(URI uri) {
if (mProxyService == null) {
+ mProxyService = IProxyService.Stub.asInterface(
+ ServiceManager.getService(PROXY_SERVICE));
+ }
+ if (mProxyService == null) {
Log.e(TAG, "select: no proxy service return NO_PROXY");
return Lists.newArrayList(java.net.Proxy.NO_PROXY);
}
@@ -53,6 +74,9 @@ public class PacProxySelector extends ProxySelector {
} catch (RemoteException e) {
e.printStackTrace();
}
+ if (response == null) {
+ return mDefaultList;
+ }
return parseResponse(response);
}
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 5b38f5793a74..c3e14381f3af 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -48,7 +48,6 @@ public final class Proxy {
private static final String TAG = "Proxy";
private static final ProxySelector sDefaultProxySelector;
- private static PacProxySelector sPacProxySelector;
/**
* Used to notify an app that's caching the default connection proxy
@@ -352,11 +351,8 @@ public final class Proxy {
System.clearProperty("http.nonProxyHosts");
System.clearProperty("https.nonProxyHosts");
}
- if ((pacFileUrl != null) && !TextUtils.isEmpty(pacFileUrl)) {
- if (sPacProxySelector == null) {
- sPacProxySelector = new PacProxySelector();
- }
- ProxySelector.setDefault(sPacProxySelector);
+ if (!TextUtils.isEmpty(pacFileUrl)) {
+ ProxySelector.setDefault(new PacProxySelector());
} else {
ProxySelector.setDefault(sDefaultProxySelector);
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1363e3ca2a5a..813b55f14beb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -218,6 +218,7 @@
<protected-broadcast android:name="android.location.GPS_ENABLED_CHANGE" />
<protected-broadcast android:name="android.location.PROVIDERS_CHANGED" />
<protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
+ <protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
diff --git a/packages/services/PacProcessor/Android.mk b/packages/services/PacProcessor/Android.mk
index e4afde69eb22..d9566d5022d1 100644
--- a/packages/services/PacProcessor/Android.mk
+++ b/packages/services/PacProcessor/Android.mk
@@ -18,24 +18,15 @@ 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
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
-include $(BUILD_EXECUTABLE)
+LOCAL_PACKAGE_NAME := PacProcessor
+LOCAL_CERTIFICATE := platform
+
+LOCAL_REQUIRED_MODULES := libjni_pacprocessor
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/services/PacProcessor/AndroidManifest.xml b/packages/services/PacProcessor/AndroidManifest.xml
new file mode 100644
index 000000000000..6740c169ff21
--- /dev/null
+++ b/packages/services/PacProcessor/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.pacprocessor">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:label="@string/app_name">
+
+ <service android:name=".PacService"
+ android:exported="true">
+ </service>
+
+ </application>
+
+</manifest>
diff --git a/packages/services/PacProcessor/IProxyService.cpp b/packages/services/PacProcessor/IProxyService.cpp
deleted file mode 100644
index 3707d8554b34..000000000000
--- a/packages/services/PacProcessor/IProxyService.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-#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
deleted file mode 100644
index 57c527b5944e..000000000000
--- a/packages/services/PacProcessor/IProxyService.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#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
deleted file mode 100644
index 7084a47fe435..000000000000
--- a/packages/services/PacProcessor/ProxyService.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#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
deleted file mode 100644
index a0861b2d620e..000000000000
--- a/packages/services/PacProcessor/ProxyService.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#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/com/android/net/IProxyService.aidl b/packages/services/PacProcessor/com/android/net/IProxyService.aidl
new file mode 100644
index 000000000000..4e54aba5c3bf
--- /dev/null
+++ b/packages/services/PacProcessor/com/android/net/IProxyService.aidl
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+package com.android.net;
+
+/** @hide */
+interface IProxyService
+{
+ String resolvePacFile(String host, String url);
+
+ oneway void setPacFile(String scriptContents);
+
+ oneway void startPacSystem();
+ oneway void stopPacSystem();
+}
diff --git a/packages/services/PacProcessor/jni/Android.mk b/packages/services/PacProcessor/jni/Android.mk
new file mode 100644
index 000000000000..f16c90b367dd
--- /dev/null
+++ b/packages/services/PacProcessor/jni/Android.mk
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2013 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 := \
+ jni_init.cpp \
+ com_android_pacprocessor_PacNative.cpp
+
+LOCAL_C_INCLUDES += \
+ external/chromium-libpac/src
+
+LOCAL_SHARED_LIBRARIES := \
+ libandroidfw \
+ libandroid_runtime \
+ liblog \
+ libutils \
+ libnativehelper \
+ libpac
+
+LOCAL_MODULE := libjni_pacprocessor
+LOCAL_MODULE_TAGS := optional
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp b/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp
new file mode 100644
index 000000000000..c5aa13bb26eb
--- /dev/null
+++ b/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 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 "PacProcessor"
+
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+#include "android_runtime/AndroidRuntime.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "proxy_resolver_v8.h"
+
+namespace android {
+
+class ProxyErrorLogger : public net::ProxyErrorListener {
+public:
+ ~ProxyErrorLogger() {
+
+ }
+ void AlertMessage(String16 message) {
+ String8 str(message);
+ ALOGD("Alert: %s", str.string());
+ }
+ void ErrorMessage(String16 message) {
+ String8 str(message);
+ ALOGE("Error: %s", str.string());
+ }
+};
+
+net::ProxyResolverV8* proxyResolver = NULL;
+ProxyErrorLogger* logger = NULL;
+bool pacSet = false;
+
+String16 jstringToString16(JNIEnv* env, jstring jstr) {
+ const jchar* str = env->GetStringCritical(jstr, 0);
+ String16 str16(str, env->GetStringLength(jstr));
+ env->ReleaseStringCritical(jstr, str);
+ return str16;
+}
+
+jstring string16ToJstring(JNIEnv* env, String16 string) {
+ const char16_t* str = string.string();
+ size_t len = string.size();
+
+ return env->NewString(str, len);
+}
+
+static jboolean com_android_pacprocessor_PacNative_createV8ParserNativeLocked(JNIEnv* env,
+ jobject) {
+ if (proxyResolver == NULL) {
+ logger = new ProxyErrorLogger();
+ proxyResolver = new net::ProxyResolverV8(net::ProxyResolverJSBindings::CreateDefault(),
+ logger);
+ pacSet = false;
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+static jboolean com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked(JNIEnv* env,
+ jobject) {
+ if (proxyResolver != NULL) {
+ delete logger;
+ delete proxyResolver;
+ logger = NULL;
+ proxyResolver = NULL;
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+static jboolean com_android_pacprocessor_PacNative_setProxyScriptNativeLocked(JNIEnv* env, jobject,
+ jstring script) {
+ String16 script16 = jstringToString16(env, script);
+
+ if (proxyResolver == NULL) {
+ ALOGE("V8 Parser not started when setting PAC script");
+ return JNI_TRUE;
+ }
+
+ if (proxyResolver->SetPacScript(script16) != OK) {
+ ALOGE("Unable to set PAC script");
+ return JNI_TRUE;
+ }
+ pacSet = true;
+
+ return JNI_FALSE;
+}
+
+static jstring com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked(JNIEnv* env, jobject,
+ jstring url, jstring host) {
+ String16 url16 = jstringToString16(env, url);
+ String16 host16 = jstringToString16(env, host);
+ String16 ret;
+
+ if (proxyResolver == NULL) {
+ ALOGE("V8 Parser not initialized when running PAC script");
+ return NULL;
+ }
+
+ if (!pacSet) {
+ ALOGW("Attempting to run PAC with no script set");
+ return NULL;
+ }
+
+ if (proxyResolver->GetProxyForURL(url16, host16, &ret) != OK) {
+ String8 ret8(ret);
+ ALOGE("Error Running PAC: %s", ret8.string());
+ return NULL;
+ }
+
+ jstring jret = string16ToJstring(env, ret);
+
+ return jret;
+}
+
+static JNINativeMethod gMethods[] = {
+ { "createV8ParserNativeLocked", "()Z",
+ (void*)com_android_pacprocessor_PacNative_createV8ParserNativeLocked},
+ { "destroyV8ParserNativeLocked", "()Z",
+ (void*)com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked},
+ { "setProxyScriptNativeLocked", "(Ljava/lang/String;)Z",
+ (void*)com_android_pacprocessor_PacNative_setProxyScriptNativeLocked},
+ { "makeProxyRequestNativeLocked", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+ (void*)com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked},
+};
+
+int register_com_android_pacprocessor_PacNative(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "com/android/pacprocessor/PacNative",
+ gMethods, NELEM(gMethods));
+}
+
+} /* namespace android */
diff --git a/packages/services/PacProcessor/jni/jni_init.cpp b/packages/services/PacProcessor/jni/jni_init.cpp
new file mode 100644
index 000000000000..bda33fb33c07
--- /dev/null
+++ b/packages/services/PacProcessor/jni/jni_init.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 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 "PacProcessor"
+
+#include <utils/Log.h>
+#include "jni.h"
+
+namespace android {
+ extern int register_com_android_pacprocessor_PacNative(JNIEnv *env);
+}
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ JNIEnv *env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ ALOGE("ERROR: GetEnv failed");
+ return -1;
+ }
+
+ register_com_android_pacprocessor_PacNative(env);
+
+ return JNI_VERSION_1_6;
+}
diff --git a/packages/services/PacProcessor/main_pacserver.cpp b/packages/services/PacProcessor/main_pacserver.cpp
deleted file mode 100644
index 19588b5074c2..000000000000
--- a/packages/services/PacProcessor/main_pacserver.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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();
-}
diff --git a/packages/services/PacProcessor/res/values/strings.xml b/packages/services/PacProcessor/res/values/strings.xml
new file mode 100644
index 000000000000..301a2b6cb1ee
--- /dev/null
+++ b/packages/services/PacProcessor/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_name">PacProcessor</string>
+
+</resources>
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
new file mode 100644
index 000000000000..c67fe9ffa916
--- /dev/null
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+package com.android.pacprocessor;
+
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class PacNative {
+ private static final String TAG = "PacProxy";
+
+ private String mCurrentPac;
+
+ private boolean mIsActive;
+
+ // Only make native calls from inside synchronized blocks.
+ private native boolean createV8ParserNativeLocked();
+ private native boolean destroyV8ParserNativeLocked();
+
+ private native boolean setProxyScriptNativeLocked(String script);
+
+ private native String makeProxyRequestNativeLocked(String url, String host);
+
+ static {
+ System.loadLibrary("jni_pacprocessor");
+ }
+
+ PacNative() {
+
+ }
+
+ public synchronized boolean startPacSupport() {
+ if (createV8ParserNativeLocked()) {
+ Log.e(TAG, "Unable to Create v8 Proxy Parser.");
+ return true;
+ }
+ mIsActive = true;
+ return false;
+ }
+
+ public synchronized boolean stopPacSupport() {
+ if (mIsActive) {
+ if (destroyV8ParserNativeLocked()) {
+ Log.e(TAG, "Unable to Destroy v8 Proxy Parser.");
+ return true;
+ }
+ mIsActive = false;
+ }
+ return false;
+ }
+
+ public synchronized boolean setCurrentProxyScript(String script) {
+ if (setProxyScriptNativeLocked(script)) {
+ Log.e(TAG, "Unable to parse proxy script.");
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized String makeProxyRequest(String url, String host) {
+ String ret = makeProxyRequestNativeLocked(url, host);
+ if ((ret == null) || (ret.length() == 0)) {
+ Log.e(TAG, "v8 Proxy request failed.");
+ ret = null;
+ }
+ return ret;
+ }
+
+ public synchronized boolean isActive() {
+ return mIsActive;
+ }
+}
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
new file mode 100644
index 000000000000..7e760251ac8a
--- /dev/null
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
+package com.android.pacprocessor;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.net.IProxyService;
+
+public class PacService extends Service {
+ private static final String TAG = "PacService";
+
+ private PacNative mPacNative;
+ private ProxyServiceStub mStub;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (mPacNative == null) {
+ mPacNative = new PacNative();
+ mStub = new ProxyServiceStub(mPacNative);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mPacNative != null) {
+ mPacNative.stopPacSupport();
+ mPacNative = null;
+ mStub = null;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (mPacNative == null) {
+ mPacNative = new PacNative();
+ mStub = new ProxyServiceStub(mPacNative);
+ }
+ return mStub;
+ }
+
+ private static class ProxyServiceStub extends IProxyService.Stub {
+ private final PacNative mPacNative;
+
+ public ProxyServiceStub(PacNative pacNative) {
+ mPacNative = pacNative;
+ }
+
+ @Override
+ public String resolvePacFile(String host, String url) throws RemoteException {
+ return mPacNative.makeProxyRequest(url, host);
+ }
+
+ @Override
+ public void setPacFile(String script) throws RemoteException {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ Log.e(TAG, "Only system user is allowed to call setPacFile");
+ throw new SecurityException();
+ }
+ mPacNative.setCurrentProxyScript(script);
+ }
+
+ @Override
+ public void startPacSystem() throws RemoteException {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ Log.e(TAG, "Only system user is allowed to call startPacSystem");
+ throw new SecurityException();
+ }
+ mPacNative.startPacSupport();
+ }
+
+ @Override
+ public void stopPacSystem() throws RemoteException {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ Log.e(TAG, "Only system user is allowed to call stopPacSystem");
+ throw new SecurityException();
+ }
+ mPacNative.stopPacSupport();
+ }
+ }
+}
diff --git a/packages/services/Proxy/com/android/net/IProxyService.aidl b/packages/services/Proxy/com/android/net/IProxyService.aidl
deleted file mode 100644
index 7e9ed799c7c3..000000000000
--- a/packages/services/Proxy/com/android/net/IProxyService.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.android.net;
-
-/** @hide */
-interface IProxyService
-{
- /**
- * Keep up-to-date with
- * frameworks/base/packages/services/PacProcessor/IProxyService.h
- */
- String resolvePacFile(String host, String url);
-
- int setPacFile(String scriptContents);
-
- int startPacSystem();
- int stopPacSystem();
-}
diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java
index defe9f075147..0b68ff5595eb 100644
--- a/services/java/com/android/server/connectivity/PacManager.java
+++ b/services/java/com/android/server/connectivity/PacManager.java
@@ -1,14 +1,31 @@
+/**
+ * Copyright (c) 2013, 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.
+ */
package com.android.server.connectivity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.net.ConnectivityManager;
+import android.content.ServiceConnection;
import android.net.ProxyProperties;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -17,42 +34,26 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
import com.android.net.IProxyService;
+import com.android.server.IoThread;
+import libcore.io.Streams;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.params.ConnRouteParams;
-import org.apache.http.conn.routing.HttpRoute;
-import org.apache.http.conn.routing.HttpRoutePlanner;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.HttpContext;
-
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.ProxySelector;
import java.net.URL;
import java.net.URLConnection;
/**
* @hide
*/
-public class PacManager implements Runnable {
- public static final int NO_ERROR = 0;
- public static final int PERMISSION_DENIED = 1;
- public static final String PROXY_SERVICE = "com.android.net.IProxyService";
+public class PacManager {
+ public static final String PROXY_PACKAGE = "com.android.pacprocessor";
+ public static final String PROXY_SERVICE = "com.android.pacprocessor.PacService";
+ public static final String PROXY_SERVICE_NAME = "com.android.net.IProxyService";
- private static final String TAG = "PACManager";
+ private static final String TAG = "PacManager";
private static final String ACTION_PAC_REFRESH = "android.net.proxy.PAC_REFRESH";
@@ -64,31 +65,57 @@ public class PacManager implements Runnable {
/** Keep these values up-to-date with ProxyService.java */
public static final String KEY_PROXY = "keyProxy";
private String mCurrentPac;
- private volatile String mPacUrl;
+ @GuardedBy("mProxyLock")
+ private String mPacUrl;
private AlarmManager mAlarmManager;
+ @GuardedBy("mProxyLock")
private IProxyService mProxyService;
private PendingIntent mPacRefreshIntent;
+ private ServiceConnection mConnection;
private Context mContext;
private int mCurrentDelay;
+ /**
+ * Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac.
+ */
+ private final Object mProxyLock = new Object();
+
+ private Runnable mPacDownloader = new Runnable() {
+ @Override
+ public void run() {
+ String file;
+ synchronized (mProxyLock) {
+ if (mPacUrl == null) return;
+ try {
+ file = get(mPacUrl);
+ } catch (IOException ioe) {
+ file = null;
+ Log.w(TAG, "Failed to load PAC file: " + ioe);
+ }
+ }
+ if (file != null) {
+ synchronized (mProxyLock) {
+ if (!file.equals(mCurrentPac)) {
+ setCurrentProxyScript(file);
+ }
+ }
+ longSchedule();
+ } else {
+ reschedule();
+ }
+ }
+ };
+
class PacRefreshIntentReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
- new Thread(PacManager.this).start();
+ IoThread.getHandler().post(mPacDownloader);
}
}
public PacManager(Context context) {
mContext = context;
- mProxyService = IProxyService.Stub.asInterface(
- ServiceManager.getService(PROXY_SERVICE));
- if (mProxyService == null) {
- // Added because of b10267814 where mako is restarting.
- Log.e(TAG, "PacManager: no proxy service");
- } else {
- Log.d(TAG, "PacManager: mProxyService available");
- }
mPacRefreshIntent = PendingIntent.getBroadcast(
context, 0, new Intent(ACTION_PAC_REFRESH), 0);
@@ -103,26 +130,28 @@ public class PacManager implements Runnable {
return mAlarmManager;
}
- public void setCurrentProxyScriptUrl(ProxyProperties proxy) {
- if (mProxyService == null) {
- Log.e(TAG, "setCurrentProxyScriptUrl: no proxy service");
- return;
- }
+ public synchronized void setCurrentProxyScriptUrl(ProxyProperties proxy) {
if (!TextUtils.isEmpty(proxy.getPacFileUrl())) {
- try {
- mProxyService.startPacSystem();
+ synchronized (mProxyLock) {
mPacUrl = proxy.getPacFileUrl();
- mCurrentDelay = DELAY_1;
- getAlarmManager().cancel(mPacRefreshIntent);
- new Thread(this).start();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e);
}
+ mCurrentDelay = DELAY_1;
+ getAlarmManager().cancel(mPacRefreshIntent);
+ bind();
} else {
- try {
- mProxyService.stopPacSystem();
- } catch (RemoteException e) {
- e.printStackTrace();
+ getAlarmManager().cancel(mPacRefreshIntent);
+ synchronized (mProxyLock) {
+ mPacUrl = null;
+ mCurrentPac = null;
+ if (mProxyService != null) {
+ try {
+ mProxyService.stopPacSystem();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to stop PAC service", e);
+ } finally {
+ unbind();
+ }
+ }
}
}
}
@@ -132,51 +161,10 @@ public class PacManager implements Runnable {
*
* @throws IOException
*/
- public static String get(String urlString) throws IOException {
+ private static String get(String urlString) throws IOException {
URL url = new URL(urlString);
URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
- BufferedReader in = new BufferedReader(new InputStreamReader(
- urlConnection.getInputStream()));
- String inputLine;
- String resp = "";
- while ((inputLine = in.readLine()) != null) {
- resp = resp + inputLine + "\n";
- }
- in.close();
- return resp;
- }
-
- private static String toString(InputStream content) throws IOException {
- StringBuffer buffer = new StringBuffer();
- String line;
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(content));
-
- while ((line = bufferedReader.readLine()) != null) {
- if (buffer.length() != 0) {
- buffer.append('\n');
- }
- buffer.append(line);
- }
-
- return buffer.toString();
- }
-
- @Override
- public void run() {
- String file;
- try {
- file = get(mPacUrl);
- } catch (IOException ioe) {
- file = null;
- }
- if (file != null) {
- if (!file.equals(mCurrentPac)) {
- setCurrentProxyScript(file);
- }
- longSchedule();
- } else {
- reschedule();
- }
+ return new String(Streams.readFully(urlConnection.getInputStream()));
}
private int getNextDelay(int currentDelay) {
@@ -227,14 +215,60 @@ public class PacManager implements Runnable {
return false;
}
try {
- if (mProxyService.setPacFile(script) != NO_ERROR) {
- Log.e(TAG, "Unable to parse proxy script.");
- return false;
- }
+ mProxyService.setPacFile(script);
mCurrentPac = script;
} catch (RemoteException e) {
Log.e(TAG, "Unable to set PAC file", e);
}
return true;
}
+
+ private void bind() {
+ if (mContext == null) {
+ Log.e(TAG, "No context for binding");
+ return;
+ }
+ Intent intent = new Intent();
+ intent.setClassName(PROXY_PACKAGE, PROXY_SERVICE);
+ mConnection = new ServiceConnection() {
+ @Override
+ public void onServiceDisconnected(ComponentName component) {
+ synchronized (mProxyLock) {
+ mProxyService = null;
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName component, IBinder binder) {
+ synchronized (mProxyLock) {
+ try {
+ Log.d(TAG, "Adding service " + PROXY_SERVICE_NAME + " "
+ + binder.getInterfaceDescriptor());
+ } catch (RemoteException e1) {
+ Log.e(TAG, "Remote Exception", e1);
+ }
+ ServiceManager.addService(PROXY_SERVICE_NAME, binder);
+ mProxyService = IProxyService.Stub.asInterface(binder);
+ if (mProxyService == null) {
+ Log.e(TAG, "No proxy service");
+ } else {
+ try {
+ mProxyService.startPacSystem();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e);
+ }
+ IoThread.getHandler().post(mPacDownloader);
+ }
+ }
+ }
+ };
+ Log.e(TAG, "Attempting to bind");
+ mContext.bindService(intent, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE);
+ }
+
+ private void unbind() {
+ mContext.unbindService(mConnection);
+ mConnection = null;
+ }
}