Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: jni/AbpEngine.cpp

Issue 5697499218051072: Usage of new API, cleanups (reduced) (Closed)
Patch Set: Addressed new review issues Created April 28, 2014, 8:34 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « .hgignore ('k') | jni/Android.mk » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <jni.h>
19 #include <AdblockPlus.h>
20 #include "AndroidLogSystem.h"
21 #include "AndroidWebRequest.h"
22 #include "Utils.h"
23 #include "Debug.h"
24
25 JavaVM* globalJvm;
26 AdblockPlus::FilterEngine* filterEngine;
27 jobject jniObject;
28 bool manualUpdate = false;
29
30 extern "C"
31 {
32 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_initialize(
33 JNIEnv *pEnv, jobject object, jstring basePath, jstring version,
34 jstring sdkVersion, jstring locale, jboolean developmentBuild);
35 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_release(JNIEnv * pEnv, jobject);
36 JNIEXPORT jboolean JNICALL Java_org_adblockplus_android_ABPEngine_isFirstRun(J NIEnv *pEnv, jobject);
37 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getListe dSubscriptions(JNIEnv *pEnv, jobject);
38 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getRecom mendedSubscriptions(JNIEnv *pEnv, jobject);
39 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_addSubscription( JNIEnv *pEnv, jobject, jstring url);
40 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_removeSubscripti on(JNIEnv *pEnv, jobject, jstring url);
41 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_refreshSubscript ion(JNIEnv *pEnv, jobject, jstring url);
42 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_actualizeSubscri ptionStatus(JNIEnv *pEnv, jobject, jstring url);
43 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_setAcceptableAds Enabled(JNIEnv *pEnv, jobject, jboolean enabled);
44 JNIEXPORT jstring JNICALL Java_org_adblockplus_android_ABPEngine_getDocumentat ionLink(
45 JNIEnv *env, jobject object);
46 JNIEXPORT jboolean JNICALL Java_org_adblockplus_android_ABPEngine_matches(
47 JNIEnv *pEnv, jobject, jstring url, jstring contentType, jobjectArray docu mentUrls);
48 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getSelec torsForDomain(JNIEnv *pEnv, jobject, jstring domain);
49 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_checkUpdates(JNI Env *pEnv, jobject);
50 };
51
52 jobjectArray subscriptionsAsJavaArray(JNIEnv *pEnv, std::vector<AdblockPlus::Sub scriptionPtr> subscriptions)
53 {
54 D(D_WARN, "subscriptionsAsJavaArray()");
55 static jclass cls = reinterpret_cast<jclass>(pEnv->NewGlobalRef(pEnv->FindClas s("org/adblockplus/android/Subscription")));
56 static jmethodID cid = pEnv->GetMethodID(cls, "<init>", "()V");
57 static jfieldID ftitle = pEnv->GetFieldID(cls, "title", "Ljava/lang/String;");
58 static jfieldID furl = pEnv->GetFieldID(cls, "url", "Ljava/lang/String;");
59
60 const std::string surl = filterEngine->GetPref("subscriptions_exceptionsurl")- >AsString();
61 AdblockPlus::SubscriptionPtr acceptableAdsSubscription = filterEngine->GetSubs cription(surl);
62
63 int size = subscriptions.size();
64 for (std::vector<AdblockPlus::SubscriptionPtr>::const_iterator it = subscripti ons.begin();
65 it != subscriptions.end(); it++)
66 {
67 if (*acceptableAdsSubscription == **it)
68 size--;
69 }
70
71 const jobjectArray ret = (jobjectArray) pEnv->NewObjectArray(size, cls, NULL);
72
73 int i = 0;
74 for (std::vector<AdblockPlus::SubscriptionPtr>::const_iterator it = subscripti ons.begin();
75 it != subscriptions.end(); it++)
76 {
77 if (*acceptableAdsSubscription == **it)
78 continue;
79 jobject subscription = pEnv->NewObject(cls, cid);
80 pEnv->SetObjectField(subscription, ftitle, pEnv->NewStringUTF((*it)->GetProp erty("title")->AsString().c_str()));
81 pEnv->SetObjectField(subscription, furl, pEnv->NewStringUTF((*it)->GetProper ty("url")->AsString().c_str()));
82 pEnv->SetObjectArrayElement(ret, i, subscription);
83 i++;
84 }
85
86 return ret;
87 }
88
89 void UpdateSubscriptionStatus(const AdblockPlus::SubscriptionPtr subscription)
90 {
91 D(D_WARN, "UpdateSubscriptionStatus()");
92
93 std::string downloadStatus = subscription->GetProperty("downloadStatus")->IsNu ll() ? "" : subscription->GetProperty("downloadStatus")->AsString();
94 int64_t lastDownload = subscription->GetProperty("lastDownload")->AsInt();
95
96 std::string status = "synchronize_never";
97 int64_t time = 0;
98
99 if (subscription->IsUpdating())
100 {
101 status = "synchronize_in_progress";
102 }
103 else if (!downloadStatus.empty() && downloadStatus != "synchronize_ok")
104 {
105 status = downloadStatus;
106 }
107 else if (lastDownload > 0)
108 {
109 time = lastDownload;
110 status = "synchronize_last_at";
111 }
112
113 JNIEnv* jniEnv = NULL;
114 int stat = globalJvm->GetEnv((void **)&jniEnv, JNI_VERSION_1_6);
115 if (stat == JNI_EDETACHED)
116 {
117 if (globalJvm->AttachCurrentThread(&jniEnv, NULL) != 0)
118 throw std::runtime_error("Failed to get JNI environment");
119 }
120
121 jstring jUrl = jniEnv->NewStringUTF(subscription->GetProperty("url")->AsString ().c_str());
122 jstring jStatus = jniEnv->NewStringUTF(status.c_str());
123 jlong jTime = time * 1000;
124
125 static jclass cls = jniEnv->GetObjectClass(jniObject);
126 static jmethodID mid = jniEnv->GetMethodID(cls, "onFilterChanged", "(Ljava/lan g/String;Ljava/lang/String;J)V");
127 if (mid)
128 jniEnv->CallVoidMethod(jniObject, mid, jUrl, jStatus, jTime);
129 jniEnv->DeleteLocalRef(jUrl);
130 jniEnv->DeleteLocalRef(jStatus);
131
132 if (stat == JNI_EDETACHED)
133 globalJvm->DetachCurrentThread();
134 }
135
136 void FilterChangedCallback(const std::string& action, const AdblockPlus::JsValue Ptr item)
137 {
138 D(D_WARN, "FilterChangedCallback()");
139
140 if (action == "subscription.lastDownload" || action == "subscription.downloadS tatus")
141 {
142 AdblockPlus::SubscriptionPtr subscription = AdblockPlus::SubscriptionPtr(new AdblockPlus::Subscription(item));
143 UpdateSubscriptionStatus(subscription);
144 }
145 }
146
147 void UpdateAvailableCallback(AdblockPlus::JsValueList& params)
148 {
149 D(D_WARN, "UpdateAvailableCallback()");
150 std::string updateUrl(params.size() >= 1 && !params[0]->IsNull() ? params[0]-> AsString() : "");
151 if (updateUrl.empty())
152 return;
153
154 JNIEnv* jniEnv = NULL;
155 int stat = globalJvm->GetEnv((void **)&jniEnv, JNI_VERSION_1_6);
156 if (stat == JNI_EDETACHED)
157 {
158 if (globalJvm->AttachCurrentThread(&jniEnv, NULL) != 0)
159 throw std::runtime_error("Failed to get JNI environment");
160 }
161
162 jstring jUrl = jniEnv->NewStringUTF(updateUrl.c_str());
163
164 static jclass cls = jniEnv->GetObjectClass(jniObject);
165 static jmethodID mid = jniEnv->GetMethodID(cls, "onUpdateEvent", "(Ljava/lang/ String;Ljava/lang/String;)V");
166 if (mid)
167 jniEnv->CallVoidMethod(jniObject, mid, jUrl, NULL);
168 jniEnv->DeleteLocalRef(jUrl);
169
170 if (stat == JNI_EDETACHED)
171 globalJvm->DetachCurrentThread();
172 }
173
174 void UpdaterCallback(const std::string& error)
175 {
176 JNIEnv* jniEnv = NULL;
177 int stat = globalJvm->GetEnv((void **)&jniEnv, JNI_VERSION_1_6);
178 if (stat == JNI_EDETACHED)
179 {
180 if (globalJvm->AttachCurrentThread(&jniEnv, NULL) != 0)
181 throw std::runtime_error("Failed to get JNI environment");
182 }
183
184 static jclass cls = jniEnv->GetObjectClass(jniObject);
185 static jmethodID mid = jniEnv->GetMethodID(cls, "onUpdateEvent", "(Ljava/lang/ String;Ljava/lang/String;)V");
186
187 if (!error.empty())
188 {
189 jstring jError = jniEnv->NewStringUTF(error.c_str());
190 if (mid)
191 jniEnv->CallVoidMethod(jniObject, mid, NULL, jError);
192 jniEnv->DeleteLocalRef(jError);
193 }
194 else if (manualUpdate)
195 {
196 if (mid)
197 jniEnv->CallVoidMethod(jniObject, mid, NULL, NULL);
198 }
199
200 if (stat == JNI_EDETACHED)
201 globalJvm->DetachCurrentThread();
202 }
203
204 void ThrowJavaException(JNIEnv* env, const std::string& message)
205 {
206 jclass exceptionClass = env->FindClass("java/lang/Exception");
207 env->ThrowNew(exceptionClass, message.c_str());
208 }
209
210 void ThrowJavaException(JNIEnv* env, const std::exception& e)
211 {
212 ThrowJavaException(env, std::string("Exception from libadblockplus: ") + e.wha t());
213 }
214
215 void ThrowJavaException(JNIEnv* env)
216 {
217 ThrowJavaException(env, "Unknown exception from libadblockplus");
218 }
219
220 jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
221 {
222 return JNI_VERSION_1_6;
223 }
224
225 void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
226 {
227 }
228
229 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_initialize(
230 JNIEnv *pEnv, jobject pObject, jstring basePath, jstring version,
231 jstring sdkVersion, jstring locale, jboolean developmentBuild)
232 {
233 D(D_WARN, "nativeInitialize()");
234 try
235 {
236 int status = pEnv->GetJavaVM(&globalJvm);
237
238 jniObject = pEnv->NewGlobalRef(pObject);
239
240 AdblockPlus::AppInfo appInfo;
241 appInfo.name = "adblockplusandroid";
242 appInfo.version = GetString(pEnv, version);
243 appInfo.application = "android";
244 appInfo.applicationVersion = GetString(pEnv, sdkVersion);
245 appInfo.locale = GetString(pEnv, locale);
246 appInfo.developmentBuild = developmentBuild;
247
248 D(D_INFO, "AppInfo: name=%s, version=%s, application=%s, applicationVersion= %s , locale=%s, developmentBuild=%s",
249 appInfo.name.c_str(), appInfo.version.c_str(), appInfo.application.c_str() ,
250 appInfo.applicationVersion.c_str(), appInfo.locale.c_str(),
251 appInfo.developmentBuild ? "true" : "false");
252
253 AdblockPlus::JsEnginePtr jsEngine(AdblockPlus::JsEngine::New(appInfo));
254
255 AdblockPlus::DefaultFileSystem* defaultFileSystem = new AdblockPlus::Default FileSystem();
256 AndroidLogSystem* androidLogSystem = new AndroidLogSystem();
257 AndroidWebRequest* androidWebRequest = new AndroidWebRequest(globalJvm);
258
259 defaultFileSystem->SetBasePath(GetString(pEnv, basePath));
260 jsEngine->SetLogSystem(AdblockPlus::LogSystemPtr(androidLogSystem));
261 jsEngine->SetFileSystem(AdblockPlus::FileSystemPtr(defaultFileSystem));
262 jsEngine->SetWebRequest(AdblockPlus::WebRequestPtr(androidWebRequest));
263 jsEngine->SetEventCallback("updateAvailable", std::tr1::bind(&UpdateAvailabl eCallback, std::tr1::placeholders::_1));
264
265 filterEngine = new AdblockPlus::FilterEngine(jsEngine);
266 filterEngine->SetFilterChangeCallback(&FilterChangedCallback);
267 }
268 catch (const std::exception& e)
269 {
270 ThrowJavaException(pEnv, e);
271 }
272 catch (...)
273 {
274 ThrowJavaException(pEnv);
275 }
276 }
277
278 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_release(JNIEnv *pE nv, jobject)
279 {
280 D(D_WARN, "nativeRelease()");
281 try
282 {
283 AdblockPlus::JsEnginePtr jsEngine = filterEngine->GetJsEngine();
284 jsEngine->RemoveEventCallback("updateAvailable");
285 filterEngine->RemoveFilterChangeCallback();
286 delete filterEngine;
287 pEnv->DeleteGlobalRef(jniObject);
288 jniObject = NULL;
289 globalJvm = NULL;
290 }
291 catch (const std::exception& e)
292 {
293 ThrowJavaException(pEnv, e);
294 }
295 catch (...)
296 {
297 ThrowJavaException(pEnv);
298 }
299 }
300
301 JNIEXPORT jboolean JNICALL Java_org_adblockplus_android_ABPEngine_isFirstRun(JNI Env *pEnv, jobject)
302 {
303 try
304 {
305 return filterEngine->IsFirstRun() ? JNI_TRUE : JNI_FALSE;
306 }
307 catch (const std::exception& e)
308 {
309 ThrowJavaException(pEnv, e);
310 }
311 catch (...)
312 {
313 ThrowJavaException(pEnv);
314 }
315 return JNI_FALSE;
316 }
317
318 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getListedS ubscriptions(JNIEnv *pEnv, jobject)
319 {
320 D(D_WARN, "getListedSubscriptions()");
321 try
322 {
323 const std::vector<AdblockPlus::SubscriptionPtr> subscriptions = filterEngine ->GetListedSubscriptions();
324 return subscriptionsAsJavaArray(pEnv, subscriptions);
325 }
326 catch (const std::exception& e)
327 {
328 ThrowJavaException(pEnv, e);
329 }
330 catch (...)
331 {
332 ThrowJavaException(pEnv);
333 }
334 return 0;
335 }
336
337 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getRecomme ndedSubscriptions(JNIEnv *pEnv, jobject)
338 {
339 D(D_WARN, "getRecommendedSubscriptions()");
340 try
341 {
342 const std::vector<AdblockPlus::SubscriptionPtr> subscriptions = filterEngine ->FetchAvailableSubscriptions();
343 return subscriptionsAsJavaArray(pEnv, subscriptions);
344 }
345 catch (const std::exception& e)
346 {
347 ThrowJavaException(pEnv, e);
348 }
349 catch (...)
350 {
351 ThrowJavaException(pEnv);
352 }
353 return 0;
354 }
355
356 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_addSubscription(JN IEnv *pEnv, jobject, jstring url)
357 {
358 D(D_WARN, "addSubscription()");
359 try
360 {
361 const std::string surl = GetString(pEnv, url);
362 AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription(su rl);
363 subscription->AddToList();
364 }
365 catch (const std::exception& e)
366 {
367 ThrowJavaException(pEnv, e);
368 }
369 catch (...)
370 {
371 ThrowJavaException(pEnv);
372 }
373 }
374
375 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_removeSubscription (JNIEnv *pEnv, jobject, jstring url)
376 {
377 D(D_WARN, "removeSubscription()");
378 try
379 {
380 const std::string surl = GetString(pEnv, url);
381 AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription(su rl);
382 if (subscription->IsListed())
383 {
384 subscription->RemoveFromList();
385 }
386 }
387 catch (const std::exception& e)
388 {
389 ThrowJavaException(pEnv, e);
390 }
391 catch (...)
392 {
393 ThrowJavaException(pEnv);
394 }
395 }
396
397 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_refreshSubscriptio n(JNIEnv *pEnv, jobject, jstring url)
398 {
399 D(D_WARN, "refreshSubscription()");
400 try
401 {
402 const std::string surl = GetString(pEnv, url);
403 AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription(su rl);
404 subscription->UpdateFilters();
405 }
406 catch (const std::exception& e)
407 {
408 ThrowJavaException(pEnv, e);
409 }
410 catch (...)
411 {
412 ThrowJavaException(pEnv);
413 }
414 }
415
416 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_actualizeSubscript ionStatus(JNIEnv *pEnv, jobject, jstring url)
417 {
418 D(D_WARN, "actualizeSubscriptionStatus()");
419 try
420 {
421 const std::string surl = GetString(pEnv, url);
422 AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription(su rl);
423 UpdateSubscriptionStatus(subscription);
424 }
425 catch (const std::exception& e)
426 {
427 ThrowJavaException(pEnv, e);
428 }
429 catch (...)
430 {
431 ThrowJavaException(pEnv);
432 }
433 }
434
435 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_setAcceptableAdsEn abled(JNIEnv *pEnv, jobject, jboolean enabled)
436 {
437 D(D_WARN, "setAcceptableAdsEnabled()");
438 try
439 {
440 const std::string surl = filterEngine->GetPref("subscriptions_exceptionsurl" )->AsString();
441 AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription(su rl);
442 if (enabled == JNI_TRUE)
443 {
444 subscription->AddToList();
445 }
446 else if (subscription->IsListed())
447 {
448 subscription->RemoveFromList();
449 }
450 }
451 catch (const std::exception& e)
452 {
453 ThrowJavaException(pEnv, e);
454 }
455 catch (...)
456 {
457 ThrowJavaException(pEnv);
458 }
459 }
460
461 JNIEXPORT jstring JNICALL Java_org_adblockplus_android_ABPEngine_getDocumentatio nLink(
462 JNIEnv *env, jobject object)
463 {
464 const std::string documentationLink = filterEngine->GetPref("documentation_lin k")->AsString();
465 return env->NewStringUTF(documentationLink.c_str());
466 }
467
468 JNIEXPORT jboolean JNICALL Java_org_adblockplus_android_ABPEngine_matches(
469 JNIEnv *pEnv, jobject, jstring url, jstring contentType, jobjectArray document Urls)
470 {
471 try
472 {
473 const std::string surl = GetString(pEnv, url);
474 const std::string stype = GetString(pEnv, contentType);
475 const int documentUrlsLength = pEnv->GetArrayLength(documentUrls);
476 std::vector<std::string> sdocumentUrls;
477 for(int i = 0; i < documentUrlsLength; i++)
478 {
479 jstring documentUrl = static_cast<jstring>(pEnv->GetObjectArrayElement(do cumentUrls, i));
480 sdocumentUrls.push_back(GetString(pEnv, documentUrl));
481 }
482
483 AdblockPlus::FilterPtr filter = filterEngine->Matches(surl, stype, sdocument Urls);
484
485 if (! filter)
486 return JNI_FALSE;
487
488 // hack: if there is no referrer, block only if filter is domain-specific
489 // (to re-enable in-app ads blocking, proposed on 12.11.2012 Monday meeting)
490 // (documentUrls contains the referrers on Android)
491 if (!sdocumentUrls.size() &&
492 (filter->GetProperty("text")->AsString()).find("||") != std::string::npo s)
493 return JNI_FALSE;
494
495 return filter->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION ? JNI_FALSE : JNI_TRUE;
496 }
497 catch (const std::exception& e)
498 {
499 ThrowJavaException(pEnv, e);
500 }
501 catch (...)
502 {
503 ThrowJavaException(pEnv);
504 }
505 return JNI_FALSE;
506 }
507
508 JNIEXPORT jobjectArray JNICALL Java_org_adblockplus_android_ABPEngine_getSelecto rsForDomain(JNIEnv *pEnv, jobject, jstring domain)
509 {
510 try
511 {
512 const std::string sdomain = GetString(pEnv, domain);
513 const std::vector<std::string> selectors = filterEngine->GetElementHidingSel ectors(sdomain);
514
515 static jclass cls = reinterpret_cast<jclass>(pEnv->NewGlobalRef(pEnv->FindCl ass("java/lang/String")));
516
517 D(D_WARN, "Selectors: %d", selectors.size());
518 const jobjectArray ret = (jobjectArray) pEnv->NewObjectArray(selectors.size( ), cls, NULL);
519
520 int i = 0;
521 for (std::vector<std::string>::const_iterator it = selectors.begin();
522 it != selectors.end(); it++)
523 {
524 jstring selector = pEnv->NewStringUTF((*it).c_str());
525 pEnv->SetObjectArrayElement(ret, i, selector);
526 pEnv->DeleteLocalRef(selector);
527 i++;
528 }
529
530 return ret;
531 }
532 catch (const std::exception& e)
533 {
534 ThrowJavaException(pEnv, e);
535 }
536 catch (...)
537 {
538 ThrowJavaException(pEnv);
539 }
540 return 0;
541 }
542
543 JNIEXPORT void JNICALL Java_org_adblockplus_android_ABPEngine_checkUpdates(JNIEn v *pEnv, jobject)
544 {
545 try
546 {
547 manualUpdate = true;
548 filterEngine->ForceUpdateCheck(UpdaterCallback);
549 }
550 catch (const std::exception& e)
551 {
552 ThrowJavaException(pEnv, e);
553 }
554 catch (...)
555 {
556 ThrowJavaException(pEnv);
557 }
558 }
OLDNEW
« no previous file with comments | « .hgignore ('k') | jni/Android.mk » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld