diff --git a/README.md b/README.md index c06a7678..727e2b97 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ _a.k.a. things that can go wrong if this app doesn't work._ This is a list of stuff that might impact this app's functionality if unavailable. This is only meant to be an index. You can read more in the source code. -Greylisted APIs or internal constants: (some constants are hardcoded or implicitly used) +Greylisted/blacklisted APIs or internal constants: (some constants are hardcoded or implicitly used) * [`Landroid/net/ConnectivityManager;->getLastTetherError(Ljava/lang/String;)I,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#123309) * [`Landroid/net/MacAddress;->ALL_ZEROS_ADDRESS:Landroid/net/MacAddress;,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#125559) @@ -144,6 +144,7 @@ Greylisted APIs or internal constants: (some constants are hardcoded or implicit * [`Landroid/net/wifi/p2p/WifiP2pConfig$Builder;->MAC_ANY_ADDRESS:Landroid/net/MacAddress;,blacklist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#134299) * [`Landroid/net/wifi/p2p/WifiP2pManager;->WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION:Ljava/lang/String;,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#134686) * [`Landroid/net/wifi/p2p/WifiP2pManager;->startWps(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/WpsInfo;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V,greylist`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#134738) +* (since API 30) `Landroid/net/TetheringManager$TetheringEventCallback;->onTetherableInterfaceRegexpsChanged(Landroid/net/TetheringManager$TetheringInterfaceRegexps;)V,blacklist` * (since API 28) [`Landroid/provider/Settings$Global;->SOFT_AP_TIMEOUT_ENABLED:Ljava/lang/String;,greylist-max-o`](https://android.googlesource.com/platform/prebuilts/runtime/+/3d07e5c/appcompat/hiddenapi-flags.csv#158307) * (prior to API 30) `Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I,greylist-max-q` * (prior to API 30) `Lcom/android/internal/R$array;->config_tether_usb_regexs:I,greylist-max-q` @@ -178,7 +179,6 @@ Hidden whitelisted APIs: (same catch as above, however, things in this list are * (since API 30) `Landroid/net/TetheringManager$TetheringRequest$Builder;->build()Landroid/net/TetheringManager$TetheringRequest;,system-api,test-api,whitelist` * (since API 30) `Landroid/net/TetheringManager$TetheringRequest$Builder;->setExemptFromEntitlementCheck(Z)Landroid/net/TetheringManager$TetheringRequest$Builder;,system-api,test-api,whitelist` * (since API 30) `Landroid/net/TetheringManager$TetheringRequest$Builder;->setShouldShowEntitlementUi(Z)Landroid/net/TetheringManager$TetheringRequest$Builder;,system-api,test-api,whitelist` -* (since API 30) `Landroid/net/TetheringManager$TetheringRequest$Builder;->setStaticIpv4Addresses(Landroid/net/LinkAddress;Landroid/net/LinkAddress;)Landroid/net/TetheringManager$TetheringRequest$Builder;,system-api,test-api,whitelist` * `Landroid/net/TetheringManager;->ACTION_TETHER_STATE_CHANGED:Ljava/lang/String;,system-api,test-api,whitelist` * (since API 26) `Landroid/net/TetheringManager;->EXTRA_ACTIVE_LOCAL_ONLY:Ljava/lang/String;,system-api,test-api,whitelist` * `Landroid/net/TetheringManager;->EXTRA_ACTIVE_TETHER:Ljava/lang/String;,system-api,test-api,whitelist` diff --git a/build.gradle.kts b/build.gradle.kts index 6892a357..b878f78f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,7 @@ +plugins { + id("com.github.ben-manes.versions") version "0.28.0" +} + buildscript { val kotlinVersion = "1.3.72" extra.set("kotlinVersion", kotlinVersion) diff --git a/mobile/build.gradle.kts b/mobile/build.gradle.kts index 692763df..a49a22c3 100644 --- a/mobile/build.gradle.kts +++ b/mobile/build.gradle.kts @@ -64,7 +64,7 @@ android { } dependencies { - val lifecycleVersion = "2.3.0-alpha03" + val lifecycleVersion = "2.3.0-alpha04" val roomVersion = "2.2.5" coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.5") @@ -81,7 +81,7 @@ dependencies { implementation("androidx.preference:preference:1.1.1") implementation("androidx.room:room-ktx:$roomVersion") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01") - implementation("com.android.billingclient:billing-ktx:2.2.1") + implementation("com.android.billingclient:billing-ktx:3.0.0") implementation("com.github.topjohnwu.libsu:core:2.5.1") implementation("com.google.android.gms:play-services-oss-licenses:17.0.0") implementation("com.google.android.material:material:1.2.0-beta01") @@ -89,7 +89,7 @@ dependencies { implementation("com.google.firebase:firebase-crashlytics:17.0.1") implementation("com.google.zxing:core:3.4.0") implementation("com.jakewharton.timber:timber:4.7.1") - implementation("com.linkedin.dexmaker:dexmaker:2.25.1") + implementation("com.linkedin.dexmaker:dexmaker:2.28.0") implementation("com.takisoft.preferencex:preferencex-simplemenu:1.1.0") implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7") diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt index c2b9615a..77eb1d4f 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/EBegFragment.kt @@ -31,14 +31,14 @@ class EBegFragment : AppCompatDialogFragment() { }.setListener(this).build().also { it.startConnection(this) } } - override fun onBillingSetupFinished(billingResult: BillingResult?) { - if (billingResult?.responseCode == BillingClient.BillingResponseCode.OK) { + override fun onBillingSetupFinished(billingResult: BillingResult) { + if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { billingClient.queryPurchases(BillingClient.SkuType.INAPP).apply { if (responseCode == BillingClient.BillingResponseCode.OK) { onPurchasesUpdated(this.billingResult, purchasesList) } } - } else Timber.e("onBillingSetupFinished: ${billingResult?.responseCode}") + } else Timber.e("onBillingSetupFinished: ${billingResult.responseCode}") } override fun onBillingServiceDisconnected() { @@ -46,11 +46,11 @@ class EBegFragment : AppCompatDialogFragment() { billingClient.startConnection(this) } - override fun onPurchasesUpdated(billingResult: BillingResult?, purchases: MutableList?) { - if (billingResult?.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { + override fun onPurchasesUpdated(billingResult: BillingResult, purchases: MutableList?) { + if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { // directly consume in-app purchase, so that people can donate multiple times purchases.filter { it.purchaseState == Purchase.PurchaseState.PURCHASED }.map(this::consumePurchase) - } else Timber.e("onPurchasesUpdated: ${billingResult?.responseCode}") + } else Timber.e("onPurchasesUpdated: ${billingResult.responseCode}") } private fun consumePurchase(purchase: Purchase) = GlobalScope.launch(Dispatchers.Main.immediate) { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt index 178742ed..7e454314 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterService.kt @@ -241,6 +241,7 @@ class RepeaterService : Service(), CoroutineScope, WifiP2pManager.ChannelListene if (!safeMode && key == KEY_OPERATING_CHANNEL) setOperatingChannel() } + @SuppressLint("NewApi") // networkId is available since Android 4.2 private fun onPersistentGroupsChanged() { val channel = channel ?: return val device = binder.thisDevice ?: return diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt index 87343cd2..3d788862 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/client/ClientsFragment.kt @@ -109,10 +109,11 @@ class ClientsFragment : Fragment() { "▲ ${Formatter.formatFileSize(app, send)}/s\t\t▼ ${Formatter.formatFileSize(app, receive)}/s" } - private inner class ClientViewHolder(val binding: ListitemClientBinding) : RecyclerView.ViewHolder(binding.root), - View.OnClickListener, PopupMenu.OnMenuItemClickListener { + private inner class ClientViewHolder(parent: ViewGroup, val binding: ListitemClientBinding = + ListitemClientBinding.inflate(LayoutInflater.from(parent.context), parent, false)) : + RecyclerView.ViewHolder(binding.root), View.OnClickListener, PopupMenu.OnMenuItemClickListener { init { - binding.lifecycleOwner = binding.root.findViewTreeLifecycleOwner() + binding.lifecycleOwner = parent.findViewTreeLifecycleOwner()!! binding.root.setOnClickListener(this) binding.description.movementMethod = LinkMovementMethod.getInstance() } @@ -178,9 +179,7 @@ class ClientsFragment : Fragment() { binding.swipeRefresher.isRefreshing = false } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = - ClientViewHolder(ListitemClientBinding.inflate(LayoutInflater.from(parent.context), parent, false)) - + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ClientViewHolder(parent) override fun onBindViewHolder(holder: ClientViewHolder, position: Int) { val client = getItem(position) holder.binding.client = client diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetherType.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetherType.kt index 6ea49aac..2cf1d6d1 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetherType.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetherType.kt @@ -59,8 +59,8 @@ enum class TetherType(@DrawableRes val icon: Int) { } @RequiresApi(30) - override fun onTetherableInterfaceRegexpsChanged() { - Timber.i("onTetherableInterfaceRegexpsChanged") + override fun onTetherableInterfaceRegexpsChanged(args: Array?) { + Timber.i("onTetherableInterfaceRegexpsChanged: ${args?.contentToString()}") TetheringManager.unregisterTetheringEventCallback(this) requiresUpdate = true listener() diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt index 8443e40e..514a942c 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/TetheringManager.kt @@ -333,7 +333,7 @@ object TetheringManager { * *@param reg The new regular expressions. * @hide */ - fun onTetherableInterfaceRegexpsChanged() {} + fun onTetherableInterfaceRegexpsChanged(args: Array?) {} /** * Called when there was a change in the list of tetherable interfaces. Tetherable @@ -437,7 +437,7 @@ object TetheringManager { callback?.onUpstreamChanged(args!![0] as Network?) } "onTetherableInterfaceRegexpsChanged" -> { - if (regexpsSent) callback?.onTetherableInterfaceRegexpsChanged() + if (regexpsSent) callback?.onTetherableInterfaceRegexpsChanged(args) regexpsSent = true } "onTetherableInterfacesChanged" -> { diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt index 4fdad918..ac56936e 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/wifi/SoftApConfigurationCompat.kt @@ -1,5 +1,6 @@ package be.mygod.vpnhotspot.net.wifi +import android.annotation.SuppressLint import android.annotation.TargetApi import android.net.MacAddress import android.net.wifi.SoftApConfiguration @@ -237,6 +238,7 @@ data class SoftApConfigurationCompat( * https://android.googlesource.com/platform/packages/apps/Settings/+/android-5.0.0_r1/src/com/android/settings/wifi/WifiApDialog.java#88 * https://android.googlesource.com/platform/packages/apps/Settings/+/b1af85d/src/com/android/settings/wifi/tether/WifiTetherSettings.java#162 */ + @SuppressLint("NewApi") // https://android.googlesource.com/platform/frameworks/base/+/android-5.0.0_r1/wifi/java/android/net/wifi/WifiConfiguration.java#1385 @Deprecated("Class deprecated in framework") @Suppress("DEPRECATION") fun toWifiConfiguration(): android.net.wifi.WifiConfiguration { diff --git a/mobile/src/main/res/layout/dialog_wifi_ap.xml b/mobile/src/main/res/layout/dialog_wifi_ap.xml index f6e3dab2..1acdf0c2 100644 --- a/mobile/src/main/res/layout/dialog_wifi_ap.xml +++ b/mobile/src/main/res/layout/dialog_wifi_ap.xml @@ -127,7 +127,7 @@ android:layout_height="wrap_content" android:layout_marginTop="8dip" style="@style/wifi_item_label" - android:text="Hidden network"/> + android:text="@string/wifi_hidden_network"/> diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 2a70fd19..b2f73d88 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -2,11 +2,15 @@ VPN Hotspot @@ -163,6 +167,7 @@ 2.4 GHz Band 5.0 GHz Band 6.0 GHz Band + Hidden network Save