diff options
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; + } } |