diff --git a/app/build.gradle b/app/build.gradle index f6965894..05431d39 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -158,7 +158,8 @@ dependencies { kapt "io.requery:requery-processor:$requeryVersion" implementation 'com.google.code.findbugs:jsr305:3.0.2' - def okhttp3Version = "3.12.1" + def okhttp3Version = "4.8.1" + implementation "com.squareup.okhttp3:okhttp:$okhttp3Version" implementation "com.squareup.okhttp3:logging-interceptor:$okhttp3Version" implementation 'com.google.code.gson:gson:1.7.2' diff --git a/app/src/main/java/com/etesync/syncadapter/HttpClient.kt b/app/src/main/java/com/etesync/syncadapter/HttpClient.kt index 9945dc0c..c663d3f2 100644 --- a/app/src/main/java/com/etesync/syncadapter/HttpClient.kt +++ b/app/src/main/java/com/etesync/syncadapter/HttpClient.kt @@ -29,7 +29,6 @@ import java.util.* import java.util.concurrent.TimeUnit import java.util.logging.Level import javax.net.ssl.* -import java.util.logging.Logger as LoggerType class HttpClient private constructor( val okHttpClient: OkHttpClient, @@ -58,7 +57,7 @@ class HttpClient private constructor( override fun close() { - okHttpClient.cache()?.close() + okHttpClient.cache?.close() certManager?.close() } @@ -76,8 +75,10 @@ class HttpClient private constructor( init { // add network logging, if requested if (logger.isLoggable(Level.FINEST)) { - val loggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { - message -> logger.finest(message) + val loggingInterceptor = HttpLoggingInterceptor(object: HttpLoggingInterceptor.Logger { + override fun log(message: String) { + logger.finest(message) + } }) loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY orig.addInterceptor(loggingInterceptor) @@ -163,7 +164,7 @@ class HttpClient private constructor( var request = chain.request() /* Only add to the host we want. */ - if (host == null || request.url().host() == host) { + if (host == null || request.url.host == host) { if (token != null && request.header(HEADER_AUTHORIZATION) == null) { request = request.newBuilder() .header(HEADER_AUTHORIZATION, "Token $token") @@ -186,8 +187,8 @@ class HttpClient private constructor( factory.trustManagers.first() as X509TrustManager }() - val hostnameVerifier = certManager?.hostnameVerifier(OkHostnameVerifier.INSTANCE) - ?: OkHostnameVerifier.INSTANCE + val hostnameVerifier = certManager?.hostnameVerifier(OkHostnameVerifier) + ?: OkHostnameVerifier var keyManager: KeyManager? = null certificateAlias?.let { alias -> diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/CalendarsSyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/CalendarsSyncAdapterService.kt index 930aab6e..c377a886 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/CalendarsSyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/CalendarsSyncAdapterService.kt @@ -22,7 +22,7 @@ import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.resource.LocalCalendar -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.util.* class CalendarsSyncAdapterService : SyncAdapterService() { @@ -44,7 +44,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() { updateLocalCalendars(provider, account, settings) - val principal = HttpUrl.get(settings.uri!!)!! + val principal = settings.uri?.toHttpUrlOrNull()!! for (calendar in AndroidCalendar.find(account, provider, LocalCalendar.Factory, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) { Logger.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name) diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncAdapterService.kt index 7f0467e0..52dda953 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncAdapterService.kt @@ -17,7 +17,7 @@ import com.etesync.syncadapter.InvalidAccountException import com.etesync.syncadapter.R import com.etesync.syncadapter.log.Logger import com.etesync.syncadapter.resource.LocalAddressBook -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class ContactsSyncAdapterService : SyncAdapterService() { @@ -52,7 +52,7 @@ class ContactsSyncAdapterService : SyncAdapterService() { Logger.log.info("Synchronizing address book: " + addressBook.url) Logger.log.info("Taking settings from: " + addressBook.mainAccount) - val principal = HttpUrl.get(settings.uri!!)!! + val principal = settings.uri?.toHttpUrlOrNull()!! ContactsSyncManager(context, account, settings, extras, authority, provider, syncResult, addressBook, principal).use { it.performSync() } diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncManager.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncManager.kt index 948abee3..8bc2a875 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncManager.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/ContactsSyncManager.kt @@ -16,20 +16,21 @@ import at.bitfire.ical4android.CalendarStorageException import at.bitfire.vcard4android.BatchOperation import at.bitfire.vcard4android.Contact import at.bitfire.vcard4android.ContactsStorageException +import com.etesync.journalmanager.Exceptions +import com.etesync.journalmanager.JournalEntryManager +import com.etesync.journalmanager.model.SyncEntry import com.etesync.syncadapter.AccountSettings import com.etesync.syncadapter.Constants import com.etesync.syncadapter.HttpClient import com.etesync.syncadapter.R -import com.etesync.journalmanager.Exceptions -import com.etesync.journalmanager.JournalEntryManager import com.etesync.syncadapter.log.Logger import com.etesync.syncadapter.model.CollectionInfo -import com.etesync.journalmanager.model.SyncEntry import com.etesync.syncadapter.resource.LocalAddress import com.etesync.syncadapter.resource.LocalAddressBook import com.etesync.syncadapter.resource.LocalContact import com.etesync.syncadapter.resource.LocalGroup import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.Request import org.apache.commons.collections4.SetUtils import java.io.FileNotFoundException @@ -215,14 +216,14 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra class ResourceDownloader(internal var context: Context) : Contact.Downloader { override fun download(url: String, accepts: String): ByteArray? { - val httpUrl = HttpUrl.parse(url) + val httpUrl = url.toHttpUrlOrNull() if (httpUrl == null) { Logger.log.log(Level.SEVERE, "Invalid external resource URL", url) return null } - val host = httpUrl.host() + val host = httpUrl.host if (host == null) { Logger.log.log(Level.SEVERE, "External resource URL doesn't specify a host name", url) return null @@ -236,7 +237,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra .url(httpUrl) .build()).execute() - val body = response.body() + val body = response.body if (body != null) { return body.bytes() } diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt index 2fbe353b..45c228d2 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt @@ -26,6 +26,7 @@ import com.etesync.syncadapter.* import com.etesync.journalmanager.Crypto import com.etesync.journalmanager.Exceptions import com.etesync.journalmanager.JournalManager +import com.etesync.syncadapter.* import com.etesync.syncadapter.log.Logger import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity @@ -33,7 +34,7 @@ import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.PermissionsActivity import com.etesync.syncadapter.utils.NotificationUtils -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.lang.Math.abs import java.util.* import java.util.logging.Level @@ -207,7 +208,7 @@ abstract class SyncAdapterService : Service() { val settings = AccountSettings(context, account) val httpClient = HttpClient.Builder(context, settings).setForeground(false).build() - val journalsManager = JournalManager(httpClient.okHttpClient, HttpUrl.get(settings.uri!!)!!) + val journalsManager = JournalManager(httpClient.okHttpClient, settings.uri?.toHttpUrlOrNull()!!) var journals = journalFetcher.list(journalsManager, settings, serviceType) diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/TasksSyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/TasksSyncAdapterService.kt index 28d6fdbc..313153c0 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/TasksSyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/TasksSyncAdapterService.kt @@ -27,7 +27,7 @@ import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.resource.LocalTaskList -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.dmfs.tasks.contract.TaskContract import java.util.* @@ -65,7 +65,7 @@ class TasksSyncAdapterService: SyncAdapterService() { updateLocalTaskLists(taskProvider, account, accountSettings) - val principal = HttpUrl.get(accountSettings.uri!!)!! + val principal = accountSettings.uri?.toHttpUrlOrNull()!! for (taskList in AndroidTaskList.find(account, taskProvider, LocalTaskList.Factory, "${TaskContract.TaskLists.SYNC_ENABLED}!=0", null)) { Logger.log.info("Synchronizing task list #${taskList.id} [${taskList.syncId}]") diff --git a/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt b/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt index 65df29bf..1cbf7b14 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt @@ -44,7 +44,7 @@ import com.etesync.syncadapter.utils.HintManager import com.etesync.syncadapter.utils.ShowcaseBuilder import com.etesync.syncadapter.utils.packageInstalled import com.google.android.material.snackbar.Snackbar -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.jetbrains.anko.doAsync import tourguide.tourguide.ToolTip import java.util.logging.Level @@ -438,7 +438,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe val accountManager = AccountManager.get(this) val settings = AccountSettings(this@AccountActivity, account) val authToken = settings.authToken - val principal = HttpUrl.get(settings.uri!!) + val principal = settings.uri?.toHttpUrlOrNull() doAsync { try { diff --git a/app/src/main/java/com/etesync/syncadapter/ui/AddMemberFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/AddMemberFragment.kt index d74a0964..0b585983 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/AddMemberFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/AddMemberFragment.kt @@ -18,6 +18,7 @@ import com.etesync.journalmanager.UserInfoManager import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class AddMemberFragment : DialogFragment() { private lateinit var account: Account @@ -42,7 +43,7 @@ class AddMemberFragment : DialogFragment() { e.printStackTrace() } - remote = HttpUrl.get(settings!!.uri!!) + remote = settings?.uri?.toHttpUrlOrNull()!! MemberAdd().execute() } diff --git a/app/src/main/java/com/etesync/syncadapter/ui/ChangeEncryptionPasswordActivity.kt b/app/src/main/java/com/etesync/syncadapter/ui/ChangeEncryptionPasswordActivity.kt index e43b7809..55c702ba 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/ChangeEncryptionPasswordActivity.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/ChangeEncryptionPasswordActivity.kt @@ -24,7 +24,7 @@ import com.etesync.journalmanager.UserInfoManager import com.etesync.syncadapter.log.Logger import com.etesync.syncadapter.syncadapter.requestSync import com.google.android.material.textfield.TextInputLayout -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.jetbrains.anko.doAsync import org.jetbrains.anko.uiThread import java.util.* @@ -70,7 +70,7 @@ open class ChangeEncryptionPasswordActivity : BaseActivity() { Logger.log.info("Finished deriving old key") var cryptoManager: Crypto.CryptoManager - val principal = HttpUrl.get(settings.uri!!)!! + val principal = settings.uri?.toHttpUrlOrNull()!! try { val userInfoManager = UserInfoManager(httpClient, principal) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt index c673da84..a8cc1e0e 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt @@ -17,7 +17,7 @@ import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.model.MyEntityDataStore -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.jetbrains.anko.doAsync import org.jetbrains.anko.uiThread import java.util.concurrent.Future @@ -54,7 +54,7 @@ class CollectionMembersListFragment : ListFragment(), AdapterView.OnItemClickLis try { val settings = AccountSettings(context!!, account) val httpClient = HttpClient.Builder(context, settings).build().okHttpClient - val journalsManager = JournalManager(httpClient, HttpUrl.get(settings.uri!!)!!) + val journalsManager = JournalManager(httpClient, settings.uri?.toHttpUrlOrNull()!!) val journal = JournalManager.Journal.fakeWithUid(journalEntity.uid) members = journalsManager.listMembers(journal) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/CreateCollectionFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/CreateCollectionFragment.kt index d543edb7..d61e4ba9 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/CreateCollectionFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/CreateCollectionFragment.kt @@ -27,7 +27,7 @@ import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.utils.TaskProviderHandling -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class CreateCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks { @@ -100,7 +100,7 @@ class CreateCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks info.serviceID = serviceEntity.id val settings = AccountSettings(context, account) - val principal = HttpUrl.get(settings.uri!!) + val principal = settings.uri?.toHttpUrlOrNull() val httpClient = HttpClient.Builder(context, settings).build().okHttpClient val journalManager = JournalManager(httpClient, principal!!) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/DeleteCollectionFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/DeleteCollectionFragment.kt index fbeded62..3c413ed8 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/DeleteCollectionFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/DeleteCollectionFragment.kt @@ -25,7 +25,7 @@ import com.etesync.journalmanager.Exceptions import com.etesync.journalmanager.JournalManager import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.JournalEntity -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class DeleteCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks { @@ -86,7 +86,7 @@ class DeleteCollectionFragment : DialogFragment(), LoaderManager.LoaderCallbacks val data = (context.applicationContext as App).data val settings = AccountSettings(context, account) - val principal = HttpUrl.get(settings.uri!!) + val principal = settings.uri?.toHttpUrlOrNull() val httpClient = HttpClient.Builder(context, settings).build().okHttpClient val journalManager = JournalManager(httpClient, principal!!) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/RemoveMemberFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/RemoveMemberFragment.kt index 89003650..16e62018 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/RemoveMemberFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/RemoveMemberFragment.kt @@ -10,7 +10,7 @@ import androidx.fragment.app.DialogFragment import com.etesync.syncadapter.* import com.etesync.journalmanager.JournalManager import com.etesync.syncadapter.model.CollectionInfo -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class RemoveMemberFragment : DialogFragment() { private var settings: AccountSettings? = null @@ -46,7 +46,7 @@ class RemoveMemberFragment : DialogFragment() { val httpClient = HttpClient.Builder(context, settings).build() try { - val remote = HttpUrl.get(settings!!.uri!!) + val remote = settings?.uri?.toHttpUrlOrNull() val journalsManager = JournalManager(httpClient.okHttpClient, remote!!) val journal = JournalManager.Journal.fakeWithUid(info!!.uid!!) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/setup/BaseConfigurationFinder.kt b/app/src/main/java/com/etesync/syncadapter/ui/setup/BaseConfigurationFinder.kt index 2f207938..6785e5e6 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/setup/BaseConfigurationFinder.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/setup/BaseConfigurationFinder.kt @@ -16,6 +16,7 @@ import com.etesync.journalmanager.UserInfoManager import com.etesync.syncadapter.log.Logger import com.etesync.syncadapter.model.CollectionInfo import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.OkHttpClient import java.io.IOException import java.io.Serializable @@ -35,7 +36,7 @@ class BaseConfigurationFinder(protected val context: Context, protected val cred val cardDavConfig = findInitialConfiguration(CollectionInfo.Type.ADDRESS_BOOK) val calDavConfig = findInitialConfiguration(CollectionInfo.Type.CALENDAR) - val authenticator = JournalAuthenticator(httpClient, HttpUrl.get(credentials.uri!!)!!) + val authenticator = JournalAuthenticator(httpClient, credentials.uri?.toHttpUrlOrNull()!!) var authtoken: String? = null var userInfo: UserInfoManager.UserInfo? = null @@ -43,7 +44,7 @@ class BaseConfigurationFinder(protected val context: Context, protected val cred authtoken = authenticator.getAuthToken(credentials.userName, credentials.password) val authenticatedHttpClient = HttpClient.Builder(context, credentials.uri.host, authtoken!!).build().okHttpClient - val userInfoManager = UserInfoManager(authenticatedHttpClient, HttpUrl.get(credentials.uri)!!) + val userInfoManager = UserInfoManager(authenticatedHttpClient, credentials.uri.toHttpUrlOrNull()!!) userInfo = userInfoManager.fetch(credentials.userName) } catch (e: Exceptions.HttpException) { Logger.log.warning(e.message) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/setup/LoginCredentialsFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/setup/LoginCredentialsFragment.kt index e5cff8ff..846b6f9d 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/setup/LoginCredentialsFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/setup/LoginCredentialsFragment.kt @@ -22,7 +22,7 @@ import com.etesync.syncadapter.R import com.etesync.syncadapter.ui.WebViewActivity import com.google.android.material.textfield.TextInputLayout import net.cachapa.expandablelayout.ExpandableLayout -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.net.URI class LoginCredentialsFragment : Fragment() { @@ -105,9 +105,9 @@ class LoginCredentialsFragment : Fragment() { val server = customServer.text.toString() // If this field is null, just use the default if (!server.isEmpty()) { - val url = HttpUrl.parse(server) + val url = server.toHttpUrlOrNull() if (url != null) { - uri = url.uri() + uri = url.toUri() } else { customServer.error = getString(R.string.login_custom_server_error) valid = false diff --git a/app/src/main/java/com/etesync/syncadapter/ui/setup/SetupUserInfoFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/setup/SetupUserInfoFragment.kt index b9599962..f1bd4bf2 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/setup/SetupUserInfoFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/setup/SetupUserInfoFragment.kt @@ -17,7 +17,7 @@ import com.etesync.journalmanager.Constants import com.etesync.journalmanager.Crypto import com.etesync.journalmanager.UserInfoManager import com.etesync.syncadapter.log.Logger -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull class SetupUserInfoFragment : DialogFragment() { private lateinit var account: Account @@ -53,7 +53,7 @@ class SetupUserInfoFragment : DialogFragment() { val cryptoManager: Crypto.CryptoManager val httpClient = HttpClient.Builder(context, settings).build().okHttpClient - val userInfoManager = UserInfoManager(httpClient, HttpUrl.get(settings.uri!!)!!) + val userInfoManager = UserInfoManager(httpClient, settings.uri?.toHttpUrlOrNull()!!) var userInfo: UserInfoManager.UserInfo? = userInfoManager.fetch(account.name) if (userInfo == null) {