Loading app/build.gradle.kts +5 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,8 @@ android { buildFeatures { buildConfig = true compose = true dataBinding = true viewBinding = true } // Java namespace for our classes (not to be confused with Android package ID) Loading Loading @@ -229,6 +231,7 @@ dependencies { // core implementation(libs.kotlin.stdlib) implementation(libs.kotlinx.coroutines) implementation(libs.material) coreLibraryDesugaring(libs.android.desugaring) // Hilt Loading @@ -251,6 +254,7 @@ dependencies { implementation(libs.androidx.preference) implementation(libs.androidx.security) implementation(libs.androidx.work.base) implementation(libs.fragment) // Jetpack Compose implementation(libs.compose.accompanist.permissions) Loading Loading @@ -295,6 +299,7 @@ dependencies { exclude(group="org.ogce", module="xpp3") exclude(group="com.squareup.okhttp3") } implementation(libs.elib) // for tests androidTestImplementation(libs.androidx.arch.core.testing) Loading app/src/androidTest/kotlin/at/bitfire/davdroid/ui/setup/LoginActivityTest.ktdeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line package at.bitfire.davdroid.ui.setup import android.content.Intent import android.net.Uri import org.junit.Assert.assertEquals import org.junit.Test class LoginActivityTest { @Test fun loginInfoFromIntent() { val intent = Intent().apply { data = Uri.parse("https://example.com/nextcloud") putExtra(LoginActivity.EXTRA_USERNAME, "user") putExtra(LoginActivity.EXTRA_PASSWORD, "password") } val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com/nextcloud", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_withPort() { val intent = Intent().apply { data = Uri.parse("https://example.com:444/nextcloud") putExtra(LoginActivity.EXTRA_USERNAME, "user") putExtra(LoginActivity.EXTRA_PASSWORD, "password") } val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com:444/nextcloud", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com/path")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com/path", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit_withPort() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com:0/path")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com:0/path", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit_email() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("mailto:user@example.com")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals(null, loginInfo.baseUri) assertEquals("user@example.com", loginInfo.credentials!!.username) assertEquals(null, loginInfo.credentials.password) } } No newline at end of file app/src/main/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ android:networkSecurityConfig="@xml/network_security_config" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" android:theme="@style/AppTheme" android:resizeableActivity="true" tools:ignore="UnusedAttribute" android:supportsRtl="true"> Loading app/src/main/kotlin/at/bitfire/davdroid/Constants.kt +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,17 @@ object Constants { val FEDIVERSE_HANDLE = "@davx5app@fosstodon.org" val FEDIVERSE_URL = "https://fosstodon.org/@davx5app".toUri() const val AUTH_TOKEN_TYPE = "oauth2-access-token" const val EELO_SYNC_HOST = "murena.io" const val E_SYNC_URL = "e.email" const val MURENA_DAV_URL = "https://murena.io/remote.php/dav" // NOTE: Android 7 and up don't allow 2 min sync frequencies unless system frameworks are modified const val DEFAULT_CALENDAR_SYNC_INTERVAL = 15 * 60L // 15 minutes const val DEFAULT_CONTACTS_SYNC_INTERVAL = 15 * 60L // 15 minutes /** * Appends query parameters for anonymized usage statistics (app ID, version). * Can be used by the called Website to get an idea of which versions etc. are currently used. Loading app/src/main/kotlin/at/bitfire/davdroid/ECloudAccountHelper.kt 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright ECORP SAS 2022 * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package at.bitfire.davdroid import android.accounts.AccountManager import android.app.Activity import android.content.Context import com.google.android.material.dialog.MaterialAlertDialogBuilder object ECloudAccountHelper { fun alreadyHasECloudAccount(context: Context) : Boolean { val accountManager = AccountManager.get(context) val eCloudAccounts = accountManager.getAccountsByType(context.getString(R.string.eelo_account_type)) return eCloudAccounts.isNotEmpty() } fun showMultipleECloudAccountNotAcceptedDialog(activity: Activity) { MaterialAlertDialogBuilder(activity, R.style.CustomAlertDialogStyle) .setIcon(R.drawable.ic_error) .setMessage(R.string.multiple_ecloud_account_not_permitted_message) .setCancelable(false) .setPositiveButton(android.R.string.ok) { _, _ -> activity.finish() } .show() } } No newline at end of file Loading
app/build.gradle.kts +5 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,8 @@ android { buildFeatures { buildConfig = true compose = true dataBinding = true viewBinding = true } // Java namespace for our classes (not to be confused with Android package ID) Loading Loading @@ -229,6 +231,7 @@ dependencies { // core implementation(libs.kotlin.stdlib) implementation(libs.kotlinx.coroutines) implementation(libs.material) coreLibraryDesugaring(libs.android.desugaring) // Hilt Loading @@ -251,6 +254,7 @@ dependencies { implementation(libs.androidx.preference) implementation(libs.androidx.security) implementation(libs.androidx.work.base) implementation(libs.fragment) // Jetpack Compose implementation(libs.compose.accompanist.permissions) Loading Loading @@ -295,6 +299,7 @@ dependencies { exclude(group="org.ogce", module="xpp3") exclude(group="com.squareup.okhttp3") } implementation(libs.elib) // for tests androidTestImplementation(libs.androidx.arch.core.testing) Loading
app/src/androidTest/kotlin/at/bitfire/davdroid/ui/setup/LoginActivityTest.ktdeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line package at.bitfire.davdroid.ui.setup import android.content.Intent import android.net.Uri import org.junit.Assert.assertEquals import org.junit.Test class LoginActivityTest { @Test fun loginInfoFromIntent() { val intent = Intent().apply { data = Uri.parse("https://example.com/nextcloud") putExtra(LoginActivity.EXTRA_USERNAME, "user") putExtra(LoginActivity.EXTRA_PASSWORD, "password") } val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com/nextcloud", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_withPort() { val intent = Intent().apply { data = Uri.parse("https://example.com:444/nextcloud") putExtra(LoginActivity.EXTRA_USERNAME, "user") putExtra(LoginActivity.EXTRA_PASSWORD, "password") } val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com:444/nextcloud", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com/path")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com/path", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit_withPort() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com:0/path")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals("https://example.com:0/path", loginInfo.baseUri.toString()) assertEquals("user", loginInfo.credentials!!.username) assertEquals("password", loginInfo.credentials.password) } @Test fun loginInfoFromIntent_implicit_email() { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("mailto:user@example.com")) val loginInfo = LoginActivity.loginInfoFromIntent(intent) assertEquals(null, loginInfo.baseUri) assertEquals("user@example.com", loginInfo.credentials!!.username) assertEquals(null, loginInfo.credentials.password) } } No newline at end of file
app/src/main/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ android:networkSecurityConfig="@xml/network_security_config" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" android:theme="@style/AppTheme" android:resizeableActivity="true" tools:ignore="UnusedAttribute" android:supportsRtl="true"> Loading
app/src/main/kotlin/at/bitfire/davdroid/Constants.kt +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,17 @@ object Constants { val FEDIVERSE_HANDLE = "@davx5app@fosstodon.org" val FEDIVERSE_URL = "https://fosstodon.org/@davx5app".toUri() const val AUTH_TOKEN_TYPE = "oauth2-access-token" const val EELO_SYNC_HOST = "murena.io" const val E_SYNC_URL = "e.email" const val MURENA_DAV_URL = "https://murena.io/remote.php/dav" // NOTE: Android 7 and up don't allow 2 min sync frequencies unless system frameworks are modified const val DEFAULT_CALENDAR_SYNC_INTERVAL = 15 * 60L // 15 minutes const val DEFAULT_CONTACTS_SYNC_INTERVAL = 15 * 60L // 15 minutes /** * Appends query parameters for anonymized usage statistics (app ID, version). * Can be used by the called Website to get an idea of which versions etc. are currently used. Loading
app/src/main/kotlin/at/bitfire/davdroid/ECloudAccountHelper.kt 0 → 100644 +42 −0 Original line number Diff line number Diff line /* * Copyright ECORP SAS 2022 * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package at.bitfire.davdroid import android.accounts.AccountManager import android.app.Activity import android.content.Context import com.google.android.material.dialog.MaterialAlertDialogBuilder object ECloudAccountHelper { fun alreadyHasECloudAccount(context: Context) : Boolean { val accountManager = AccountManager.get(context) val eCloudAccounts = accountManager.getAccountsByType(context.getString(R.string.eelo_account_type)) return eCloudAccounts.isNotEmpty() } fun showMultipleECloudAccountNotAcceptedDialog(activity: Activity) { MaterialAlertDialogBuilder(activity, R.style.CustomAlertDialogStyle) .setIcon(R.drawable.ic_error) .setMessage(R.string.multiple_ecloud_account_not_permitted_message) .setCancelable(false) .setPositiveButton(android.R.string.ok) { _, _ -> activity.finish() } .show() } } No newline at end of file