diff options
| author | David Göransson <david.goransson@mullvad.net> | 2024-10-08 16:09:13 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2024-10-08 16:09:13 +0200 |
| commit | 65bdbb5158242d80617dd9b40a9be33333831ce9 (patch) | |
| tree | ebf0bd03ecff93868b877657c0cad1b097b77e8e | |
| parent | a0086e992faf269a6819e1c593962d360ee052aa (diff) | |
| parent | 24df46bece887df0bd17af55399d69e8021e7d4e (diff) | |
| download | mullvadvpn-65bdbb5158242d80617dd9b40a9be33333831ce9.tar.xz mullvadvpn-65bdbb5158242d80617dd9b40a9be33333831ce9.zip | |
Merge branch 'fix-all-baselined-lint-issues-droid-218'
39 files changed, 237 insertions, 235 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 979eb466e2..4d5ab430ca 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -47,9 +47,9 @@ android { lint { lintConfig = file("${rootProject.projectDir}/config/lint.xml") - baseline = file("lint-baseline.xml") abortOnError = true warningsAsErrors = true + checkDependencies = true } } diff --git a/android/app/lint-baseline.xml b/android/app/lint-baseline.xml deleted file mode 100644 index 9f67e68efa..0000000000 --- a/android/app/lint-baseline.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.4.0" type="baseline" client="gradle" dependencies="false" name="AGP (8.4.0)" variant="all" version="8.4.0"> - - <issue - id="UseCheckPermission" - message="The result of `checkPermission` is not used" - errorLine1=" mockedPackageManager.checkPermission(internet, packageName)" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt" - line="88" - column="21"/> - </issue> - - <issue - id="DataExtractionRules" - message="The attribute `android:allowBackup` is deprecated from Android 12 and higher and may be removed in future versions. Consider adding the attribute `android:dataExtractionRules` specifying an `@xml` resource which configures cloud backups and device transfers on Android 12 and higher." - errorLine1=" android:allowBackup="false"" - errorLine2=" ~~~~~"> - <location - file="src/main/AndroidManifest.xml" - line="23" - column="39"/> - </issue> - - <issue - id="QueryAllPackagesPermission" - message="A `<queries>` declaration should generally be used instead of QUERY_ALL_PACKAGES; see https://g.co/dev/packagevisibility for details" - errorLine1=" <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/AndroidManifest.xml" - line="6" - column="22"/> - </issue> - -</issues> diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index cfe2c7c4df..f428b876c7 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -11,7 +11,7 @@ android:theme="@style/Theme.App.Starting" android:extractNativeLibs="true" android:allowBackup="false" - android:banner="@drawable/banner" + android:banner="@mipmap/ic_banner" android:name=".MullvadApplication" tools:ignore="DataExtractionRules,GoogleAppIndexingWarning"/> </manifest> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 8dc3c4e385..24c430f444 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -3,7 +3,10 @@ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> + <!-- Suppress warning, just using queries tag is not enough for our all, we need access to all + packages to allow the user to select apps for split tunneling --> + <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" + tools:ignore="QueryAllPackagesPermission" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- https://developer.android.com/guide/components/fg-service-types#system-exempted --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SYSTEM_EXEMPTED" /> @@ -20,9 +23,12 @@ android:required="false" /> <uses-feature android:glEsVersion="0x00020000" android:required="false" /> + <application android:name=".MullvadApplication" + android:banner="@mipmap/ic_banner" android:allowBackup="false" - android:banner="@drawable/banner" + android:fullBackupContent="@xml/full_backup_content" + android:dataExtractionRules="@xml/data_extraction_rules" android:extractNativeLibs="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt index a2485f2e99..df7d3dede0 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/notificationbanner/NotificationBanner.kt @@ -18,6 +18,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -118,23 +119,13 @@ private fun Notification(notificationBannerData: NotificationData) { .testTag(NOTIFICATION_BANNER) ) { val (status, textTitle, textMessage, actionIcon) = createRefs() - Box( - modifier = - Modifier.background( - color = - when (statusLevel) { - StatusLevel.Error -> MaterialTheme.colorScheme.error - StatusLevel.Warning -> MaterialTheme.colorScheme.warning - StatusLevel.Info -> MaterialTheme.colorScheme.surfaceContainer - }, - shape = CircleShape, - ) - .size(Dimens.notificationStatusIconSize) - .constrainAs(status) { - top.linkTo(textTitle.top) - start.linkTo(parent.start) - bottom.linkTo(textTitle.bottom) - } + NotificationDot( + statusLevel, + Modifier.constrainAs(status) { + top.linkTo(textTitle.top) + start.linkTo(parent.start) + bottom.linkTo(textTitle.bottom) + }, ) Text( text = title.uppercase(), @@ -173,24 +164,58 @@ private fun Notification(notificationBannerData: NotificationData) { ) } action?.let { - IconButton( + NotificationAction( + it.icon, + onClick = it.onClick, + contentDescription = it.contentDescription, modifier = Modifier.constrainAs(actionIcon) { - top.linkTo(parent.top) - end.linkTo(parent.end) - bottom.linkTo(parent.bottom) - } - .testTag(NOTIFICATION_BANNER_ACTION) - .padding(all = Dimens.notificationEndIconPadding), - onClick = it.onClick, - ) { - Icon( - modifier = Modifier.padding(Dimens.notificationIconPadding), - imageVector = it.icon, - contentDescription = it.contentDescription, - tint = MaterialTheme.colorScheme.onSurface, - ) - } + top.linkTo(parent.top) + end.linkTo(parent.end) + bottom.linkTo(parent.bottom) + }, + ) } } } + +@Composable +private fun NotificationDot(statusLevel: StatusLevel, modifier: Modifier) { + Box( + modifier = + modifier + .background( + color = + when (statusLevel) { + StatusLevel.Error -> MaterialTheme.colorScheme.error + StatusLevel.Warning -> MaterialTheme.colorScheme.warning + StatusLevel.Info -> MaterialTheme.colorScheme.surfaceContainer + }, + shape = CircleShape, + ) + .size(Dimens.notificationStatusIconSize) + ) +} + +@Composable +private fun NotificationAction( + imageVector: ImageVector, + contentDescription: String?, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + IconButton( + modifier = + modifier + .testTag(NOTIFICATION_BANNER_ACTION) + .padding(all = Dimens.notificationEndIconPadding), + onClick = onClick, + ) { + Icon( + modifier = Modifier.padding(Dimens.notificationIconPadding), + imageVector = imageVector, + contentDescription = contentDescription, + tint = MaterialTheme.colorScheme.onSurface, + ) + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt index 3d49a7afca..04f3c05a11 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt @@ -41,6 +41,7 @@ import net.mullvad.mullvadvpn.compose.textfield.CustomTextField import net.mullvad.mullvadvpn.compose.util.MAX_VOUCHER_LENGTH import net.mullvad.mullvadvpn.compose.util.vouchersVisualTransformation import net.mullvad.mullvadvpn.constant.VOUCHER_LENGTH +import net.mullvad.mullvadvpn.lib.model.DAYS_PER_VOUCHER_MONTH import net.mullvad.mullvadvpn.lib.model.RedeemVoucherError import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens @@ -162,18 +163,18 @@ fun RedeemVoucherDialog( val message = stringResource( R.string.added_to_your_account, - when (days) { - 0 -> { + when { + days == 0 -> { stringResource(R.string.less_than_one_day) } - in 1..59 -> { + days < 2 * DAYS_PER_VOUCHER_MONTH -> { pluralStringResource(id = R.plurals.days, count = days, days) } else -> { pluralStringResource( id = R.plurals.months, - count = days / 30, - days / 30, + count = days / DAYS_PER_VOUCHER_MONTH, + days / DAYS_PER_VOUCHER_MONTH, ) } }, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/extensions/ResourcesExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/extensions/ResourcesExtensions.kt index 11b41dd27a..9611897e76 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/extensions/ResourcesExtensions.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/extensions/ResourcesExtensions.kt @@ -2,20 +2,20 @@ package net.mullvad.mullvadvpn.compose.extensions import android.content.res.Resources import net.mullvad.mullvadvpn.R -import org.joda.time.DateTime import org.joda.time.Duration -import org.joda.time.Period + +private const val DAYS_IN_STANDARD_YEAR = 365 fun Resources.getExpiryQuantityString(accountExpiry: Duration): String { - val expiryPeriod = Period(DateTime.now(), accountExpiry) + val days = accountExpiry.standardDays.toInt() + val years = (accountExpiry.standardDays / DAYS_IN_STANDARD_YEAR).toInt() + return if (accountExpiry.millis <= 0) { getString(R.string.out_of_time) - } else if (expiryPeriod.years > 0) { - getRemainingText(this, R.plurals.years_left, expiryPeriod.years) - } else if (expiryPeriod.months >= 3) { - getRemainingText(this, R.plurals.months_left, expiryPeriod.months) - } else if (expiryPeriod.months > 0 || expiryPeriod.days >= 1) { - getRemainingText(this, R.plurals.days_left, expiryPeriod.days) + } else if (years > 1) { + getRemainingText(this, R.plurals.years_left, years) + } else if (days >= 1) { + getRemainingText(this, R.plurals.days_left, days) } else { getString(R.string.less_than_a_day_left) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt index 9dcd016767..7a3d338022 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt @@ -94,6 +94,9 @@ private fun PreviewLoginScreen( AppTheme { LoginScreen(state = state) } } +private const val TOP_SPACER_WEIGHT = 1f +private const val BOTTOM_SPACER_WEIGHT = 3f + @Destination<RootGraph>(style = LoginTransition::class) @Composable fun Login( @@ -177,7 +180,7 @@ private fun LoginScreen( .background(MaterialTheme.colorScheme.primary) .verticalScroll(scrollState) ) { - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(TOP_SPACER_WEIGHT)) LoginIcon( state.loginState, modifier = @@ -185,7 +188,7 @@ private fun LoginScreen( .padding(bottom = Dimens.largePadding), ) LoginContent(state, onAccountNumberChange, onLoginClick, onDeleteHistoryClick) - Spacer(modifier = Modifier.weight(3f)) + Spacer(modifier = Modifier.weight(BOTTOM_SPACER_WEIGHT)) CreateAccountPanel(onCreateAccountClick, isEnabled = state.loginState is Idle) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt index b64de576ee..5bdcc961e7 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt @@ -13,7 +13,6 @@ import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -23,8 +22,6 @@ import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.constant.EMPTY_STRING import net.mullvad.mullvadvpn.constant.NEWLINE_STRING @@ -53,9 +50,6 @@ fun CustomTextField( imeAction = ImeAction.Done, ), ) { - - val scope = rememberCoroutineScope() - // This is the same implementation as in BasicTextField.kt but with initial selection set at the // end of the text rather than in the beginning. // This is a fix for https://issuetracker.google.com/issues/272693535. @@ -97,16 +91,7 @@ fun CustomTextField( singleLine = true, placeholder = placeholderText?.let { { Text(text = it) } }, keyboardOptions = keyboardOptions, - keyboardActions = - KeyboardActions( - onDone = { - scope.launch { - // https://issuetracker.google.com/issues/305518328 - delay(100) - onSubmit(value) - } - } - ), + keyboardActions = KeyboardActions(onDone = { onSubmit(value) }), visualTransformation = visualTransformation, colors = colors, isError = !isValidValue, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditApiAccessMethodViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditApiAccessMethodViewModel.kt index 4d85ae9868..48e4ac85ac 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditApiAccessMethodViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/EditApiAccessMethodViewModel.kt @@ -38,6 +38,7 @@ import net.mullvad.mullvadvpn.repository.ApiAccessRepository import net.mullvad.mullvadvpn.util.delayAtLeast import org.apache.commons.validator.routines.InetAddressValidator +@Suppress("TooManyFunctions") class EditApiAccessMethodViewModel( private val apiAccessRepository: ApiAccessRepository, private val inetAddressValidator: InetAddressValidator, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt index c34b182aa6..4ddad8477b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt @@ -43,6 +43,7 @@ import net.mullvad.mullvadvpn.usecase.customlists.CustomListActionUseCase import net.mullvad.mullvadvpn.usecase.customlists.CustomListsRelayItemUseCase import net.mullvad.mullvadvpn.usecase.customlists.FilterCustomListsRelayItemUseCase +@Suppress("TooManyFunctions") class SelectLocationViewModel( private val relayListFilterRepository: RelayListFilterRepository, private val availableProvidersUseCase: AvailableProvidersUseCase, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt index 7829d0ce24..5ca136341e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt @@ -43,6 +43,7 @@ sealed interface VpnSettingsSideEffect { data object NavigateToDnsDialog : VpnSettingsSideEffect } +@Suppress("TooManyFunctions") class VpnSettingsViewModel( private val repository: SettingsRepository, private val relayListRepository: RelayListRepository, diff --git a/android/app/src/main/res/xml/data_extraction_rules.xml b/android/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000000..b762ef705c --- /dev/null +++ b/android/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Sample data extraction rules file; uncomment and customize as necessary. + See https://developer.android.com/about/versions/12/backup-restore#xml-changes + for details. +--> +<data-extraction-rules> + <cloud-backup> + <exclude domain="root" /> + <exclude domain="file" /> + <exclude domain="database" /> + <exclude domain="sharedpref" /> + <exclude domain="external" /> + </cloud-backup> + <device-transfer> + <exclude domain="root" /> + <exclude domain="file" /> + <exclude domain="database" /> + <exclude domain="sharedpref" /> + <exclude domain="external" /> + </device-transfer> +</data-extraction-rules> diff --git a/android/app/src/main/res/xml/full_backup_content.xml b/android/app/src/main/res/xml/full_backup_content.xml new file mode 100644 index 0000000000..e88e6597d9 --- /dev/null +++ b/android/app/src/main/res/xml/full_backup_content.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Full backup content file + See https://developer.android.com/guide/topics/manifest/application-element#fullBackupContent + for details. +--> +<full-backup-content> + <exclude domain="file" /> + <exclude domain="database" /> + <exclude domain="sharedpref" /> + <exclude domain="external" /> + <exclude domain="root" /> + <exclude domain="device_file" /> + <exclude domain="device_database" /> + <exclude domain="device_sharedpref" /> + <exclude domain="device_root" /> +</full-backup-content> diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt index 560dafb24a..efa97c6ab0 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt @@ -1,6 +1,7 @@ package net.mullvad.mullvadvpn.applist import android.Manifest +import android.annotation.SuppressLint import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import io.mockk.every @@ -22,6 +23,7 @@ class ApplicationsProviderTest { unmockkAll() } + @SuppressLint("UseCheckPermission") @Test fun `fetch all apps should work`() { val launchWithInternetPackageName = "launch_with_internet_package_name" @@ -75,6 +77,7 @@ class ApplicationsProviderTest { verifyAll { mockedPackageManager.getInstalledApplications(PackageManager.GET_META_DATA) + // Ensure checkPermission was invoked on all packages listOf( launchWithInternetPackageName, launchWithoutInternetPackageName, diff --git a/android/build.gradle.kts b/android/build.gradle.kts index f62e00c87e..24bcb0e4d0 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -71,7 +71,6 @@ buildscript { } } -val baselineFile = file("$rootDir/config/baseline.xml") val configFile = files("$rootDir/config/detekt.yml") val projectSource = file(projectDir) @@ -82,7 +81,6 @@ detekt { allRules = false config.setFrom(configFile) source.setFrom(projectSource) - baseline = baselineFile parallel = true ignoreFailures = false autoCorrect = true diff --git a/android/config/baseline.xml b/android/config/baseline.xml deleted file mode 100644 index 34abe7b924..0000000000 --- a/android/config/baseline.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" ?> -<SmellBaseline> - <ManuallySuppressedIssues></ManuallySuppressedIssues> - <CurrentIssues> - <ID>CyclomaticComplexMethod:MockApiDispatcher.kt$MockApiDispatcher$override fun dispatch(request: RecordedRequest): MockResponse</ID> - <ID>EmptyKtFile:build.gradle.kts$.build.gradle.kts</ID> - <ID>LongMethod:NotificationBanner.kt$@Composable private fun Notification(notificationBannerData: NotificationData)</ID> - <ID>MagicNumber:CustomTextField.kt$100</ID> - <ID>MagicNumber:LoginScreen.kt$3f</ID> - <ID>MagicNumber:RedeemVoucherDialog.kt$30</ID> - <ID>MagicNumber:RedeemVoucherDialog.kt$59</ID> - <ID>MagicNumber:ResourcesExtensions.kt$3</ID> - <ID>NestedBlockDepth:MockApiDispatcher.kt$MockApiDispatcher$override fun dispatch(request: RecordedRequest): MockResponse</ID> - <ID>PrintStackTrace:Extensions.kt$ex</ID> - <ID>ReturnCount:RelayNameComparator.kt$RelayNameComparator$private infix fun List<String>.compareWith(other: List<String>): Int</ID> - <ID>ReturnCount:TalpidVpnService.kt$TalpidVpnService$private fun createTun(config: TunConfig): CreateTunResult</ID> - <ID>TooManyFunctions:EditApiAccessMethodViewModel.kt$EditApiAccessMethodViewModel : ViewModel</ID> - <ID>TooManyFunctions:SelectLocationViewModel.kt$SelectLocationViewModel : ViewModel</ID> - <ID>TooManyFunctions:VpnSettingsViewModel.kt$VpnSettingsViewModel : ViewModel</ID> - <ID>UnusedParameter:SimpleMullvadHttpClient.kt$SimpleMullvadHttpClient$body: JSONArray? = null</ID> - <ID>UnusedPrivateMember:ConnectivityListener.kt$ConnectivityListener$private fun finalize()</ID> - </CurrentIssues> -</SmellBaseline> diff --git a/android/lib/build.gradle.kts b/android/lib/build.gradle.kts deleted file mode 100644 index 8b13789179..0000000000 --- a/android/lib/build.gradle.kts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/android/lib/common/src/main/AndroidManifest.xml b/android/lib/common/src/main/AndroidManifest.xml index acaad2f3b4..cc947c5679 100644 --- a/android/lib/common/src/main/AndroidManifest.xml +++ b/android/lib/common/src/main/AndroidManifest.xml @@ -1,4 +1 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"> - <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /> -</manifest> +<manifest /> diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/RelayNameComparator.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/RelayNameComparator.kt index a1b1d3b092..4b848dde7b 100644 --- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/RelayNameComparator.kt +++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/RelayNameComparator.kt @@ -6,28 +6,32 @@ internal object RelayNameComparator : Comparator<RelayItem.Location.Relay> { override fun compare(o1: RelayItem.Location.Relay, o2: RelayItem.Location.Relay): Int { val partitions1 = o1.name.split(regex) val partitions2 = o2.name.split(regex) - return if (partitions1.size > partitions2.size) partitions1 compareWith partitions2 - else -(partitions2 compareWith partitions1) - } - private infix fun List<String>.compareWith(other: List<String>): Int { - this.forEachIndexed { index, s -> - if (other.size <= index) return 1 - val partsCompareResult = compareStringOrInt(other[index], s) - if (partsCompareResult != 0) return partsCompareResult - } - return 0 + partitions1 + .zip(partitions2) + .map { (p1, p2) -> compareStringOrInt(p1, p2) } + .forEach { + if (it != 0) { + // Parts differed, return compare result + return it + } + } + return partitions1.size.compareTo(partitions2.size) } - private fun compareStringOrInt(s1: String, s2: String): Int { - val int1 = s1.toIntOrNull() - val int2 = s2.toIntOrNull() - return if (int1 == null || int2 == null || int1 == int2) { - s2.compareTo(s1) + private fun compareStringOrInt(p1: String, p2: String): Int { + val int1 = p1.toIntOrNull() + val int2 = p2.toIntOrNull() + return if (int1 is Int && int2 is Int && int1 != int2) { + // If both are Int and not equal (they might have leading zeros) we should compare them + // as numbers + int1.compareTo(int2) } else { - int2.compareTo(int1) + p1.compareTo(p2) } } + // Regexp that splits digit and non digit, e.g se-got-wg-101 would be ["se-got-wg-", "101"] so + // that the number later can be sorted, e.g 9 being listed before 10. private val regex = "(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)".toRegex() } diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/VoucherConstant.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/VoucherConstant.kt new file mode 100644 index 0000000000..a27efa6bf3 --- /dev/null +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/VoucherConstant.kt @@ -0,0 +1,3 @@ +package net.mullvad.mullvadvpn.lib.model + +const val DAYS_PER_VOUCHER_MONTH = 30 diff --git a/android/lib/resource/build.gradle.kts b/android/lib/resource/build.gradle.kts index c162b25a0c..fa9cd5d63e 100644 --- a/android/lib/resource/build.gradle.kts +++ b/android/lib/resource/build.gradle.kts @@ -23,7 +23,6 @@ android { lint { lintConfig = file("lint.xml") - baseline = file("lint-baseline.xml") abortOnError = true warningsAsErrors = true } diff --git a/android/lib/resource/lint-baseline.xml b/android/lib/resource/lint-baseline.xml deleted file mode 100644 index d46970e0db..0000000000 --- a/android/lib/resource/lint-baseline.xml +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.1.4" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.4)" variant="all" version="8.1.4"> - - <issue - id="ObsoleteSdkInt" - message="This folder configuration (`v26`) is unnecessary; `minSdkVersion` is 26. Merge all the resources in this folder into `mipmap-anydpi`."> - <location - file="src/main/res/mipmap-anydpi-v26"/> - </issue> - - <issue - id="VectorPath" - message="Very long vector path (917 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector." - errorLine1=" <path android:fillColor="#FF294D73"" - errorLine2=" ~~~~~~~~~"> - <location - file="src/main/res/drawable/account_history_remove_pressed.xml" - line="7" - column="30"/> - </issue> - - <issue - id="VectorPath" - message="Very long vector path (1165 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector." - errorLine1=" <path android:pathData="M74.2,74.5c-8,10.3 -29,11.9 -38.3,0.4c-0.2,-0.9 1.9,-2.5 3.2,-4.3c0.6,-0.9 1.2,-1.8 1.6,-2.7c0.6,-1.7 -0.6,-1.6 -1.4,-3.1c-0.1,-0.3 -0.3,-0.6 -0.1,-0.9c0.2,-0.6 1.1,-1 1.3,-0.9c3.9,2.6 11.3,1.8 15.8,-3.4c0,0 1.4,0.3 2.1,0.5l-2.1,-1.4l-0.1,-0.1c-0.1,0.1 -0.2,0.1 -0.3,0.2c-9.4,7.1 -15.5,4.1 -15.5,4.1c-0.2,-0.2 -0.8,-0.8 -1.3,-1.2c-6.4,-4.5 -10.9,-10.5 -13,-14.4l-0.8,4.1l0.2,-5.5l-2.7,3.8l2,-4.1c-1.5,-0.2 -2.4,-1.7 -2,-2.9c0.3,-1.3 1.9,-2.2 3.3,-1.6l0.9,-4l-0.2,4.3c0,0 0.2,0.1 0.4,0.1l2.8,-3.4l-1.9,3.3c3,-0.6 8,-0.7 13.3,-0.3l5.5,2.7c2.7,2.4 6.4,5.5 10.5,8.1L67.9,56l1.3,1.9h-1.1l2.3,2.8l-2.1,-0.3c0,0.2 2.1,2.6 2.1,2.6l-1.7,0.2c0.1,0.2 1.7,2.3 1.7,2.3l-1.3,-0.1c0.1,0.3 2,3.5 2,3.5s-0.7,-0.2 -1.1,-0.3C71.7,72.3 74.1,73 74.2,74.5zM72.8,46.2c-0.8,2.5 -3.7,6 -2.6,8.7c-0.4,-0.1 -9.4,-3.1 -11.9,-4.5c-4,-2.5 -7.6,-5.6 -10.3,-8l-0.1,-0.1L38.6,38c-0.1,-0.1 -0.2,-0.1 -0.3,-0.2c1.3,0.1 6.3,0.7 8.5,0.2c-0.4,-1.2 -0.3,-2.7 0.3,-4.1c0.9,-2 2.5,-3.3 4,-3.3c0.3,0 0.6,0.1 0.9,0.2c0.9,-0.8 1.9,-1.5 3.1,-1.9c6.3,-2.5 15.5,2 17.9,8.1C74.1,40 73.8,43.2 72.8,46.2zM52,31.6c-1.4,-0.6 -3.2,0.5 -4,2.6c-0.9,2 -0.5,4.1 0.9,4.7c1.3,0.6 3.2,-0.5 4,-2.6C53.7,34.3 53.3,32.1 52,31.6z"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/drawable/icon_android_mono.xml" - line="6" - column="29"/> - </issue> - - <issue - id="VectorPath" - message="Very long vector path (917 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector." - errorLine1=" <path android:fillColor="#99FFFFFF"" - errorLine2=" ~~~~~~~~~"> - <location - file="src/main/res/drawable/icon_close.xml" - line="7" - column="30"/> - </issue> - - <issue - id="VectorPath" - message="Very long vector path (1161 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector." - errorLine1=" <path android:pathData="M21.2552,12C21.2552,12.408 21.2182,12.792 21.1688,13.176L23.7719,15.156C24.0063,15.336 24.068,15.66 23.9199,15.924L21.4526,20.076C21.3045,20.34 20.9838,20.448 20.7001,20.34L17.6282,19.14C16.9867,19.608 16.2959,20.016 15.5433,20.316L15.0745,23.496C15.0375,23.784 14.7785,24 14.4701,24L9.5354,24C9.227,24 8.9679,23.784 8.9309,23.496L8.4621,20.316C7.7096,20.016 7.0187,19.62 6.3772,19.14L3.3054,20.34C3.034,20.436 2.7009,20.34 2.5529,20.076L0.0855,15.924C-0.0625,15.66 -0.0008,15.336 0.2336,15.156L2.8366,13.176C2.7873,12.792 2.7502,12.396 2.7502,12C2.7502,11.604 2.7873,11.208 2.8366,10.824L0.2336,8.844C-0.0008,8.664 -0.0748,8.34 0.0855,8.076L2.5529,3.924C2.7009,3.66 3.0217,3.552 3.3054,3.66L6.3772,4.86C7.0187,4.392 7.7096,3.984 8.4621,3.684L8.9309,0.504C8.9679,0.216 9.227,0 9.5354,0L14.4701,0C14.7785,0 15.0375,0.216 15.0745,0.504L15.5433,3.684C16.2959,3.984 16.9867,4.38 17.6282,4.86L20.7001,3.66C20.9715,3.564 21.3046,3.66 21.4526,3.924L23.9199,8.076C24.068,8.34 24.0063,8.664 23.7719,8.844L21.1688,10.824C21.2182,11.208 21.2552,11.592 21.2552,12ZM12,17C14.7571,17 17,14.7571 17,12C17,9.2429 14.7571,7 12,7C9.2429,7 7,9.2429 7,12C7,14.7571 9.2429,17 12,17Z"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/drawable/icon_settings.xml" - line="6" - column="29"/> - </issue> - - <issue - id="IconDensities" - message="Missing the following drawables in `drawable-hdpi`: banner.png (found in drawable-xhdpi)"> - <location - file="src/main/res/drawable-hdpi"/> - </issue> - - <issue - id="IconDensities" - message="Missing the following drawables in `drawable-mdpi`: banner.png (found in drawable-xhdpi)"> - <location - file="src/main/res/drawable-mdpi"/> - </issue> - - <issue - id="IconDensities" - message="Missing the following drawables in `drawable-xxhdpi`: banner.png (found in drawable-xhdpi)"> - <location - file="src/main/res/drawable-xxhdpi"/> - </issue> - -</issues> diff --git a/android/lib/resource/src/main/res/drawable-xhdpi/banner.png b/android/lib/resource/src/main/res/drawable-xhdpi/banner.png Binary files differdeleted file mode 100644 index da8eee678d..0000000000 --- a/android/lib/resource/src/main/res/drawable-xhdpi/banner.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/drawable/ic_banner_foreground.xml b/android/lib/resource/src/main/res/drawable/ic_banner_foreground.xml new file mode 100644 index 0000000000..0e542f5c0d --- /dev/null +++ b/android/lib/resource/src/main/res/drawable/ic_banner_foreground.xml @@ -0,0 +1,62 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:width="320dp" + android:height="180dp" + android:viewportWidth="640" + android:viewportHeight="360" + tools:ignore="VectorRaster"> + <group android:scaleX="0.6666667" + android:scaleY="0.6666667" + android:translateX="106.666664" + android:translateY="60"> + <path + android:pathData="M55,233.34C55,232.84 55.33,232.51 55.83,232.51H65.66C66.32,232.51 66.76,232.73 66.98,233.34L81.22,265.62H81.56L95.52,233.34C95.74,232.79 96.19,232.51 96.85,232.51H106.51C107.01,232.51 107.34,232.84 107.34,233.34V288.29C107.34,288.78 107.01,289.11 106.51,289.11H97.12C96.63,289.11 96.3,288.78 96.3,288.29V256.45H95.96L85.53,280.33C85.2,281.1 84.7,281.43 83.98,281.43H78.3C77.58,281.43 77.08,281.1 76.75,280.33L66.32,256.45H65.99V288.29C65.99,288.78 65.66,289.11 65.16,289.11H55.83C55.33,289.11 55,288.78 55,288.29V233.34Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M119.65,268.28V233.34C119.65,232.84 119.98,232.51 120.48,232.51H130.97C131.46,232.51 131.79,232.84 131.79,233.34V268.61C131.79,275.3 135.55,279.17 141.24,279.17C146.87,279.17 150.57,275.35 150.57,268.61V233.34C150.57,232.84 150.9,232.51 151.39,232.51H161.88C162.38,232.51 162.71,232.84 162.71,233.34V268.28C162.71,282.32 153.77,290 141.18,290C128.59,290.05 119.65,282.37 119.65,268.28Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M174.97,233.34C174.97,232.84 175.3,232.51 175.8,232.51H186.29C186.78,232.51 187.11,232.84 187.11,233.34V277.67C187.11,278.01 187.28,278.17 187.61,278.17H212.45C212.95,278.17 213.28,278.5 213.28,279V288.23C213.28,288.73 212.95,289.06 212.45,289.06H175.8C175.3,289.06 174.97,288.73 174.97,288.23V233.34Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M222.28,233.34C222.28,232.84 222.61,232.51 223.11,232.51H233.6C234.1,232.51 234.43,232.84 234.43,233.34V277.67C234.43,278.01 234.59,278.17 234.92,278.17H259.77C260.27,278.17 260.6,278.5 260.6,279V288.23C260.6,288.73 260.27,289.06 259.77,289.06H223.11C222.61,289.06 222.28,288.73 222.28,288.23V233.34Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M277.93,289.06C277.38,289.06 277.05,288.73 276.88,288.23L258.99,233.4C258.83,232.79 259.16,232.51 259.71,232.51H270.48C271.03,232.51 271.42,232.73 271.58,233.34L282.85,270.49H283.07L294,233.34C294.16,232.79 294.49,232.51 295.05,232.51H305.7C306.2,232.51 306.53,232.84 306.36,233.4L288.48,288.23C288.31,288.73 287.98,289.06 287.48,289.06H277.93Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M326.29,233.34C326.46,232.84 326.79,232.51 327.4,232.51H337.83C338.38,232.51 338.72,232.84 338.88,233.34L357.93,288.29C358.09,288.78 357.93,289.11 357.38,289.11H346.61C346.06,289.11 345.67,288.84 345.51,288.29L342.3,278.39H322.6L319.45,288.29C319.28,288.84 318.95,289.11 318.34,289.11H307.52C306.97,289.11 306.8,288.78 306.97,288.29L326.29,233.34ZM338.94,267.94L332.59,248.16H332.37L326.02,267.94H338.94Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M366.15,233.34C366.15,232.84 366.48,232.51 366.98,232.51H387.91C397.73,232.51 404.63,236.71 407.34,245.23C408.33,248.38 408.83,251.53 408.83,260.76C408.83,269.99 408.33,273.14 407.34,276.29C404.63,284.8 397.73,289.01 387.91,289.01H366.98C366.48,289.01 366.15,288.67 366.15,288.18V233.34ZM378.85,278.23H385.2C390.83,278.23 394.2,276.57 395.64,272.04C396.19,270.38 396.57,268.22 396.57,260.87C396.57,253.52 396.24,251.36 395.64,249.7C394.26,245.17 390.83,243.51 385.2,243.51H378.85C378.52,243.51 378.36,243.68 378.36,244.01V277.78C378.3,278.06 378.47,278.23 378.85,278.23Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M453.27,289.06C452.67,289.06 452.33,288.73 452.17,288.23L434.28,233.4C434.12,232.79 434.45,232.51 435,232.51H445.77C446.32,232.51 446.7,232.73 446.87,233.34L458.13,270.49H458.35L469.28,233.34C469.45,232.79 469.78,232.51 470.33,232.51H480.99C481.48,232.51 481.82,232.84 481.65,233.4L463.87,288.23C463.71,288.73 463.38,289.06 462.88,289.06H453.27Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M490.59,289.11C490.1,289.11 489.77,288.78 489.77,288.29V233.34C489.77,232.84 490.1,232.51 490.59,232.51H512.46C524.71,232.51 532.05,239.92 532.05,250.7C532.05,261.37 524.6,268.83 512.46,268.83H502.46C502.13,268.83 501.97,268.99 501.97,269.33V288.18C501.97,288.67 501.64,289.01 501.14,289.01H490.59V289.11ZM519.85,250.75C519.85,246.22 516.82,243.07 511.68,243.07H502.41C502.08,243.07 501.91,243.24 501.91,243.57V257.77C501.91,258.11 502.08,258.27 502.41,258.27H511.68C516.82,258.33 519.85,255.34 519.85,250.75Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M541.55,233.34C541.55,232.84 541.88,232.51 542.38,232.51H552.32C552.87,232.51 553.42,232.73 553.7,233.34L573.57,268.94H574.01V233.34C574.01,232.84 574.34,232.51 574.84,232.51H584.17C584.67,232.51 585,232.84 585,233.34V288.29C585,288.78 584.67,289.11 584.17,289.11H574.34C573.68,289.11 573.24,288.84 572.97,288.29L553.03,252.8H552.59V288.29C552.59,288.78 552.26,289.11 551.77,289.11H542.43C541.94,289.11 541.61,288.78 541.61,288.29L541.55,233.34Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M263.63,123.4L259.71,131.36L265.,123.95C265.01,124 264.68,134.62 264.68,134.62L266.17,126.6C270.15,134.18 278.92,145.84 291.24,154.52C292.17,155.18 293.39,156.34 293.78,156.78C293.78,156.78 305.54,162.75 323.64,148.93C323.81,148.82 324.03,148.71 324.2,148.6L324.47,148.77L328.45,151.42C327.07,151.04 324.42,150.37 324.42,150.37C315.69,160.43 301.51,162.09 293.89,157.01C293.55,156.78 291.68,157.56 291.35,158.66C291.13,159.27 291.35,159.93 291.62,160.43C293.17,163.31 295.49,163.03 294.38,166.4C293.61,168.23 292.51,169.99 291.29,171.65C288.75,175.08 284.78,178.12 285.16,179.95C303.16,202.17 343.74,199.07 359.2,179.23C358.98,176.35 354.45,174.97 351.3,167.95C352.19,168.23 353.51,168.61 353.51,168.56C353.51,168.5 349.76,162.42 349.59,161.81L352.02,161.98C352.02,161.98 348.82,158 348.71,157.61L351.97,157.17C351.97,157.17 347.88,152.47 347.83,152.09L351.97,152.75L347.44,147.28H349.59L347.05,143.57L326.46,135.45C318.57,130.53 311.55,124.5 306.25,119.86L295.6,114.66C285.38,113.89 275.83,114.17 269.98,115.33L273.73,108.92L268.27,115.44C267.94,115.33 267.55,115.22 267.55,115.22L267.94,106.93L266.12,114.66L263.63,123.4Z" + android:fillColor="#D2943B" + android:fillType="evenOdd" + tools:ignore="VectorPath" /> + <path + android:pathData="M266.12,114.66C263.41,113.39 260.27,115.22 259.71,117.7C259.05,120.08 260.71,123.01 263.63,123.4C266.39,121.68 268.77,117.26 266.12,114.66Z" + android:fillColor="#FFCD86" + android:fillType="evenOdd"/> + <path + android:pathData="M306.31,108.64C305.48,106.37 305.7,103.44 306.86,100.68C308.52,96.86 311.66,94.32 314.64,94.32C315.25,94.32 315.8,94.43 316.36,94.65C318.07,93.11 320.05,91.83 322.26,90.95C334.41,86.09 352.24,94.76 356.82,106.7C359.03,112.51 358.37,118.81 356.49,124.61C354.95,129.37 349.32,136.22 351.41,141.36C350.58,141.14 333.3,135.28 328.34,132.63C320.55,127.76 313.6,121.79 308.35,117.21L308.18,117.04L290.52,108.64C290.3,108.53 290.08,108.42 289.91,108.31C292.34,108.42 302,109.58 306.31,108.64Z" + android:fillColor="#FFD524" + android:fillType="evenOdd"/> + <path + android:pathData="M317.35,105.18C319.02,101.38 318.53,97.49 316.27,96.5C314,95.51 310.82,97.79 309.16,101.6C307.5,105.4 307.98,109.29 310.25,110.28C312.51,111.27 315.69,108.99 317.35,105.18Z" + android:fillColor="#ffffff"/> + <path + android:pathData="M316.74,95.48C313.82,94.21 309.9,96.7 307.96,101.07C306.03,105.43 306.92,109.96 309.84,111.29C312.77,112.56 316.69,110.07 318.62,105.71C320.55,101.34 319.67,96.81 316.74,95.48ZM317.02,105.04C315.47,108.53 312.55,110.63 310.5,109.74C308.41,108.8 307.96,105.27 309.51,101.73C311.06,98.25 313.98,96.15 316.08,97.03C318.12,97.97 318.57,101.56 317.02,105.04Z" + android:fillColor="#192E45"/> + </group> +</vector> diff --git a/android/lib/resource/src/main/res/drawable/icon_android_mono.xml b/android/lib/resource/src/main/res/drawable/icon_android_mono.xml index 0d0aa38c12..45e0acfdd5 100644 --- a/android/lib/resource/src/main/res/drawable/icon_android_mono.xml +++ b/android/lib/resource/src/main/res/drawable/icon_android_mono.xml @@ -1,9 +1,11 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="108dp" + xmlns:tools="http://schemas.android.com/tools" + android:width="108dp" android:height="108dp" android:viewportWidth="108" android:viewportHeight="108"> <path android:pathData="M74.2,74.5c-8,10.3 -29,11.9 -38.3,0.4c-0.2,-0.9 1.9,-2.5 3.2,-4.3c0.6,-0.9 1.2,-1.8 1.6,-2.7c0.6,-1.7 -0.6,-1.6 -1.4,-3.1c-0.1,-0.3 -0.3,-0.6 -0.1,-0.9c0.2,-0.6 1.1,-1 1.3,-0.9c3.9,2.6 11.3,1.8 15.8,-3.4c0,0 1.4,0.3 2.1,0.5l-2.1,-1.4l-0.1,-0.1c-0.1,0.1 -0.2,0.1 -0.3,0.2c-9.4,7.1 -15.5,4.1 -15.5,4.1c-0.2,-0.2 -0.8,-0.8 -1.3,-1.2c-6.4,-4.5 -10.9,-10.5 -13,-14.4l-0.8,4.1l0.2,-5.5l-2.7,3.8l2,-4.1c-1.5,-0.2 -2.4,-1.7 -2,-2.9c0.3,-1.3 1.9,-2.2 3.3,-1.6l0.9,-4l-0.2,4.3c0,0 0.2,0.1 0.4,0.1l2.8,-3.4l-1.9,3.3c3,-0.6 8,-0.7 13.3,-0.3l5.5,2.7c2.7,2.4 6.4,5.5 10.5,8.1L67.9,56l1.3,1.9h-1.1l2.3,2.8l-2.1,-0.3c0,0.2 2.1,2.6 2.1,2.6l-1.7,0.2c0.1,0.2 1.7,2.3 1.7,2.3l-1.3,-0.1c0.1,0.3 2,3.5 2,3.5s-0.7,-0.2 -1.1,-0.3C71.7,72.3 74.1,73 74.2,74.5zM72.8,46.2c-0.8,2.5 -3.7,6 -2.6,8.7c-0.4,-0.1 -9.4,-3.1 -11.9,-4.5c-4,-2.5 -7.6,-5.6 -10.3,-8l-0.1,-0.1L38.6,38c-0.1,-0.1 -0.2,-0.1 -0.3,-0.2c1.3,0.1 6.3,0.7 8.5,0.2c-0.4,-1.2 -0.3,-2.7 0.3,-4.1c0.9,-2 2.5,-3.3 4,-3.3c0.3,0 0.6,0.1 0.9,0.2c0.9,-0.8 1.9,-1.5 3.1,-1.9c6.3,-2.5 15.5,2 17.9,8.1C74.1,40 73.8,43.2 72.8,46.2zM52,31.6c-1.4,-0.6 -3.2,0.5 -4,2.6c-0.9,2 -0.5,4.1 0.9,4.7c1.3,0.6 3.2,-0.5 4,-2.6C53.7,34.3 53.3,32.1 52,31.6z" android:fillColor="#000000" - android:fillType="evenOdd" /> + android:fillType="evenOdd" + tools:ignore="VectorPath" /> </vector> diff --git a/android/lib/resource/src/main/res/mipmap-hdpi/ic_launcher.png b/android/lib/resource/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differdeleted file mode 100644 index eb38145c3c..0000000000 --- a/android/lib/resource/src/main/res/mipmap-hdpi/ic_launcher.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/mipmap-mdpi/ic_launcher.png b/android/lib/resource/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differdeleted file mode 100644 index 13f0df6b36..0000000000 --- a/android/lib/resource/src/main/res/mipmap-mdpi/ic_launcher.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/lib/resource/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differdeleted file mode 100644 index 2534ca44e3..0000000000 --- a/android/lib/resource/src/main/res/mipmap-xhdpi/ic_launcher.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/lib/resource/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differdeleted file mode 100644 index b01a564765..0000000000 --- a/android/lib/resource/src/main/res/mipmap-xxhdpi/ic_launcher.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/lib/resource/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differdeleted file mode 100644 index 063b31017e..0000000000 --- a/android/lib/resource/src/main/res/mipmap-xxxhdpi/ic_launcher.png +++ /dev/null diff --git a/android/lib/resource/src/main/res/mipmap/ic_banner.xml b/android/lib/resource/src/main/res/mipmap/ic_banner.xml new file mode 100644 index 0000000000..7a6010ef37 --- /dev/null +++ b/android/lib/resource/src/main/res/mipmap/ic_banner.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@color/darkBlue"/> + <foreground android:drawable="@drawable/ic_banner_foreground"/> +</adaptive-icon>
\ No newline at end of file diff --git a/android/lib/resource/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/lib/resource/src/main/res/mipmap/ic_launcher.xml index 56eaaf98c2..56eaaf98c2 100644 --- a/android/lib/resource/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/lib/resource/src/main/res/mipmap/ic_launcher.xml diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt index 905f59f313..edeec9a6fe 100644 --- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt +++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt @@ -55,6 +55,10 @@ class ConnectivityListener { connectivityManager.unregisterNetworkCallback(callback) } + // DROID-1401 + // This function has never been used and should most likely be merged into unregister(), + // along with ensuring that the lifecycle of it is correct. + @Suppress("UnusedPrivateMember") private fun finalize() { destroySender(senderAddress) senderAddress = 0L diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt index cf8a775e13..9470c88318 100644 --- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt +++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt @@ -74,6 +74,9 @@ open class TalpidVpnService : LifecycleVpnService() { synchronized(this) { activeTunStatus = null } } + // DROID-1407 + // Function is to be cleaned up and lint suppression to be removed. + @Suppress("ReturnCount") private fun createTun(config: TunConfig): CreateTunResult { if (prepare(this) != null) { // VPN permission wasn't granted diff --git a/android/test/build.gradle.kts b/android/test/build.gradle.kts deleted file mode 100644 index 8b13789179..0000000000 --- a/android/test/build.gradle.kts +++ /dev/null @@ -1 +0,0 @@ - diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/SimpleMullvadHttpClient.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/SimpleMullvadHttpClient.kt index 5e702a2d80..b5dcc1d647 100644 --- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/SimpleMullvadHttpClient.kt +++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/SimpleMullvadHttpClient.kt @@ -167,7 +167,7 @@ class SimpleMullvadHttpClient(context: Context) { ): JSONArray? { val future = RequestFuture.newFuture<JSONArray>() val request = - object : JsonArrayRequest(method, url, null, future, onErrorResponse) { + object : JsonArrayRequest(method, url, body, future, onErrorResponse) { override fun getHeaders(): MutableMap<String, String> { val headers = HashMap<String, String>() headers.put("Content-Type", "application/json") diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/Extensions.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/Extensions.kt index 356cacb97e..ddb28e3937 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/Extensions.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/Extensions.kt @@ -14,8 +14,7 @@ fun Buffer.getAccountNumber(): String? { return try { JSONObject(readUtf8()).getString("account_number") } catch (ex: JSONException) { - Logger.e("Unable to parse account number") - ex.printStackTrace() + Logger.e("Unable to parse account number", ex) null } } diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt index a2978808d7..e230152efe 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt @@ -32,6 +32,7 @@ class MockApiDispatcher : Dispatcher() { private var cachedPubKeyFromAppUnderTest: String? = null + @Suppress("CyclomaticComplexMethod", "NestedBlockDepth") override fun dispatch(request: RecordedRequest): MockResponse { Logger.d("Request: $request (body=${request.body.peek().readUtf8()})") return when (request.path ?: "") { |
