Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v3.2 #94

Merged
merged 7 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog / Ad-Free

### v3.2/42 (2023-12-08)
- Improve Accuradio Detector to support bigContentView, tickerView and contentView (#93, thanks to @unseenlarks)
- Use generic reflection approach UserDefinedText Detector to search for user defined ad texts

### v3.1/41
- Fix bug with local music plugin: folder selection

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "ch.abertschi.adfree"
minSdkVersion 23
targetSdkVersion 27
versionCode 41
versionName "3.1"
versionCode 42
versionName "3.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ class AccuradioDetector : AdDetectable, AnkoLogger, AbstractNotificationDetector
}
}

override fun flagAsAdvertisement(payload: AdPayload): Boolean {

private fun inspectContentViews(contentView: RemoteViews?): Boolean {
try {
val contentView = payload.statusbarNotification?.notification?.contentView
info(payload)
if (contentView != null) {
val actions = extractObject(contentView, "mActions") as List<*>?
if (actions != null) {
Expand Down Expand Up @@ -88,4 +87,18 @@ class AccuradioDetector : AdDetectable, AnkoLogger, AbstractNotificationDetector
}
return false
}

override fun flagAsAdvertisement(payload: AdPayload): Boolean {
// XXX: Support old deprecated fields
val contentView = payload.statusbarNotification.notification?.contentView
val bigView = payload.statusbarNotification.notification?.bigContentView
val tickerView = payload.statusbarNotification.notification?.tickerView

for (v in listOf(contentView, bigView, tickerView)) {
if (inspectContentViews(v)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Notification
import android.os.Bundle
import ch.abertschi.adfree.model.TextRepository
import ch.abertschi.adfree.model.TextRepositoryData
import com.thoughtworks.xstream.XStream
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.warn
import java.util.*
Expand Down Expand Up @@ -38,8 +39,9 @@ class UserDefinedTextDetector(private val repo: TextRepository) : AdDetectable,
}
}

override fun flagAsAdvertisement(payload: AdPayload): Boolean {
val extras = payload.statusbarNotification?.notification?.extras
// Use a fixed approach and search for predefined fields
private fun flagAsAdvertisementFixed(payload: AdPayload): Boolean {
val extras = payload.statusbarNotification.notification?.extras
val title = extractString(extras, Notification.EXTRA_TITLE)
val subTitle = extractString(extras, Notification.EXTRA_SUB_TEXT)

Expand All @@ -59,6 +61,27 @@ class UserDefinedTextDetector(private val repo: TextRepository) : AdDetectable,
return false;
}

private fun flagAsAdvertisementDynamic(payload: AdPayload): Boolean {
/*
* XXX: This implementation is inefficient but simple.
* Will a reflection approach be better?
*/
val str = XStream().toXML(payload)!!.toLowerCase()
for (entry in payload.matchedTextDetectorEntries) {
for (entryLine in entry.content) {
if (entryLine.trim().isEmpty()) {
continue
}
if (str.contains(entryLine.trim().toLowerCase())) {
return true
}
}
}
return false
}
override fun flagAsAdvertisement(payload: AdPayload) =
flagAsAdvertisementFixed(payload) || flagAsAdvertisementDynamic(payload)

override fun getMeta(): AdDetectorMeta = AdDetectorMeta(
"User defined text", "flag a notification based on the presence of text",
false,
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/ch/abertschi/adfree/model/TextRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class TextRepository : AnkoLogger {
private val context: Context
private val ID_KEY: String = "k_"
private val ID_KEYS: String = "keys"
private val ID_USE_REFLECTION_FOR_MATCH = "_use_reflection"

private var dataEntries: ArrayList<TextRepositoryData>

Expand All @@ -56,6 +57,8 @@ class TextRepository : AnkoLogger {
return sharedPreferences.getStringSet(ID_KEYS, HashSet<String>())
}



private fun getEntryByFormattedKey(key: String): TextRepositoryData? {
var dataStr: String = sharedPreferences.getString(key, null) ?: return null
return TextRepositoryData.deserialzeFromString(dataStr)
Expand All @@ -72,6 +75,18 @@ class TextRepository : AnkoLogger {
return entries
}

/*
* Boolean to indicate if a generic reflection based
* approach should be used to find a matching text entry in all fields of the payload
*/
fun useReflectionForMatch(): Boolean {
return sharedPreferences.getBoolean(ID_USE_REFLECTION_FOR_MATCH, false)
}

fun setReflectionForMatch(useIt: Boolean) {
sharedPreferences.edit().putBoolean(ID_USE_REFLECTION_FOR_MATCH, useIt).apply()
}

fun getAllEntries(): ArrayList<TextRepositoryData> {
return ArrayList(dataEntries)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ import ch.abertschi.adfree.ad.AdObservable
import ch.abertschi.adfree.plugin.AdPlugin
import ch.abertschi.adfree.plugin.PluginHandler
import ch.abertschi.adfree.view.setting.SettingsView
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.collections.forEachWithIndex
import java.util.concurrent.TimeUnit



/**
Expand Down
3 changes: 3 additions & 0 deletions metadata/en-US/changelogs/42.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### v3.2/42 (2023-12-08)
- Improve Accuradio Detector to support bigContentView, tickerView and contentView (#93, thanks to @unseenlarks)
- Use generic reflection approach UserDefinedText Detector to search for user defined ad texts
2 changes: 1 addition & 1 deletion metadata/en-US/full_description.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ad-free is an ad audio blocker for Android.
Ad-free is an ad audio blocker for Android.

This app is a research project attempting to show flaws in the way how
audio advertisement is shown on Android. It is a proof-of-concept of a
Expand Down
2 changes: 1 addition & 1 deletion metadata/en-US/short_description.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ad-free is a modularized audio ad blocker for Spotify and more on Android.
Ad-free is a modularized audio ad blocker for Spotify and more on Android.
Loading