├── 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 | 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 --------------------------------------------------------------------------------