diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d49967e..7865712 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,11 +10,11 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v4
with:
- java-version: 11
+ java-version: 21
distribution: adopt-hotspot
- name: Setup Android SDK
- uses: android-actions/setup-android@v2
+ uses: android-actions/setup-android@v3
- name: Build release APK
run: ./gradlew assembleRelease
diff --git a/.gitignore b/.gitignore
index 726f90d..da436dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,8 @@ captures/
.idea/dictionaries
.idea/libraries
.idea/caches
+.idea/deploymentTargetDropDown.xml
+.idea/deploymentTargetSelector.xml
# Keystore files
*.jks
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index fb7f4a8..b86273d 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/dynamic.xml b/.idea/dynamic.xml
new file mode 100644
index 0000000..bf7b438
--- /dev/null
+++ b/.idea/dynamic.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index c7de50b..6c7c6be 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -5,17 +5,17 @@
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index a5f05cd..e34606c 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -21,5 +21,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..4cb7457
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6199cc2..f988785 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/.idea/other.xml b/.idea/other.xml
new file mode 100644
index 0000000..f3d4a2e
--- /dev/null
+++ b/.idea/other.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a9e11e8..1636725 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,32 +1,58 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlin-android-extensions'
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+ id 'kotlin-parcelize'
+}
android {
- compileSdkVersion 33
+ compileSdkVersion 35
+
+ namespace "tech.httptoolkit.android"
defaultConfig {
applicationId "tech.httptoolkit.android.v1"
minSdkVersion 21
- targetSdkVersion 33
+ targetSdkVersion 34
versionCode 33
versionName "1.4.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- buildConfigField "String", "SENTRY_DSN", "null"
+ manifestPlaceholders = [
+ sentryEnabled: "false",
+ sentryDsn: "null"
+ ]
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- buildConfigField "String", "SENTRY_DSN", "\"https://6943ce7476d54485a5998ad45289a9bc@sentry.io/1809979\""
+
+ manifestPlaceholders = [
+ sentryEnabled: "true",
+ sentryDsn: "https://6943ce7476d54485a5998ad45289a9bc@sentry.io/1809979"
+ ]
}
}
+
lintOptions {
lintConfig file("./lint.xml")
}
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
+ }
+
+ kotlinOptions {
+ jvmTarget = '11'
+ }
+
+ buildFeatures {
+ viewBinding true
+ buildConfig true
+ }
}
repositories {
@@ -38,22 +64,22 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
- implementation 'androidx.appcompat:appcompat:1.3.0'
- implementation 'androidx.core:core-ktx:1.1.0'
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'androidx.core:core-ktx:1.15.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
+ implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.beust:klaxon:5.5'
implementation 'com.squareup.okhttp3:okhttp:4.3.0'
- implementation 'com.google.android.material:material:1.4.0'
+ implementation 'com.google.android.material:material:1.12.0'
implementation 'net.swiftzer.semver:semver:1.1.1'
- implementation 'io.sentry:sentry-android:1.7.27'
+ implementation 'io.sentry:sentry-android:7.18.0'
implementation 'org.slf4j:slf4j-nop:1.7.25'
- implementation 'com.google.android.gms:play-services-base:10.2.4'
- implementation 'com.android.installreferrer:installreferrer:1.1'
+ implementation 'com.google.android.gms:play-services-base:18.5.0'
+ implementation 'com.android.installreferrer:installreferrer:2.2'
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test:runner:1.2.0'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ androidTestImplementation 'androidx.test:runner:1.6.2'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 427a792..4b6ad75 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,13 +1,13 @@
+ xmlns:tools="http://schemas.android.com/tools">
-
+
+
@@ -19,9 +19,14 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:node="remove" />
-
-
+
@@ -104,5 +110,8 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/tech/httptoolkit/android/ApplicationListActivity.kt b/app/src/main/java/tech/httptoolkit/android/ApplicationListActivity.kt
index 3244d21..f5cf49a 100644
--- a/app/src/main/java/tech/httptoolkit/android/ApplicationListActivity.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ApplicationListActivity.kt
@@ -8,12 +8,13 @@ import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.widget.PopupMenu
+import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.widget.doAfterTextChanged
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import kotlinx.android.synthetic.main.apps_list.*
import kotlinx.coroutines.*
+import tech.httptoolkit.android.databinding.AppsListBinding
import java.util.*
import kotlin.collections.ArrayList
@@ -23,6 +24,8 @@ const val UNSELECTED_APPS_EXTRA = "tech.httptoolkit.android.UNSELECTED_APPS_EXTR
class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefreshListener,
CoroutineScope by MainScope(), PopupMenu.OnMenuItemClickListener, View.OnClickListener {
+ private lateinit var binding: AppsListBinding
+
private val allApps = ArrayList()
private val filteredApps = ArrayList()
@@ -34,31 +37,43 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.apps_list)
blockedPackages = intent.getStringArrayExtra(UNSELECTED_APPS_EXTRA)!!.toHashSet()
- apps_list_recyclerView.adapter =
+ binding = AppsListBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.appsListRecyclerView.adapter =
ApplicationListAdapter(
filteredApps,
::isAppEnabled,
::setAppEnabled
)
- apps_list_swipeRefreshLayout.setOnRefreshListener(this)
- apps_list_more_menu.setOnClickListener(this)
+ binding.appsListSwipeRefreshLayout.setOnRefreshListener(this)
+ binding.appsListMoreMenu.setOnClickListener(this)
- apps_list_filterEditText.doAfterTextChanged {
+ binding.appsListFilterEditText.doAfterTextChanged {
textFilter = it.toString()
applyFilters()
}
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ setResult(RESULT_OK, Intent().putExtra(
+ UNSELECTED_APPS_EXTRA,
+ blockedPackages.toTypedArray()
+ ))
+ finish()
+ }
+ })
+
onRefresh()
}
override fun onRefresh() {
launch(Dispatchers.Main) {
- if (apps_list_swipeRefreshLayout.isRefreshing.not()) {
- apps_list_swipeRefreshLayout.isRefreshing = true
+ if (binding.appsListSwipeRefreshLayout.isRefreshing.not()) {
+ binding.appsListSwipeRefreshLayout.isRefreshing = true
}
val apps = loadAllApps()
@@ -66,18 +81,18 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
allApps.addAll(apps)
applyFilters()
- apps_list_swipeRefreshLayout.isRefreshing = false
+ binding.appsListSwipeRefreshLayout.isRefreshing = false
}
}
private fun applyFilters() {
filteredApps.clear()
filteredApps.addAll(allApps.filter(::matchesFilters))
- apps_list_recyclerView.adapter?.notifyDataSetChanged()
+ binding.appsListRecyclerView.adapter?.notifyDataSetChanged()
}
private fun matchesFilters(app: PackageInfo): Boolean {
- val appInfo = app.applicationInfo
+ val appInfo = app.applicationInfo ?: return false
val appLabel = AppLabelCache.getAppLabel(packageManager, appInfo)
val isSystemApp = appInfo.flags and ApplicationInfo.FLAG_SYSTEM == 1
@@ -103,13 +118,14 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
private suspend fun loadAllApps(): List =
withContext(Dispatchers.IO) {
- return@withContext packageManager.getInstalledPackages(PackageManager.GET_META_DATA).apply {
- sortBy { pkg ->
- AppLabelCache.getAppLabel(packageManager, pkg.applicationInfo).toUpperCase(
+ return@withContext packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
+ .filter { pkg ->
+ pkg.applicationInfo != null
+ }.sortedBy { pkg ->
+ AppLabelCache.getAppLabel(packageManager, pkg.applicationInfo!!).toUpperCase(
Locale.getDefault()
)
}
- }
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@@ -136,7 +152,7 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
if (showEnabledOnly) {
applyFilters()
} else {
- apps_list_recyclerView.adapter?.notifyDataSetChanged()
+ binding.appsListRecyclerView.adapter?.notifyDataSetChanged()
}
true
}
@@ -147,7 +163,7 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
override fun onClick(v: View?) {
when (v?.id) {
R.id.apps_list_more_menu -> {
- PopupMenu(ContextThemeWrapper(this, R.style.PopupMenu), apps_list_more_menu).apply {
+ PopupMenu(ContextThemeWrapper(this, R.style.PopupMenu), binding.appsListMoreMenu).apply {
this.inflate(R.menu.menu_app_list)
this.menu.findItem(R.id.action_show_system).isChecked = showSystem
this.menu.findItem(R.id.action_show_enabled).isChecked = showEnabledOnly
@@ -162,12 +178,4 @@ class ApplicationListActivity : AppCompatActivity(), SwipeRefreshLayout.OnRefres
}
}
}
-
- override fun onBackPressed() {
- setResult(RESULT_OK, Intent().putExtra(
- UNSELECTED_APPS_EXTRA,
- blockedPackages.toTypedArray()
- ))
- finish()
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/tech/httptoolkit/android/ApplicationListAdapter.kt b/app/src/main/java/tech/httptoolkit/android/ApplicationListAdapter.kt
index 2edfe3e..8eda66b 100644
--- a/app/src/main/java/tech/httptoolkit/android/ApplicationListAdapter.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ApplicationListAdapter.kt
@@ -2,22 +2,23 @@ package tech.httptoolkit.android
import android.content.pm.PackageInfo
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import kotlinx.android.synthetic.main.item_app_row.view.*
+import tech.httptoolkit.android.databinding.ItemAppRowBinding
class ApplicationListAdapter(
private val data: MutableList,
private val isAppWhitelisted: (PackageInfo) -> Boolean,
private val onCheckChanged: (PackageInfo, Boolean) -> Unit
-) :
- RecyclerView.Adapter() {
+) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppsViewHolder {
- return AppsViewHolder(
- LayoutInflater.from(parent.context).inflate(R.layout.item_app_row, parent, false)
+ val binding = ItemAppRowBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
)
+ return AppsViewHolder(binding)
}
override fun getItemCount() = data.size
@@ -26,23 +27,25 @@ class ApplicationListAdapter(
holder.bind(data[position])
}
- inner class AppsViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ inner class AppsViewHolder(
+ private val binding: ItemAppRowBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
private val packageManager by lazy {
itemView.context.packageManager
}
init {
- itemView.row_app_switch.setOnCheckedChangeListener { _, isChecked ->
+ binding.rowAppSwitch.setOnCheckedChangeListener { _, isChecked ->
onCheckChanged(data[layoutPosition], isChecked)
}
}
fun bind(packageInfo: PackageInfo) {
- val appInfo = packageInfo.applicationInfo
- itemView.row_app_icon_image.setImageDrawable(appInfo.loadIcon(packageManager))
- itemView.row_app_name.text = AppLabelCache.getAppLabel(packageManager, appInfo)
- itemView.row_app_package_name.text = packageInfo.packageName
- itemView.row_app_switch.isChecked = isAppWhitelisted(packageInfo)
+ val appInfo = packageInfo.applicationInfo!!
+ binding.rowAppIconImage.setImageDrawable(appInfo.loadIcon(packageManager))
+ binding.rowAppName.text = AppLabelCache.getAppLabel(packageManager, appInfo)
+ binding.rowAppPackageName.text = packageInfo.packageName
+ binding.rowAppSwitch.isChecked = isAppWhitelisted(packageInfo)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/tech/httptoolkit/android/HttpToolkitApplication.kt b/app/src/main/java/tech/httptoolkit/android/HttpToolkitApplication.kt
index 468d726..180b747 100644
--- a/app/src/main/java/tech/httptoolkit/android/HttpToolkitApplication.kt
+++ b/app/src/main/java/tech/httptoolkit/android/HttpToolkitApplication.kt
@@ -10,7 +10,6 @@ import com.android.installreferrer.api.InstallReferrerClient.InstallReferrerResp
import com.android.installreferrer.api.InstallReferrerStateListener
import com.beust.klaxon.Klaxon
import io.sentry.Sentry
-import io.sentry.android.AndroidSentryClientFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import net.swiftzer.semver.SemVer
@@ -67,17 +66,13 @@ class HttpToolkitApplication : Application() {
prefs.edit().putBoolean(APP_CRASHED_PREF, true).apply()
}
- if (BuildConfig.SENTRY_DSN != null) {
- Sentry.init(BuildConfig.SENTRY_DSN, AndroidSentryClientFactory(this))
- }
-
// Check if we've been recreated unexpectedly, with no crashes in the meantime:
val appCrashed = prefs.getBoolean(APP_CRASHED_PREF, false)
prefs.edit().putBoolean(APP_CRASHED_PREF, false).apply()
vpnWasKilled = vpnShouldBeRunning && !isVpnActive() && !appCrashed && !isProbablyEmulator
if (vpnWasKilled) {
- Sentry.capture("VPN killed in the background")
+ Sentry.captureMessage("VPN killed in the background")
// The UI will show an alert next time the MainActivity is created.
}
@@ -293,7 +288,7 @@ private fun tryParseSemver(version: String?): SemVer? = try {
private fun getInstalledVersion(context: Context): SemVer {
return SemVer.parse(
- context.packageManager.getPackageInfo(context.packageName, 0).versionName
+ context.packageManager.getPackageInfo(context.packageName, 0).versionName!!
)
}
diff --git a/app/src/main/java/tech/httptoolkit/android/MainActivity.kt b/app/src/main/java/tech/httptoolkit/android/MainActivity.kt
index 6f552de..1613de8 100644
--- a/app/src/main/java/tech/httptoolkit/android/MainActivity.kt
+++ b/app/src/main/java/tech/httptoolkit/android/MainActivity.kt
@@ -392,7 +392,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
// We report errors only that aren't simple connection failures
if (e !is SocketTimeoutException && e !is ConnectException) {
- Sentry.capture(e)
+ Sentry.captureException(e)
}
}
}
@@ -544,7 +544,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
// ignored us) then try try again.
requestNotificationPermission(true)
} else {
- Sentry.capture("Non-OK result $resultCode for requestCode $requestCode")
+ Sentry.captureMessage("Non-OK result $resultCode for requestCode $requestCode")
mainState = MainState.FAILED
updateUi()
}
@@ -599,7 +599,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
// We report errors only that aren't simple connection failures
if (e !is SocketTimeoutException && e !is ConnectException) {
- Sentry.capture(e)
+ Sentry.captureException(e)
}
}
}
diff --git a/app/src/main/java/tech/httptoolkit/android/PortListActivity.kt b/app/src/main/java/tech/httptoolkit/android/PortListActivity.kt
index a0d787e..21b6da5 100644
--- a/app/src/main/java/tech/httptoolkit/android/PortListActivity.kt
+++ b/app/src/main/java/tech/httptoolkit/android/PortListActivity.kt
@@ -3,11 +3,12 @@ package tech.httptoolkit.android
import android.content.Intent
import android.os.Bundle
import android.widget.PopupMenu
+import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.widget.doAfterTextChanged
-import kotlinx.android.synthetic.main.ports_list.*
import kotlinx.coroutines.*
+import tech.httptoolkit.android.databinding.PortsListBinding
import java.util.*
val DEFAULT_PORTS = setOf(
@@ -26,37 +27,41 @@ class PortListActivity : AppCompatActivity(), CoroutineScope by MainScope() {
private lateinit var ports: TreeSet // TreeSet = Mutable + Sorted
+ private lateinit var binding: PortsListBinding
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.ports_list)
+
+ binding = PortsListBinding.inflate(layoutInflater)
+ setContentView(binding.root)
ports = intent.getIntArrayExtra(SELECTED_PORTS_EXTRA)!!
.toCollection(TreeSet())
- ports_list_recyclerView.adapter =
+ binding.portsListRecyclerView.adapter =
PortListAdapter(
ports,
::deletePort
)
- ports_list_input.filters = arrayOf(MinMaxInputFilter(MIN_PORT, MAX_PORT))
+ binding.portsListInput.filters = arrayOf(MinMaxInputFilter(MIN_PORT, MAX_PORT))
// Match the UI enabled state to the input field contents:
- ports_list_add_button.isEnabled = false
- ports_list_input.doAfterTextChanged {
- ports_list_add_button.isEnabled = isValidInput(it.toString())
+ binding.portsListAddButton.isEnabled = false
+ binding.portsListInput.doAfterTextChanged {
+ binding.portsListAddButton.isEnabled = isValidInput(it.toString())
}
// Add ports when enter/+ is pressed/clicked:
- ports_list_add_button.setOnClickListener { addEnteredPort() }
- ports_list_input.setOnEditorActionListener { _, _, _ ->
+ binding.portsListAddButton.setOnClickListener { addEnteredPort() }
+ binding.portsListInput.setOnEditorActionListener { _, _, _ ->
addEnteredPort()
return@setOnEditorActionListener true
}
// Show the menu, and listen for clicks:
- ports_list_more_menu.setOnClickListener {
- PopupMenu(ContextThemeWrapper(this, R.style.PopupMenu), ports_list_more_menu).apply {
+ binding.portsListMoreMenu.setOnClickListener {
+ PopupMenu(ContextThemeWrapper(this, R.style.PopupMenu), binding.portsListMoreMenu).apply {
this.inflate(R.menu.menu_ports_list)
this.menu.findItem(R.id.action_reset_ports).isEnabled =
@@ -75,6 +80,16 @@ class PortListActivity : AppCompatActivity(), CoroutineScope by MainScope() {
}
}.show()
}
+
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ setResult(RESULT_OK, Intent().putExtra(
+ SELECTED_PORTS_EXTRA,
+ ports.toIntArray()
+ ))
+ finish()
+ }
+ })
}
private fun isValidInput(input: String): Boolean =
@@ -82,10 +97,10 @@ class PortListActivity : AppCompatActivity(), CoroutineScope by MainScope() {
!ports.contains(input.toInt())
private fun addEnteredPort() {
- if (!isValidInput(ports_list_input.text.toString())) return
+ if (!isValidInput(binding.portsListInput.text.toString())) return
- ports.add(ports_list_input.text.toString().toInt())
- ports_list_input.text.clear()
+ ports.add(binding.portsListInput.text.toString().toInt())
+ binding.portsListInput.text.clear()
updateList()
}
@@ -95,14 +110,6 @@ class PortListActivity : AppCompatActivity(), CoroutineScope by MainScope() {
}
private fun updateList() {
- ports_list_recyclerView.adapter?.notifyDataSetChanged()
- }
-
- override fun onBackPressed() {
- setResult(RESULT_OK, Intent().putExtra(
- SELECTED_PORTS_EXTRA,
- ports.toIntArray()
- ))
- finish()
+ binding.portsListRecyclerView.adapter?.notifyDataSetChanged()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/tech/httptoolkit/android/PortListAdapter.kt b/app/src/main/java/tech/httptoolkit/android/PortListAdapter.kt
index 010ae1f..b67a0ad 100644
--- a/app/src/main/java/tech/httptoolkit/android/PortListAdapter.kt
+++ b/app/src/main/java/tech/httptoolkit/android/PortListAdapter.kt
@@ -1,10 +1,9 @@
package tech.httptoolkit.android
import android.view.LayoutInflater
-import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import kotlinx.android.synthetic.main.item_port_row.view.*
+import tech.httptoolkit.android.databinding.ItemPortRowBinding
val PORT_DESCRIPTIONS = mapOf(
80 to "Standard HTTP port",
@@ -26,9 +25,12 @@ class PortListAdapter(
) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PortViewHolder {
- return PortViewHolder(
- LayoutInflater.from(parent.context).inflate(R.layout.item_port_row, parent, false)
+ val binding = ItemPortRowBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
)
+ return PortViewHolder(binding)
}
override fun getItemCount() = ports.size
@@ -37,18 +39,20 @@ class PortListAdapter(
holder.bind(ports.elementAt(position))
}
- inner class PortViewHolder(v: View) : RecyclerView.ViewHolder(v) {
+ inner class PortViewHolder(
+ private val binding: ItemPortRowBinding
+ ) : RecyclerView.ViewHolder(binding.root) {
init {
- itemView.row_port_delete.setOnClickListener { _ ->
+ binding.rowPortDelete.setOnClickListener {
onPortDeleted(ports.elementAt(layoutPosition))
}
}
fun bind(port: Int) {
- itemView.row_port.text = port.toString()
- itemView.row_port_description.text = PORT_DESCRIPTIONS[port]
- ?: "Unknown port";
+ binding.rowPort.text = port.toString()
+ binding.rowPortDescription.text = PORT_DESCRIPTIONS[port]
+ ?: "Unknown port"
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/tech/httptoolkit/android/ProxyDetails.kt b/app/src/main/java/tech/httptoolkit/android/ProxyDetails.kt
index 9189d8f..fd7f216 100644
--- a/app/src/main/java/tech/httptoolkit/android/ProxyDetails.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ProxyDetails.kt
@@ -2,11 +2,10 @@ package tech.httptoolkit.android
import android.os.Parcelable
import android.util.Base64
-import android.util.Log
import com.beust.klaxon.Converter
import com.beust.klaxon.Json
import com.beust.klaxon.JsonValue
-import kotlinx.android.parcel.Parcelize
+import kotlinx.parcelize.Parcelize
import java.io.ByteArrayInputStream
import java.security.cert.Certificate
import java.security.cert.CertificateFactory
diff --git a/app/src/main/java/tech/httptoolkit/android/ProxySetup.kt b/app/src/main/java/tech/httptoolkit/android/ProxySetup.kt
index ccffb17..e7d5d89 100644
--- a/app/src/main/java/tech/httptoolkit/android/ProxySetup.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ProxySetup.kt
@@ -191,7 +191,7 @@ fun whereIsCertTrusted(proxyConfig: ProxyConfig): String? {
proxyCertAliases.any { alias -> alias.startsWith("system:") } -> "system"
proxyCertAliases.any { alias -> alias.startsWith("user:") } -> "user"
else -> {
- Sentry.capture("Cert has no recognizable aliases")
+ Sentry.captureMessage("Cert has no recognizable aliases")
return "unknown-store"
}
}
diff --git a/app/src/main/java/tech/httptoolkit/android/ProxyVpnRunnable.kt b/app/src/main/java/tech/httptoolkit/android/ProxyVpnRunnable.kt
index 7711b2c..560bbbf 100644
--- a/app/src/main/java/tech/httptoolkit/android/ProxyVpnRunnable.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ProxyVpnRunnable.kt
@@ -95,7 +95,7 @@ class ProxyVpnRunnable(
(e is PacketHeaderException && errorMessage.contains("IP version should be 4 but was 6"))
if (!isIgnorable) {
- Sentry.capture(e)
+ Sentry.captureException(e)
}
}
diff --git a/app/src/main/java/tech/httptoolkit/android/ProxyVpnService.kt b/app/src/main/java/tech/httptoolkit/android/ProxyVpnService.kt
index 000824a..d2f1aa7 100644
--- a/app/src/main/java/tech/httptoolkit/android/ProxyVpnService.kt
+++ b/app/src/main/java/tech/httptoolkit/android/ProxyVpnService.kt
@@ -277,7 +277,7 @@ class ProxyVpnService : VpnService(), IProtectSocket {
vpnInterface?.close()
vpnInterface = null
} catch (e: IOException) {
- Sentry.capture(e)
+ Sentry.captureException(e)
}
stopForeground(true)
@@ -296,7 +296,7 @@ class ProxyVpnService : VpnService(), IProtectSocket {
vpnInterface?.close()
vpnInterface = null
} catch (e: IOException) {
- Sentry.capture(e)
+ Sentry.captureException(e)
}
stopForeground(true)
diff --git a/build.gradle b/build.gradle
index 435200f..72863e1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,15 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.60'
+ ext.kotlin_version = '1.9.25'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.2.2'
+ classpath 'com.android.tools.build:gradle:8.7.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'com.google.gms:google-services:4.0.1'
+ classpath 'com.google.gms:google-services:4.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -22,6 +22,6 @@ allprojects {
}
}
-task clean(type: Delete) {
+tasks.register('clean', Delete) {
delete rootProject.buildDir
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 40afac2..16cce85 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Dec 04 13:54:32 CET 2020
+#Wed Nov 20 12:08:44 CET 2024
distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME