diff --git a/Makefile b/Makefile index d6d3a41..7257bb8 100644 --- a/Makefile +++ b/Makefile @@ -208,7 +208,7 @@ tag_release: ## Tag the current commit with the current version .PHONY: bumposs ## Bump to the latest oss and update teh versions. bumposs: update-oss update-version - git commit -sm "android: bumping OSS" -m "OSS and Version updated to ${VERSION_LONG}" go.toolchain.rev android/build.gradle go.mod go.sum + git commit -sm "android: bump OSS" -m "OSS and Version updated to ${VERSION_LONG}" go.toolchain.rev android/build.gradle go.mod go.sum git tag -a "$(VERSION_LONG)" -m "OSS and Version updated to ${VERSION_LONG}" .PHONY: bump_version_code diff --git a/android/build.gradle b/android/build.gradle index 4d125ba..d2b1ad6 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -11,7 +11,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:8.5.1' + classpath 'com.android.tools.build:gradle:8.6.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" classpath("com.ncorti.ktfmt.gradle:plugin:0.17.0") @@ -38,7 +38,7 @@ android { minSdkVersion 26 targetSdkVersion 34 versionCode 241 - versionName "1.75.81-t4ad3f0122-g0126db799b1" + versionName "1.77.12-ta8f9c0d6e-g753b8d3fb4b" // This setting, which defaults to 'true', will cause Tailscale to fall // back to the Google DNS servers if it cannot determine what the @@ -112,7 +112,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.13.1' implementation "androidx.browser:browser:1.8.0" implementation "androidx.security:security-crypto:1.1.0-alpha06" - implementation "androidx.work:work-runtime:2.9.0" + implementation "androidx.work:work-runtime:2.9.1" // Kotlin dependencies. implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" @@ -123,20 +123,20 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" // Compose dependencies. - def composeBom = platform('androidx.compose:compose-bom:2024.06.00') + def composeBom = platform('androidx.compose:compose-bom:2024.09.03') implementation composeBom - implementation 'androidx.compose.material3:material3:1.2.1' - implementation 'androidx.compose.material:material-icons-core:1.6.8' - implementation "androidx.compose.ui:ui:1.6.8" - implementation "androidx.compose.ui:ui-tooling:1.6.8" - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3' - implementation 'androidx.activity:activity-compose:1.9.0' + implementation 'androidx.compose.material3:material3:1.3.0' + implementation 'androidx.compose.material:material-icons-core:1.7.3' + implementation "androidx.compose.ui:ui:1.7.3" + implementation "androidx.compose.ui:ui-tooling:1.7.3" + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6' + implementation 'androidx.activity:activity-compose:1.9.2' implementation "com.google.accompanist:accompanist-permissions:$accompanist_version" implementation "com.google.accompanist:accompanist-systemuicontroller:$accompanist_version" implementation "androidx.core:core-splashscreen:1.1.0-rc01" // Navigation dependencies. - def nav_version = "2.7.7" + def nav_version = "2.8.2" implementation "androidx.navigation:navigation-compose:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" @@ -151,7 +151,7 @@ dependencies { // Integration Tests androidTestImplementation composeBom - androidTestImplementation 'androidx.test:runner:1.6.1' + androidTestImplementation 'androidx.test:runner:1.6.2' androidTestImplementation 'androidx.test.ext:junit-ktx:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' @@ -164,7 +164,7 @@ dependencies { // Unit Tests testImplementation 'junit:junit:4.13.2' - testImplementation 'org.mockito:mockito-core:5.4.0' + testImplementation 'org.mockito:mockito-core:5.12.0' testImplementation 'org.mockito:mockito-inline:5.2.0' testImplementation 'org.mockito.kotlin:mockito-kotlin:5.4.0' diff --git a/android/src/main/java/com/tailscale/ipn/App.kt b/android/src/main/java/com/tailscale/ipn/App.kt index dd89972..f0b3dde 100644 --- a/android/src/main/java/com/tailscale/ipn/App.kt +++ b/android/src/main/java/com/tailscale/ipn/App.kt @@ -371,16 +371,27 @@ open class UninitializedApp : Application() { fun startVPN() { val intent = Intent(this, IPNService::class.java).apply { action = IPNService.ACTION_START_VPN } + // FLAG_UPDATE_CURRENT ensures that if the intent is already pending, the existing intent will + // be updated rather than creating multiple redundant instances. + val pendingIntent = + PendingIntent.getService( + this, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or + PendingIntent.FLAG_IMMUTABLE // FLAG_IMMUTABLE for Android 12+ + ) + try { - startForegroundService(intent) + pendingIntent.send() } catch (foregroundServiceStartException: IllegalStateException) { TSLog.e( TAG, - "startVPN hit ForegroundServiceStartNotAllowedException in startForegroundService(): $foregroundServiceStartException") + "startVPN hit ForegroundServiceStartNotAllowedException: $foregroundServiceStartException") } catch (securityException: SecurityException) { - TSLog.e(TAG, "startVPN hit SecurityException in startForegroundService(): $securityException") + TSLog.e(TAG, "startVPN hit SecurityException: $securityException") } catch (e: Exception) { - TSLog.e(TAG, "startVPN hit exception in startForegroundService(): $e") + TSLog.e(TAG, "startVPN hit exception: $e") } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt b/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt index e2b7ab3..baae957 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/Avatar.kt @@ -13,9 +13,9 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Person -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -55,7 +55,7 @@ fun Avatar(profile: IpnLocal.LoginProfile?, size: Int = 50, action: (() -> Unit) .focusable() // Make this outer Box focusable (after onFocusChanged) .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = true), // Apply ripple effect inside circular bounds + indication = ripple(bounded = true), // Apply ripple effect inside circular bounds onClick = { action?.invoke() focusManager.clearFocus() // Clear focus after clicking the avatar diff --git a/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt b/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt index de31170..8d0ef3a 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/view/SharedViews.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.CheckCircle -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -21,6 +20,7 @@ import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember @@ -76,7 +76,7 @@ fun BackArrow(action: () -> Unit, focusRequester: FocusRequester) { Modifier.focusRequester(focusRequester) .clickable( interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(bounded = false), + indication = ripple(bounded = false), onClick = { action() })) } } diff --git a/go.mod b/go.mod index e7b4478..9c44a3b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/tailscale/wireguard-go v0.0.0-20240905161824-799c1978fafc golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab inet.af/netaddr v0.0.0-20220617031823-097006376321 - tailscale.com v1.75.0-pre.0.20241004185700-4ad3f0122574 + tailscale.com v1.75.0-pre.0.20241014151013-a8f9c0d6e40a ) require ( diff --git a/go.sum b/go.sum index 3095a6f..f674216 100644 --- a/go.sum +++ b/go.sum @@ -256,5 +256,5 @@ inet.af/netaddr v0.0.0-20220617031823-097006376321 h1:B4dC8ySKTQXasnjDTMsoCMf1sQ inet.af/netaddr v0.0.0-20220617031823-097006376321/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= -tailscale.com v1.75.0-pre.0.20241004185700-4ad3f0122574 h1:Ql1Ojbp3j2u1bekVmDqo0fhBkM0jXA1trjtJi/zbuaw= -tailscale.com v1.75.0-pre.0.20241004185700-4ad3f0122574/go.mod h1:myCwmhYBvMCF/5OgBYuIW42zscuEo30bAml7wABVZLk= +tailscale.com v1.75.0-pre.0.20241014151013-a8f9c0d6e40a h1:nGLKfmPOA8dmMqGUjBDIaUD4RkXo+QpP3TXoAKVwvHU= +tailscale.com v1.75.0-pre.0.20241014151013-a8f9c0d6e40a/go.mod h1:myCwmhYBvMCF/5OgBYuIW42zscuEo30bAml7wABVZLk=