1 /*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "PacProcessor"
18
19 #include <utils/Log.h>
20 #include <utils/Mutex.h>
21 #include "android_runtime/AndroidRuntime.h"
22
23 #include "jni.h"
24 #include "JNIHelp.h"
25
26 #include "proxy_resolver_v8.h"
27
28 namespace android {
29
30 class ProxyErrorLogger : public net::ProxyErrorListener {
31 public:
~ProxyErrorLogger()32 ~ProxyErrorLogger() {
33
34 }
AlertMessage(String16 message)35 void AlertMessage(String16 message) {
36 String8 str(message);
37 ALOGD("Alert: %s", str.string());
38 }
ErrorMessage(String16 message)39 void ErrorMessage(String16 message) {
40 String8 str(message);
41 ALOGE("Error: %s", str.string());
42 }
43 };
44
45 net::ProxyResolverV8* proxyResolver = NULL;
46 ProxyErrorLogger* logger = NULL;
47 bool pacSet = false;
48
jstringToString16(JNIEnv * env,jstring jstr)49 String16 jstringToString16(JNIEnv* env, jstring jstr) {
50 const jchar* str = env->GetStringCritical(jstr, 0);
51 String16 str16(str, env->GetStringLength(jstr));
52 env->ReleaseStringCritical(jstr, str);
53 return str16;
54 }
55
string16ToJstring(JNIEnv * env,String16 string)56 jstring string16ToJstring(JNIEnv* env, String16 string) {
57 const char16_t* str = string.string();
58 size_t len = string.size();
59
60 return env->NewString(str, len);
61 }
62
com_android_pacprocessor_PacNative_createV8ParserNativeLocked(JNIEnv * env,jobject)63 static jboolean com_android_pacprocessor_PacNative_createV8ParserNativeLocked(JNIEnv* env,
64 jobject) {
65 if (proxyResolver == NULL) {
66 logger = new ProxyErrorLogger();
67 proxyResolver = new net::ProxyResolverV8(net::ProxyResolverJSBindings::CreateDefault(),
68 logger);
69 pacSet = false;
70 return JNI_FALSE;
71 }
72 return JNI_TRUE;
73 }
74
com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked(JNIEnv * env,jobject)75 static jboolean com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked(JNIEnv* env,
76 jobject) {
77 if (proxyResolver != NULL) {
78 delete logger;
79 delete proxyResolver;
80 logger = NULL;
81 proxyResolver = NULL;
82 return JNI_FALSE;
83 }
84 return JNI_TRUE;
85 }
86
com_android_pacprocessor_PacNative_setProxyScriptNativeLocked(JNIEnv * env,jobject,jstring script)87 static jboolean com_android_pacprocessor_PacNative_setProxyScriptNativeLocked(JNIEnv* env, jobject,
88 jstring script) {
89 String16 script16 = jstringToString16(env, script);
90
91 if (proxyResolver == NULL) {
92 ALOGE("V8 Parser not started when setting PAC script");
93 return JNI_TRUE;
94 }
95
96 if (proxyResolver->SetPacScript(script16) != OK) {
97 ALOGE("Unable to set PAC script");
98 return JNI_TRUE;
99 }
100 pacSet = true;
101
102 return JNI_FALSE;
103 }
104
com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked(JNIEnv * env,jobject,jstring url,jstring host)105 static jstring com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked(JNIEnv* env, jobject,
106 jstring url, jstring host) {
107 String16 url16 = jstringToString16(env, url);
108 String16 host16 = jstringToString16(env, host);
109 String16 ret;
110
111 if (proxyResolver == NULL) {
112 ALOGE("V8 Parser not initialized when running PAC script");
113 return NULL;
114 }
115
116 if (!pacSet) {
117 ALOGW("Attempting to run PAC with no script set");
118 return NULL;
119 }
120
121 if (proxyResolver->GetProxyForURL(url16, host16, &ret) != OK) {
122 String8 ret8(ret);
123 ALOGE("Error Running PAC: %s", ret8.string());
124 return NULL;
125 }
126
127 jstring jret = string16ToJstring(env, ret);
128
129 return jret;
130 }
131
132 static JNINativeMethod gMethods[] = {
133 { "createV8ParserNativeLocked", "()Z",
134 (void*)com_android_pacprocessor_PacNative_createV8ParserNativeLocked},
135 { "destroyV8ParserNativeLocked", "()Z",
136 (void*)com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked},
137 { "setProxyScriptNativeLocked", "(Ljava/lang/String;)Z",
138 (void*)com_android_pacprocessor_PacNative_setProxyScriptNativeLocked},
139 { "makeProxyRequestNativeLocked", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
140 (void*)com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked},
141 };
142
register_com_android_pacprocessor_PacNative(JNIEnv * env)143 int register_com_android_pacprocessor_PacNative(JNIEnv* env) {
144 return jniRegisterNativeMethods(env, "com/android/pacprocessor/PacNative",
145 gMethods, NELEM(gMethods));
146 }
147
148 } /* namespace android */
149