├── app
├── .gitignore
├── fdroid
│ └── .DS_Store
├── playstore
│ ├── .DS_Store
│ └── release
│ │ ├── baselineProfiles
│ │ ├── 0
│ │ │ └── app-playstore-release.dm
│ │ └── 1
│ │ │ └── app-playstore-release.dm
│ │ └── output-metadata.json
└── src
│ ├── main
│ ├── res
│ │ ├── values-apd
│ │ │ └── strings.xml
│ │ ├── values-ars
│ │ │ └── strings.xml
│ │ ├── values-ne
│ │ │ └── strings.xml
│ │ ├── values-th
│ │ │ └── strings.xml
│ │ ├── font
│ │ │ ├── nunito_bold.ttf
│ │ │ ├── nunito_black.ttf
│ │ │ ├── nunito_light.ttf
│ │ │ ├── nunito_medium.ttf
│ │ │ └── nunito_regular.ttf
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_round.webp
│ │ │ └── ic_launcher_foreground.webp
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_round.webp
│ │ │ └── ic_launcher_foreground.webp
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_round.webp
│ │ │ └── ic_launcher_foreground.webp
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_round.webp
│ │ │ └── ic_launcher_foreground.webp
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_round.webp
│ │ │ └── ic_launcher_foreground.webp
│ │ ├── values
│ │ │ ├── ic_launcher_background.xml
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── themes.xml
│ │ │ └── donottranslate.xml
│ │ ├── values-apc
│ │ │ └── strings.xml
│ │ ├── values-ar
│ │ │ └── strings.xml
│ │ ├── xml
│ │ │ └── locales_config.xml
│ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values-v31
│ │ │ └── colors.xml
│ │ ├── drawable
│ │ │ ├── ic_shield_off.xml
│ │ │ ├── ic_shield.xml
│ │ │ ├── wrapper.xml
│ │ │ ├── ic_shield_check.xml
│ │ │ ├── incognito.xml
│ │ │ ├── blob.xml
│ │ │ └── logo.xml
│ │ ├── values-pl
│ │ │ └── strings.xml
│ │ ├── values-ca
│ │ │ └── strings.xml
│ │ └── layout
│ │ │ └── notification_network_speed.xml
│ ├── ic_launcher-playstore.png
│ ├── go
│ │ ├── go.mod
│ │ ├── pidfile.go
│ │ ├── build-android.bat
│ │ └── build-android.sh
│ ├── aidl
│ │ └── com
│ │ │ └── kin
│ │ │ └── athena
│ │ │ └── service
│ │ │ └── shizuku
│ │ │ └── IShizukuFirewallService.aidl
│ ├── cpp
│ │ └── CMakeLists.txt
│ └── java
│ │ └── com
│ │ └── kin
│ │ └── athena
│ │ ├── service
│ │ ├── vpn
│ │ │ └── network
│ │ │ │ ├── transport
│ │ │ │ ├── ItTransportHeader.kt
│ │ │ │ ├── udp
│ │ │ │ │ ├── UDPModel.kt
│ │ │ │ │ └── UDPSoar.kt
│ │ │ │ ├── dns
│ │ │ │ │ ├── DNSModel.kt
│ │ │ │ │ └── DNSExtensions.kt
│ │ │ │ ├── extenions
│ │ │ │ │ └── NetworkExtensions.kt
│ │ │ │ ├── icmp
│ │ │ │ │ ├── ICMPExtensions.kt
│ │ │ │ │ └── ICMPModel.kt
│ │ │ │ └── ipv4
│ │ │ │ │ └── Ipv4Model.kt
│ │ │ │ └── util
│ │ │ │ └── PacketUtil.kt
│ │ ├── firewall
│ │ │ ├── rule
│ │ │ │ ├── FirewallRule.kt
│ │ │ │ ├── FilterRule.kt
│ │ │ │ ├── DNSRule.kt
│ │ │ │ └── HTTPRule.kt
│ │ │ ├── model
│ │ │ │ └── FirewallModel.kt
│ │ │ ├── handler
│ │ │ │ └── PacketHandler.kt
│ │ │ └── utils
│ │ │ │ └── FirewallStatus.kt
│ │ └── utils
│ │ │ └── receiver
│ │ │ └── AppChangeReceiver.kt
│ │ ├── domain
│ │ ├── usecase
│ │ │ ├── preferences
│ │ │ │ ├── PreferencesUseCases.kt
│ │ │ │ ├── SavePreferences.kt
│ │ │ │ └── LoadPreferences.kt
│ │ │ ├── log
│ │ │ │ ├── LogUseCases.kt
│ │ │ │ ├── DeleteLogs.kt
│ │ │ │ ├── DeleteLog.kt
│ │ │ │ ├── GetLog.kt
│ │ │ │ ├── GetLogs.kt
│ │ │ │ └── AddLog.kt
│ │ │ ├── networkFilter
│ │ │ │ ├── NetworkFilterUseCases.kt
│ │ │ │ ├── DeleteIps.kt
│ │ │ │ ├── DeleteIp.kt
│ │ │ │ ├── AddIp.kt
│ │ │ │ └── GetIps.kt
│ │ │ └── application
│ │ │ │ ├── ObserveApplication.kt
│ │ │ │ ├── GetExistingPackageIds.kt
│ │ │ │ ├── ApplicationUseCases.kt
│ │ │ │ ├── GetApplications.kt
│ │ │ │ ├── CheckApplicationExists.kt
│ │ │ │ ├── UpdatePinnedStatus.kt
│ │ │ │ ├── AddApplication.kt
│ │ │ │ ├── AddApplications.kt
│ │ │ │ ├── DeleteApplication.kt
│ │ │ │ ├── UpdateApplication.kt
│ │ │ │ ├── GetApplication.kt
│ │ │ │ └── GetFilteredApplications.kt
│ │ ├── repository
│ │ │ ├── SettingsRepository.kt
│ │ │ ├── NetworkFilterRepository.kt
│ │ │ ├── LogRepository.kt
│ │ │ ├── ApplicationRepository.kt
│ │ │ └── CustomDomainRepository.kt
│ │ └── model
│ │ │ ├── CustomDomain.kt
│ │ │ ├── Ip.kt
│ │ │ ├── NetworkStatsState.kt
│ │ │ ├── Log.kt
│ │ │ ├── Application.kt
│ │ │ └── BackupData.kt
│ │ ├── core
│ │ ├── utils
│ │ │ ├── Error.kt
│ │ │ ├── extensions
│ │ │ │ ├── TimeExtensions.kt
│ │ │ │ ├── DrawableExtensions.kt
│ │ │ │ └── NetworkExtensions.kt
│ │ │ ├── Result.kt
│ │ │ ├── constants
│ │ │ │ └── ProjectConstants.kt
│ │ │ └── NotificationHelper.kt
│ │ └── logging
│ │ │ └── Logger.kt
│ │ ├── presentation
│ │ ├── screens
│ │ │ ├── settings
│ │ │ │ └── subSettings
│ │ │ │ │ ├── lock
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── ActionType.kt
│ │ │ │ │ │ └── TitleText.kt
│ │ │ │ │ └── LockScreen.kt
│ │ │ │ │ ├── proxy
│ │ │ │ │ └── ProxyScreen.kt
│ │ │ │ │ ├── dns
│ │ │ │ │ ├── hosts
│ │ │ │ │ │ └── SingleWriterMultipleReaderFile.kt
│ │ │ │ │ └── components
│ │ │ │ │ │ └── SystemlessHostsDialog.kt
│ │ │ │ │ └── network
│ │ │ │ │ └── viewModel
│ │ │ │ │ └── NetworkViewModel.kt
│ │ │ └── home
│ │ │ │ └── viewModel
│ │ │ │ └── ApplicationListState.kt
│ │ ├── navigation
│ │ │ └── routes
│ │ │ │ ├── LogRoutes.kt
│ │ │ │ └── HomeRoutes.kt
│ │ ├── MainViewModel.kt
│ │ └── components
│ │ │ ├── material
│ │ │ ├── MaterialButton.kt
│ │ │ ├── Chip.kt
│ │ │ ├── MaterialScaffold.kt
│ │ │ ├── MaterialPlaceholder.kt
│ │ │ ├── MaterialActionButton.kt
│ │ │ ├── MaterialText.kt
│ │ │ └── MaterialBar.kt
│ │ │ └── CircleWrapper.kt
│ │ ├── di
│ │ ├── BackupManagerEntryPoint.kt
│ │ ├── database
│ │ │ └── DatabaseModule.kt
│ │ ├── firewall
│ │ │ └── WorkerModule.kt
│ │ └── repository
│ │ │ ├── SettingsModule.kt
│ │ │ ├── LogModule.kt
│ │ │ └── NetworkFilter.kt
│ │ └── data
│ │ ├── service
│ │ ├── billing
│ │ │ └── BillingInterface.kt
│ │ └── ScreenManager.kt
│ │ ├── local
│ │ ├── dao
│ │ │ ├── BlockedDao.kt
│ │ │ └── LogDao.kt
│ │ └── database
│ │ │ └── Database.kt
│ │ ├── database
│ │ └── entity
│ │ │ └── CustomDomainEntity.kt
│ │ ├── repository
│ │ ├── NetworkFilterRepository.kt
│ │ └── LogRepository.kt
│ │ └── mapper
│ │ └── CustomDomainMapper.kt
│ ├── fdroid
│ └── java
│ │ └── com
│ │ └── kin
│ │ └── athena
│ │ ├── di
│ │ └── BillingModule.kt
│ │ └── data
│ │ └── service
│ │ └── billing
│ │ └── BillingProvider.kt
│ └── playstore
│ └── java
│ └── com
│ └── kin
│ └── athena
│ ├── di
│ └── BillingModule.kt
│ └── data
│ └── service
│ └── billing
│ └── BillingProvider.kt
├── metadata
└── en-US
│ ├── changelogs
│ └── 1.txt
│ ├── title.txt
│ ├── images
│ ├── icon.png
│ └── phoneScreenshots
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ ├── 6.png
│ │ └── 7.png
│ ├── short_description.txt
│ └── full_description.txt
├── .github
├── FUNDING.yml
├── github.png
├── play_store.png
├── ISSUE_TEMPLATE
│ ├── question.md
│ ├── feature_request.md
│ └── bug_report.md
├── dependabot.yml
└── workflows
│ └── nightly-build.yml
├── .DS_Store
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── settings.gradle.kts
└── .gitignore
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/metadata/en-US/changelogs/1.txt:
--------------------------------------------------------------------------------
1 | - Alpha Version
2 |
--------------------------------------------------------------------------------
/metadata/en-US/title.txt:
--------------------------------------------------------------------------------
1 | Athena: Firewall & Adblocker
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | ko_fi: kin69_
2 | liberapay: Kin69
3 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/.DS_Store
--------------------------------------------------------------------------------
/.github/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/.github/github.png
--------------------------------------------------------------------------------
/app/fdroid/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/fdroid/.DS_Store
--------------------------------------------------------------------------------
/.github/play_store.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/.github/play_store.png
--------------------------------------------------------------------------------
/app/playstore/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/playstore/.DS_Store
--------------------------------------------------------------------------------
/metadata/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/values-apd/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ars/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ne/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values-th/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/metadata/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Firewall & AdBlocker (Root/VPN Supported). Material3 And Minimalistic Design
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/font/nunito_bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/font/nunito_bold.ttf
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/res/font/nunito_black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/font/nunito_black.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/nunito_light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/font/nunito_light.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/nunito_medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/font/nunito_medium.ttf
--------------------------------------------------------------------------------
/app/src/main/res/font/nunito_regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/font/nunito_regular.ttf
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Ask a question or start a discussion.
4 | ---
5 |
6 | ## Summary
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/6.png
--------------------------------------------------------------------------------
/metadata/en-US/images/phoneScreenshots/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/metadata/en-US/images/phoneScreenshots/7.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
--------------------------------------------------------------------------------
/app/playstore/release/baselineProfiles/0/app-playstore-release.dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/playstore/release/baselineProfiles/0/app-playstore-release.dm
--------------------------------------------------------------------------------
/app/playstore/release/baselineProfiles/1/app-playstore-release.dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kin69/Athena/HEAD/app/playstore/release/baselineProfiles/1/app-playstore-release.dm
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #151515
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values-apc/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | العربية
4 | اللغة العربية
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ar/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | اللغة العربية
4 | ع ر ب ي ة
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #332F2F
4 | #000000
5 | #000000
6 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/locales_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/metadata/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | Athena Firewall - Modern Design, Extra Privacy
2 |
3 | Features:
4 | • 📝 Root/VPN Mode
5 | • 🌟 Material3, Minimalistic Design
6 | • 🔒 DNS Blocklist (categories,custom)
7 | • 🚀 Logs
8 | • 🔐 Notify on install
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3dp
4 | 16dp
5 | 12dp
6 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
2 | android.useAndroidX=true
3 | kotlin.code.style=official
4 | android.nonTransitiveRClass=true
5 | org.gradle.configuration-cache=true
6 | org.gradle.parallel=true
7 | org.gradle.caching=true
8 | org.gradle.daemon=true
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jul 29 10:52:29 CEST 2025
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "gradle"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | rebase-strategy: "disabled"
8 |
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: "weekly"
13 | rebase-strategy: "disabled"
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v31/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | @android:color/system_accent1_500
4 | @android:color/system_accent1_100
5 | @android:color/system_neutral1_900
6 | @android:color/system_neutral2_300
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shield_off.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shield.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wrapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Szukaj
4 | Logi
5 | Ustawienia
6 | Pozwól
7 | Anuluj
8 | Aktywuj
9 | Dezaktywuj
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_shield_check.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/incognito.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/go/go.mod:
--------------------------------------------------------------------------------
1 | module nflog
2 |
3 | go 1.21
4 |
5 | require (
6 | github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185
7 | github.com/florianl/go-nflog/v2 v2.0.1
8 | github.com/google/gopacket v1.1.19
9 | )
10 |
11 | require (
12 | github.com/google/go-cmp v0.6.0 // indirect
13 | github.com/josharian/native v1.1.0 // indirect
14 | github.com/mdlayher/netlink v1.7.2 // indirect
15 | github.com/mdlayher/socket v0.5.0 // indirect
16 | golang.org/x/net v0.20.0 // indirect
17 | golang.org/x/sync v0.6.0 // indirect
18 | golang.org/x/sys v0.16.0 // indirect
19 | )
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/donottranslate.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | GNU General Public License v3.0
4 | Get Premium €4.99
5 | ❌ %1$s
6 | https://example.com/blocklist.txt
7 | Athena
8 | UID
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/aidl/com/kin/athena/service/shizuku/IShizukuFirewallService.aidl:
--------------------------------------------------------------------------------
1 | package com.kin.athena.service.shizuku;
2 |
3 | interface IShizukuFirewallService {
4 | void destroy() = 16777114; // Destroy method with specific transaction code
5 |
6 | boolean enableFirewallChain() = 1;
7 | boolean disableFirewallChain() = 2;
8 | boolean isFirewallChainEnabled() = 3;
9 |
10 | boolean setPackageNetworking(String packageName, boolean enabled) = 4;
11 | boolean getPackageNetworking(String packageName) = 5;
12 |
13 | String executeCommand(String command) = 6;
14 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/blob.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google {
4 | content {
5 | includeGroupByRegex("com\\.android.*")
6 | includeGroupByRegex("com\\.google.*")
7 | includeGroupByRegex("androidx.*")
8 | }
9 | }
10 | mavenCentral()
11 | gradlePluginPortal()
12 | }
13 | }
14 | dependencyResolutionManagement {
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | google()
18 | mavenCentral()
19 | maven { setUrl("https://jitpack.io") }
20 | }
21 | }
22 |
23 | rootProject.name = "Athena"
24 | include(":app")
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | title: ''
4 | about: Suggest feature.
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
--------------------------------------------------------------------------------
/app/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.22.1)
2 |
3 | project("athena")
4 |
5 | add_library(${CMAKE_PROJECT_NAME} SHARED
6 | athena.h
7 | athena.c
8 | session/ip.c
9 | session/session.c
10 | protocols/icmp.c
11 | protocols/tcp.c
12 | protocols/udp.c
13 | utils/util.c
14 | )
15 |
16 | target_link_libraries(${CMAKE_PROJECT_NAME}
17 | android
18 | log)
19 |
20 | # Add 16KB page alignment for Android 15+ compatibility
21 | if(ANDROID_PLATFORM_LEVEL GREATER_EQUAL 35)
22 | target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
23 | -Wl,-z,max-page-size=16384
24 | )
25 | endif()
26 |
27 | # Always add 16KB alignment for future compatibility
28 | target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
29 | -Wl,-z,max-page-size=16384
30 | )
--------------------------------------------------------------------------------
/app/src/main/go/pidfile.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "os"
6 | "path/filepath"
7 | "strconv"
8 |
9 | "github.com/dchest/safefile"
10 | )
11 |
12 | var pidFile = flag.String("pidfile", "", "Store the PID into a file")
13 |
14 | func PidFileCreate() error {
15 | var file = getPidFilePath()
16 | if file == nil {
17 | return nil
18 | }
19 |
20 | if err := os.MkdirAll(filepath.Dir(*file), 0755); err != nil {
21 | return err
22 | }
23 | return safefile.WriteFile(*file, []byte(strconv.Itoa(os.Getpid())), 0644)
24 | }
25 |
26 | func PidFileRemove() error {
27 | var file = getPidFilePath()
28 | if file == nil {
29 | return nil
30 | }
31 |
32 | return os.Remove(*file)
33 | }
34 |
35 | func getPidFilePath() *string {
36 | var file string
37 | if pidFile == nil || len(*pidFile) == 0 {
38 | return nil
39 | } else {
40 | file = *pidFile
41 | }
42 |
43 | return &file
44 | }
45 |
--------------------------------------------------------------------------------
/app/playstore/release/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "com.kin.athena",
8 | "variantName": "playstoreRelease",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "attributes": [],
14 | "versionCode": 104,
15 | "versionName": "1.1",
16 | "outputFile": "app-playstore-release.apk"
17 | }
18 | ],
19 | "elementType": "File",
20 | "baselineProfiles": [
21 | {
22 | "minApi": 28,
23 | "maxApi": 30,
24 | "baselineProfiles": [
25 | "baselineProfiles/1/app-playstore-release.dm"
26 | ]
27 | },
28 | {
29 | "minApi": 31,
30 | "maxApi": 2147483647,
31 | "baselineProfiles": [
32 | "baselineProfiles/0/app-playstore-release.dm"
33 | ]
34 | }
35 | ],
36 | "minSdkVersionForDexing": 23
37 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | title: "[BUG]"
4 | about: Create a report to help us improve
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 | ## Required Information
10 |
11 | - [ ] I’m using the latest Athena version
12 |
13 | - [ ] The device is rooted, and nothing has been removed via ADB
14 |
15 | ### Steps to Reproduce the Bug
16 | 1. Go to '...'
17 | 2. Click on '...'
18 | 3. Scroll down to '...'
19 | 4. See the error
20 |
21 | ### Expected Behavior
22 | Describe what you expected to happen clearly and concisely.
23 |
24 |
25 | ## Strongly Recommended Information
26 |
27 | ### Screenshots
28 | If applicable, add screenshots to help explain your problem.
29 |
30 | ### Smartphone Information
31 | - **Device:** [e.g. Nothing Phone 1]
32 | - **OS:** [e.g. Android 13]
33 | - **Athena Version:** [e.g. 1.2.5]
34 |
35 | ## Additional Information (Optional)
36 |
37 | ### Additional Context
38 | Add any other context or details about the problem here.
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/ItTransportHeader.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport
19 |
20 | interface ITransportHeader {
21 | val sourcePort: Int
22 | val destinationPort: Int
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/preferences/PreferencesUseCases.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.preferences
19 |
20 | data class PreferencesUseCases(
21 | val loadSettings: LoadPreferences,
22 | val saveSettings: SavePreferences
23 | )
--------------------------------------------------------------------------------
/app/src/main/res/values-ca/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cerca
4 | Registres
5 | Configuració
6 | Permet
7 | Cancel·la
8 | Habilita
9 | Deshabilita
10 | Fet
11 | Esborra
12 | Neteja
13 | Reintenta
14 | Detalls
15 | Temps d\'instalació
16 | WiFi
17 | Dades mòbils
18 | Ignora l\'VPN
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/Error.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils
19 |
20 | sealed class Error : Throwable() {
21 | data class ServerError(override val message: String) : Error()
22 | data class PackageError(override val message: String) : Error()
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/lock/components/ActionType.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.settings.subSettings.lock.components
19 |
20 | enum class ActionType {
21 | PASSCODE,
22 | FINGERPRINT,
23 | PATTERN
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/LogUseCases.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 | data class LogUseCases(
21 | val getLogs: GetLogs,
22 | val deleteLog: DeleteLog,
23 | val addLog: AddLog,
24 | val getLog: GetLog,
25 | val deleteLogs: DeleteLogs,
26 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/networkFilter/NetworkFilterUseCases.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.networkFilter
19 |
20 | data class NetworkFilterUseCases(
21 | val getIps: GetIps,
22 | val deleteIp: DeleteIp,
23 | val addIp: AddIp,
24 | val deleteIps: DeleteIps,
25 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/repository/SettingsRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.repository
19 |
20 | import com.kin.athena.domain.model.Settings
21 |
22 | interface SettingsRepository {
23 | suspend fun saveSettings(settings: Settings)
24 | suspend fun loadSettings(): Settings
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/udp/UDPModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.udp
19 |
20 | import com.kin.athena.service.vpn.network.transport.ITransportHeader
21 |
22 | data class UDPModel(
23 | override var sourcePort: Int,
24 | override var destinationPort: Int,
25 | var length: Int,
26 | var checksum: Int,
27 | ) : ITransportHeader
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/CustomDomain.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | data class CustomDomain(
21 | val id: Long = 0,
22 | val domain: String,
23 | val description: String = "",
24 | val isRegex: Boolean = false,
25 | val isAllowlist: Boolean = true,
26 | val createdAt: Long = System.currentTimeMillis(),
27 | val isEnabled: Boolean = true
28 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/navigation/routes/LogRoutes.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.navigation.routes
19 |
20 | sealed class LogRoutes(val route: String) {
21 | data object Logs : HomeRoutes("logs")
22 | data object Ips : LogRoutes("ips")
23 | data object Packet : LogRoutes("packet/{logID}") {
24 | fun createRoute(logId: Int) = "packet/${logId}"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/repository/NetworkFilterRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.repository
19 |
20 | import com.kin.athena.domain.model.Ip
21 | import kotlinx.coroutines.flow.Flow
22 |
23 | interface NetworkFilterRepository {
24 | suspend fun insertIp(ip: Ip)
25 |
26 | suspend fun deleteIp(ip: String)
27 |
28 | suspend fun deleteIps()
29 |
30 | fun getAllIps(): Flow>
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/BackupManagerEntryPoint.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di
19 |
20 | import com.kin.athena.domain.manager.BackupManager
21 | import dagger.hilt.EntryPoint
22 | import dagger.hilt.InstallIn
23 | import dagger.hilt.components.SingletonComponent
24 |
25 | @EntryPoint
26 | @InstallIn(SingletonComponent::class)
27 | interface BackupManagerEntryPoint {
28 | fun backupManager(): BackupManager
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/service/billing/BillingInterface.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.service.billing
19 |
20 | interface BillingInterface {
21 | fun showPurchaseDialog(productId: String, onSuccess: () -> Unit)
22 | fun isReady(): Boolean
23 | fun getProductPrice(productId: String): String?
24 | fun getAllProductPrices(): Map
25 | fun checkExistingPurchases(onPremiumOwned: () -> Unit)
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/dns/DNSModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.dns
19 |
20 | data class DNSModel(
21 | val transactionId: Int,
22 | val flags: Int,
23 | val questionCount: Int,
24 | val answerCount: Int,
25 | val authorityCount: Int,
26 | val additionalCount: Int,
27 | val domainName: String,
28 | val queryType: Int,
29 | val queryClass: Int
30 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/Ip.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | import androidx.room.ColumnInfo
21 | import androidx.room.Entity
22 | import androidx.room.Index
23 | import androidx.room.PrimaryKey
24 |
25 | @Entity(
26 | tableName = "NetworkFilter",
27 | indices = [Index(value = ["ip"])]
28 | )
29 | data class Ip(
30 | @PrimaryKey
31 | @ColumnInfo(name = "ip")
32 | val ip: String = "",
33 | )
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/navigation/routes/HomeRoutes.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.navigation.routes
19 |
20 | sealed class HomeRoutes(val route: String) {
21 | data object Debug : HomeRoutes("debug")
22 | data object Home : HomeRoutes("home")
23 | data object Details : HomeRoutes("details/{applicationID}") {
24 | fun createRoute(applicationID: String) = "details/$applicationID"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/repository/LogRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.repository
19 |
20 | import com.kin.athena.domain.model.Log
21 | import kotlinx.coroutines.flow.Flow
22 |
23 | interface LogRepository {
24 |
25 | suspend fun insertLog(log: Log)
26 |
27 | suspend fun deleteLogById(id: Int)
28 |
29 | suspend fun deleteLogs()
30 |
31 | suspend fun getLogById(id: Int): Log?
32 |
33 | suspend fun getAllLogs(): Flow>
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/extenions/NetworkExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.extenions
19 |
20 | import kotlinx.coroutines.Dispatchers
21 | import kotlinx.coroutines.withContext
22 | import java.net.InetAddress
23 | import java.nio.ByteBuffer
24 |
25 | fun Int.toIp(): String {
26 | val bytes = ByteBuffer.allocate(4).putInt(this).array()
27 | return InetAddress.getByAddress(bytes).hostAddress ?: "Empty"
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/home/viewModel/ApplicationListState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.home.viewModel
19 |
20 | import com.kin.athena.domain.model.Application
21 |
22 | sealed class ApplicationListState {
23 | object Loading : ApplicationListState()
24 | data class Success(
25 | val applications: List,
26 | val totalCount: Int
27 | ) : ApplicationListState()
28 | data class Error(val message: String) : ApplicationListState()
29 | }
--------------------------------------------------------------------------------
/app/src/fdroid/java/com/kin/athena/di/BillingModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di
19 |
20 | import com.kin.athena.data.service.billing.BillingProvider
21 | import dagger.Module
22 | import dagger.Provides
23 | import dagger.hilt.InstallIn
24 | import dagger.hilt.components.SingletonComponent
25 | import javax.inject.Singleton
26 |
27 | @Module
28 | @InstallIn(SingletonComponent::class)
29 | object BillingModule {
30 |
31 | @Provides
32 | @Singleton
33 | fun provideBillingProvider(): BillingProvider {
34 | return BillingProvider()
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/extensions/TimeExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils.extensions
19 |
20 | import java.text.SimpleDateFormat
21 | import java.util.Date
22 | import java.util.Locale
23 | import java.util.TimeZone
24 |
25 | fun Long.toFormattedDateTime(pattern: String = "yyyy-MM-dd HH:mm:ss", timeZone: TimeZone = TimeZone.getDefault()): String {
26 | val date = Date(this)
27 | val formatter = SimpleDateFormat(pattern, Locale.getDefault())
28 | formatter.timeZone = timeZone
29 | return formatter.format(date)
30 | }
--------------------------------------------------------------------------------
/app/src/playstore/java/com/kin/athena/di/BillingModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di
19 |
20 | import com.kin.athena.data.service.billing.BillingProvider
21 | import dagger.Module
22 | import dagger.Provides
23 | import dagger.hilt.InstallIn
24 | import dagger.hilt.components.SingletonComponent
25 | import javax.inject.Singleton
26 |
27 | @Module
28 | @InstallIn(SingletonComponent::class)
29 | object BillingModule {
30 |
31 | @Provides
32 | @Singleton
33 | fun provideBillingProvider(): BillingProvider {
34 | return BillingProvider()
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/icmp/ICMPExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.icmp
19 |
20 | import java.nio.ByteBuffer
21 |
22 | fun ByteBuffer.toICMPPacket(): ICMPModel {
23 | val type = get().toInt()
24 | val code = get().toInt()
25 | val checksum = getShort().toInt()
26 | val identifier = getShort().toInt()
27 | val sequenceNumber = getShort().toInt()
28 |
29 | val data = ByteArray(remaining())
30 | get(data)
31 |
32 | return ICMPModel(type, code, checksum, identifier, sequenceNumber, data)
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/udp/UDPSoar.kt:
--------------------------------------------------------------------------------
1 | package com.kin.athena.service.vpn.network.transport.udp
2 |
3 |
4 | import org.xbill.DNS.*;
5 | import com.kin.athena.service.vpn.network.transport.ipv4.IPv4
6 | import java.nio.ByteBuffer
7 |
8 | fun soarResponse(clientPacketData: ByteBuffer, ipHeader: IPv4): ByteArray {
9 | val udpHeader = clientPacketData.toUDPHeader()
10 | val udpData = ByteBuffer.wrap(udpHeader.extractUDPData(clientPacketData))
11 |
12 | val message = Message(udpData)
13 | message.header.setFlag(Flags.QR.toInt())
14 | message.header.rcode = Rcode.NOERROR
15 | message.addRecord(createSOAResponse(), Section.AUTHORITY)
16 | return message.toWire()
17 | }
18 |
19 | fun handleDnsResponse(requestPacket: UDPModel, ipHeader: IPv4, responsePayload: ByteArray): ByteArray {
20 | return createResponsePacket(ipHeader, requestPacket, responsePayload)
21 | }
22 |
23 | private fun createSOAResponse(): SOARecord {
24 | val NEGATIVE_CACHE_TTL_SECONDS = 5L
25 | val name = Name("dnsnet.dnsnet.invalid.")
26 |
27 | return SOARecord(
28 | name,
29 | DClass.IN,
30 | NEGATIVE_CACHE_TTL_SECONDS,
31 | name,
32 | name,
33 | 0,
34 | 0,
35 | 0,
36 | 0,
37 | NEGATIVE_CACHE_TTL_SECONDS
38 | )
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/ObserveApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.domain.usecase.application
18 |
19 | import com.kin.athena.domain.model.Application
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import kotlinx.coroutines.flow.Flow
22 | import javax.inject.Inject
23 |
24 | class ObserveApplication @Inject constructor(
25 | private val packageRepository: ApplicationRepository
26 | ) {
27 | fun execute(applicationID: String): Flow {
28 | return packageRepository.observeApplicationByID(applicationID)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/rule/FirewallRule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.rule
19 |
20 | import com.kin.athena.domain.usecase.log.LogUseCases
21 | import com.kin.athena.service.firewall.model.FireWallModel
22 | import com.kin.athena.service.firewall.model.FirewallResult
23 | import com.kin.athena.service.vpn.network.transport.dns.DNSModel
24 |
25 | interface FirewallRule {
26 | fun check(
27 | packet: FireWallModel,
28 | dnsModel: DNSModel?,
29 | logUseCases: LogUseCases,
30 | result: FirewallResult
31 | ): FirewallResult
32 | }
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # User-specific configurations
2 | /.idea
3 | .idea/caches/
4 | .idea/libraries/
5 | .idea/shelf/
6 | .idea/.name
7 | .idea/compiler.xml
8 | .idea/copyright/profiles_settings.xml
9 | .idea/encodings.xml
10 | .idea/misc.xml
11 | .idea/modules.xml
12 | .idea/scopes/scope_settings.xml
13 | .idea/vcs.xml
14 | .idea/jsLibraryMappings.xml
15 | .idea/datasources.xml
16 | .idea/dataSources.ids
17 | .idea/sqlDataSources.xml
18 | .idea/dynamic.xml
19 | .idea/uiDesigner.xml
20 |
21 | # Claude
22 | .claude/
23 |
24 | # Android Studio
25 | app/release/
26 | .kotlin/
27 | /*/build/
28 | /*/local.properties
29 | /*/out
30 | /*/*/build
31 | /build
32 | /*/*/production
33 | *.ipr
34 | *~
35 | *.swp
36 |
37 | # IntelliJ IDEA
38 | *.iws
39 | /out/
40 |
41 |
42 | # Gradle files
43 | .gradle/
44 | .gradle
45 | build/
46 |
47 | # Local configuration file (sdk path, etc)
48 | /local.properties
49 | local.properties
50 |
51 | # Log/OS Files
52 | *.log
53 | .profile
54 |
55 |
56 | # Android Studio generated files and folders
57 | captures/
58 | .externalNativeBuild/
59 | .cxx/
60 | *.apk
61 | output.json
62 |
63 | # IntelliJ
64 | *.iml
65 | .idea/
66 | misc.xml
67 | deploymentTargetDropDown.xml
68 | render.experimental.xml
69 |
70 | # Keystore files
71 | *.jks
72 | *.keystore
73 |
74 | # Android Profiling
75 | *.hprof
76 |
77 | # Generated native libraries
78 | app/libs/
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/GetExistingPackageIds.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import javax.inject.Inject
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.core.utils.Error
24 |
25 | class GetExistingPackageIds @Inject constructor(
26 | private val applicationRepository: ApplicationRepository
27 | ) {
28 | suspend fun execute(packageIds: List): List {
29 | return applicationRepository.getExistingPackageIds(packageIds)
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation
19 |
20 | import androidx.lifecycle.ViewModel
21 | import androidx.lifecycle.viewModelScope
22 | import com.kin.athena.presentation.screens.settings.viewModel.SettingsViewModel
23 | import kotlinx.coroutines.flow.MutableStateFlow
24 | import kotlinx.coroutines.flow.asStateFlow
25 | import kotlinx.coroutines.launch
26 |
27 | class MainViewModel: ViewModel() {
28 | private val _isReady = MutableStateFlow(false)
29 | val isReady = _isReady.asStateFlow()
30 |
31 | fun showSlashScreen(value: Boolean) {
32 | _isReady.value = value
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/model/FirewallModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.model
19 |
20 | import com.kin.athena.data.service.NetworkManager
21 |
22 | enum class FirewallResult {
23 | ACCEPT(),
24 | DROP(),
25 | DNS_BLOCKED(),
26 | }
27 |
28 | data class FireWallModel(
29 | val destinationIP: String = "",
30 | val destinationPort: Int = 0,
31 | val sourceIP: String = "",
32 | val sourcePort: Int = 0,
33 | val protocol: Byte = 0,
34 | var uid: Int = 0,
35 | var shouldLog: Boolean = true,
36 | var networkType: NetworkManager.ConnectionType = NetworkManager.ConnectionType.WIFI
37 | )
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/ApplicationUseCases.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.domain.usecase.application
18 |
19 | data class ApplicationUseCases(
20 | val getApplications: GetApplications,
21 | val deleteApplication: DeleteApplication,
22 | val addApplication: AddApplication,
23 | val addApplications: AddApplications,
24 | val updateApplication: UpdateApplication,
25 | val getApplication: GetApplication,
26 | val observeApplication: ObserveApplication,
27 | val checkApplicationExists: CheckApplicationExists,
28 | val getExistingPackageIds: GetExistingPackageIds,
29 | val getFilteredApplications: GetFilteredApplications,
30 | val updatePinnedStatus: UpdatePinnedStatus
31 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/local/dao/BlockedDao.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.local.dao
19 |
20 | import androidx.room.Dao
21 | import androidx.room.Insert
22 | import androidx.room.OnConflictStrategy
23 | import androidx.room.Query
24 | import com.kin.athena.domain.model.Ip
25 | import kotlinx.coroutines.flow.Flow
26 |
27 | @Dao
28 | interface NetworkFilterDao {
29 | @Insert(onConflict = OnConflictStrategy.REPLACE)
30 | suspend fun insertIp(ip: Ip)
31 |
32 | @Query("DELETE FROM NetworkFilter WHERE ip = :ip")
33 | suspend fun deleteIp(ip: String)
34 |
35 | @Query("DELETE FROM NetworkFilter")
36 | suspend fun deleteIps()
37 |
38 | @Query("SELECT * FROM NetworkFilter")
39 | fun getAllIps(): Flow>
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/DeleteLogs.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 |
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.domain.model.Log
24 | import com.kin.athena.domain.repository.LogRepository
25 | import javax.inject.Inject
26 |
27 | class DeleteLogs @Inject constructor(
28 | private val logRepository: LogRepository
29 | ) {
30 | suspend fun execute(): Result {
31 | return try {
32 | logRepository.deleteLogs()
33 | Result.Success(Unit)
34 | } catch (e: Exception) {
35 | Result.Failure(Error.ServerError(e.message ?: "Error while deleting log"))
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/DeleteLog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Log
23 | import com.kin.athena.domain.repository.LogRepository
24 | import javax.inject.Inject
25 |
26 | class DeleteLog @Inject constructor(
27 | private val logRepository: LogRepository
28 | ) {
29 | suspend fun execute(id: Int): Result {
30 | return try {
31 | logRepository.deleteLogById(id)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while deleting log $id"))
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/GetLog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Log
23 | import com.kin.athena.domain.repository.LogRepository
24 | import javax.inject.Inject
25 |
26 | class GetLog @Inject constructor(
27 | private val logRepository: LogRepository
28 | ) {
29 | suspend fun execute(id: Int): Result {
30 | return try {
31 | val log = logRepository.getLogById(id)
32 | Result.Success(log)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while obtaining log $id"))
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/networkFilter/DeleteIps.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.networkFilter
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.repository.NetworkFilterRepository
23 | import javax.inject.Inject
24 |
25 | class DeleteIps @Inject constructor(
26 | private val networkFilterRepository: NetworkFilterRepository
27 | ) {
28 | suspend fun execute(): Result {
29 | return try {
30 | networkFilterRepository.deleteIps()
31 | Result.Success(Unit)
32 | } catch (e: Exception) {
33 | Result.Failure(Error.ServerError(e.message ?: "Error while deleting ips"))
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/networkFilter/DeleteIp.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.networkFilter
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.repository.NetworkFilterRepository
23 | import javax.inject.Inject
24 |
25 | class DeleteIp @Inject constructor(
26 | private val networkFilterRepository: NetworkFilterRepository
27 | ) {
28 | suspend fun execute(ip: String): Result {
29 | return try {
30 | networkFilterRepository.deleteIp(ip)
31 | Result.Success(Unit)
32 | } catch (e: Exception) {
33 | Result.Failure(Error.ServerError(e.message ?: "Error while deleting ip $ip"))
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/extensions/DrawableExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils.extensions
19 |
20 | import android.graphics.Bitmap
21 | import android.graphics.Canvas
22 | import android.graphics.drawable.BitmapDrawable
23 | import android.graphics.drawable.Drawable
24 |
25 | fun Drawable.toBitmap(): Bitmap {
26 | if (this is BitmapDrawable) {
27 | return this.bitmap
28 | }
29 | val width = if (intrinsicWidth > 0) intrinsicWidth else 1
30 | val height = if (intrinsicHeight > 0) intrinsicHeight else 1
31 |
32 | val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
33 | val canvas = Canvas(bitmap)
34 |
35 | setBounds(0, 0, canvas.width, canvas.height)
36 | draw(canvas)
37 |
38 | return bitmap
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/GetLogs.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Log
23 | import com.kin.athena.domain.repository.LogRepository
24 | import kotlinx.coroutines.flow.Flow
25 | import javax.inject.Inject
26 |
27 | class GetLogs @Inject constructor(
28 | private val logRepository: LogRepository
29 | ) {
30 | suspend fun execute(): Result>?, Error> {
31 | return try {
32 | val log = logRepository.getAllLogs()
33 | Result.Success(log)
34 | } catch (e: Exception) {
35 | Result.Failure(Error.ServerError(e.message ?: "Error while obtaining logs"))
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/networkFilter/AddIp.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.networkFilter
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Ip
23 | import com.kin.athena.domain.repository.NetworkFilterRepository
24 | import javax.inject.Inject
25 |
26 | class AddIp @Inject constructor(
27 | private val networkFilterRepository: NetworkFilterRepository
28 | ) {
29 | suspend fun execute(ip: Ip): Result {
30 | return try {
31 | networkFilterRepository.insertIp(ip)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while adding ip $ip"))
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/local/dao/LogDao.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.local.dao
19 |
20 | import androidx.room.Dao
21 | import androidx.room.Insert
22 | import androidx.room.OnConflictStrategy
23 | import androidx.room.Query
24 | import com.kin.athena.domain.model.Log
25 | import kotlinx.coroutines.flow.Flow
26 |
27 | @Dao
28 | interface LogDao {
29 |
30 | @Insert(onConflict = OnConflictStrategy.REPLACE)
31 | suspend fun insertLog(log: Log)
32 |
33 | @Query("DELETE FROM logs WHERE id = :id")
34 | suspend fun deleteLogById(id: Int)
35 |
36 | @Query("DELETE FROM logs")
37 | suspend fun deleteLogs()
38 |
39 | @Query("SELECT * FROM logs WHERE id = :id")
40 | suspend fun getLogById(id: Int): Log?
41 |
42 | @Query("SELECT * FROM logs")
43 | fun getAllLogs(): Flow>
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/preferences/SavePreferences.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.preferences
19 |
20 | import com.kin.athena.core.utils.Result
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.domain.model.Settings
23 | import com.kin.athena.domain.repository.SettingsRepository
24 | import javax.inject.Inject
25 |
26 | class SavePreferences @Inject constructor(
27 | private val settingsRepository: SettingsRepository
28 | ) {
29 | suspend fun execute(settings: Settings): Result {
30 | return try {
31 | settingsRepository.saveSettings(settings)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while saving preferences"))
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/preferences/LoadPreferences.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.preferences
19 |
20 |
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.domain.model.Settings
24 | import com.kin.athena.domain.repository.SettingsRepository
25 | import javax.inject.Inject
26 |
27 |
28 | class LoadPreferences @Inject constructor(
29 | private val settingsRepository: SettingsRepository
30 | ) {
31 | suspend fun execute(): Result {
32 | return try {
33 | val settings = settingsRepository.loadSettings()
34 | Result.Success(settings)
35 | } catch (e: Exception) {
36 | Result.Failure(Error.ServerError(e.message ?: "Error while loading preferences"))
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/GetApplications.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.domain.usecase.application
18 |
19 | import com.kin.athena.domain.repository.ApplicationRepository
20 | import com.kin.athena.core.utils.Result
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.domain.model.Application
23 | import javax.inject.Inject
24 |
25 | class GetApplications @Inject constructor(
26 | private val packageRepository: ApplicationRepository
27 | ) {
28 | suspend fun execute(): Result, Error> {
29 | return try {
30 | val packages = packageRepository.getAllApplications()
31 | Result.Success(packages)
32 | } catch (e: Exception) {
33 | Result.Failure(Error.ServerError(e.message ?: "Error while retrieving packages"))
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/proxy/ProxyScreen.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.presentation.screens.settings.subSettings.proxy
18 |
19 | import androidx.compose.runtime.Composable
20 | import androidx.compose.ui.res.stringResource
21 | import androidx.navigation.NavController
22 | import com.kin.athena.R
23 | import com.kin.athena.presentation.screens.settings.components.SettingsScaffold
24 | import com.kin.athena.presentation.screens.settings.viewModel.SettingsViewModel
25 |
26 | @Composable
27 | fun ProxyScreen(
28 | navController: NavController,
29 | settings: SettingsViewModel,
30 | ) {
31 | SettingsScaffold(
32 | settings = settings,
33 | title = stringResource(id = R.string.proxy_title),
34 | onBackNavClicked = { navController.navigateUp() }
35 | ) {
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/CheckApplicationExists.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import javax.inject.Inject
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.core.utils.Error
24 |
25 | class CheckApplicationExists @Inject constructor(
26 | private val applicationRepository: ApplicationRepository
27 | ) {
28 | suspend fun execute(packageId: String): Result {
29 | return try {
30 | val exists = applicationRepository.isPackageIdExists(packageId)
31 | Result.Success(exists)
32 | } catch (e: Exception) {
33 | Result.Failure(Error.ServerError(e.message ?: "Error while checking package existence for $packageId"))
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/UpdatePinnedStatus.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.core.utils.Result
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.domain.repository.ApplicationRepository
23 | import javax.inject.Inject
24 |
25 | class UpdatePinnedStatus @Inject constructor(
26 | private val packageRepository: ApplicationRepository
27 | ) {
28 | suspend fun execute(packageId: String, isPinned: Boolean): Result {
29 | return try {
30 | packageRepository.updatePinnedStatus(packageId, isPinned)
31 | Result.Success(Unit)
32 | } catch (e: Exception) {
33 | Result.Failure(Error.ServerError(e.message ?: "Error while updating pinned status for package $packageId"))
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/networkFilter/GetIps.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.networkFilter
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Ip
23 | import com.kin.athena.domain.repository.NetworkFilterRepository
24 | import kotlinx.coroutines.flow.Flow
25 | import javax.inject.Inject
26 |
27 | class GetIps @Inject constructor(
28 | private val networkFilterRepository: NetworkFilterRepository
29 | ) {
30 | suspend fun execute(): Result>, Error> {
31 | return try {
32 | val ips = networkFilterRepository.getAllIps()
33 | Result.Success(ips)
34 | } catch (e: Exception) {
35 | Result.Failure(Error.ServerError(e.message ?: "Error while getting ips"))
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/AddApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import javax.inject.Inject
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.core.utils.Error
24 | import com.kin.athena.domain.model.Application
25 |
26 | class AddApplication @Inject constructor(
27 | private val packageRepository: ApplicationRepository
28 | ) {
29 | suspend fun execute(application: Application): Result {
30 | return try {
31 | packageRepository.insertApplication(application)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while adding package ${application.packageID}"))
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/log/AddLog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.log
19 |
20 | import com.kin.athena.core.utils.Error
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.domain.model.Application
23 | import com.kin.athena.domain.model.Log
24 | import com.kin.athena.domain.repository.ApplicationRepository
25 | import com.kin.athena.domain.repository.LogRepository
26 | import javax.inject.Inject
27 |
28 | class AddLog @Inject constructor(
29 | private val logRepository: LogRepository
30 | ) {
31 | suspend fun execute(log: Log): Result {
32 | return try {
33 | logRepository.insertLog(log)
34 | Result.Success(Unit)
35 | } catch (e: Exception) {
36 | Result.Failure(Error.ServerError(e.message ?: "Error while adding log $log"))
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/AddApplications.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import javax.inject.Inject
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.core.utils.Error
24 | import com.kin.athena.domain.model.Application
25 |
26 | class AddApplications @Inject constructor(
27 | private val packageRepository: ApplicationRepository
28 | ) {
29 | suspend fun execute(applications: List): Result {
30 | return try {
31 | packageRepository.insertApplications(applications)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while adding ${applications.size} packages"))
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/DeleteApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import com.kin.athena.core.utils.Result
22 | import com.kin.athena.core.utils.Error
23 | import com.kin.athena.domain.model.Application
24 | import javax.inject.Inject
25 |
26 | class DeleteApplication @Inject constructor(
27 | private val packageRepository: ApplicationRepository
28 | ) {
29 | suspend fun execute(application: Application): Result {
30 | return try {
31 | packageRepository.deleteApplication(application)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.PackageError(e.message ?: "Error while deleting package ${application.packageID}"))
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/UpdateApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.core.utils.Result
21 | import com.kin.athena.core.utils.Error
22 | import com.kin.athena.domain.model.Application
23 | import com.kin.athena.domain.repository.ApplicationRepository
24 | import javax.inject.Inject
25 |
26 | class UpdateApplication @Inject constructor(
27 | private val packageRepository: ApplicationRepository
28 | ) {
29 | suspend fun execute(application: Application): Result {
30 | return try {
31 | packageRepository.updateApplication(application)
32 | Result.Success(Unit)
33 | } catch (e: Exception) {
34 | Result.Failure(Error.ServerError(e.message ?: "Error while updating package ${application.packageID}"))
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/ipv4/Ipv4Model.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.ipv4
19 |
20 | data class IPv4(
21 | var ipVersion: Byte,
22 | var internetHeaderLength: Byte,
23 | var dscpOrTypeOfService: Byte,
24 | var ecn: Byte,
25 | var totalLength: Int,
26 | var identification: Int,
27 | var flagsAndFragmentOffset: Short,
28 | var timeToLive: Byte,
29 | var protocol: Byte,
30 | var headerChecksum: Int,
31 | var sourceIP: Int,
32 | var destinationIP: Int,
33 | var uid: Int = -1,
34 | ) {
35 | val fragmentOffset: Short
36 | get() = (flagsAndFragmentOffset.toInt() and 0x1FFF).toShort()
37 |
38 | val isFragmentationAllowed: Boolean
39 | get() = (flagsAndFragmentOffset.toInt() and 0x4000) != 0
40 |
41 | val iPHeaderLength: Int
42 | get() = internetHeaderLength.toInt() * 4
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/handler/PacketHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.service.firewall.handler
18 |
19 | import com.kin.athena.core.logging.Logger
20 | import com.kin.athena.service.firewall.model.FireWallModel
21 | import com.kin.athena.service.firewall.model.FirewallResult
22 | import com.kin.athena.service.vpn.network.transport.dns.DNSModel
23 | import com.kin.athena.service.vpn.network.transport.ipv4.IPv4
24 |
25 | fun filterPacket(protocol: Any?, ipHeader: IPv4?, ruleManager: RuleHandler, dnsModel: DNSModel? = null, uid: Int? = null, bypassCheck: Boolean = false): Triple {
26 | val handler = ProtocolHandlerFactory.getHandler(protocol)
27 | val fireWallModel = handler?.handle(protocol, ipHeader) ?: uid?.let { FireWallModel(uid = uid) }
28 | return fireWallModel?.let { ruleManager.handle(it, dnsModel, bypassCheck) } ?: Triple(true, 0, FirewallResult.ACCEPT)
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/database/entity/CustomDomainEntity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.database.entity
19 |
20 | import androidx.room.Entity
21 | import androidx.room.PrimaryKey
22 | import androidx.room.ColumnInfo
23 |
24 | @Entity(tableName = "custom_domains")
25 | data class CustomDomainEntity(
26 | @PrimaryKey(autoGenerate = true)
27 | val id: Long = 0,
28 |
29 | @ColumnInfo(name = "domain")
30 | val domain: String,
31 |
32 | @ColumnInfo(name = "description")
33 | val description: String = "",
34 |
35 | @ColumnInfo(name = "is_regex")
36 | val isRegex: Boolean = false,
37 |
38 | @ColumnInfo(name = "is_allowlist")
39 | val isAllowlist: Boolean = true,
40 |
41 | @ColumnInfo(name = "created_at")
42 | val createdAt: Long = System.currentTimeMillis(),
43 |
44 | @ColumnInfo(name = "is_enabled")
45 | val isEnabled: Boolean = true
46 | )
--------------------------------------------------------------------------------
/app/src/fdroid/java/com/kin/athena/data/service/billing/BillingProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.service.billing
19 |
20 | import android.app.Activity
21 | import javax.inject.Inject
22 | import javax.inject.Singleton
23 |
24 | @Singleton
25 | class BillingProvider @Inject constructor() {
26 |
27 | private var currentActivity: Activity? = null
28 | private var currentBillingInterface: BillingInterface? = null
29 |
30 | fun setActivity(activity: Activity) {
31 | if (currentActivity != activity) {
32 | currentActivity = activity
33 | currentBillingInterface = createBillingInterface(activity)
34 | }
35 | }
36 |
37 | fun getBillingInterface(): BillingInterface? {
38 | return currentBillingInterface
39 | }
40 |
41 | private fun createBillingInterface(activity: Activity): BillingInterface {
42 | return FDroidBillingManager(activity)
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/playstore/java/com/kin/athena/data/service/billing/BillingProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.service.billing
19 |
20 | import android.app.Activity
21 | import javax.inject.Inject
22 | import javax.inject.Singleton
23 |
24 | @Singleton
25 | class BillingProvider @Inject constructor() {
26 |
27 | private var currentActivity: Activity? = null
28 | private var currentBillingInterface: BillingInterface? = null
29 |
30 | fun setActivity(activity: Activity) {
31 | if (currentActivity != activity) {
32 | currentActivity = activity
33 | currentBillingInterface = createBillingInterface(activity)
34 | }
35 | }
36 |
37 | fun getBillingInterface(): BillingInterface? {
38 | return currentBillingInterface
39 | }
40 |
41 | private fun createBillingInterface(activity: Activity): BillingInterface {
42 | return PlayStoreBillingManager(activity)
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/extensions/NetworkExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils.extensions
19 |
20 | import com.kin.athena.core.logging.Logger
21 | import kotlinx.coroutines.Dispatchers
22 | import kotlinx.coroutines.withContext
23 | import java.net.InetAddress
24 | import java.net.UnknownHostException
25 |
26 | /**
27 | * Extension function to resolve an IP address to a hostname.
28 | *
29 | * @return The hostname as a String, or null if the resolution fails.
30 | */
31 | suspend fun String.resolveIpToHostname(): String? {
32 | return withContext(Dispatchers.IO) {
33 | try {
34 | val address = InetAddress.getByName(this@resolveIpToHostname)
35 | if (address.hostName == this@resolveIpToHostname) {
36 | null
37 | } else {
38 | address.hostName
39 | }
40 | } catch (e: Exception) {
41 | null
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialButton.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.material3.Icon
21 | import androidx.compose.material3.IconButton
22 | import androidx.compose.material3.MaterialTheme
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.draw.scale
26 | import androidx.compose.ui.graphics.vector.ImageVector
27 |
28 | @Composable
29 | fun MaterialButton(
30 | imageVector: ImageVector,
31 | contentDescription: String,
32 | scale: Float = 1f,
33 | onClick: () -> Unit,
34 | ) {
35 | IconButton(onClick = onClick) {
36 | Icon(
37 | imageVector = imageVector,
38 | contentDescription = contentDescription,
39 | tint = MaterialTheme.colorScheme.onSurface,
40 | modifier = Modifier.scale(scale)
41 | )
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/lock/components/TitleText.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.settings.subSettings.lock.components
19 |
20 | import androidx.compose.foundation.layout.padding
21 | import androidx.compose.material3.MaterialTheme
22 | import androidx.compose.material3.Text
23 | import androidx.compose.runtime.Composable
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.graphics.Color
26 | import androidx.compose.ui.text.font.FontWeight
27 | import androidx.compose.ui.text.style.TextAlign
28 | import androidx.compose.ui.unit.dp
29 |
30 |
31 | @Composable
32 | fun TitleText(
33 | text: String,
34 | color: Color = MaterialTheme.colorScheme.onBackground
35 | ) {
36 | Text(
37 | text = text,
38 | modifier = Modifier.padding(16.dp),
39 | textAlign = TextAlign.Center,
40 | fontWeight = FontWeight.Bold,
41 | color = color
42 | )
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/repository/NetworkFilterRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.repository
19 |
20 | import com.kin.athena.data.local.provider.DatabaseProvider
21 | import com.kin.athena.domain.model.Ip
22 | import com.kin.athena.domain.repository.NetworkFilterRepository
23 | import kotlinx.coroutines.flow.Flow
24 | import javax.inject.Inject
25 |
26 | class NetworkFilterImpl @Inject constructor(
27 | private val provider: DatabaseProvider
28 | ) : NetworkFilterRepository {
29 | override suspend fun insertIp(ip: Ip) {
30 | provider.networkFilterDao().insertIp(ip)
31 | }
32 |
33 | override suspend fun deleteIp(ip: String) {
34 | provider.networkFilterDao().deleteIp(ip)
35 | }
36 |
37 | override suspend fun deleteIps() {
38 | provider.networkFilterDao().deleteIps()
39 | }
40 |
41 | override fun getAllIps(): Flow> {
42 | return provider.networkFilterDao().getAllIps()
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/Result.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils
19 |
20 | import com.kin.athena.core.logging.Logger
21 |
22 | sealed class Result {
23 | data class Success(val data: T) : Result()
24 | data class Failure(val error: E) : Result()
25 |
26 | inline fun fold(
27 | ifFailure: (E) -> R = { defaultFailureHandler(it) },
28 | ifSuccess: (T) -> R
29 | ): R = when (this) {
30 | is Success -> ifSuccess(data)
31 | is Failure -> ifFailure(error)
32 | }
33 |
34 | companion object {
35 | inline fun defaultFailureHandler(error: E): Nothing {
36 | if (error is Throwable) {
37 | Logger.error(error.stackTraceToString())
38 | } else {
39 | Logger.error(error.toString())
40 | }
41 | throw RuntimeException("Unhandled Result Failure: $error")
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/CircleWrapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components
19 |
20 | import androidx.compose.foundation.background
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.padding
23 | import androidx.compose.foundation.shape.RoundedCornerShape
24 | import androidx.compose.material3.MaterialTheme
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.graphics.Color
28 | import androidx.compose.ui.unit.Dp
29 | import androidx.compose.ui.unit.dp
30 |
31 | @Composable
32 | fun CircleWrapper(
33 | color: Color = MaterialTheme.colorScheme.background,
34 | size: Dp = 8.dp,
35 | content: @Composable () -> Unit
36 | ) {
37 | Box(
38 | modifier = Modifier
39 | .background(
40 | color = color,
41 | shape = RoundedCornerShape(50)
42 | )
43 | .padding(size),
44 | ) {
45 | content()
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/icmp/ICMPModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.icmp
19 |
20 | data class ICMPModel(
21 | val type: Int,
22 | val code: Int,
23 | val checksum: Int,
24 | val identifier: Int,
25 | val sequenceNumber: Int,
26 | val data: ByteArray
27 | ) {
28 | override fun equals(other: Any?): Boolean {
29 | if (this === other) return true
30 | if (javaClass != other?.javaClass) return false
31 |
32 | other as ICMPModel
33 |
34 | return type == other.type &&
35 | code == other.code &&
36 | checksum == other.checksum &&
37 | identifier == other.identifier &&
38 | sequenceNumber == other.sequenceNumber &&
39 | data.contentEquals(other.data)
40 | }
41 |
42 | override fun hashCode(): Int {
43 | return listOf(type, code, checksum, identifier, sequenceNumber, data.contentHashCode()).fold(0) { acc, i -> 31 * acc + i }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/repository/LogRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.repository
19 |
20 | import com.kin.athena.data.local.provider.DatabaseProvider
21 | import com.kin.athena.domain.model.Log
22 | import com.kin.athena.domain.repository.LogRepository
23 | import kotlinx.coroutines.flow.Flow
24 | import javax.inject.Inject
25 |
26 | class LogRepositoryImpl @Inject constructor(
27 | private val provider: DatabaseProvider
28 | ) : LogRepository {
29 | override suspend fun insertLog(log: Log) {
30 | provider.logDao().insertLog(log)
31 | }
32 |
33 | override suspend fun deleteLogById(id: Int) {
34 | provider.logDao().deleteLogById(id)
35 | }
36 |
37 | override suspend fun deleteLogs() {
38 | provider.logDao().deleteLogs()
39 | }
40 |
41 | override suspend fun getLogById(id: Int): Log? {
42 | return provider.logDao().getLogById(id)
43 | }
44 |
45 | override suspend fun getAllLogs(): Flow> {
46 | return provider.logDao().getAllLogs()
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/database/DatabaseModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di.database
19 |
20 | import com.kin.athena.data.database.dao.CustomDomainDao
21 | import com.kin.athena.data.local.provider.DatabaseProvider
22 | import com.kin.athena.data.repository.CustomDomainRepositoryImpl
23 | import com.kin.athena.domain.repository.CustomDomainRepository
24 | import dagger.Module
25 | import dagger.Provides
26 | import dagger.hilt.InstallIn
27 | import dagger.hilt.components.SingletonComponent
28 | import javax.inject.Singleton
29 |
30 | @Module
31 | @InstallIn(SingletonComponent::class)
32 | object DatabaseModule {
33 |
34 | @Provides
35 | @Singleton
36 | fun provideCustomDomainDao(databaseProvider: DatabaseProvider): CustomDomainDao {
37 | return databaseProvider.instance().customDomainDao()
38 | }
39 |
40 | @Provides
41 | @Singleton
42 | fun provideCustomDomainRepository(
43 | customDomainDao: CustomDomainDao
44 | ): CustomDomainRepository {
45 | return CustomDomainRepositoryImpl(customDomainDao)
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/GetApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.domain.usecase.application
18 |
19 | import com.kin.athena.core.utils.Error
20 | import com.kin.athena.core.utils.Result
21 | import com.kin.athena.domain.model.Application
22 | import com.kin.athena.domain.repository.ApplicationRepository
23 | import javax.inject.Inject
24 |
25 | class GetApplication @Inject constructor(
26 | private val packageRepository: ApplicationRepository
27 | ) {
28 | suspend fun execute(applicationID: String): Result {
29 | return try {
30 | val application = packageRepository.getApplicationByID(packageId = applicationID)
31 | application?.let {
32 | Result.Success(application)
33 | } ?: run {
34 | Result.Failure(Error.ServerError("Application $applicationID was not found"))
35 | }
36 | } catch (e: Exception) {
37 | Result.Failure(Error.ServerError(e.message ?: "Error while retrieving packages"))
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/NetworkStatsState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | /**
21 | * Data class representing the current network statistics state for the logging screen.
22 | * Contains counts of allowed, blocked, and total network requests along with firewall status.
23 | */
24 | data class NetworkStatsState(
25 | /**
26 | * Number of network requests that were allowed by the firewall
27 | */
28 | val allowedCount: Long = 0L,
29 |
30 | /**
31 | * Number of network requests that were blocked by the firewall
32 | */
33 | val blockedCount: Long = 0L,
34 |
35 | /**
36 | * Total number of network requests processed (allowedCount + blockedCount)
37 | */
38 | val totalCount: Long = 0L,
39 |
40 | /**
41 | * Whether the firewall is currently active and processing requests
42 | */
43 | val isFirewallActive: Boolean = false,
44 |
45 | /**
46 | * Timestamp when the current firewall session started, null if no session is active
47 | */
48 | val sessionStartTime: Long? = null
49 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/Chip.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.clickable
21 | import androidx.compose.foundation.layout.padding
22 | import androidx.compose.foundation.shape.RoundedCornerShape
23 | import androidx.compose.material3.MaterialTheme
24 | import androidx.compose.material3.Surface
25 | import androidx.compose.runtime.Composable
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.unit.dp
28 |
29 | @Composable
30 | fun Chip(
31 | onClick: () -> Unit,
32 | label: @Composable () -> Unit,
33 | modifier: Modifier = Modifier
34 | ) {
35 | Surface(
36 | modifier = modifier.clickable { onClick() },
37 | shape = RoundedCornerShape(16.dp),
38 | color = MaterialTheme.colorScheme.secondaryContainer,
39 | tonalElevation = 1.dp
40 | ) {
41 | androidx.compose.foundation.layout.Box(
42 | modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
43 | ) {
44 | label()
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/local/database/Database.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.local.database
19 |
20 | import androidx.room.Database
21 | import androidx.room.RoomDatabase
22 | import com.kin.athena.core.utils.constants.AppConstants
23 | import com.kin.athena.data.local.dao.ApplicationDao
24 | import com.kin.athena.data.local.dao.LogDao
25 | import com.kin.athena.data.local.dao.NetworkFilterDao
26 | import com.kin.athena.data.database.dao.CustomDomainDao
27 | import com.kin.athena.data.database.entity.CustomDomainEntity
28 | import com.kin.athena.domain.model.Application
29 | import com.kin.athena.domain.model.Ip
30 | import com.kin.athena.domain.model.Log
31 |
32 | @Database(
33 | entities = [Application::class, Log::class, Ip::class, CustomDomainEntity::class],
34 | version = AppConstants.DatabaseConstants.DATABASE_VERSION,
35 | exportSchema = false
36 | )
37 | abstract class AppDatabase : RoomDatabase() {
38 | abstract fun packageDao(): ApplicationDao
39 | abstract fun logDao(): LogDao
40 | abstract fun blockedDao() : NetworkFilterDao
41 | abstract fun customDomainDao(): CustomDomainDao
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/mapper/CustomDomainMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.mapper
19 |
20 | import com.kin.athena.data.database.entity.CustomDomainEntity
21 | import com.kin.athena.domain.model.CustomDomain
22 |
23 | fun CustomDomainEntity.toDomain(): CustomDomain {
24 | return CustomDomain(
25 | id = id,
26 | domain = domain,
27 | description = description,
28 | isRegex = isRegex,
29 | isAllowlist = isAllowlist,
30 | createdAt = createdAt,
31 | isEnabled = isEnabled
32 | )
33 | }
34 |
35 | fun CustomDomain.toEntity(): CustomDomainEntity {
36 | return CustomDomainEntity(
37 | id = id,
38 | domain = domain,
39 | description = description,
40 | isRegex = isRegex,
41 | isAllowlist = isAllowlist,
42 | createdAt = createdAt,
43 | isEnabled = isEnabled
44 | )
45 | }
46 |
47 | fun List.toDomainList(): List {
48 | return map { it.toDomain() }
49 | }
50 |
51 | fun List.toEntityList(): List {
52 | return map { it.toEntity() }
53 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/notification_network_speed.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
33 |
34 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/logging/Logger.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.logging
19 |
20 | import android.util.Log
21 |
22 | object Logger {
23 | enum class LogLevel { DEBUG, INFO, WARN, ERROR }
24 |
25 | private var currentLogLevel: LogLevel = LogLevel.DEBUG
26 | fun debug(message: String) = log(LogLevel.DEBUG, message)
27 | fun info(message: String) = log(LogLevel.INFO, message)
28 | fun warn(message: String) = log(LogLevel.WARN, message)
29 | fun warning(message: String) = log(LogLevel.WARN, message)
30 | fun error(message: String, throwable: Throwable? = null) = log(LogLevel.ERROR, message, throwable)
31 |
32 | private fun log(level: LogLevel, message: String, throwable: Throwable? = null) {
33 | if (currentLogLevel <= level) {
34 | when (level) {
35 | LogLevel.DEBUG -> Log.d("Athena", "[ + ] $message", throwable)
36 | LogLevel.INFO -> Log.i("Athena", "[ + ] $message", throwable)
37 | LogLevel.WARN -> Log.w("Athena", "[ ! ] $message", throwable)
38 | LogLevel.ERROR -> Log.e("Athena", "[ ! ] $message", throwable)
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/firewall/WorkerModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di.firewall
19 |
20 | import android.content.Context
21 | import androidx.work.ListenableWorker
22 | import androidx.work.WorkerParameters
23 | import com.kin.athena.presentation.screens.settings.subSettings.dns.hosts.RuleDatabaseUpdateWorker
24 | import dagger.Binds
25 | import dagger.Module
26 | import dagger.hilt.InstallIn
27 | import dagger.hilt.components.SingletonComponent
28 | import dagger.multibindings.IntoMap
29 | import dagger.MapKey
30 | import dagger.assisted.Assisted
31 | import dagger.assisted.AssistedFactory
32 | import kotlin.reflect.KClass
33 |
34 | @MapKey
35 | annotation class WorkerKey(val value: KClass)
36 |
37 | @AssistedFactory
38 | interface RuleDatabaseUpdateWorkerFactory {
39 | fun create(@Assisted context: Context, @Assisted params: WorkerParameters): RuleDatabaseUpdateWorker
40 | }
41 |
42 | @Module
43 | @InstallIn(SingletonComponent::class)
44 | abstract class WorkerModule {
45 |
46 | @Binds
47 | @IntoMap
48 | @WorkerKey(RuleDatabaseUpdateWorker::class)
49 | abstract fun bindRuleDatabaseUpdateWorker(
50 | factory: RuleDatabaseUpdateWorkerFactory
51 | ): RuleDatabaseUpdateWorkerFactory
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/repository/SettingsModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di.repository
19 |
20 | import android.app.Application
21 | import com.kin.athena.data.repository.SettingsRepositoryImpl
22 | import com.kin.athena.domain.repository.SettingsRepository
23 | import com.kin.athena.domain.usecase.preferences.LoadPreferences
24 | import com.kin.athena.domain.usecase.preferences.PreferencesUseCases
25 | import com.kin.athena.domain.usecase.preferences.SavePreferences
26 | import dagger.Module
27 | import dagger.Provides
28 | import dagger.hilt.InstallIn
29 | import dagger.hilt.components.SingletonComponent
30 | import javax.inject.Singleton
31 |
32 | @Module
33 | @InstallIn(SingletonComponent::class)
34 | object SettingsModule {
35 |
36 | @Provides
37 | @Singleton
38 | fun provideSettingsRepository(application: Application): SettingsRepository {
39 | return SettingsRepositoryImpl(application)
40 | }
41 |
42 | @Provides
43 | @Suppress
44 | fun providePreferenceUseCases(repository: SettingsRepository): PreferencesUseCases {
45 | return PreferencesUseCases(
46 | loadSettings = LoadPreferences(repository),
47 | saveSettings = SavePreferences(repository)
48 | )
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/constants/ProjectConstants.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils.constants
19 |
20 | object ProjectConstants {
21 | const val DONATE = "https://ko-fi.com/kin69_"
22 | val SHA_256_SIGNING = setOf(
23 | "3dac74ea57cbf9d5dd10ac2f443036afd38581588dd4dafa02d230bddb4250dd", // Play Store signature
24 | "f8388448de6d3eb4831a60aa4194a0524cbb443fe5806090c1a403565f49a06b", // Github signature
25 | "628704bf1c86130eff49ad991c1b4dc9006700112e5ebe692da3da43f074d8fd" // Build
26 | )
27 | const val DEVELOPER = "Vexzure"
28 |
29 | const val PROJECT_DOWNLOADS = "https://github.com/Kin69/Athena"
30 | const val PROJECT_SOURCE_CODE = "https://github.com/Kin69/Athena"
31 | const val LICENSE_URL = "https://www.gnu.org/licenses/gpl-3.0.en.html"
32 | const val SUPPORT_MAIL = "support@easyapps.me"
33 | const val SUPPORT_DISCORD = "https://discord.gg/ZrP4G8z23H"
34 | const val GITHUB_FEATURE_REQUEST = "https://github.com/Kin69/Athena/issues"
35 |
36 | // Store URLs - update these with your actual package name
37 | const val PLAY_STORE_URL = "market://details?id=com.kin.athena"
38 | const val PLAY_STORE_WEB_URL = "https://play.google.com/store/apps/details?id=com.kin.athena"
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialScaffold.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.layout.Box
21 | import androidx.compose.foundation.layout.consumeWindowInsets
22 | import androidx.compose.foundation.layout.imePadding
23 | import androidx.compose.foundation.layout.padding
24 | import androidx.compose.material3.MaterialTheme
25 | import androidx.compose.material3.Scaffold
26 | import androidx.compose.runtime.Composable
27 | import androidx.compose.ui.Modifier
28 |
29 | @Composable
30 | fun MaterialScaffold(
31 | topBar: @Composable () -> Unit = {},
32 | floatingActionButton: @Composable () -> Unit = {},
33 | content: @Composable () -> Unit
34 | ) {
35 | Scaffold(
36 | containerColor = MaterialTheme.colorScheme.background,
37 | topBar = { topBar() },
38 | floatingActionButton = { floatingActionButton() },
39 | content = { padding ->
40 | Box(
41 | modifier = Modifier
42 | .padding(padding)
43 | .imePadding()
44 | .consumeWindowInsets(padding)
45 | ) {
46 | content()
47 | }
48 | }
49 | )
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/data/service/ScreenManager.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.data.service
19 |
20 | import android.content.BroadcastReceiver
21 | import android.content.Context
22 | import android.content.Intent
23 | import dagger.hilt.android.AndroidEntryPoint
24 | import javax.inject.Inject
25 | import javax.inject.Singleton
26 |
27 | @AndroidEntryPoint
28 | class ScreenStateReceiver : BroadcastReceiver() {
29 |
30 | @Inject
31 | lateinit var screenStateManager: ScreenStateManager
32 |
33 | override fun onReceive(context: Context, intent: Intent) {
34 | when (intent.action) {
35 | Intent.ACTION_SCREEN_OFF -> {
36 | screenStateManager.updateScreenStatus(ScreenManager.SCREEN_OFF)
37 | }
38 | Intent.ACTION_SCREEN_ON -> {
39 | screenStateManager.updateScreenStatus(ScreenManager.SCREEN_ON)
40 | }
41 | }
42 | }
43 | }
44 |
45 | @Singleton
46 | class ScreenStateManager
47 | {
48 | var currentScreenStatus: ScreenManager = ScreenManager.SCREEN_ON
49 |
50 | fun updateScreenStatus(screenStatus: ScreenManager) {
51 | currentScreenStatus = screenStatus
52 | }
53 | }
54 |
55 | enum class ScreenManager {
56 | SCREEN_OFF,
57 | SCREEN_ON
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/utils/FirewallStatus.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.utils
19 |
20 | import androidx.annotation.Nullable
21 |
22 | sealed class FirewallStatus(val loaded: Float) {
23 | object OFFLINE : FirewallStatus(0f)
24 | data class LOADING(val progress: Float = 0f) : FirewallStatus(progress)
25 | object ONLINE : FirewallStatus(100f)
26 | object MAGISK_SYSTEMLESS_ERROR : FirewallStatus(0f)
27 |
28 | fun not(): FirewallStatus {
29 | return when (this) {
30 | MAGISK_SYSTEMLESS_ERROR -> OFFLINE
31 | OFFLINE -> ONLINE
32 | is LOADING -> OFFLINE
33 | ONLINE -> OFFLINE
34 | }
35 | }
36 |
37 | fun name(): String {
38 | return when (this) {
39 | MAGISK_SYSTEMLESS_ERROR -> "OFFLINE"
40 | OFFLINE -> "OFFLINE"
41 | is LOADING -> "LOADING"
42 | ONLINE -> "ONLINE"
43 | }
44 | }
45 |
46 | fun getRulesLoaded(): Float {
47 | try {
48 | return when (this) {
49 | MAGISK_SYSTEMLESS_ERROR -> 0.0f
50 | OFFLINE -> 0.0f
51 | is LOADING -> this.progress
52 | ONLINE -> 1.0f
53 | }
54 | } catch (e: NullPointerException) {
55 | return 0f
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/Log.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | import androidx.room.ColumnInfo
21 | import androidx.room.Entity
22 | import androidx.room.Index
23 | import androidx.room.PrimaryKey
24 | import androidx.room.TypeConverter
25 | import com.kin.athena.service.firewall.model.FirewallResult
26 | import com.kin.athena.service.firewall.utils.FirewallStatus
27 |
28 | @Entity(
29 | tableName = "logs",
30 | indices = [Index(value = ["uid"])]
31 | )
32 | data class Log(
33 | @PrimaryKey(autoGenerate = true)
34 | @ColumnInfo(name = "id")
35 | val id: Int = 0,
36 |
37 | @ColumnInfo(name = "packet_time")
38 | val time: Long = System.currentTimeMillis(),
39 |
40 | @ColumnInfo(name = "protocol")
41 | val protocol: String,
42 |
43 | @ColumnInfo(name = "uid")
44 | val packageID: Int,
45 |
46 | @ColumnInfo(name = "source_ip")
47 | val sourceIP: String,
48 |
49 | @ColumnInfo(name = "source_address")
50 | val destinationAddress: String?,
51 |
52 | @ColumnInfo(name = "source_port")
53 | val sourcePort: String,
54 |
55 | @ColumnInfo(name = "destination_ip")
56 | val destinationIP: String,
57 |
58 | @ColumnInfo(name = "destination_port")
59 | val destinationPort: String,
60 |
61 | @ColumnInfo(name = "packet_status")
62 | val packetStatus: FirewallResult,
63 | )
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/dns/hosts/SingleWriterMultipleReaderFile.kt:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2024 Charles Lombardo
2 | *
3 | * Derived from DNS66:
4 | * Copyright (C) 2016 - 2019 Julian Andres Klode
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | */
11 |
12 |
13 | package com.kin.athena.presentation.screens.settings.subSettings.dns.hosts
14 |
15 | import java.io.File
16 | import java.io.FileInputStream
17 | import java.io.FileNotFoundException
18 | import java.io.FileOutputStream
19 | import java.io.IOException
20 | import java.io.InputStream
21 |
22 |
23 | class SingleWriterMultipleReaderFile(file: File) {
24 | val activeFile = file.absoluteFile
25 | val workFile = File(activeFile.absolutePath + ".dnsnet-new")
26 |
27 | @Throws(FileNotFoundException::class)
28 | fun openRead(): InputStream = FileInputStream(activeFile)
29 |
30 |
31 | @Throws(IOException::class)
32 | fun startWrite(): FileOutputStream {
33 | if (workFile.exists() && !workFile.delete()) {
34 | throw IOException("Cannot delete working file")
35 | }
36 | return FileOutputStream(workFile)
37 | }
38 |
39 | @Throws(IOException::class)
40 | fun finishWrite(stream: FileOutputStream) {
41 | try {
42 | stream.close()
43 | } catch (e: IOException) {
44 | failWrite(stream)
45 | throw e
46 | }
47 | if (!workFile.renameTo(activeFile)) {
48 | failWrite(stream)
49 | throw IOException("Cannot commit transaction")
50 | }
51 | }
52 |
53 | @Throws(IOException::class)
54 | fun failWrite(stream: FileOutputStream) {
55 | FileHelper.closeOrWarn(stream, "Cannot close working file")
56 | if (!workFile.delete()) {
57 | throw IOException("Cannot delete working file")
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/transport/dns/DNSExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.vpn.network.transport.dns
19 |
20 | import java.nio.ByteBuffer
21 |
22 | fun ByteBuffer.readDomainName(): String {
23 | val domainParts = mutableListOf()
24 | var length = get().toInt() and 0xFF
25 | while (length > 0) {
26 | val part = ByteArray(length)
27 | get(part)
28 | domainParts.add(part.toString(Charsets.UTF_8))
29 | length = get().toInt() and 0xFF
30 | }
31 | return domainParts.joinToString(".")
32 | }
33 |
34 | fun ByteBuffer.toDNSModel(): DNSModel {
35 | val transactionId = this.short.toInt()
36 | val flags = this.short.toInt()
37 | val questionCount = this.short.toInt()
38 | val answerCount = this.short.toInt()
39 | val authorityCount = this.short.toInt()
40 | val additionalCount = this.short.toInt()
41 | val domainName = this.readDomainName()
42 | val queryType = this.short.toInt()
43 | val queryClass = this.short.toInt()
44 |
45 | return DNSModel(
46 | transactionId = transactionId,
47 | flags = flags,
48 | questionCount = questionCount,
49 | answerCount = answerCount,
50 | authorityCount = authorityCount,
51 | additionalCount = additionalCount,
52 | domainName = domainName,
53 | queryType = queryType,
54 | queryClass = queryClass
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/repository/ApplicationRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 | package com.kin.athena.domain.repository
18 |
19 | import com.kin.athena.domain.model.Application
20 | import kotlinx.coroutines.flow.Flow
21 |
22 |
23 | interface ApplicationRepository {
24 |
25 | suspend fun getAllApplications(): List
26 |
27 | suspend fun insertApplication(application: Application)
28 |
29 | suspend fun insertApplications(applications: List)
30 |
31 | suspend fun updateApplication(application: Application)
32 |
33 | suspend fun deleteApplication(application: Application)
34 |
35 | suspend fun getApplicationByID(packageId: String): Application?
36 |
37 | fun observeApplicationByID(packageId: String): Flow
38 |
39 | suspend fun isPackageIdExists(packageId: String): Boolean
40 |
41 | suspend fun getExistingPackageIds(packageIds: List): List
42 |
43 | suspend fun getFilteredApplications(
44 | showSystemPackages: Boolean,
45 | showOfflinePackages: Boolean,
46 | searchQuery: String,
47 | limit: Int,
48 | offset: Int
49 | ): List
50 |
51 | suspend fun getFilteredApplicationsCount(
52 | showSystemPackages: Boolean,
53 | showOfflinePackages: Boolean,
54 | searchQuery: String
55 | ): Int
56 |
57 | suspend fun updatePinnedStatus(packageId: String, isPinned: Boolean)
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/repository/LogModule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di.repository
19 |
20 | import com.kin.athena.data.local.provider.DatabaseProvider
21 | import com.kin.athena.data.repository.LogRepositoryImpl
22 | import com.kin.athena.domain.repository.LogRepository
23 | import com.kin.athena.domain.usecase.log.AddLog
24 | import com.kin.athena.domain.usecase.log.DeleteLog
25 | import com.kin.athena.domain.usecase.log.DeleteLogs
26 | import com.kin.athena.domain.usecase.log.GetLog
27 | import com.kin.athena.domain.usecase.log.GetLogs
28 | import com.kin.athena.domain.usecase.log.LogUseCases
29 | import dagger.Module
30 | import dagger.Provides
31 | import dagger.hilt.InstallIn
32 | import dagger.hilt.components.SingletonComponent
33 | import javax.inject.Singleton
34 |
35 | @Module
36 | @InstallIn(SingletonComponent::class)
37 | object LogModule {
38 | @Provides
39 | @Singleton
40 | fun provideLogRepository(provider: DatabaseProvider): LogRepository {
41 | return LogRepositoryImpl(provider)
42 | }
43 |
44 | @Provides
45 | @Singleton
46 | fun provideLogUseCases(repository: LogRepository): LogUseCases {
47 | return LogUseCases(
48 | getLogs = GetLogs(repository),
49 | deleteLog = DeleteLog(repository),
50 | getLog = GetLog(repository),
51 | addLog = AddLog(repository),
52 | deleteLogs = DeleteLogs(repository)
53 | )
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialPlaceholder.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.layout.Arrangement
21 | import androidx.compose.foundation.layout.Box
22 | import androidx.compose.foundation.layout.Column
23 | import androidx.compose.foundation.layout.fillMaxSize
24 | import androidx.compose.foundation.layout.imePadding
25 | import androidx.compose.material3.MaterialTheme
26 | import androidx.compose.material3.Text
27 | import androidx.compose.runtime.Composable
28 | import androidx.compose.ui.Alignment
29 | import androidx.compose.ui.Modifier
30 | import androidx.compose.ui.unit.dp
31 | import androidx.compose.ui.unit.sp
32 |
33 | @Composable
34 | fun MaterialPlaceholder(
35 | placeholderIcon: @Composable () -> Unit,
36 | placeholderText: String
37 | ) {
38 | Box(
39 | modifier = Modifier
40 | .imePadding()
41 | .fillMaxSize(),
42 | contentAlignment = Alignment.Center,
43 | ) {
44 | Column(
45 | horizontalAlignment = Alignment.CenterHorizontally,
46 | verticalArrangement = Arrangement.spacedBy(14.dp)
47 | ) {
48 | placeholderIcon()
49 |
50 | Text(
51 | text = placeholderText,
52 | color = MaterialTheme.colorScheme.outline,
53 | fontSize = 14.sp
54 | )
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/di/repository/NetworkFilter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.di.repository
19 |
20 | import com.kin.athena.data.local.provider.DatabaseProvider
21 | import com.kin.athena.data.repository.NetworkFilterImpl
22 | import com.kin.athena.domain.repository.NetworkFilterRepository
23 | import com.kin.athena.domain.usecase.networkFilter.AddIp
24 | import com.kin.athena.domain.usecase.networkFilter.DeleteIp
25 | import com.kin.athena.domain.usecase.networkFilter.DeleteIps
26 | import com.kin.athena.domain.usecase.networkFilter.GetIps
27 | import com.kin.athena.domain.usecase.networkFilter.NetworkFilterUseCases
28 | import dagger.Module
29 | import dagger.Provides
30 | import dagger.hilt.InstallIn
31 | import dagger.hilt.components.SingletonComponent
32 | import javax.inject.Singleton
33 |
34 | @Module
35 | @InstallIn(SingletonComponent::class)
36 | object NetworkFilter {
37 | @Provides
38 | @Singleton
39 | fun provideNetworkFilterRepository(provider: DatabaseProvider): NetworkFilterRepository {
40 | return NetworkFilterImpl(provider)
41 | }
42 |
43 | @Provides
44 | @Singleton
45 | fun provideNetworkFilterCases(repository: NetworkFilterRepository): NetworkFilterUseCases {
46 | return NetworkFilterUseCases(
47 | getIps = GetIps(repository),
48 | deleteIp = DeleteIp(repository),
49 | addIp = AddIp(repository),
50 | deleteIps = DeleteIps(repository)
51 | )
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/repository/CustomDomainRepository.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.repository
19 |
20 | import com.kin.athena.domain.model.CustomDomain
21 | import kotlinx.coroutines.flow.Flow
22 |
23 | interface CustomDomainRepository {
24 |
25 | fun getAllowlistDomains(): Flow>
26 |
27 | fun getBlocklistDomains(): Flow>
28 |
29 | fun getEnabledAllowlistDomains(): Flow>
30 |
31 | fun getEnabledBlocklistDomains(): Flow>
32 |
33 | fun getAllDomains(): Flow>
34 |
35 | suspend fun getDomainById(id: Long): CustomDomain?
36 |
37 | suspend fun isDomainExists(domain: String, isAllowlist: Boolean): Boolean
38 |
39 | suspend fun insertDomain(domain: CustomDomain): Long
40 |
41 | suspend fun insertDomains(domains: List)
42 |
43 | suspend fun updateDomain(domain: CustomDomain)
44 |
45 | suspend fun deleteDomain(domain: CustomDomain)
46 |
47 | suspend fun deleteDomainById(id: Long)
48 |
49 | suspend fun deleteAllDomainsByType(isAllowlist: Boolean)
50 |
51 | suspend fun updateDomainEnabled(id: Long, isEnabled: Boolean)
52 |
53 | suspend fun getAllowlistCount(): Int
54 |
55 | suspend fun getBlocklistCount(): Int
56 |
57 | suspend fun getEnabledAllowlistCount(): Int
58 |
59 | suspend fun getEnabledBlocklistCount(): Int
60 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/core/utils/NotificationHelper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.core.utils
19 |
20 | import android.app.NotificationChannel
21 | import android.app.NotificationManager
22 | import android.app.PendingIntent
23 | import android.content.Context
24 | import android.content.Intent
25 | import android.os.Build
26 | import androidx.core.app.NotificationManagerCompat
27 | import androidx.core.app.NotificationChannelCompat
28 |
29 | object NotificationUtils {
30 | private const val CHANNEL_ID = "service_channel"
31 |
32 | fun createNotificationChannel(
33 | context: Context,
34 | channelId: String = CHANNEL_ID,
35 | channelName: Int,
36 | channelDescription: Int,
37 | importance: Int = NotificationManager.IMPORTANCE_DEFAULT
38 | ): String {
39 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
40 | val name = context.getString(channelName)
41 | val descriptionText = context.getString(channelDescription)
42 | val channel = NotificationChannel(channelId, name, importance).apply {
43 | description = descriptionText
44 | }
45 | val notificationManager: NotificationManager =
46 | context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
47 | notificationManager.createNotificationChannel(
48 | channel,
49 | )
50 | }
51 |
52 | return channelId
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/Application.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | import androidx.room.ColumnInfo
21 | import androidx.room.Entity
22 | import androidx.room.Index
23 | import androidx.room.PrimaryKey
24 | import com.kin.athena.core.utils.constants.AppConstants
25 |
26 | @Entity(
27 | tableName = "applications",
28 | indices = [Index(value = ["uid"]), Index(value = ["display_name"]), Index(value = ["package_id"])]
29 | )
30 |
31 | data class Application(
32 | @PrimaryKey
33 | @ColumnInfo(name = "package_id")
34 | val packageID: String,
35 |
36 | @ColumnInfo(name = "uid")
37 | val uid: Int,
38 |
39 | @ColumnInfo(name = "system_app")
40 | val systemApp: Boolean,
41 |
42 | @ColumnInfo(name = "internet_access")
43 | val internetAccess: Boolean = true,
44 |
45 | @ColumnInfo(name = "cellular_access")
46 | val cellularAccess: Boolean = true,
47 |
48 | @ColumnInfo(name = "bypass_vpn")
49 | val bypassVpn: Boolean = false,
50 |
51 | @ColumnInfo(name = "uses_google_play_services")
52 | val usesGooglePlayServices: Boolean = false,
53 |
54 | @ColumnInfo(name = "display_name")
55 | val displayName: String = "",
56 |
57 | @ColumnInfo(name = "last_updated")
58 | val lastUpdated: Long = System.currentTimeMillis(),
59 |
60 | @ColumnInfo(name = "requires_network")
61 | val requiresNetwork: Boolean = true,
62 |
63 | @ColumnInfo(name = "is_pinned")
64 | val isPinned: Boolean = false
65 | )
--------------------------------------------------------------------------------
/app/src/main/go/build-android.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | REM Build nflog for Android
3 | REM This script compiles the Go code for Android arm64-v8a and armeabi-v7a architectures
4 |
5 | setlocal enabledelayedexpansion
6 |
7 | REM Configuration
8 | set NDK_VERSION=27.0.12077973
9 | if "%ANDROID_HOME%"=="" set ANDROID_HOME=%USERPROFILE%\AppData\Local\Android\Sdk
10 | set NDK=%ANDROID_HOME%\ndk\%NDK_VERSION%
11 |
12 | REM Check if NDK exists
13 | if not exist "%NDK%" (
14 | echo Error: Android NDK not found at %NDK%
15 | echo Please set ANDROID_HOME or install NDK version %NDK_VERSION%
16 | exit /b 1
17 | )
18 |
19 | REM Set up environment
20 | set PATH=%NDK%\toolchains\llvm\prebuilt\windows-x86_64\bin;%PATH%
21 | set GOOS=android
22 | set CGO_ENABLED=1
23 |
24 | REM Output directories
25 | set OUTPUT_DIR=..\..\..\libs
26 | if not exist "%OUTPUT_DIR%\arm64-v8a" mkdir "%OUTPUT_DIR%\arm64-v8a"
27 | if not exist "%OUTPUT_DIR%\armeabi-v7a" mkdir "%OUTPUT_DIR%\armeabi-v7a"
28 |
29 | echo Building nflog for Android...
30 |
31 | REM Build for arm64-v8a
32 | echo Building for arm64-v8a...
33 | set GOARCH=arm64
34 | set CC=aarch64-linux-android21-clang
35 | set CXX=aarch64-linux-android21-clang++
36 | set CGO_CFLAGS=-O2 -fPIC -DANDROID
37 | set CGO_CPPFLAGS=-O2 -fPIC -DANDROID
38 | set CGO_CXXFLAGS=-O2 -fPIC -DANDROID
39 | set CGO_FFLAGS=-O2 -fPIC
40 | set CGO_LDFLAGS=-s -w -Wl,-z,max-page-size=16384
41 |
42 | go clean
43 | go build -x -ldflags="-s -w" -compiler gc -gcflags="-m -dwarf=false" -o "%OUTPUT_DIR%\arm64-v8a\libnflog.so" .
44 |
45 | REM Build for armeabi-v7a
46 | echo Building for armeabi-v7a...
47 | set GOARCH=arm
48 | set CC=armv7a-linux-androideabi21-clang
49 | set CXX=armv7a-linux-androideabi21-clang++
50 | set CGO_CFLAGS=-O2 -fPIC -DANDROID -mfpu=neon
51 | set CGO_CPPFLAGS=-O2 -fPIC -DANDROID -mfpu=neon
52 | set CGO_CXXFLAGS=-O2 -fPIC -DANDROID -mfpu=neon
53 | set CGO_FFLAGS=-O2 -fPIC -mfpu=neon
54 | set CGO_LDFLAGS=-s -w -Wl,-z,max-page-size=16384
55 |
56 | go clean
57 | go build -x -ldflags="-s -w" -compiler gc -gcflags="-m -dwarf=false" -o "%OUTPUT_DIR%\armeabi-v7a\libnflog.so" .
58 |
59 | echo Build completed successfully!
60 | echo Executables created:
61 | echo - %OUTPUT_DIR%\arm64-v8a\libnflog.so
62 | echo - %OUTPUT_DIR%\armeabi-v7a\libnflog.so
63 |
64 | endlocal
--------------------------------------------------------------------------------
/app/src/main/go/build-android.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | NDK_VERSION="27.0.12077973"
6 | ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}"
7 | NDK="$ANDROID_HOME/ndk/$NDK_VERSION"
8 |
9 | if [ ! -d "$NDK" ]; then
10 | echo "Error: Android NDK not found at $NDK"
11 | echo "Please set ANDROID_HOME or install NDK version $NDK_VERSION"
12 | exit 1
13 | fi
14 |
15 | if [[ "$OSTYPE" == "darwin"* ]]; then
16 | if [[ $(uname -m) == "arm64" ]]; then
17 | TOOLCHAIN_PATH="$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin"
18 | else
19 | TOOLCHAIN_PATH="$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin"
20 | fi
21 | else
22 | TOOLCHAIN_PATH="$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin"
23 | fi
24 |
25 | export PATH="$PATH:$TOOLCHAIN_PATH"
26 | export GOOS='android'
27 | export CGO_ENABLED=1
28 |
29 | # Output directories
30 | OUTPUT_DIR="../../../libs"
31 | mkdir -p "$OUTPUT_DIR/arm64-v8a"
32 | mkdir -p "$OUTPUT_DIR/armeabi-v7a"
33 |
34 | echo "Building nflog for Android..."
35 |
36 | # Build for arm64-v8a
37 | echo "Building for arm64-v8a..."
38 | export GOARCH='arm64'
39 | export CC="aarch64-linux-android21-clang"
40 | export CXX="aarch64-linux-android21-clang++"
41 | export CGO_CFLAGS="-O2 -fPIC -DANDROID"
42 | export CGO_CPPFLAGS="-O2 -fPIC -DANDROID"
43 | export CGO_CXXFLAGS="-O2 -fPIC -DANDROID"
44 | export CGO_FFLAGS="-O2 -fPIC"
45 | export CGO_LDFLAGS="-s -w -Wl,-z,max-page-size=16384"
46 |
47 | go clean
48 | go build -x -ldflags="-s -w" -compiler gc -gcflags="-m -dwarf=false" -o "$OUTPUT_DIR/arm64-v8a/libnflog.so" .
49 |
50 | # Build for armeabi-v7a
51 | echo "Building for armeabi-v7a..."
52 | export GOARCH='arm'
53 | export CC="armv7a-linux-androideabi21-clang"
54 | export CXX="armv7a-linux-androideabi21-clang++"
55 | export CGO_CFLAGS="-O2 -fPIC -DANDROID -mfpu=neon"
56 | export CGO_CPPFLAGS="-O2 -fPIC -DANDROID -mfpu=neon"
57 | export CGO_CXXFLAGS="-O2 -fPIC -DANDROID -mfpu=neon"
58 | export CGO_FFLAGS="-O2 -fPIC -mfpu=neon"
59 | export CGO_LDFLAGS="-s -w -Wl,-z,max-page-size=16384"
60 |
61 | go clean
62 | go build -x -ldflags="-s -w" -compiler gc -gcflags="-m -dwarf=false" -o "$OUTPUT_DIR/armeabi-v7a/libnflog.so" .
63 |
64 | echo "Build completed successfully!"
65 | echo "Executables created:"
66 | echo " - $OUTPUT_DIR/arm64-v8a/libnflog.so"
67 | echo " - $OUTPUT_DIR/armeabi-v7a/libnflog.so"
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/rule/FilterRule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.rule
19 |
20 | import com.kin.athena.domain.model.Ip
21 | import com.kin.athena.domain.usecase.log.LogUseCases
22 | import com.kin.athena.domain.usecase.networkFilter.NetworkFilterUseCases
23 | import com.kin.athena.service.firewall.model.FireWallModel
24 | import com.kin.athena.service.firewall.model.FirewallResult
25 | import com.kin.athena.service.vpn.network.transport.dns.DNSModel
26 | import kotlinx.coroutines.CoroutineScope
27 | import kotlinx.coroutines.Dispatchers
28 | import kotlinx.coroutines.launch
29 | import javax.inject.Inject
30 |
31 | class FilterRule @Inject constructor(
32 | private val networkFilterUseCases: NetworkFilterUseCases
33 | ) : FirewallRule {
34 | init {
35 | observeIps()
36 | }
37 |
38 | private var ips: List? = null
39 |
40 | fun observeIps() {
41 | CoroutineScope(Dispatchers.IO).launch {
42 | val packagesList = networkFilterUseCases.getIps.execute()
43 | packagesList.fold(
44 | ifSuccess = {
45 | it.collect { ip ->
46 | ips = ip
47 | }
48 | }
49 | )
50 | }
51 | }
52 |
53 | override fun check(
54 | packet: FireWallModel,
55 | dnsModel: DNSModel?,
56 | logUseCases: LogUseCases,
57 | result: FirewallResult
58 | ): FirewallResult {
59 | val isBlocked = ips?.firstOrNull { it.ip == packet.destinationIP } == null
60 |
61 | return if (!isBlocked) FirewallResult.DROP else FirewallResult.ACCEPT
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/vpn/network/util/PacketUtil.kt:
--------------------------------------------------------------------------------
1 | package com.kin.athena.service.vpn.network.util
2 |
3 | import java.nio.ByteBuffer
4 | import java.nio.ByteOrder
5 |
6 | object PacketUtil {
7 | var packetId: Int = 0
8 | get() = field++
9 | private set
10 |
11 | fun read(buffer: ByteArray, offset: Int, length: Int): Int {
12 | if (offset < 0 || offset >= buffer.size || length < 1 || length > 4) {
13 | throw IllegalArgumentException("Invalid offset ($offset) or length ($length) for buffer size ${buffer.size}")
14 | }
15 | var value = 0
16 | val end = (offset + length).coerceAtMost(buffer.size)
17 | for (i in offset until end) {
18 | value = value shl 8 or (buffer[i].toInt() and 0xFF)
19 | }
20 | return value
21 | }
22 |
23 | private fun getNetworkInt(buffer: ByteArray, start: Int, length: Int): Int {
24 | return read(buffer, start, length)
25 | }
26 |
27 | fun calculateChecksum(data: ByteArray, offset: Int, length: Int): ByteArray {
28 | var sum = 0L
29 | var i = offset
30 | while (i < length - 1) {
31 | sum += getNetworkInt(data, i, 2).toLong() and 0xFFFFL
32 | i += 2
33 | }
34 | if (i < length) {
35 | sum += (data[i].toInt() and 0xFF) shl 8
36 | }
37 | while (sum shr 16 > 0) {
38 | sum = (sum and 0xFFFFL) + (sum shr 16)
39 | }
40 | val checksum = (sum.inv() and 0xFFFF).toInt()
41 | return byteArrayOf((checksum shr 8).toByte(), checksum.toByte())
42 | }
43 |
44 | fun calculateUDPHeaderChecksum(
45 | data: ByteArray?,
46 | offset: Int,
47 | udpLength: Int,
48 | destIp: Int,
49 | sourceIp: Int
50 | ): ByteArray {
51 | val bufferSize = if (udpLength % 2 == 0) udpLength + 12 else udpLength + 13
52 | val buffer = ByteBuffer.allocate(bufferSize).apply {
53 | order(ByteOrder.BIG_ENDIAN)
54 | putInt(sourceIp)
55 | putInt(destIp)
56 | put(0.toByte())
57 | put(17.toByte()) // UDP protocol number
58 | putShort(udpLength.toShort())
59 | data?.let { put(it, offset, udpLength) }
60 | if (udpLength % 2 != 0) put(0.toByte())
61 | }
62 | return calculateChecksum(buffer.array(), 0, bufferSize)
63 | }
64 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/network/viewModel/NetworkViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.settings.subSettings.network.viewModel
19 |
20 | import androidx.compose.runtime.MutableState
21 | import androidx.compose.runtime.State
22 | import androidx.compose.runtime.derivedStateOf
23 | import androidx.compose.runtime.mutableStateOf
24 | import androidx.compose.ui.text.input.TextFieldValue
25 | import androidx.lifecycle.ViewModel
26 | import androidx.lifecycle.ViewModelProvider
27 | import androidx.lifecycle.viewModelScope
28 | import com.kin.athena.core.logging.Logger
29 | import com.kin.athena.domain.model.Ip
30 | import com.kin.athena.domain.usecase.networkFilter.NetworkFilterUseCases
31 | import com.kin.athena.service.utils.manager.FirewallManager
32 | import dagger.hilt.android.lifecycle.HiltViewModel
33 | import kotlinx.coroutines.launch
34 | import javax.inject.Inject
35 |
36 |
37 | @HiltViewModel
38 | class IpDialogViewModel @Inject constructor(
39 | val firewallManager: FirewallManager,
40 | ) : ViewModel() {
41 |
42 | private val _dialogIpv4TextField: MutableState = mutableStateOf(TextFieldValue(""))
43 | val dialogIpv4TextField: State = _dialogIpv4TextField
44 |
45 |
46 | fun updateIpv4DialogText(text: TextFieldValue) {
47 | Logger.error(text.text)
48 | _dialogIpv4TextField.value = text
49 | }
50 |
51 | private val _dialogIpv6TextField: MutableState = mutableStateOf(TextFieldValue(""))
52 | val dialogIpv6TextField: State = _dialogIpv6TextField
53 |
54 |
55 | fun updateIpv6DialogText(text: TextFieldValue) {
56 | _dialogIpv6TextField.value = text
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/utils/receiver/AppChangeReceiver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.utils.receiver
19 |
20 | import android.content.BroadcastReceiver
21 | import android.content.Context
22 | import android.content.Intent
23 | import android.content.IntentFilter
24 |
25 | interface AppChangeCallback {
26 | fun onAppInstalled(packageName: String?)
27 | fun onAppUninstalled(packageName: String?)
28 | }
29 |
30 | class AppChangeReceiver(private val callback: AppChangeCallback) : BroadcastReceiver() {
31 |
32 | private var isRegistered = false
33 |
34 | override fun onReceive(context: Context, intent: Intent) {
35 | val action = intent.action
36 | val packageName = intent.data?.encodedSchemeSpecificPart
37 |
38 | when (action) {
39 | Intent.ACTION_PACKAGE_ADDED -> callback.onAppInstalled(packageName)
40 | Intent.ACTION_PACKAGE_REMOVED -> callback.onAppUninstalled(packageName)
41 | }
42 | }
43 |
44 | fun register(context: Context) {
45 | if (!isRegistered) {
46 | val intentFilter = IntentFilter().apply {
47 | addAction(Intent.ACTION_PACKAGE_ADDED)
48 | addAction(Intent.ACTION_PACKAGE_REMOVED)
49 | addDataScheme("package")
50 | }
51 |
52 | context.registerReceiver(this, intentFilter)
53 | isRegistered = true
54 | }
55 | }
56 |
57 | fun unregister(context: Context) {
58 | if (isRegistered) {
59 | try {
60 | context.unregisterReceiver(this)
61 | isRegistered = false
62 | } catch (e: IllegalArgumentException) {
63 | // Receiver was not registered, ignore
64 | isRegistered = false
65 | }
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialActionButton.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.layout.Row
21 | import androidx.compose.foundation.layout.Spacer
22 | import androidx.compose.foundation.layout.imePadding
23 | import androidx.compose.foundation.layout.padding
24 | import androidx.compose.foundation.layout.width
25 | import androidx.compose.foundation.shape.RoundedCornerShape
26 | import androidx.compose.material3.ExtendedFloatingActionButton
27 | import androidx.compose.material3.FloatingActionButton
28 | import androidx.compose.material3.Icon
29 | import androidx.compose.material3.Text
30 | import androidx.compose.runtime.Composable
31 | import androidx.compose.ui.Alignment
32 | import androidx.compose.ui.Modifier
33 | import androidx.compose.ui.graphics.vector.ImageVector
34 | import androidx.compose.ui.text.font.FontWeight
35 | import androidx.compose.ui.unit.dp
36 |
37 | @Composable
38 | fun MaterialActionButton(
39 | text: String,
40 | icon: ImageVector,
41 | modifier: Modifier = Modifier,
42 | onClick: () -> Unit,
43 | ) {
44 | ExtendedFloatingActionButton(
45 | modifier = modifier
46 | .imePadding(),
47 | shape = RoundedCornerShape(24.dp),
48 | onClick = { onClick() },
49 | content = {
50 | Row(
51 | verticalAlignment = Alignment.CenterVertically
52 | ) {
53 | Icon(
54 | imageVector = icon,
55 | contentDescription = null
56 | )
57 | Spacer(modifier = Modifier.width(8.dp))
58 | Text(
59 | text = text,
60 | fontWeight = FontWeight.Bold
61 | )
62 | }
63 | }
64 | )
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/lock/LockScreen.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.settings.subSettings.lock
19 |
20 | import androidx.compose.runtime.*
21 | import androidx.navigation.NavController
22 | import com.kin.athena.presentation.components.material.MaterialScaffold
23 | import com.kin.athena.presentation.screens.settings.subSettings.lock.components.ActionType
24 | import com.kin.athena.presentation.screens.settings.subSettings.lock.components.FingerprintLock
25 | import com.kin.athena.presentation.screens.settings.subSettings.lock.components.PasscodeLock
26 | import com.kin.athena.presentation.screens.settings.subSettings.lock.components.PatternLock
27 | import com.kin.athena.presentation.screens.settings.viewModel.SettingsViewModel
28 |
29 | @Composable
30 | fun LockScreen(
31 | settingsViewModel: SettingsViewModel,
32 | navController: NavController,
33 | action: ActionType?,
34 | ) {
35 | MaterialScaffold {
36 | if (action != null) {
37 | when (action) {
38 | ActionType.PASSCODE -> PasscodeLock(settingsViewModel, navController)
39 | ActionType.FINGERPRINT -> FingerprintLock(settingsViewModel = settingsViewModel, navController = navController)
40 | ActionType.PATTERN -> PatternLock(settingsViewModel = settingsViewModel, navController = navController)
41 | }
42 | } else {
43 | when {
44 | settingsViewModel.settings.value.pattern != null -> PatternLock(settingsViewModel = settingsViewModel, navController = navController)
45 | settingsViewModel.settings.value.fingerprint -> FingerprintLock(settingsViewModel = settingsViewModel, navController = navController)
46 | settingsViewModel.settings.value.passcode != null -> PasscodeLock(settingsViewModel, navController)
47 | }
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/rule/DNSRule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.rule
19 |
20 | import com.kin.athena.core.logging.Logger
21 | import com.kin.athena.domain.usecase.log.LogUseCases
22 | import com.kin.athena.presentation.screens.settings.subSettings.dns.hosts.RuleDatabase
23 | import com.kin.athena.service.firewall.model.FireWallModel
24 | import com.kin.athena.service.firewall.model.FirewallResult
25 | import com.kin.athena.service.vpn.network.transport.dns.DNSModel
26 | import javax.inject.Inject
27 |
28 | class DNSRule @Inject constructor(
29 | private val ruleDatabase: RuleDatabase
30 | ) : FirewallRule {
31 | private var isDnsBlockingEnabled = true
32 |
33 | suspend fun updateBlocklist(progressCallback: (suspend (Int) -> Unit)? = null) {
34 | ruleDatabase.initialize(progressCallback = progressCallback)
35 | }
36 |
37 | fun enableDnsBlocking() {
38 | isDnsBlockingEnabled = true
39 | Logger.info("DNS blocking enabled")
40 | }
41 |
42 | fun disableDnsBlocking() {
43 | isDnsBlockingEnabled = false
44 | Logger.info("DNS blocking disabled")
45 | }
46 |
47 | fun isDnsBlockingEnabled(): Boolean {
48 | return isDnsBlockingEnabled
49 | }
50 |
51 | override fun check(
52 | packet: FireWallModel,
53 | dnsModel: DNSModel?,
54 | logUseCases: LogUseCases,
55 | result: FirewallResult
56 | ): FirewallResult {
57 | // If DNS blocking is disabled, always allow
58 | if (!isDnsBlockingEnabled) {
59 | return result
60 | }
61 |
62 | dnsModel?.let {
63 | if (ruleDatabase.isBlocked(dnsModel.domainName)) {
64 | Logger.info("Blocked ${dnsModel.domainName}")
65 | return FirewallResult.DNS_BLOCKED
66 | } else {
67 | return FirewallResult.ACCEPT
68 |
69 | }
70 | } ?: return FirewallResult.ACCEPT
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/usecase/application/GetFilteredApplications.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.usecase.application
19 |
20 | import com.kin.athena.domain.repository.ApplicationRepository
21 | import javax.inject.Inject
22 | import com.kin.athena.core.utils.Result
23 | import com.kin.athena.core.utils.Error
24 | import com.kin.athena.domain.model.Application
25 |
26 | data class FilteredApplicationResult(
27 | val applications: List,
28 | val totalCount: Int,
29 | val hasMore: Boolean
30 | )
31 |
32 | class GetFilteredApplications @Inject constructor(
33 | private val applicationRepository: ApplicationRepository
34 | ) {
35 | suspend fun execute(
36 | showSystemPackages: Boolean,
37 | showOfflinePackages: Boolean,
38 | searchQuery: String,
39 | limit: Int = Int.MAX_VALUE,
40 | offset: Int = 0
41 | ): Result {
42 | return try {
43 | val applications = applicationRepository.getFilteredApplications(
44 | showSystemPackages, showOfflinePackages, searchQuery, limit, offset
45 | )
46 | val totalCount = applicationRepository.getFilteredApplicationsCount(
47 | showSystemPackages, showOfflinePackages, searchQuery
48 | )
49 | val hasMore = offset + applications.size < totalCount
50 |
51 | com.kin.athena.core.logging.Logger.info("GetFilteredApplications: offset=$offset, limit=$limit, got ${applications.size} apps, totalCount=$totalCount, hasMore=$hasMore")
52 |
53 | Result.Success(
54 | FilteredApplicationResult(
55 | applications = applications,
56 | totalCount = totalCount,
57 | hasMore = hasMore
58 | )
59 | )
60 | } catch (e: Exception) {
61 | Result.Failure(Error.ServerError(e.message ?: "Error while retrieving filtered packages"))
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/screens/settings/subSettings/dns/components/SystemlessHostsDialog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.screens.settings.subSettings.dns.components
19 |
20 | import androidx.compose.foundation.background
21 | import androidx.compose.foundation.layout.Arrangement
22 | import androidx.compose.foundation.layout.Column
23 | import androidx.compose.foundation.layout.Spacer
24 | import androidx.compose.foundation.layout.fillMaxWidth
25 | import androidx.compose.foundation.layout.height
26 | import androidx.compose.foundation.layout.padding
27 | import androidx.compose.foundation.shape.RoundedCornerShape
28 | import androidx.compose.material3.MaterialTheme
29 | import androidx.compose.material3.Text
30 | import androidx.compose.runtime.Composable
31 | import androidx.compose.ui.Alignment
32 | import androidx.compose.ui.Modifier
33 | import androidx.compose.ui.res.stringResource
34 | import androidx.compose.ui.unit.dp
35 | import com.kin.athena.R
36 | import com.kin.athena.presentation.screens.settings.components.SettingDialog
37 |
38 | @Composable
39 | fun MagiskSystemlessHostsDialog(onDismiss: () -> Unit) {
40 | SettingDialog(
41 | text = stringResource(R.string.magisk_title),
42 | onExit = onDismiss
43 | ) {
44 | Column(
45 | modifier = Modifier
46 | .fillMaxWidth()
47 | .background(color = MaterialTheme.colorScheme.surfaceContainerLow, shape = RoundedCornerShape(18.dp)),
48 | verticalArrangement = Arrangement.Center,
49 | horizontalAlignment = Alignment.Start,
50 | ) {
51 | Spacer(modifier = Modifier.height(16.dp))
52 | Text(
53 | text = stringResource(R.string.magisk_steps),
54 | style = MaterialTheme.typography.bodyMedium,
55 | modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
56 | )
57 | Spacer(modifier = Modifier.height(16.dp))
58 | }
59 | Spacer(modifier = Modifier.height(16.dp))
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialText.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.layout.Column
21 | import androidx.compose.foundation.layout.padding
22 | import androidx.compose.material3.MaterialTheme
23 | import androidx.compose.material3.Text
24 | import androidx.compose.runtime.Composable
25 | import androidx.compose.ui.Alignment
26 | import androidx.compose.ui.Modifier
27 | import androidx.compose.ui.graphics.Color
28 | import androidx.compose.ui.text.style.TextAlign
29 | import androidx.compose.ui.text.style.TextOverflow
30 | import androidx.compose.ui.unit.TextUnit
31 | import androidx.compose.ui.unit.dp
32 | import androidx.compose.ui.unit.sp
33 |
34 | @Composable
35 | fun MaterialText(
36 | title: String,
37 | description: String? = null,
38 | modifier: Modifier = Modifier,
39 | titleSize: TextUnit = 14.sp,
40 | descriptionSize: TextUnit = 11.sp,
41 | center: Boolean = false,
42 | titleColor: Color = MaterialTheme.colorScheme.onSurface,
43 | descriptionColor: Color = MaterialTheme.colorScheme.onSurfaceVariant
44 | ) {
45 | Column(
46 | modifier = modifier,
47 | horizontalAlignment = if (center) Alignment.CenterHorizontally else Alignment.Start,) {
48 | Text(
49 | text = title,
50 | style = MaterialTheme.typography.titleMedium.copy(fontSize = titleSize),
51 | color = titleColor,
52 | modifier = Modifier.padding(bottom = 3.dp),
53 | textAlign = if (center) TextAlign.Center else TextAlign.Start
54 | )
55 | if (description != null) {
56 | Text(
57 | text = description,
58 | style = MaterialTheme.typography.bodySmall.copy(fontSize = descriptionSize),
59 | color = descriptionColor,
60 | modifier = Modifier.padding(bottom = 3.dp),
61 | maxLines = 6,
62 | overflow = TextOverflow.Ellipsis
63 | )
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/service/firewall/rule/HTTPRule.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.service.firewall.rule
19 |
20 | import com.kin.athena.core.logging.Logger
21 | import com.kin.athena.core.utils.extensions.resolveIpToHostname
22 | import com.kin.athena.domain.model.Log
23 | import com.kin.athena.domain.usecase.log.LogUseCases
24 | import com.kin.athena.domain.usecase.preferences.PreferencesUseCases
25 | import com.kin.athena.service.firewall.model.FireWallModel
26 | import com.kin.athena.service.firewall.model.FirewallResult
27 | import com.kin.athena.service.vpn.network.transport.dns.DNSModel
28 | import com.kin.athena.service.vpn.network.util.NetworkConstants
29 | import kotlinx.coroutines.CoroutineScope
30 | import kotlinx.coroutines.Dispatchers
31 | import kotlinx.coroutines.launch
32 | import kotlinx.coroutines.sync.Mutex
33 | import kotlinx.coroutines.sync.withLock
34 | import javax.inject.Inject
35 |
36 | class HTTPRule @Inject constructor(
37 | private val preferencesUseCases: PreferencesUseCases,
38 | private val externalScope: CoroutineScope
39 | ) : FirewallRule {
40 |
41 | private var blockHTTP = false
42 | private var allowLocal = false
43 |
44 | init {
45 | updateHTTPStatus()
46 | }
47 |
48 | fun updateHTTPStatus(enabled: Boolean? = null) {
49 | externalScope.launch(Dispatchers.IO) {
50 | preferencesUseCases.loadSettings.execute().fold(
51 | ifSuccess = { settings ->
52 | blockHTTP = settings.blockPort80
53 | allowLocal = settings.allowLocal
54 | },
55 | ifFailure = { error ->
56 | Logger.error("Failed to load settings: ${error.message}")
57 | }
58 | )
59 | }
60 | }
61 |
62 | override fun check(
63 | packet: FireWallModel,
64 | dnsModel: DNSModel?,
65 | logUseCases: LogUseCases,
66 | result: FirewallResult
67 | ): FirewallResult {
68 | return if (packet.destinationPort == 80 && blockHTTP) FirewallResult.DROP else FirewallResult.ACCEPT
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/domain/model/BackupData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.domain.model
19 |
20 | import kotlinx.serialization.Serializable
21 |
22 | @Serializable
23 | data class BackupData(
24 | val version: Int = 1,
25 | val timestamp: Long = System.currentTimeMillis(),
26 | val settings: SettingsBackup,
27 | val customDomains: List,
28 | val customBlocklists: List,
29 | val applications: List = emptyList()
30 | )
31 |
32 | @Serializable
33 | data class SettingsBackup(
34 | val automaticTheme: Boolean,
35 | val darkTheme: Boolean,
36 | val useDynamicIcons: Boolean,
37 | val dynamicTheme: Boolean,
38 | val amoledTheme: Boolean,
39 | val customColor: Int,
40 | val screenProtection: Boolean,
41 | val blockPort80: Boolean,
42 | val logs: Boolean,
43 | val showSystemPackages: Boolean,
44 | val showOfflinePackages: Boolean,
45 | val wiFiDefault: Boolean,
46 | val cellularDefault: Boolean,
47 | val startOnBoot: Boolean,
48 | val allowLocal: Boolean,
49 | val blockWifiWhenScreenOff: Boolean,
50 | val blockCellularWhenScreenOff: Boolean,
51 | val permanentNotification: Boolean,
52 | val networkSpeedMonitor: Boolean,
53 | val sendNotificationOnInstall: Boolean,
54 | val malwareProtection: Boolean,
55 | val adBlocker: Boolean,
56 | val trackerProtection: Boolean,
57 | val autoUpdateInterval: Long
58 | )
59 |
60 | @Serializable
61 | data class CustomDomainBackup(
62 | val domain: String,
63 | val description: String,
64 | val isRegex: Boolean,
65 | val isAllowlist: Boolean,
66 | val isEnabled: Boolean
67 | )
68 |
69 | @Serializable
70 | data class CustomBlocklistBackup(
71 | val title: String,
72 | val url: String,
73 | val state: String // IGNORE, DENY, ALLOW
74 | )
75 |
76 | @Serializable
77 | data class ApplicationBackup(
78 | val packageID: String,
79 | val internetAccess: Boolean,
80 | val cellularAccess: Boolean,
81 | val bypassVpn: Boolean = false,
82 | val isPinned: Boolean = false
83 | )
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kin/athena/presentation/components/material/MaterialBar.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Vexzure
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program 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 this program. If not, see .
16 | */
17 |
18 | package com.kin.athena.presentation.components.material
19 |
20 | import androidx.compose.foundation.layout.Row
21 | import androidx.compose.foundation.layout.RowScope
22 | import androidx.compose.foundation.layout.fillMaxWidth
23 | import androidx.compose.material.icons.Icons
24 | import androidx.compose.material.icons.automirrored.rounded.ArrowBackIos
25 | import androidx.compose.material.icons.rounded.ArrowBackIos
26 | import androidx.compose.material3.ExperimentalMaterial3Api
27 | import androidx.compose.material3.MaterialTheme
28 | import androidx.compose.material3.Text
29 | import androidx.compose.material3.TopAppBar
30 | import androidx.compose.material3.TopAppBarDefaults
31 | import androidx.compose.runtime.Composable
32 | import androidx.compose.ui.Alignment
33 | import androidx.compose.ui.Modifier
34 | import androidx.compose.ui.res.stringResource
35 | import com.kin.athena.R
36 |
37 | @OptIn(ExperimentalMaterial3Api::class)
38 | @Composable
39 | fun MaterialBar(
40 | title: String,
41 | actions: @Composable RowScope.() -> Unit = {},
42 | onBackNavClicked: (() -> Unit)? = null
43 | ) {
44 | TopAppBar(
45 | colors = TopAppBarDefaults.topAppBarColors(
46 | containerColor = MaterialTheme.colorScheme.background
47 | ),
48 | title = {
49 | Row(
50 | modifier = Modifier.fillMaxWidth(),
51 | verticalAlignment = Alignment.CenterVertically
52 | ) {
53 | Text(
54 | text = title,
55 | style = MaterialTheme.typography.titleLarge,
56 | modifier = Modifier.weight(1f)
57 | )
58 | }
59 | },
60 | actions = actions,
61 | navigationIcon = {
62 | onBackNavClicked?.let {
63 | MaterialButton(
64 | imageVector = Icons.AutoMirrored.Rounded.ArrowBackIos,
65 | contentDescription = "",
66 | scale = 0.8f
67 | ) {
68 | onBackNavClicked()
69 | }
70 | }
71 | }
72 | )
73 | }
--------------------------------------------------------------------------------
/.github/workflows/nightly-build.yml:
--------------------------------------------------------------------------------
1 | name: Nightly Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | workflow_dispatch:
8 | inputs:
9 | commit:
10 | description: 'Commit hash to build'
11 | required: false
12 | default: 'dd326c7564c7a50ebae7b6fed73b3a1682a9f145'
13 | type: string
14 |
15 | concurrency:
16 | group: ${{ github.workflow }}
17 | cancel-in-progress: true
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | permissions:
23 | contents: read
24 | packages: write
25 |
26 | steps:
27 | - name: Check out repository
28 | uses: actions/checkout@v5
29 | with:
30 | submodules: true
31 |
32 | - name: Set up Java 17
33 | uses: actions/setup-java@v5
34 | with:
35 | java-version: 17
36 | distribution: 'adopt'
37 | cache: gradle
38 |
39 | - name: Set up Go
40 | uses: actions/setup-go@v6
41 | with:
42 | go-version: '1.21'
43 | cache: false
44 |
45 | - name: Set up Android NDK
46 | uses: nttld/setup-ndk@v1
47 | with:
48 | ndk-version: r27c
49 |
50 | - name: Grant execution permission to Gradle Wrapper
51 | run: chmod +x gradlew
52 |
53 | - name: Build Play Store Release APK
54 | run: ./gradlew assemblePlaystoreRelease
55 |
56 | - name: Sign app APK
57 | uses: r0adkll/sign-android-release@v1
58 | id: sign_app
59 | with:
60 | releaseDirectory: app/build/outputs/apk/playstore/release
61 | signingKeyBase64: ${{ secrets.KEY_BASE64 }}
62 | alias: ${{ secrets.KEY_ALIAS }}
63 | keyStorePassword: ${{ secrets.KEYSTORE_PASS }}
64 | keyPassword: ${{ secrets.KEYSTORE_PASS }}
65 | env:
66 | BUILD_TOOLS_VERSION: "34.0.0"
67 |
68 | - name: Rename APK
69 | run: mv app/build/outputs/apk/playstore/release/app-playstore-release-signed.apk Athena-nightly.apk
70 |
71 | - name: Extract nightly changelog
72 | run: |
73 | sed -n '/## \[Nightly\]/,/## \[/p' CHANGELOG.md | sed '$ d' | tail -n +2 > nightly-changelog.txt
74 | echo "" >> nightly-changelog.txt
75 | echo "---" >> nightly-changelog.txt
76 | echo "" >> nightly-changelog.txt
77 | echo "**Build Info:**" >> nightly-changelog.txt
78 | echo "- Commit: \`${{ github.sha }}\`" >> nightly-changelog.txt
79 | echo "- Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> nightly-changelog.txt
80 |
81 | - name: Upload the APK
82 | uses: actions/upload-artifact@v4.6.0
83 | with:
84 | name: Athena-Nightly
85 | path: Athena-nightly.apk
86 |
87 | - name: Update nightly release
88 | uses: eine/tip@master
89 | with:
90 | tag: Nightly
91 | token: ${{ secrets.TOKEN }}
92 | files: Athena-nightly.apk
93 | body_path: nightly-changelog.txt
--------------------------------------------------------------------------------