diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 08f429dfe3cd..64d18bb0f679 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -450,6 +450,7 @@ jobs:
api-level:
- 21
- 29
+ - 34
steps:
- name: Checkout
@@ -488,6 +489,7 @@ jobs:
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
+ arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
@@ -497,10 +499,20 @@ jobs:
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
+ arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
script: ./gradlew -PandroidBuild=true :okhttp-android:connectedCheck :android-test:connectedCheck
env:
API_LEVEL: ${{ matrix.api-level }}
+ - name: Run Release Tests
+ uses: reactivecircus/android-emulator-runner@v2
+ with:
+ api-level: ${{ matrix.api-level }}
+ arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
+ script: ./gradlew -PandroidBuild=true :android-test-app:connectedCheck
+ env:
+ API_LEVEL: ${{ matrix.api-level }}
+
testloom:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'loom')
diff --git a/android-test-app/build.gradle.kts b/android-test-app/build.gradle.kts
new file mode 100644
index 000000000000..da419a24d774
--- /dev/null
+++ b/android-test-app/build.gradle.kts
@@ -0,0 +1,51 @@
+@file:Suppress("UnstableApiUsage")
+
+plugins {
+ id("com.android.application")
+ id("kotlin-android")
+}
+
+android {
+ compileSdk = 34
+
+ namespace = "okhttp.android.testapp"
+
+ testBuildType = "release"
+
+ defaultConfig {
+ minSdk = 21
+ targetSdk = 34
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ compileOptions {
+ targetCompatibility(JavaVersion.VERSION_11)
+ sourceCompatibility(JavaVersion.VERSION_11)
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_11.toString()
+ }
+
+ buildTypes {
+ release {
+ isShrinkResources = true
+ isMinifyEnabled = true
+ signingConfig = signingConfigs.getByName("debug")
+ setProguardFiles(listOf(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"))
+ testProguardFiles("test-proguard-rules.pro")
+ }
+ }
+}
+
+dependencies {
+ implementation(libs.playservices.safetynet)
+ implementation(projects.okhttp)
+ implementation(projects.okhttpAndroid)
+ implementation(libs.androidx.activity)
+
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(libs.androidx.test.runner)
+ androidTestImplementation(libs.assertk)
+}
diff --git a/android-test-app/proguard-rules.pro b/android-test-app/proguard-rules.pro
new file mode 100644
index 000000000000..63c217b3ab3d
--- /dev/null
+++ b/android-test-app/proguard-rules.pro
@@ -0,0 +1 @@
+# no rules should be needed
diff --git a/android-test-app/src/androidTest/kotlin/okhttp/android/testapp/PublicSuffixDatabaseTest.kt b/android-test-app/src/androidTest/kotlin/okhttp/android/testapp/PublicSuffixDatabaseTest.kt
new file mode 100644
index 000000000000..f7debc9d345e
--- /dev/null
+++ b/android-test-app/src/androidTest/kotlin/okhttp/android/testapp/PublicSuffixDatabaseTest.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 Block, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package okhttp3.android
+
+import assertk.assertThat
+import assertk.assertions.isEqualTo
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import org.junit.Test
+
+/**
+ * Run with "./gradlew :android-test-app:connectedCheck -PandroidBuild=true" and make sure ANDROID_SDK_ROOT is set.
+ */
+class PublicSuffixDatabaseTest {
+
+ @Test
+ fun testTopLevelDomain() {
+ assertThat("https://www.google.com/robots.txt".toHttpUrl().topPrivateDomain()).isEqualTo("google.com")
+ }
+}
diff --git a/android-test-app/src/main/AndroidManifest.xml b/android-test-app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000000..5b8c081626df
--- /dev/null
+++ b/android-test-app/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt b/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt
new file mode 100644
index 000000000000..7517b0ab05f2
--- /dev/null
+++ b/android-test-app/src/main/kotlin/okhttp/android/testapp/MainActivity.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 Block, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package okhttp.android.testapp
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import okhttp3.Call
+import okhttp3.Callback
+import okhttp3.CookieJar
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.internal.publicsuffix.PublicSuffixDatabase
+import okio.FileSystem
+import okio.IOException
+import okio.Path.Companion.toPath
+import java.net.CookieHandler
+import java.net.URI
+
+class MainActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val client = OkHttpClient()
+
+ val url = "https://github.com/square/okhttp".toHttpUrl()
+ println(url.topPrivateDomain())
+
+ client.newCall(Request(url)).enqueue(object : Callback {
+ override fun onFailure(call: Call, e: IOException) {
+ println("failed: $e")
+ }
+
+ override fun onResponse(call: Call, response: Response) {
+ println("response: ${response.code}")
+ response.close()
+ }
+ })
+ }
+}
diff --git a/android-test-app/src/main/kotlin/okhttp/android/testapp/TestApplication.kt b/android-test-app/src/main/kotlin/okhttp/android/testapp/TestApplication.kt
new file mode 100644
index 000000000000..bd6bef4f68c1
--- /dev/null
+++ b/android-test-app/src/main/kotlin/okhttp/android/testapp/TestApplication.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 Block, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package okhttp.android.testapp
+
+import android.app.Application
+
+class TestApplication: Application() {
+}
diff --git a/android-test-app/src/main/res/values/strings.xml b/android-test-app/src/main/res/values/strings.xml
new file mode 100644
index 000000000000..3f2b0bb2327a
--- /dev/null
+++ b/android-test-app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ android-test
+
diff --git a/android-test-app/src/main/res/xml/network_security_config.xml b/android-test-app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 000000000000..353fa8080ccf
--- /dev/null
+++ b/android-test-app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android-test-app/test-proguard-rules.pro b/android-test-app/test-proguard-rules.pro
new file mode 100644
index 000000000000..8962eae7dbbf
--- /dev/null
+++ b/android-test-app/test-proguard-rules.pro
@@ -0,0 +1 @@
+-dontwarn **
diff --git a/build.gradle.kts b/build.gradle.kts
index a0245c40a9c8..08ed5fa5f7e7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -72,6 +72,7 @@ subprojects {
if (project.name == "okhttp-android") return@subprojects
if (project.name == "android-test") return@subprojects
if (project.name == "regression-test") return@subprojects
+ if (project.name == "android-test-app") return@subprojects
apply(plugin = "checkstyle")
apply(plugin = "ru.vyarus.animalsniffer")
diff --git a/gradle.properties b/gradle.properties
index d76a006f4a78..60888d311670 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,4 +9,4 @@ kotlin.incremental.js.ir=true
androidBuild=false
graalBuild=false
loomBuild=false
-android.experimental.lint.version=8.1.0-rc01
+android.experimental.lint.version=8.2.0
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4319f6abaecc..92ccdb44027d 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -14,6 +14,7 @@ org-junit-jupiter = "5.10.1"
[libraries]
amazonCorretto = "software.amazon.cryptools:AmazonCorrettoCryptoProvider:2.3.1"
+androidx-activity = "androidx.activity:activity-ktx:1.8.2"
androidx-annotation = "androidx.annotation:annotation:1.7.1"
androidx-espresso-core = "androidx.test.espresso:espresso-core:3.5.1"
androidx-junit = "androidx.test.ext:junit:1.1.5"
@@ -33,7 +34,7 @@ conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref =
conscrypt-openjdk = { module = "org.conscrypt:conscrypt-openjdk-uber", version.ref = "org-conscrypt" }
eclipseOsgi = "org.eclipse.platform:org.eclipse.osgi:3.18.500"
findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
-gradlePlugin-android = "com.android.tools.build:gradle:8.0.2"
+gradlePlugin-android = "com.android.tools.build:gradle:8.2.0"
gradlePlugin-androidJunit5 = "de.mannodermaus.gradle.plugins:android-junit5:1.10.0.0"
gradlePlugin-animalsniffer = "ru.vyarus:gradle-animalsniffer-plugin:1.7.1"
gradlePlugin-binaryCompatibilityValidator = "org.jetbrains.kotlinx.binary-compatibility-validator:org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin:0.13.2"
diff --git a/okhttp-testing-support/src/main/resources/META-INF/proguard/okhttp3.pro b/okhttp-testing-support/src/main/resources/META-INF/proguard/okhttp3.pro
new file mode 100644
index 000000000000..31ab0eebf6ea
--- /dev/null
+++ b/okhttp-testing-support/src/main/resources/META-INF/proguard/okhttp3.pro
@@ -0,0 +1,2 @@
+# OkHttp test platform rules uses optional classes.
+-dontwarn **
diff --git a/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro b/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
index c5b800388776..74fc3168014a 100644
--- a/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
+++ b/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
@@ -2,6 +2,7 @@
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
+-keeppackagenames okhttp3.internal.publicsuffix.*
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
diff --git a/regression-test/build.gradle.kts b/regression-test/build.gradle.kts
index 245cb6340b21..96e980671b42 100644
--- a/regression-test/build.gradle.kts
+++ b/regression-test/build.gradle.kts
@@ -4,13 +4,13 @@ plugins {
}
android {
- compileSdk = 31
+ compileSdk = 34
namespace = "okhttp.android.regression"
defaultConfig {
minSdk = 21
- targetSdk = 31
+ targetSdk = 34
// Make sure to use the AndroidJUnitRunner (or a sub-class) in order to hook in the JUnit 5 Test Builder
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
diff --git a/settings.gradle.kts b/settings.gradle.kts
index d8ee7affa618..dfeef3319876 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -49,6 +49,7 @@ project(":okhttp-logging-interceptor").name = "logging-interceptor"
if (!isKnownBrokenIntelliJ()) {
include(":okhttp-android")
include(":android-test")
+ include(":android-test-app")
}
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")