summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2023-03-22 09:07:53 +0100
committerAlbin <albin@mullvad.net>2023-03-22 10:39:58 +0100
commit68c356e5afa2165cadef86d43966e51d9203102c (patch)
tree0a172dacad334066be40ea1239691ed963139dac
parente5d106c9260e0f282c75d105da7b0247535cdfdd (diff)
downloadmullvadvpn-68c356e5afa2165cadef86d43966e51d9203102c.tar.xz
mullvadvpn-68c356e5afa2165cadef86d43966e51d9203102c.zip
Apply project-wide `kotlinLangStyle` formatting
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/RecyclerViewMatcher.kt22
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt27
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt48
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlowTest.kt12
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragmentTest.kt46
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/MullvadApplication.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProvider.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt48
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomDnsComposeCell.kt39
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DnsCell.kt22
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt35
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/NavigationComposeCell.kt22
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Button.kt15
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingTopBar.kt51
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/HtmlText.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt65
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt261
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Switch.kt62
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Theme.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt38
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt99
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt112
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt121
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialog.kt114
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt61
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt140
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt48
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceListUiState.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/CustomTextField.kt121
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/DnsTextField.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/MtuTextField.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/theme/Theme.kt28
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt44
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt19
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt15
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt48
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlow.kt13
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt87
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/ServiceConnection.kt33
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountAndDevice.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountCreationResult.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountExpiry.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Constraint.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomDnsOptions.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceListEvent.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DevicePort.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceState.kt15
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ListItemData.kt23
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LocationConstraint.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/PublicKey.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayEndpointData.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ServiceResult.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelOptions.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardRelayEndpointData.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardTunnelOptions.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt51
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayNameComparator.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt59
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/DeviceRepository.kt75
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/PrivacyDisclaimerRepository.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt37
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt41
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt45
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt30
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt73
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt57
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt22
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt27
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt49
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt73
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt40
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt75
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt30
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt17
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt43
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt36
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt139
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt62
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/BlockingController.kt13
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt141
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectActionButton.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CustomTransformationMethod.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemsAdapter.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LocationInfo.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt43
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt39
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PrivacyDisclaimerFragment.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt60
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt59
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/UnderNotificationBannerBehavior.kt17
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt22
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt80
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt26
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConfirmNoEmailDialogFragment.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt79
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt19
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt15
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt59
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt95
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt53
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt31
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt71
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt61
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ApplicationListItemView.kt27
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt21
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotificationController.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/NotificationWithUrl.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt26
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AuthTokenCache.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt36
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/LocationInfoCache.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt16
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt37
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SplitTunneling.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountCell.kt57
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryHolder.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountInput.kt77
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt119
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLoginBorder.kt40
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AppVersionCell.kt61
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/BackButton.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Cell.kt84
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CellSwitch.kt178
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CopyableInformationView.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CustomRecyclerView.kt16
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt32
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/InformationView.kt82
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ListenableScrollView.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NavigateCell.kt22
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt61
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SitePaymentButton.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt57
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ToggleCell.kt14
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlButton.kt7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlCell.kt15
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/AdapterWithHeader.kt84
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/CacheExtensions.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ChangeMonitor.kt9
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt19
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DeviceStateExtensions.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DispatchingFlow.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt57
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt13
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SdkUtils.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedInputFormatter.kt24
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedTextFormatter.kt13
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/TimeAgoFormatter.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt250
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt76
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModel.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt87
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt25
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt35
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt49
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt43
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/CreateTunResult.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt73
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorState.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorStateCause.kt24
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt5
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifier.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifierExtensions.kt8
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestCoroutineRule.kt5
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestUtils.kt15
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsIconManagerTest.kt8
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProviderTest.kt118
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt18
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt21
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt17
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt18
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt65
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt34
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt265
-rw-r--r--android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt4
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt15
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt28
-rw-r--r--android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/CaptureScreenshotOnFailedTestRule.kt33
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt8
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt28
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt4
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/interactor/SystemSettingsInteractor.kt19
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/CleanupAccountTestRule.kt5
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ConnCheckState.kt5
-rw-r--r--android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/SimpleMullvadHttpClient.kt122
-rw-r--r--android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt77
-rw-r--r--android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt37
-rw-r--r--android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt58
230 files changed, 3610 insertions, 4215 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/RecyclerViewMatcher.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/RecyclerViewMatcher.kt
index 2e87df9720..c5093f3ceb 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/RecyclerViewMatcher.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/RecyclerViewMatcher.kt
@@ -19,27 +19,27 @@ class RecyclerViewMatcher(private val recyclerViewId: Int) {
var childView: View? = null
override fun describeTo(description: Description) {
- val idDescription = resources?.let {
- try {
- it.getResourceName(recyclerViewId)
- } catch (var4: NotFoundException) {
- "$recyclerViewId (resource name not found)"
+ val idDescription =
+ resources?.let {
+ try {
+ it.getResourceName(recyclerViewId)
+ } catch (var4: NotFoundException) {
+ "$recyclerViewId (resource name not found)"
+ }
}
- } ?: recyclerViewId.toString()
+ ?: recyclerViewId.toString()
description.appendText("with id: $idDescription")
}
override fun matchesSafely(view: View): Boolean {
resources = view.resources
- val recyclerView =
- view.rootView.findViewById<View>(recyclerViewId) as RecyclerView?
+ val recyclerView = view.rootView.findViewById<View>(recyclerViewId) as RecyclerView?
if (recyclerView == null || recyclerView.id != recyclerViewId) {
return false
}
childView = recyclerView.findViewHolderForAdapterPosition(position)?.itemView
- val targetView = targetViewId?.let { id ->
- childView?.findViewById<View>(id)
- } ?: childView
+ val targetView =
+ targetViewId?.let { id -> childView?.findViewById<View>(id) } ?: childView
return view == targetView
}
}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt
index 4c94fced01..3fffcb63c1 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt
@@ -19,11 +19,9 @@ import org.junit.Rule
import org.junit.Test
class ChangelogDialogTest {
- @get:Rule
- val composeTestRule = createComposeRule()
+ @get:Rule val composeTestRule = createComposeRule()
- @MockK
- lateinit var mockedViewModel: ChangelogViewModel
+ @MockK lateinit var mockedViewModel: ChangelogViewModel
@Before
fun setup() {
@@ -33,34 +31,25 @@ class ChangelogDialogTest {
@Test
fun testShowChangeLogWhenNeeded() {
// Arrange
- every {
- mockedViewModel.changelogDialogUiState
- } returns MutableStateFlow(ChangelogDialogUiState.Show(listOf(CHANGELOG_ITEM)))
- every {
- mockedViewModel.dismissChangelogDialog()
- } just Runs
+ every { mockedViewModel.changelogDialogUiState } returns
+ MutableStateFlow(ChangelogDialogUiState.Show(listOf(CHANGELOG_ITEM)))
+ every { mockedViewModel.dismissChangelogDialog() } just Runs
composeTestRule.setContent {
AppTheme {
ChangelogDialog(
changesList = listOf(CHANGELOG_ITEM),
version = CHANGELOG_VERSION,
- onDismiss = {
- mockedViewModel.dismissChangelogDialog()
- }
+ onDismiss = { mockedViewModel.dismissChangelogDialog() }
)
}
}
// Check changelog content showed within dialog
- composeTestRule
- .onNodeWithText(CHANGELOG_ITEM)
- .assertExists()
+ composeTestRule.onNodeWithText(CHANGELOG_ITEM).assertExists()
// perform click on Got It button to check if dismiss occur
- composeTestRule
- .onNodeWithText(CHANGELOG_BUTTON_TEXT)
- .performClick()
+ composeTestRule.onNodeWithText(CHANGELOG_BUTTON_TEXT).performClick()
// Assert
verify { mockedViewModel.dismissChangelogDialog() }
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
index 13d98455c5..741e57612e 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
@@ -18,11 +18,9 @@ import org.junit.Rule
import org.junit.Test
class DeviceRevokedScreenTest {
- @get:Rule
- val composeTestRule = createComposeRule()
+ @get:Rule val composeTestRule = createComposeRule()
- @MockK
- lateinit var mockedViewModel: DeviceRevokedViewModel
+ @MockK lateinit var mockedViewModel: DeviceRevokedViewModel
@Before
fun setup() {
@@ -33,59 +31,35 @@ class DeviceRevokedScreenTest {
@Test
fun testUnblockWarningShowingWhenSecured() {
// Arrange
- every {
- mockedViewModel.uiState
- } returns MutableStateFlow(DeviceRevokedUiState.SECURED)
+ every { mockedViewModel.uiState } returns MutableStateFlow(DeviceRevokedUiState.SECURED)
// Act
- composeTestRule.setContent {
- AppTheme {
- DeviceRevokedScreen(mockedViewModel)
- }
- }
+ composeTestRule.setContent { AppTheme { DeviceRevokedScreen(mockedViewModel) } }
// Assert
- composeTestRule
- .onNodeWithText(UNBLOCK_WARNING)
- .assertExists()
+ composeTestRule.onNodeWithText(UNBLOCK_WARNING).assertExists()
}
@Test
fun testUnblockWarningNotShowingWhenNotSecured() {
// Arrange
- every {
- mockedViewModel.uiState
- } returns MutableStateFlow(DeviceRevokedUiState.UNSECURED)
+ every { mockedViewModel.uiState } returns MutableStateFlow(DeviceRevokedUiState.UNSECURED)
// Act
- composeTestRule.setContent {
- AppTheme {
- DeviceRevokedScreen(mockedViewModel)
- }
- }
+ composeTestRule.setContent { AppTheme { DeviceRevokedScreen(mockedViewModel) } }
// Assert
- composeTestRule
- .onNodeWithText(UNBLOCK_WARNING)
- .assertDoesNotExist()
+ composeTestRule.onNodeWithText(UNBLOCK_WARNING).assertDoesNotExist()
}
@Test
fun testGoToLogin() {
// Arrange
- every {
- mockedViewModel.uiState
- } returns MutableStateFlow(DeviceRevokedUiState.UNSECURED)
- composeTestRule.setContent {
- AppTheme {
- DeviceRevokedScreen(mockedViewModel)
- }
- }
+ every { mockedViewModel.uiState } returns MutableStateFlow(DeviceRevokedUiState.UNSECURED)
+ composeTestRule.setContent { AppTheme { DeviceRevokedScreen(mockedViewModel) } }
// Act
- composeTestRule
- .onNodeWithText(GO_TO_LOGIN_BUTTON_TEXT)
- .performClick()
+ composeTestRule.onNodeWithText(GO_TO_LOGIN_BUTTON_TEXT).performClick()
// Assert
verify { mockedViewModel.onGoToLoginClicked() }
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlowTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlowTest.kt
index 709f330b0d..1dcb4dff5b 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlowTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlowTest.kt
@@ -15,9 +15,7 @@ class HandlerFlowTest {
val looper by lazy { Looper.getMainLooper() }
val handler: HandlerFlow<Data?> by lazy {
- HandlerFlow(looper) { message ->
- message.data.getParcelable(DATA_KEY)
- }
+ HandlerFlow(looper) { message -> message.data.getParcelable(DATA_KEY) }
}
@Test
@@ -32,9 +30,8 @@ class HandlerFlowTest {
}
private fun sendMessage(messageData: Data) {
- val message = Message().apply {
- data = Bundle().apply { putParcelable(DATA_KEY, messageData) }
- }
+ val message =
+ Message().apply { data = Bundle().apply { putParcelable(DATA_KEY, messageData) } }
handler.handleMessage(message)
}
@@ -42,7 +39,6 @@ class HandlerFlowTest {
companion object {
const val DATA_KEY = "data"
- @Parcelize
- data class Data(val id: Int) : Parcelable
+ @Parcelize data class Data(val id: Int) : Parcelable
}
}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragmentTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragmentTest.kt
index 0a48801f81..f0b6d0a24d 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragmentTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragmentTest.kt
@@ -62,12 +62,13 @@ class SplitTunnelingFragmentTest : KoinTest {
}
@get:Rule
- val mockProvider = MockProviderRule.create { clazz ->
- when (clazz) {
- SplitTunnelingViewModel::class -> mockedViewModel
- else -> mockkClass(clazz)
+ val mockProvider =
+ MockProviderRule.create { clazz ->
+ when (clazz) {
+ SplitTunnelingViewModel::class -> mockedViewModel
+ else -> mockkClass(clazz)
+ }
}
- }
@Before
fun setUp() {
@@ -95,21 +96,22 @@ class SplitTunnelingFragmentTest : KoinTest {
@Test
fun test_fragment_loading() {
- val scenario = launchFragmentInContainer<SplitTunnelingFragment>(
- themeResId = R.style.AppTheme, initialState = Lifecycle.State.CREATED
- )
+ val scenario =
+ launchFragmentInContainer<SplitTunnelingFragment>(
+ themeResId = R.style.AppTheme,
+ initialState = Lifecycle.State.CREATED
+ )
scenario.moveToState(Lifecycle.State.RESUMED)
sharedFlow.tryEmit(emptyList())
- verifyAll {
- mockedViewModel.listItems
- }
+ verifyAll { mockedViewModel.listItems }
}
@Test
fun test_fragment_list_displayed() = runBlocking {
launchFragmentInContainer<SplitTunnelingFragment>(
- themeResId = R.style.AppTheme, initialState = Lifecycle.State.RESUMED
+ themeResId = R.style.AppTheme,
+ initialState = Lifecycle.State.RESUMED
)
sharedFlow.emit(
@@ -125,26 +127,26 @@ class SplitTunnelingFragmentTest : KoinTest {
onView(withRecyclerView(R.id.recyclerView).atPositionOnView(0, R.id.plain_text))
.check(matches(withText("Test Item")))
- verifyAll {
- mockedViewModel.listItems
- }
+ verifyAll { mockedViewModel.listItems }
}
@Test
fun test_fragment_list_click_application_item() = runBlocking {
- val testListItem = ListItemData.build("test.package.name") {
- type = ListItemData.APPLICATION
- text = "Test App Name"
- action = ListItemData.ItemAction("test.package.name")
- widget = WidgetState.ImageState(R.drawable.ic_icons_add)
- }
+ val testListItem =
+ ListItemData.build("test.package.name") {
+ type = ListItemData.APPLICATION
+ text = "Test App Name"
+ action = ListItemData.ItemAction("test.package.name")
+ widget = WidgetState.ImageState(R.drawable.ic_icons_add)
+ }
coEvery {
mockedViewModel.processIntent(ViewIntent.ChangeApplicationGroup(testListItem))
} just Runs
launchFragmentInContainer<SplitTunnelingFragment>(
- themeResId = R.style.AppTheme, initialState = Lifecycle.State.RESUMED
+ themeResId = R.style.AppTheme,
+ initialState = Lifecycle.State.RESUMED
)
sharedFlow.emit(listOf(testListItem))
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/MullvadApplication.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/MullvadApplication.kt
index ae00e9e16d..4b34886c34 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/MullvadApplication.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/MullvadApplication.kt
@@ -12,8 +12,6 @@ class MullvadApplication : Application() {
override fun onCreate() {
super.onCreate()
// Used to create/start separate DI graphs for each process. Avoid non-common classes etc.
- startKoin {
- androidContext(this@MullvadApplication)
- }
+ startKoin { androidContext(this@MullvadApplication) }
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProvider.kt
index 774392f1a6..1220e71f07 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProvider.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsProvider.kt
@@ -9,12 +9,12 @@ class ApplicationsProvider(
private val thisPackageName: String
) {
private val applicationFilterPredicate: (ApplicationInfo) -> Boolean = { appInfo ->
- hasInternetPermission(appInfo.packageName) &&
- !isSelfApplication(appInfo.packageName)
+ hasInternetPermission(appInfo.packageName) && !isSelfApplication(appInfo.packageName)
}
fun getAppsList(): List<AppData> {
- return packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
+ return packageManager
+ .getInstalledApplications(PackageManager.GET_META_DATA)
.asSequence()
.filter(applicationFilterPredicate)
.map { info ->
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt
index cd63483d45..e07a34bef1 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt
@@ -37,48 +37,36 @@ fun BaseCell(
val cellVerticalSpacing = dimensionResource(id = R.dimen.cell_label_vertical_padding)
val subtitleVerticalSpacing = dimensionResource(id = R.dimen.cell_footer_top_padding)
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight()
- .background(background)
- ) {
-
+ Column(modifier = Modifier.fillMaxWidth().wrapContentHeight().background(background)) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
- modifier = Modifier
- .height(cellHeight)
- .fillMaxWidth()
- .clickable { onCellClicked.invoke() }
- .padding(start = startPadding, end = endPadding)
-
+ modifier =
+ Modifier.height(cellHeight)
+ .fillMaxWidth()
+ .clickable { onCellClicked.invoke() }
+ .padding(start = startPadding, end = endPadding)
) {
title()
Spacer(modifier = Modifier.weight(1.0f))
- Column(
- modifier = modifier
- .wrapContentWidth()
- .wrapContentHeight()
- ) {
- bodyView()
- }
+ Column(modifier = modifier.wrapContentWidth().wrapContentHeight()) { bodyView() }
}
if (subtitle != null) {
Row(
- modifier = subtitleModifier
- .background(MullvadDarkBlue)
- .padding(
- start = startPadding,
- top = subtitleVerticalSpacing,
- end = endPadding,
- bottom = cellVerticalSpacing
- )
- .fillMaxWidth()
- .wrapContentHeight()
+ modifier =
+ subtitleModifier
+ .background(MullvadDarkBlue)
+ .padding(
+ start = startPadding,
+ top = subtitleVerticalSpacing,
+ end = endPadding,
+ bottom = cellVerticalSpacing
+ )
+ .fillMaxWidth()
+ .wrapContentHeight()
) {
subtitle()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomDnsComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomDnsComposeCell.kt
index d5fa79fe09..3ed13f812f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomDnsComposeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomDnsComposeCell.kt
@@ -21,17 +21,11 @@ import net.mullvad.mullvadvpn.compose.theme.MullvadWhite60
@Preview
@Composable
private fun PreviewDnsComposeCell() {
- CustomDnsComposeCell(
- checkboxDefaultState = true,
- onToggle = {}
- )
+ CustomDnsComposeCell(checkboxDefaultState = true, onToggle = {})
}
@Composable
-fun CustomDnsComposeCell(
- checkboxDefaultState: Boolean,
- onToggle: (Boolean) -> Unit
-) {
+fun CustomDnsComposeCell(checkboxDefaultState: Boolean, onToggle: (Boolean) -> Unit) {
val titleModifier = Modifier
val bodyViewModifier = Modifier
val subtitleModifier = Modifier
@@ -40,9 +34,7 @@ fun CustomDnsComposeCell(
title = { CustomDnsCellTitle(modifier = titleModifier) },
bodyView = {
CustomDnsCellView(
- switchTriggered = {
- onToggle(it)
- },
+ switchTriggered = { onToggle(it) },
isToggled = checkboxDefaultState,
modifier = bodyViewModifier
)
@@ -53,9 +45,7 @@ fun CustomDnsComposeCell(
}
@Composable
-fun CustomDnsCellTitle(
- modifier: Modifier
-) {
+fun CustomDnsCellTitle(modifier: Modifier) {
val textSize = dimensionResource(id = R.dimen.text_medium_plus).value.sp
Text(
text = stringResource(R.string.enable_custom_dns),
@@ -63,27 +53,14 @@ fun CustomDnsCellTitle(
fontWeight = FontWeight.Bold,
fontSize = textSize,
color = MullvadWhite,
- modifier = modifier
- .wrapContentWidth(align = Alignment.End)
- .wrapContentHeight()
+ modifier = modifier.wrapContentWidth(align = Alignment.End).wrapContentHeight()
)
}
@Composable
-fun CustomDnsCellView(
- switchTriggered: (Boolean) -> Unit,
- isToggled: Boolean,
- modifier: Modifier
-) {
- Row(
- modifier = modifier
- .wrapContentWidth()
- .wrapContentHeight()
- ) {
- CellSwitch(
- isChecked = isToggled,
- onCheckedChange = null
- )
+fun CustomDnsCellView(switchTriggered: (Boolean) -> Unit, isToggled: Boolean, modifier: Modifier) {
+ Row(modifier = modifier.wrapContentWidth().wrapContentHeight()) {
+ CellSwitch(isChecked = isToggled, onCheckedChange = null)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DnsCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DnsCell.kt
index 238ecb8d8e..603c2f60df 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DnsCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DnsCell.kt
@@ -23,11 +23,7 @@ import net.mullvad.mullvadvpn.compose.theme.MullvadHelmetYellow
@Preview
@Composable
private fun PreviewDnsCell() {
- DnsCell(
- address = "0.0.0.0",
- isUnreachableLocalDnsWarningVisible = true,
- onClick = {}
- )
+ DnsCell(address = "0.0.0.0", isUnreachableLocalDnsWarningVisible = true, onClick = {})
}
@Composable
@@ -41,12 +37,7 @@ fun DnsCell(
val startPadding = 54.dp
BaseCell(
- title = {
- DnsTitle(
- address = address,
- modifier = titleModifier
- )
- },
+ title = { DnsTitle(address = address, modifier = titleModifier) },
bodyView = {
if (isUnreachableLocalDnsWarningVisible) {
Icon(
@@ -64,10 +55,7 @@ fun DnsCell(
}
@Composable
-private fun DnsTitle(
- address: String,
- modifier: Modifier = Modifier
-) {
+private fun DnsTitle(address: String, modifier: Modifier = Modifier) {
val textSize = dimensionResource(id = R.dimen.text_medium).value.sp
Text(
text = address,
@@ -75,8 +63,6 @@ private fun DnsTitle(
fontSize = textSize,
fontStyle = FontStyle.Normal,
textAlign = TextAlign.Start,
- modifier = modifier
- .wrapContentWidth(align = Alignment.End)
- .wrapContentHeight()
+ modifier = modifier.wrapContentWidth(align = Alignment.End).wrapContentHeight()
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt
index 5be7f04d3b..2bc4679710 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt
@@ -22,10 +22,7 @@ import net.mullvad.mullvadvpn.constant.MTU_MIN_VALUE
@Preview
@Composable
fun MtuComposeCellPreview() {
- MtuComposeCell(
- mtuValue = "1300",
- onEditMtu = {}
- )
+ MtuComposeCell(mtuValue = "1300", onEditMtu = {})
}
@Composable
@@ -38,24 +35,15 @@ fun MtuComposeCell(
BaseCell(
title = { MtuTitle(modifier = titleModifier) },
- bodyView = {
- MtuBodyView(
- mtuValue = mtuValue,
- modifier = titleModifier
- )
- },
+ bodyView = { MtuBodyView(mtuValue = mtuValue, modifier = titleModifier) },
subtitle = { MtuSubtitle(subtitleModifier) },
subtitleModifier = subtitleModifier,
- onCellClicked = {
- onEditMtu.invoke()
- }
+ onCellClicked = { onEditMtu.invoke() }
)
}
@Composable
-private fun MtuTitle(
- modifier: Modifier
-) {
+private fun MtuTitle(modifier: Modifier) {
val textSize = dimensionResource(id = R.dimen.text_medium_plus).value.sp
Text(
text = stringResource(R.string.wireguard_mtu),
@@ -63,22 +51,13 @@ private fun MtuTitle(
fontWeight = FontWeight.Bold,
fontSize = textSize,
color = Color.White,
- modifier = modifier
- .wrapContentWidth1(align = Alignment.End)
- .wrapContentHeight()
+ modifier = modifier.wrapContentWidth1(align = Alignment.End).wrapContentHeight()
)
}
@Composable
-private fun MtuBodyView(
- mtuValue: String,
- modifier: Modifier
-) {
- Row(
- modifier = modifier
- .wrapContentWidth1()
- .wrapContentHeight()
- ) {
+private fun MtuBodyView(mtuValue: String, modifier: Modifier) {
+ Row(modifier = modifier.wrapContentWidth1().wrapContentHeight()) {
Text(
text = mtuValue.ifEmpty { stringResource(id = R.string.hint_default) },
color = Color.White
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/NavigationComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/NavigationComposeCell.kt
index b4e05ebbd3..87ef0cbfe5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/NavigationComposeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/NavigationComposeCell.kt
@@ -19,36 +19,26 @@ import net.mullvad.mullvadvpn.R
@Preview
@Composable
private fun PreviewNavigationCell() {
- NavigationComposeCell(
- title = "Navigation sample",
- onClick = {}
- )
+ NavigationComposeCell(title = "Navigation sample", onClick = {})
}
@Composable
fun NavigationComposeCell(
title: String,
modifier: Modifier = Modifier,
- bodyView: @Composable () -> Unit = {
- DefaultNavigationView(chevronContentDescription = title)
- },
+ bodyView: @Composable () -> Unit = { DefaultNavigationView(chevronContentDescription = title) },
onClick: () -> Unit
) {
BaseCell(
onCellClicked = onClick,
title = { NavigationTitleView(title = title, modifier = modifier) },
- bodyView = {
- bodyView()
- },
+ bodyView = { bodyView() },
subtitle = null,
)
}
@Composable
-private fun NavigationTitleView(
- title: String,
- modifier: Modifier = Modifier
-) {
+private fun NavigationTitleView(title: String, modifier: Modifier = Modifier) {
val textMediumSize = dimensionResource(id = R.dimen.text_medium_plus).value.sp
Text(
text = title,
@@ -56,9 +46,7 @@ private fun NavigationTitleView(
fontWeight = FontWeight.Bold,
fontSize = textMediumSize,
color = Color.White,
- modifier = modifier
- .wrapContentWidth(align = Alignment.End)
- .wrapContentHeight()
+ modifier = modifier.wrapContentWidth(align = Alignment.End).wrapContentHeight()
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Button.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Button.kt
index dc2068c5e5..f8c7127d1a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Button.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Button.kt
@@ -29,13 +29,14 @@ fun ActionButton(
enabled = isEnabled,
// Required along with defaultMinSize to control size and padding.
contentPadding = PaddingValues(0.dp),
- modifier = modifier
- .height(dimensionResource(id = R.dimen.button_height))
- .defaultMinSize(
- minWidth = 0.dp,
- minHeight = dimensionResource(id = R.dimen.button_height)
- )
- .fillMaxWidth(),
+ modifier =
+ modifier
+ .height(dimensionResource(id = R.dimen.button_height))
+ .defaultMinSize(
+ minWidth = 0.dp,
+ minHeight = dimensionResource(id = R.dimen.button_height)
+ )
+ .fillMaxWidth(),
colors = colors
) {
Text(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingTopBar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingTopBar.kt
index b117f7cbf3..570bdf4eb4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingTopBar.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/CollapsingTopBar.kt
@@ -63,34 +63,24 @@ fun CollapsingTopBar(
val minTitleSize = 20
Spacer(
- modifier = Modifier
- .fillMaxWidth()
- .height(expandedToolbarHeight)
- .background(backgroundColor)
+ modifier = Modifier.fillMaxWidth().height(expandedToolbarHeight).background(backgroundColor)
)
Button(
- modifier = Modifier
- .wrapContentWidth()
- .wrapContentHeight(),
+ modifier = Modifier.wrapContentWidth().wrapContentHeight(),
onClick = onBackClicked,
- colors = ButtonDefaults.buttonColors(
- contentColor = Color.White,
- backgroundColor = MullvadDarkBlue
- )
+ colors =
+ ButtonDefaults.buttonColors(
+ contentColor = Color.White,
+ backgroundColor = MullvadDarkBlue
+ )
) {
Image(
painter = painterResource(id = R.drawable.icon_back),
contentDescription = stringResource(id = R.string.back),
- modifier = Modifier
- .width(iconSize)
- .height(iconSize)
- )
- Spacer(
- modifier = Modifier
- .width(iconPadding)
- .fillMaxHeight()
+ modifier = Modifier.width(iconSize).height(iconSize)
)
+ Spacer(modifier = Modifier.width(iconPadding).fillMaxHeight())
Text(
text = backTitle,
color = MullvadWhite60,
@@ -101,23 +91,22 @@ fun CollapsingTopBar(
Text(
text = title,
- style = TextStyle(
- color = Color.White,
- fontWeight = FontWeight.Bold,
- textAlign = TextAlign.End
- ),
- modifier = modifier
- .padding(
+ style =
+ TextStyle(color = Color.White, fontWeight = FontWeight.Bold, textAlign = TextAlign.End),
+ modifier =
+ modifier.padding(
start = sideMargin,
end = sideMargin,
top = (minTopPadding + (maxTopPadding - minTopPadding) * progress).dp,
bottom = verticalMargin
),
- fontSize = topBarSize(
- progress = progress,
- minTitleSize = minTitleSize,
- maxTitleSize = maxTitleSize
- ).sp
+ fontSize =
+ topBarSize(
+ progress = progress,
+ minTitleSize = minTitleSize,
+ maxTitleSize = maxTitleSize
+ )
+ .sp
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/HtmlText.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/HtmlText.kt
index 545d724228..b22390cfa8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/HtmlText.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/HtmlText.kt
@@ -8,17 +8,11 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.text.HtmlCompat
@Composable
-fun HtmlText(
- htmlFormattedString: String,
- textSize: Float,
- modifier: Modifier = Modifier
-) {
+fun HtmlText(htmlFormattedString: String, textSize: Float, modifier: Modifier = Modifier) {
AndroidView(
modifier = modifier,
factory = { context ->
- TextView(context).apply {
- setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize)
- }
+ TextView(context).apply { setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize) }
},
update = {
it.text = HtmlCompat.fromHtml(htmlFormattedString, HtmlCompat.FROM_HTML_MODE_COMPACT)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt
index bd7aa0926b..bc46f93e03 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt
@@ -34,43 +34,28 @@ fun ListItem(
val itemColor = colorResource(id = R.color.blue)
Box(
- modifier = Modifier
- .fillMaxWidth()
- .padding(vertical = 1.dp)
- .height(50.dp)
- .background(itemColor),
+ modifier =
+ Modifier.fillMaxWidth().padding(vertical = 1.dp).height(50.dp).background(itemColor),
) {
Text(
text = text,
fontSize = 18.sp,
color = Color.White,
- modifier = Modifier
- .padding(
- horizontal = 16.dp
- )
- .align(Alignment.CenterStart)
+ modifier = Modifier.padding(horizontal = 16.dp).align(Alignment.CenterStart)
)
- Box(
- modifier = Modifier
- .align(Alignment.CenterEnd)
- .padding(horizontal = 12.dp)
- ) {
+ Box(modifier = Modifier.align(Alignment.CenterEnd).padding(horizontal = 12.dp)) {
if (isLoading) {
CircularProgressIndicator(
strokeWidth = 3.dp,
color = Color.White,
- modifier = Modifier
- .height(24.dp)
- .width(24.dp)
+ modifier = Modifier.height(24.dp).width(24.dp)
)
} else if (iconResourceId != null) {
Image(
painter = painterResource(id = iconResourceId),
contentDescription = "Remove",
- modifier = Modifier
- .align(Alignment.CenterEnd)
- .clickable { onClick() }
+ modifier = Modifier.align(Alignment.CenterEnd).clickable { onClick() }
)
}
}
@@ -78,42 +63,30 @@ fun ListItem(
}
@Composable
-fun ChangeListItem(
- text: String
-) {
+fun ChangeListItem(text: String) {
ConstraintLayout {
val (bullet, changeLog) = createRefs()
val smallPadding = dimensionResource(id = R.dimen.small_padding)
Box(
- modifier = Modifier
- .constrainAs(bullet) {
+ modifier =
+ Modifier.constrainAs(bullet) {
top.linkTo(parent.top)
start.linkTo(parent.absoluteLeft)
}
) {
- Text(
- text = "•",
- fontSize = 14.sp,
- color = Color.White
- )
+ Text(text = "•", fontSize = 14.sp, color = Color.White)
}
Box(
- modifier = Modifier
- .absolutePadding(left = dimensionResource(id = R.dimen.medium_padding))
- .constrainAs(changeLog) {
- top.linkTo(parent.top)
- bottom.linkTo(parent.bottom, margin = smallPadding)
- start.linkTo(parent.start)
- end.linkTo(parent.end)
- }
+ modifier =
+ Modifier.absolutePadding(left = dimensionResource(id = R.dimen.medium_padding))
+ .constrainAs(changeLog) {
+ top.linkTo(parent.top)
+ bottom.linkTo(parent.bottom, margin = smallPadding)
+ start.linkTo(parent.start)
+ end.linkTo(parent.end)
+ }
) {
- Text(
- text = text,
- fontSize = 14.sp,
- color = Color.White,
- modifier = Modifier
-
- )
+ Text(text = text, fontSize = 14.sp, color = Color.White, modifier = Modifier)
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt
index c6d32a4df9..3d23071e94 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scaffolding.kt
@@ -78,12 +78,12 @@ fun CollapsableAwareToolbarScaffold(
BoxWithConstraints(
modifier = Modifier.onGloballyPositioned { bodyHeight = it.size.height }
) {
- val minMaxToolbarHeightDiff = with(state) {
- toolbarState.maxHeight - toolbarState.minHeight
- }
- val isContentHigherThanCollapseThreshold = with(LocalDensity.current) {
- bodyHeight > maxHeight.toPx() - minMaxToolbarHeightDiff
- }
+ val minMaxToolbarHeightDiff =
+ with(state) { toolbarState.maxHeight - toolbarState.minHeight }
+ val isContentHigherThanCollapseThreshold =
+ with(LocalDensity.current) {
+ bodyHeight > maxHeight.toPx() - minMaxToolbarHeightDiff
+ }
isCollapsable = isContentHigherThanCollapseThreshold
body()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt
index 1ca651a9a9..da5759ec1c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt
@@ -82,19 +82,24 @@ private fun Modifier.drawScrollbar(
state: ScrollState,
orientation: Orientation,
reverseScrolling: Boolean
-): Modifier = drawScrollbar(
- orientation, reverseScrolling
-) { reverseDirection, atEnd, color, alpha ->
- if (state.maxValue > 0) {
- val canvasSize = if (orientation == Orientation.Horizontal) size.width else size.height
- val totalSize = canvasSize + state.maxValue
- val thumbSize = canvasSize / totalSize * canvasSize
- val startOffset = state.value / totalSize * canvasSize
- drawScrollbar(
- orientation, reverseDirection, atEnd, color, alpha, thumbSize, startOffset
- )
+): Modifier =
+ drawScrollbar(orientation, reverseScrolling) { reverseDirection, atEnd, color, alpha ->
+ if (state.maxValue > 0) {
+ val canvasSize = if (orientation == Orientation.Horizontal) size.width else size.height
+ val totalSize = canvasSize + state.maxValue
+ val thumbSize = canvasSize / totalSize * canvasSize
+ val startOffset = state.value / totalSize * canvasSize
+ drawScrollbar(
+ orientation,
+ reverseDirection,
+ atEnd,
+ color,
+ alpha,
+ thumbSize,
+ startOffset
+ )
+ }
}
-}
fun Modifier.drawHorizontalScrollbar(
state: LazyListState,
@@ -110,57 +115,73 @@ private fun Modifier.drawScrollbar(
state: LazyListState,
orientation: Orientation,
reverseScrolling: Boolean
-): Modifier = drawScrollbar(
- orientation, reverseScrolling
-) { reverseDirection, atEnd, color, alpha ->
- val layoutInfo = state.layoutInfo
- val viewportSize = layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset
- val items = layoutInfo.visibleItemsInfo
- val itemsSize = items.fastSumBy { it.size }
- if (items.size < layoutInfo.totalItemsCount || itemsSize > viewportSize) {
- val estimatedItemSize = if (items.isEmpty()) 0f else itemsSize.toFloat() / items.size
- val totalSize = estimatedItemSize * layoutInfo.totalItemsCount
- val canvasSize = if (orientation == Orientation.Horizontal) size.width else size.height
- val thumbSize = viewportSize / totalSize * canvasSize
- val startOffset = if (items.isEmpty()) 0f else items.first().run {
- (estimatedItemSize * index - offset) / totalSize * canvasSize
+): Modifier =
+ drawScrollbar(orientation, reverseScrolling) { reverseDirection, atEnd, color, alpha ->
+ val layoutInfo = state.layoutInfo
+ val viewportSize = layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset
+ val items = layoutInfo.visibleItemsInfo
+ val itemsSize = items.fastSumBy { it.size }
+ if (items.size < layoutInfo.totalItemsCount || itemsSize > viewportSize) {
+ val estimatedItemSize = if (items.isEmpty()) 0f else itemsSize.toFloat() / items.size
+ val totalSize = estimatedItemSize * layoutInfo.totalItemsCount
+ val canvasSize = if (orientation == Orientation.Horizontal) size.width else size.height
+ val thumbSize = viewportSize / totalSize * canvasSize
+ val startOffset =
+ if (items.isEmpty()) 0f
+ else
+ items.first().run {
+ (estimatedItemSize * index - offset) / totalSize * canvasSize
+ }
+ drawScrollbar(
+ orientation,
+ reverseDirection,
+ atEnd,
+ color,
+ alpha,
+ thumbSize,
+ startOffset
+ )
}
- drawScrollbar(
- orientation, reverseDirection, atEnd, color, alpha, thumbSize, startOffset
- )
}
-}
fun Modifier.drawVerticalScrollbar(
state: LazyGridState,
spanCount: Int,
reverseScrolling: Boolean = false
-): Modifier = drawScrollbar(
- Orientation.Vertical, reverseScrolling
-) { reverseDirection, atEnd, color, alpha ->
- val layoutInfo = state.layoutInfo
- val viewportSize = layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset
- val items = layoutInfo.visibleItemsInfo
- val rowCount = (items.size + spanCount - 1) / spanCount
- var itemsSize = 0
- for (i in 0 until rowCount) {
- itemsSize += items[i * spanCount].size.height
- }
- if (items.size < layoutInfo.totalItemsCount || itemsSize > viewportSize) {
- val estimatedItemSize = if (rowCount == 0) 0f else itemsSize.toFloat() / rowCount
- val totalRow = (layoutInfo.totalItemsCount + spanCount - 1) / spanCount
- val totalSize = estimatedItemSize * totalRow
- val canvasSize = size.height
- val thumbSize = viewportSize / totalSize * canvasSize
- val startOffset = if (rowCount == 0) 0f else items.first().run {
- val rowIndex = index / spanCount
- (estimatedItemSize * rowIndex - offset.y) / totalSize * canvasSize
+): Modifier =
+ drawScrollbar(Orientation.Vertical, reverseScrolling) { reverseDirection, atEnd, color, alpha ->
+ val layoutInfo = state.layoutInfo
+ val viewportSize = layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset
+ val items = layoutInfo.visibleItemsInfo
+ val rowCount = (items.size + spanCount - 1) / spanCount
+ var itemsSize = 0
+ for (i in 0 until rowCount) {
+ itemsSize += items[i * spanCount].size.height
+ }
+ if (items.size < layoutInfo.totalItemsCount || itemsSize > viewportSize) {
+ val estimatedItemSize = if (rowCount == 0) 0f else itemsSize.toFloat() / rowCount
+ val totalRow = (layoutInfo.totalItemsCount + spanCount - 1) / spanCount
+ val totalSize = estimatedItemSize * totalRow
+ val canvasSize = size.height
+ val thumbSize = viewportSize / totalSize * canvasSize
+ val startOffset =
+ if (rowCount == 0) 0f
+ else
+ items.first().run {
+ val rowIndex = index / spanCount
+ (estimatedItemSize * rowIndex - offset.y) / totalSize * canvasSize
+ }
+ drawScrollbar(
+ Orientation.Vertical,
+ reverseDirection,
+ atEnd,
+ color,
+ alpha,
+ thumbSize,
+ startOffset
+ )
}
- drawScrollbar(
- Orientation.Vertical, reverseDirection, atEnd, color, alpha, thumbSize, startOffset
- )
}
-}
private fun DrawScope.drawScrollbar(
orientation: Orientation,
@@ -172,40 +193,35 @@ private fun DrawScope.drawScrollbar(
startOffset: Float
) {
val thicknessPx = Thickness.toPx()
- val topLeft = if (orientation == Orientation.Horizontal) {
- Offset(
- if (reverseDirection) size.width - startOffset - thumbSize else startOffset,
- if (atEnd) size.height - thicknessPx else 0f
- )
- } else {
- Offset(
- if (atEnd) size.width - thicknessPx else 0f,
- if (reverseDirection) size.height - startOffset - thumbSize else startOffset
- )
- }
- val size = if (orientation == Orientation.Horizontal) {
- Size(thumbSize, thicknessPx)
- } else {
- Size(thicknessPx, thumbSize)
- }
+ val topLeft =
+ if (orientation == Orientation.Horizontal) {
+ Offset(
+ if (reverseDirection) size.width - startOffset - thumbSize else startOffset,
+ if (atEnd) size.height - thicknessPx else 0f
+ )
+ } else {
+ Offset(
+ if (atEnd) size.width - thicknessPx else 0f,
+ if (reverseDirection) size.height - startOffset - thumbSize else startOffset
+ )
+ }
+ val size =
+ if (orientation == Orientation.Horizontal) {
+ Size(thumbSize, thicknessPx)
+ } else {
+ Size(thicknessPx, thumbSize)
+ }
- drawRect(
- color = color,
- topLeft = topLeft,
- size = size,
- alpha = alpha()
- )
+ drawRect(color = color, topLeft = topLeft, size = size, alpha = alpha())
}
private fun Modifier.drawScrollbar(
orientation: Orientation,
reverseScrolling: Boolean,
- onDraw: DrawScope.(
- reverseDirection: Boolean,
- atEnd: Boolean,
- color: Color,
- alpha: () -> Float
- ) -> Unit
+ onDraw:
+ DrawScope.(
+ reverseDirection: Boolean, atEnd: Boolean, color: Color, alpha: () -> Float
+ ) -> Unit
): Modifier = composed {
val scrolled = remember {
MutableSharedFlow<Unit>(
@@ -213,19 +229,21 @@ private fun Modifier.drawScrollbar(
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
}
- val nestedScrollConnection = remember(orientation, scrolled) {
- object : NestedScrollConnection {
- override fun onPostScroll(
- consumed: Offset,
- available: Offset,
- source: NestedScrollSource
- ): Offset {
- val delta = if (orientation == Orientation.Horizontal) consumed.x else consumed.y
- if (delta != 0f) scrolled.tryEmit(Unit)
- return Offset.Zero
+ val nestedScrollConnection =
+ remember(orientation, scrolled) {
+ object : NestedScrollConnection {
+ override fun onPostScroll(
+ consumed: Offset,
+ available: Offset,
+ source: NestedScrollSource
+ ): Offset {
+ val delta =
+ if (orientation == Orientation.Horizontal) consumed.x else consumed.y
+ if (delta != 0f) scrolled.tryEmit(Unit)
+ return Offset.Zero
+ }
}
}
- }
val alpha = remember { Animatable(0f) }
LaunchedEffect(scrolled, alpha) {
@@ -237,19 +255,18 @@ private fun Modifier.drawScrollbar(
}
val isLtr = LocalLayoutDirection.current == LayoutDirection.Ltr
- val reverseDirection = if (orientation == Orientation.Horizontal) {
- if (isLtr) reverseScrolling else !reverseScrolling
- } else reverseScrolling
+ val reverseDirection =
+ if (orientation == Orientation.Horizontal) {
+ if (isLtr) reverseScrolling else !reverseScrolling
+ } else reverseScrolling
val atEnd = if (orientation == Orientation.Vertical) isLtr else true
val color = BarColor
- Modifier
- .nestedScroll(nestedScrollConnection)
- .drawWithContent {
- drawContent()
- onDraw(reverseDirection, atEnd, color, alpha::value)
- }
+ Modifier.nestedScroll(nestedScrollConnection).drawWithContent {
+ drawContent()
+ onDraw(reverseDirection, atEnd, color, alpha::value)
+ }
}
private val BarColor: Color
@@ -264,17 +281,10 @@ private val FadeOutAnimationSpec =
internal fun ScrollbarPreview() {
val state = rememberScrollState()
Column(
- modifier = Modifier
- .drawVerticalScrollbar(state)
- .verticalScroll(state),
+ modifier = Modifier.drawVerticalScrollbar(state).verticalScroll(state),
) {
repeat(50) {
- Text(
- text = "Item ${it + 1}",
- modifier = Modifier
- .fillMaxWidth()
- .padding(16.dp)
- )
+ Text(text = "Item ${it + 1}", modifier = Modifier.fillMaxWidth().padding(16.dp))
}
}
}
@@ -283,17 +293,9 @@ internal fun ScrollbarPreview() {
@Composable
internal fun LazyListScrollbarPreview() {
val state = rememberLazyListState()
- LazyColumn(
- modifier = Modifier.drawVerticalScrollbar(state),
- state = state
- ) {
+ LazyColumn(modifier = Modifier.drawVerticalScrollbar(state), state = state) {
items(50) {
- Text(
- text = "Item ${it + 1}",
- modifier = Modifier
- .fillMaxWidth()
- .padding(16.dp)
- )
+ Text(text = "Item ${it + 1}", modifier = Modifier.fillMaxWidth().padding(16.dp))
}
}
}
@@ -302,16 +304,11 @@ internal fun LazyListScrollbarPreview() {
@Composable
internal fun HorizontalScrollbarPreview() {
val state = rememberScrollState()
- Row(
- modifier = Modifier
- .drawHorizontalScrollbar(state)
- .horizontalScroll(state)
- ) {
+ Row(modifier = Modifier.drawHorizontalScrollbar(state).horizontalScroll(state)) {
repeat(50) {
Text(
text = (it + 1).toString(),
- modifier = Modifier
- .padding(horizontal = 8.dp, vertical = 16.dp)
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 16.dp)
)
}
}
@@ -321,15 +318,11 @@ internal fun HorizontalScrollbarPreview() {
@Composable
internal fun LazyListHorizontalScrollbarPreview() {
val state = rememberLazyListState()
- LazyRow(
- modifier = Modifier.drawHorizontalScrollbar(state),
- state = state
- ) {
+ LazyRow(modifier = Modifier.drawHorizontalScrollbar(state), state = state) {
items(50) {
Text(
text = (it + 1).toString(),
- modifier = Modifier
- .padding(horizontal = 8.dp, vertical = 16.dp)
+ modifier = Modifier.padding(horizontal = 8.dp, vertical = 16.dp)
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Switch.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Switch.kt
index b30ca26f22..1b1117afb9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Switch.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Switch.kt
@@ -27,10 +27,7 @@ import net.mullvad.mullvadvpn.compose.theme.MullvadWhite
@Preview
@Composable
private fun PreviewSwitch() {
- CellSwitch(
- isChecked = false,
- onCheckedChange = null
- )
+ CellSwitch(isChecked = false, onCheckedChange = null)
}
@Composable
@@ -49,49 +46,48 @@ fun CellSwitch(
val thumbRadius = 11.dp
// To move the thumb, we need to calculate the position (along x axis)
- val animatePosition = animateFloatAsState(
- targetValue = if (isChecked)
- with(LocalDensity.current) {
- (width - thumbRadius - gapBetweenThumbAndTrackEdge - 1.dp).toPx()
- }
- else
- with(LocalDensity.current) { (thumbRadius + gapBetweenThumbAndTrackEdge + 1.dp).toPx() }
- )
+ val animatePosition =
+ animateFloatAsState(
+ targetValue =
+ if (isChecked)
+ with(LocalDensity.current) {
+ (width - thumbRadius - gapBetweenThumbAndTrackEdge - 1.dp).toPx()
+ }
+ else
+ with(LocalDensity.current) {
+ (thumbRadius + gapBetweenThumbAndTrackEdge + 1.dp).toPx()
+ }
+ )
Canvas(
- modifier = modifier
- .padding(1.dp)
- .size(width = width, height = height)
- .scale(scale = scale)
- .pointerInput(Unit) {
- if (onCheckedChange != null) {
- detectTapGestures(
- onTap = {
- onCheckedChange(!isChecked)
- }
- )
+ modifier =
+ modifier
+ .padding(1.dp)
+ .size(width = width, height = height)
+ .scale(scale = scale)
+ .pointerInput(Unit) {
+ if (onCheckedChange != null) {
+ detectTapGestures(onTap = { onCheckedChange(!isChecked) })
+ }
}
- }
) {
// Track
drawRoundRect(
color = thumbColor,
cornerRadius = CornerRadius(x = 15.dp.toPx(), y = 15.dp.toPx()),
- style = Stroke(
- width = 2.dp.toPx(),
- miter = 6.dp.toPx(),
- cap = StrokeCap.Square,
- ),
+ style =
+ Stroke(
+ width = 2.dp.toPx(),
+ miter = 6.dp.toPx(),
+ cap = StrokeCap.Square,
+ ),
)
// Thumb
drawCircle(
color = if (isChecked) thumbCheckedTrackColor else thumbUncheckedTrackColor,
radius = thumbRadius.toPx(),
- center = Offset(
- x = animatePosition.value,
- y = size.height / 2
- )
+ center = Offset(x = animatePosition.value, y = size.height / 2)
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Theme.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Theme.kt
index 4cb68f9d17..8257dab2db 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Theme.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Theme.kt
@@ -4,10 +4,6 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
@Composable
-fun AppTheme(
- content: @Composable () -> Unit
-) {
- MaterialTheme(
- content = content
- )
+fun AppTheme(content: @Composable () -> Unit) {
+ MaterialTheme(content = content)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt
index a0a9d4dd90..4395f1b0cf 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/TopBar.kt
@@ -24,10 +24,7 @@ import net.mullvad.mullvadvpn.R
@Preview
@Composable
private fun PreviewTopBar() {
- TopBar(
- backgroundColor = colorResource(R.color.blue),
- onSettingsClicked = {}
- )
+ TopBar(backgroundColor = colorResource(R.color.blue), onSettingsClicked = {})
}
@Composable
@@ -38,11 +35,11 @@ fun TopBar(
isIconAndLogoVisible: Boolean = true
) {
ConstraintLayout(
- modifier = Modifier
- .fillMaxWidth()
- .height(dimensionResource(id = R.dimen.top_bar_height))
- .background(backgroundColor)
- .then(modifier),
+ modifier =
+ Modifier.fillMaxWidth()
+ .height(dimensionResource(id = R.dimen.top_bar_height))
+ .background(backgroundColor)
+ .then(modifier),
) {
val (logo, appName, settingsIcon) = createRefs()
@@ -50,10 +47,8 @@ fun TopBar(
Image(
painter = painterResource(id = R.drawable.logo_icon),
contentDescription = null, // No meaningful user info or action.
- modifier = Modifier
- .width(44.dp)
- .height(44.dp)
- .constrainAs(logo) {
+ modifier =
+ Modifier.width(44.dp).height(44.dp).constrainAs(logo) {
centerVerticallyTo(parent)
start.linkTo(parent.start, margin = 16.dp)
}
@@ -63,9 +58,8 @@ fun TopBar(
painter = painterResource(id = R.drawable.logo_text),
tint = colorResource(id = R.color.white80),
contentDescription = null, // No meaningful user info or action.
- modifier = Modifier
- .height(16.dp)
- .constrainAs(appName) {
+ modifier =
+ Modifier.height(16.dp).constrainAs(appName) {
centerVerticallyTo(parent)
start.linkTo(logo.end, margin = 8.dp)
}
@@ -76,13 +70,11 @@ fun TopBar(
Image(
painter = painterResource(R.drawable.icon_settings),
contentDescription = stringResource(id = R.string.settings),
- modifier = Modifier
- .clickable { onSettingsClicked() }
- .fillMaxHeight()
- .padding(horizontal = 16.dp)
- .constrainAs(settingsIcon) {
- end.linkTo(parent.end)
- }
+ modifier =
+ Modifier.clickable { onSettingsClicked() }
+ .fillMaxHeight()
+ .padding(horizontal = 16.dp)
+ .constrainAs(settingsIcon) { end.linkTo(parent.end) }
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
index 419f0fc7f7..cca158c3c0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
@@ -24,15 +24,9 @@ import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.component.ChangeListItem
@Composable
-fun ChangelogDialog(
- changesList: List<String>,
- version: String,
- onDismiss: () -> Unit
-) {
+fun ChangelogDialog(changesList: List<String>, version: String, onDismiss: () -> Unit) {
AlertDialog(
- onDismissRequest = {
- onDismiss()
- },
+ onDismissRequest = { onDismiss() },
title = {
Text(
text = version,
@@ -40,47 +34,35 @@ fun ChangelogDialog(
fontSize = 30.sp,
fontStyle = FontStyle.Normal,
textAlign = TextAlign.Center,
- modifier = Modifier
- .fillMaxWidth()
+ modifier = Modifier.fillMaxWidth()
)
},
-
text = {
Column {
Text(
text = stringResource(R.string.changes_dialog_subtitle),
fontSize = 18.sp,
color = Color.White,
- modifier = Modifier
- .padding(
- vertical = dimensionResource(id = R.dimen.medium_padding)
- )
+ modifier =
+ Modifier.padding(vertical = dimensionResource(id = R.dimen.medium_padding))
)
- changesList.forEach { changeItem ->
- ChangeListItem(
- text = changeItem
- )
- }
+ changesList.forEach { changeItem -> ChangeListItem(text = changeItem) }
}
},
buttons = {
Button(
- modifier = Modifier
- .wrapContentHeight()
- .padding(all = dimensionResource(id = R.dimen.medium_padding))
- .defaultMinSize(
- minHeight = dimensionResource(id = R.dimen.button_height)
- )
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = colorResource(id = R.color.blue),
- contentColor = colorResource(id = R.color.white)
- ),
- onClick = {
- onDismiss()
- }
-
+ modifier =
+ Modifier.wrapContentHeight()
+ .padding(all = dimensionResource(id = R.dimen.medium_padding))
+ .defaultMinSize(minHeight = dimensionResource(id = R.dimen.button_height))
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(id = R.color.blue),
+ contentColor = colorResource(id = R.color.white)
+ ),
+ onClick = { onDismiss() }
) {
Text(
text = stringResource(R.string.changes_dialog_dismiss_button),
@@ -88,10 +70,11 @@ fun ChangelogDialog(
)
}
},
- properties = DialogProperties(
- dismissOnClickOutside = true,
- dismissOnBackPress = true,
- ),
+ properties =
+ DialogProperties(
+ dismissOnClickOutside = true,
+ dismissOnBackPress = true,
+ ),
backgroundColor = colorResource(id = R.color.darkBlue)
)
}
@@ -99,19 +82,16 @@ fun ChangelogDialog(
@Preview
@Composable
private fun PreviewChangelogDialogWithSingleShortItem() {
- ChangelogDialog(
- changesList = listOf("Item 1"),
- version = "1111.1",
- onDismiss = {}
- )
+ ChangelogDialog(changesList = listOf("Item 1"), version = "1111.1", onDismiss = {})
}
@Preview
@Composable
private fun PreviewChangelogDialogWithTwoLongItems() {
- val longPreviewText = "This is a sample changelog item of a Compose Preview visualization. " +
- "The purpose of this specific sample text is to visualize a long text that will result " +
- "in multiple lines in the changelog dialog."
+ val longPreviewText =
+ "This is a sample changelog item of a Compose Preview visualization. " +
+ "The purpose of this specific sample text is to visualize a long text that will result " +
+ "in multiple lines in the changelog dialog."
ChangelogDialog(
changesList = listOf(longPreviewText, longPreviewText),
@@ -124,18 +104,19 @@ private fun PreviewChangelogDialogWithTwoLongItems() {
@Composable
private fun PreviewChangelogDialogWithTenShortItems() {
ChangelogDialog(
- changesList = listOf(
- "Item 1",
- "Item 2",
- "Item 3",
- "Item 4",
- "Item 5",
- "Item 6",
- "Item 7",
- "Item 8",
- "Item 9",
- "Item 10"
- ),
+ changesList =
+ listOf(
+ "Item 1",
+ "Item 2",
+ "Item 3",
+ "Item 4",
+ "Item 5",
+ "Item 6",
+ "Item 7",
+ "Item 8",
+ "Item 9",
+ "Item 10"
+ ),
version = "1111.1",
onDismiss = {}
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt
index 228487e3cc..e83a4a42ac 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt
@@ -34,91 +34,73 @@ import net.mullvad.mullvadvpn.viewmodel.DeviceListViewModel
@Composable
fun ShowDeviceRemovalDialog(viewModel: DeviceListViewModel, device: Device) {
AlertDialog(
- onDismissRequest = {
- viewModel.clearStagedDevice()
- },
+ onDismissRequest = { viewModel.clearStagedDevice() },
title = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier
- .padding(top = 0.dp)
- .fillMaxWidth()
+ modifier = Modifier.padding(top = 0.dp).fillMaxWidth()
) {
Image(
painter = painterResource(id = R.drawable.icon_alert),
contentDescription = "Remove",
- modifier = Modifier
- .width(50.dp)
- .height(50.dp)
+ modifier = Modifier.width(50.dp).height(50.dp)
)
}
},
text = {
- val htmlFormattedDialogText = textResource(
- id = R.string.max_devices_confirm_removal_description,
- device.name.capitalizeFirstCharOfEachWord()
- ).let { introText ->
- if (device.ports.isNotEmpty()) {
- introText.plus(" " + stringResource(id = R.string.port_removal_notice))
- } else {
- introText
- }
- }
+ val htmlFormattedDialogText =
+ textResource(
+ id = R.string.max_devices_confirm_removal_description,
+ device.name.capitalizeFirstCharOfEachWord()
+ )
+ .let { introText ->
+ if (device.ports.isNotEmpty()) {
+ introText.plus(" " + stringResource(id = R.string.port_removal_notice))
+ } else {
+ introText
+ }
+ }
- HtmlText(
- htmlFormattedString = htmlFormattedDialogText,
- textSize = 16.sp.value
- )
+ HtmlText(htmlFormattedString = htmlFormattedDialogText, textSize = 16.sp.value)
},
buttons = {
- Column(
- Modifier
- .padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
- ) {
+ Column(Modifier.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)) {
Button(
- modifier = Modifier
- .height(dimensionResource(id = R.dimen.button_height))
- .defaultMinSize(
- minWidth = 0.dp,
- minHeight = dimensionResource(id = R.dimen.button_height)
- )
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = colorResource(id = R.color.red),
- contentColor = Color.White
- ),
- onClick = {
- viewModel.confirmRemovalOfStagedDevice()
- }
+ modifier =
+ Modifier.height(dimensionResource(id = R.dimen.button_height))
+ .defaultMinSize(
+ minWidth = 0.dp,
+ minHeight = dimensionResource(id = R.dimen.button_height)
+ )
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(id = R.color.red),
+ contentColor = Color.White
+ ),
+ onClick = { viewModel.confirmRemovalOfStagedDevice() }
) {
- Text(
- text = stringResource(id = R.string.confirm_removal),
- fontSize = 18.sp
- )
+ Text(text = stringResource(id = R.string.confirm_removal), fontSize = 18.sp)
}
Button(
contentPadding = PaddingValues(0.dp),
- modifier = Modifier
- .focusOrder(FocusRequester())
- .padding(top = 16.dp)
- .height(dimensionResource(id = R.dimen.button_height))
- .defaultMinSize(
- minWidth = 0.dp,
- minHeight = dimensionResource(id = R.dimen.button_height)
- )
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = colorResource(id = R.color.blue),
- contentColor = Color.White
- ),
- onClick = {
- viewModel.clearStagedDevice()
- }
+ modifier =
+ Modifier.focusOrder(FocusRequester())
+ .padding(top = 16.dp)
+ .height(dimensionResource(id = R.dimen.button_height))
+ .defaultMinSize(
+ minWidth = 0.dp,
+ minHeight = dimensionResource(id = R.dimen.button_height)
+ )
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(id = R.color.blue),
+ contentColor = Color.White
+ ),
+ onClick = { viewModel.clearStagedDevice() }
) {
- Text(
- text = stringResource(id = R.string.back),
- fontSize = 18.sp
- )
+ Text(text = stringResource(id = R.string.back), fontSize = 18.sp)
}
}
},
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
index b70aa2fddc..39869c9869 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
@@ -58,9 +58,7 @@ fun DnsDialog(
Dialog(
// Fix for https://issuetracker.google.com/issues/221643630
properties = DialogProperties(usePlatformDefaultWidth = false),
- onDismissRequest = {
- onDismiss()
- },
+ onDismissRequest = { onDismiss() },
content = {
Column(
Modifier
@@ -70,47 +68,46 @@ fun DnsDialog(
.padding(dialogPadding)
) {
Text(
- text = if (stagedDns is StagedDns.NewDns) {
- stringResource(R.string.add_dns_server_dialog_title)
- } else {
- stringResource(R.string.update_dns_server_dialog_title)
- },
+ text =
+ if (stagedDns is StagedDns.NewDns) {
+ stringResource(R.string.add_dns_server_dialog_title)
+ } else {
+ stringResource(R.string.update_dns_server_dialog_title)
+ },
color = Color.White,
fontSize = textBigSize
)
Box(
- Modifier
- .wrapContentSize()
- .clickable { textFieldFocusRequester.requestFocus() }
+ Modifier.wrapContentSize().clickable { textFieldFocusRequester.requestFocus() }
) {
DnsTextField(
value = stagedDns.item.address,
isValidValue = stagedDns.isValid(),
- onValueChanged = { newMtuValue ->
- onIpAddressChanged(newMtuValue)
- },
+ onValueChanged = { newMtuValue -> onIpAddressChanged(newMtuValue) },
onFocusChanges = {},
onSubmit = { onAttemptToSave() },
isEnabled = true,
placeholderText = stringResource(R.string.enter_value_placeholder),
- modifier = Modifier
- .padding(top = midPadding)
- .focusRequester(textFieldFocusRequester)
+ modifier =
+ Modifier.padding(top = midPadding)
+ .focusRequester(textFieldFocusRequester)
)
}
- val errorMessage = when {
- stagedDns.validationResult is StagedDns.ValidationResult.DuplicateAddress -> {
- stringResource(R.string.duplicate_address_warning)
- }
- stagedDns.item.isLocal && isAllowLanEnabled.not() -> {
- stringResource(id = R.string.confirm_local_dns)
+ val errorMessage =
+ when {
+ stagedDns.validationResult is
+ StagedDns.ValidationResult.DuplicateAddress -> {
+ stringResource(R.string.duplicate_address_warning)
+ }
+ stagedDns.item.isLocal && isAllowLanEnabled.not() -> {
+ stringResource(id = R.string.confirm_local_dns)
+ }
+ else -> {
+ null
+ }
}
- else -> {
- null
- }
- }
if (errorMessage != null) {
Text(
@@ -122,17 +119,18 @@ fun DnsDialog(
}
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .defaultMinSize(minHeight = buttonSize)
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = MullvadWhite,
- disabledContentColor = MullvadWhite60,
- disabledBackgroundColor = MullvadWhite20
- ),
+ modifier =
+ Modifier.padding(top = mediumPadding)
+ .height(buttonSize)
+ .defaultMinSize(minHeight = buttonSize)
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = MullvadWhite,
+ disabledContentColor = MullvadWhite60,
+ disabledBackgroundColor = MullvadWhite20
+ ),
onClick = { onAttemptToSave() },
enabled = stagedDns.isValid()
) {
@@ -144,15 +142,16 @@ fun DnsDialog(
if (stagedDns is StagedDns.EditDns) {
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .defaultMinSize(minHeight = buttonSize)
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = MullvadWhite
- ),
+ modifier =
+ Modifier.padding(top = mediumPadding)
+ .height(buttonSize)
+ .defaultMinSize(minHeight = buttonSize)
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = MullvadWhite
+ ),
onClick = { onRemove() }
) {
Text(
@@ -163,23 +162,19 @@ fun DnsDialog(
}
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .defaultMinSize(minHeight = buttonSize)
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = Color.White
- ),
- onClick = {
- onDismiss()
- }
+ modifier =
+ Modifier.padding(top = mediumPadding)
+ .height(buttonSize)
+ .defaultMinSize(minHeight = buttonSize)
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = Color.White
+ ),
+ onClick = { onDismiss() }
) {
- Text(
- text = stringResource(id = R.string.cancel),
- fontSize = textMediumSize
- )
+ Text(text = stringResource(id = R.string.cancel), fontSize = textMediumSize)
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialog.kt
index e4df8af467..222645c35a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialog.kt
@@ -52,15 +52,9 @@ fun MtuDialog(
val smallPadding = 5.dp
Dialog(
- onDismissRequest = {
- onDismiss()
- },
+ onDismissRequest = { onDismiss() },
content = {
- Column(
- Modifier
- .background(color = MullvadDarkBlue)
- .padding(dialogPadding)
- ) {
+ Column(Modifier.background(color = MullvadDarkBlue).padding(dialogPadding)) {
Text(
text = stringResource(id = R.string.wireguard_mtu),
color = Color.White,
@@ -68,16 +62,13 @@ fun MtuDialog(
)
Box(
- Modifier
- .wrapContentSize()
+ Modifier.wrapContentSize()
.clickable { textFieldFocusRequester.requestFocus() }
.padding(top = dialogPadding)
) {
MtuTextField(
value = mtuValue,
- onValueChanged = { newMtuValue ->
- onMtuValueChanged(newMtuValue)
- },
+ onValueChanged = { newMtuValue -> onMtuValueChanged(newMtuValue) },
onFocusChange = {},
onSubmit = { newMtuValue ->
if (newMtuValue.toIntOrNull()?.isValidMtu() == true) {
@@ -88,59 +79,50 @@ fun MtuDialog(
placeholderText = stringResource(R.string.enter_value_placeholder),
maxCharLength = 4,
isValidValue = isValidMtu,
- modifier = Modifier
- .focusRequester(textFieldFocusRequester)
+ modifier = Modifier.focusRequester(textFieldFocusRequester)
)
}
Text(
- text = stringResource(
- id = R.string.wireguard_mtu_footer,
- MTU_MIN_VALUE,
- MTU_MAX_VALUE
- ),
+ text =
+ stringResource(
+ id = R.string.wireguard_mtu_footer,
+ MTU_MIN_VALUE,
+ MTU_MAX_VALUE
+ ),
fontSize = textSmallSize,
color = MullvadWhite60,
modifier = Modifier.padding(top = smallPadding)
)
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = MullvadWhite,
- disabledContentColor = MullvadWhite60,
- disabledBackgroundColor = MullvadWhite20
- ),
+ modifier =
+ Modifier.padding(top = mediumPadding).height(buttonSize).fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = MullvadWhite,
+ disabledContentColor = MullvadWhite60,
+ disabledBackgroundColor = MullvadWhite20
+ ),
enabled = isValidMtu,
- onClick = {
- onSave()
- }
+ onClick = { onSave() }
) {
- Text(
- text = stringResource(R.string.submit_button),
- fontSize = textMediumSize
- )
+ Text(text = stringResource(R.string.submit_button), fontSize = textMediumSize)
}
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .defaultMinSize(
- minHeight = buttonSize
- )
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = MullvadWhite
- ),
- onClick = {
- onRestoreDefaultValue()
- }
+ modifier =
+ Modifier.padding(top = mediumPadding)
+ .height(buttonSize)
+ .defaultMinSize(minHeight = buttonSize)
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = MullvadWhite
+ ),
+ onClick = { onRestoreDefaultValue() }
) {
Text(
text = stringResource(R.string.reset_to_default_button),
@@ -149,25 +131,19 @@ fun MtuDialog(
}
Button(
- modifier = Modifier
- .padding(top = mediumPadding)
- .height(buttonSize)
- .defaultMinSize(
- minHeight = buttonSize
- )
- .fillMaxWidth(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MullvadBlue,
- contentColor = Color.White
- ),
- onClick = {
- onDismiss()
- }
+ modifier =
+ Modifier.padding(top = mediumPadding)
+ .height(buttonSize)
+ .defaultMinSize(minHeight = buttonSize)
+ .fillMaxWidth(),
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = MullvadBlue,
+ contentColor = Color.White
+ ),
+ onClick = { onDismiss() }
) {
- Text(
- text = stringResource(R.string.cancel),
- fontSize = textMediumSize
- )
+ Text(text = stringResource(R.string.cancel), fontSize = textMediumSize)
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt
index 6d67718f1a..ff0f471c88 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt
@@ -46,13 +46,12 @@ import net.mullvad.mullvadvpn.viewmodel.CustomDnsItem
@Composable
private fun PreviewAdvancedSettings() {
AdvancedSettingScreen(
- uiState = AdvancedSettingsUiState.DefaultUiState(
- mtu = "1337",
- isCustomDnsEnabled = true,
- customDnsItems = listOf(
- CustomDnsItem("0.0.0.0", false)
- )
- ),
+ uiState =
+ AdvancedSettingsUiState.DefaultUiState(
+ mtu = "1337",
+ isCustomDnsEnabled = true,
+ customDnsItems = listOf(CustomDnsItem("0.0.0.0", false))
+ ),
onMtuCellClick = {},
onMtuInputChange = {},
onSaveMtuClick = {},
@@ -121,28 +120,23 @@ fun AdvancedSettingScreen(
val topPadding = 6.dp
CollapsingToolbarTheme {
-
val state = rememberCollapsingToolbarScaffoldState()
val progress = state.toolbarState.progress
CollapsableAwareToolbarScaffold(
- modifier = Modifier
- .background(MullvadDarkBlue)
- .fillMaxSize(),
+ modifier = Modifier.background(MullvadDarkBlue).fillMaxSize(),
state = state,
scrollStrategy = ScrollStrategy.ExitUntilCollapsed,
isEnabledWhenCollapsable = true,
toolbar = {
- val scaffoldModifier = Modifier
- .road(
+ val scaffoldModifier =
+ Modifier.road(
whenCollapsed = Alignment.TopCenter,
whenExpanded = Alignment.BottomStart
)
CollapsingTopBar(
backgroundColor = MullvadDarkBlue,
- onBackClicked = {
- onBackClick()
- },
+ onBackClicked = { onBackClick() },
title = stringResource(id = R.string.settings_advanced),
progress = progress,
modifier = scaffoldModifier,
@@ -151,27 +145,19 @@ fun AdvancedSettingScreen(
}
) {
LazyColumn(
- modifier = Modifier
- .drawVerticalScrollbar(lazyListState)
- .fillMaxWidth()
- .wrapContentHeight()
- .animateContentSize(),
+ modifier =
+ Modifier.drawVerticalScrollbar(lazyListState)
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .animateContentSize(),
state = lazyListState
-
) {
- item {
- MtuComposeCell(
- mtuValue = uiState.mtu,
- onEditMtu = { onMtuCellClick() }
- )
- }
+ item { MtuComposeCell(mtuValue = uiState.mtu, onEditMtu = { onMtuCellClick() }) }
item {
NavigationComposeCell(
title = stringResource(id = R.string.split_tunneling),
- onClick = {
- onSplitTunnelingNavigationClick.invoke()
- }
+ onClick = { onSplitTunnelingNavigationClick.invoke() }
)
Divider()
}
@@ -179,9 +165,7 @@ fun AdvancedSettingScreen(
item {
CustomDnsComposeCell(
checkboxDefaultState = uiState.isCustomDnsEnabled,
- onToggle = { newValue ->
- onToggleDnsClick(newValue)
- }
+ onToggle = { newValue -> onToggleDnsClick(newValue) }
)
Divider()
}
@@ -190,8 +174,8 @@ fun AdvancedSettingScreen(
itemsIndexed(uiState.customDnsItems) { index, item ->
DnsCell(
address = item.address,
- isUnreachableLocalDnsWarningVisible = item.isLocal &&
- uiState.isAllowLanEnabled.not(),
+ isUnreachableLocalDnsWarningVisible =
+ item.isLocal && uiState.isAllowLanEnabled.not(),
onClick = { onDnsClick(index) },
modifier = Modifier.animateItemPlacement(),
)
@@ -207,7 +191,7 @@ fun AdvancedSettingScreen(
color = Color.White
)
},
- bodyView = { },
+ bodyView = {},
subtitle = null,
background = MullvadBlue20,
startPadding = biggerPadding
@@ -218,8 +202,7 @@ fun AdvancedSettingScreen(
item {
CustomDnsCellSubtitle(
- Modifier
- .background(MullvadDarkBlue)
+ Modifier.background(MullvadDarkBlue)
.padding(
start = cellHorizontalSpacing,
top = topPadding,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
index d0fb48348e..e0df9b7e8a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
@@ -43,59 +43,52 @@ fun DeviceListScreen(
val state = viewModel.uiState.collectAsState().value
if (state.stagedDevice != null) {
- ShowDeviceRemovalDialog(
- viewModel = viewModel,
- device = state.stagedDevice
- )
+ ShowDeviceRemovalDialog(viewModel = viewModel, device = state.stagedDevice)
}
ConstraintLayout(
- modifier = Modifier
- .fillMaxHeight()
- .fillMaxWidth()
- .background(colorResource(id = R.color.darkBlue))
+ modifier =
+ Modifier.fillMaxHeight().fillMaxWidth().background(colorResource(id = R.color.darkBlue))
) {
val (content, buttons) = createRefs()
Column(
- modifier = Modifier
- .constrainAs(content) {
- top.linkTo(parent.top)
- bottom.linkTo(buttons.top)
- height = Dimension.fillToConstraints
- width = Dimension.matchParent
- }
- .verticalScroll(rememberScrollState())
+ modifier =
+ Modifier.constrainAs(content) {
+ top.linkTo(parent.top)
+ bottom.linkTo(buttons.top)
+ height = Dimension.fillToConstraints
+ width = Dimension.matchParent
+ }
+ .verticalScroll(rememberScrollState())
) {
- ConstraintLayout(
- modifier = Modifier
- .fillMaxWidth()
- .wrapContentHeight()
- ) {
+ ConstraintLayout(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
val (icon, message, list) = createRefs()
Image(
- painter = painterResource(
- id = if (state.hasTooManyDevices) {
- R.drawable.icon_fail
- } else {
- R.drawable.icon_success
- }
- ),
+ painter =
+ painterResource(
+ id =
+ if (state.hasTooManyDevices) {
+ R.drawable.icon_fail
+ } else {
+ R.drawable.icon_success
+ }
+ ),
contentDescription = null, // No meaningful user info or action.
- modifier = Modifier
- .constrainAs(icon) {
- top.linkTo(parent.top, margin = 30.dp)
- start.linkTo(parent.start)
- end.linkTo(parent.end)
- }
- .width(64.dp)
- .height(64.dp)
+ modifier =
+ Modifier.constrainAs(icon) {
+ top.linkTo(parent.top, margin = 30.dp)
+ start.linkTo(parent.start)
+ end.linkTo(parent.end)
+ }
+ .width(64.dp)
+ .height(64.dp)
)
Column(
- modifier = Modifier
- .constrainAs(message) {
+ modifier =
+ Modifier.constrainAs(message) {
top.linkTo(icon.bottom, margin = 16.dp)
start.linkTo(parent.start, margin = 22.dp)
end.linkTo(parent.end, margin = 22.dp)
@@ -103,38 +96,40 @@ fun DeviceListScreen(
},
) {
Text(
- text = stringResource(
- id = if (state.hasTooManyDevices) {
- R.string.max_devices_warning_title
- } else {
- R.string.max_devices_resolved_title
- }
- ),
+ text =
+ stringResource(
+ id =
+ if (state.hasTooManyDevices) {
+ R.string.max_devices_warning_title
+ } else {
+ R.string.max_devices_resolved_title
+ }
+ ),
fontSize = 24.sp,
color = Color.White,
fontWeight = FontWeight.Bold
)
Text(
- text = stringResource(
- id = if (state.hasTooManyDevices) {
- R.string.max_devices_warning_description
- } else {
- R.string.max_devices_resolved_description
- }
- ),
+ text =
+ stringResource(
+ id =
+ if (state.hasTooManyDevices) {
+ R.string.max_devices_warning_description
+ } else {
+ R.string.max_devices_resolved_description
+ }
+ ),
color = Color.White,
fontSize = 14.sp,
- modifier = Modifier
- .wrapContentHeight()
- .animateContentSize()
- .padding(top = 8.dp)
+ modifier =
+ Modifier.wrapContentHeight().animateContentSize().padding(top = 8.dp)
)
}
Box(
- modifier = Modifier
- .constrainAs(list) {
+ modifier =
+ Modifier.constrainAs(list) {
top.linkTo(message.bottom, margin = 20.dp)
height = Dimension.wrapContent
width = Dimension.matchParent
@@ -156,8 +151,8 @@ fun DeviceListScreen(
}
Column(
- modifier = Modifier
- .constrainAs(buttons) {
+ modifier =
+ Modifier.constrainAs(buttons) {
bottom.linkTo(parent.bottom, margin = 22.dp)
start.linkTo(parent.start, margin = 22.dp)
end.linkTo(parent.end, margin = 22.dp)
@@ -168,23 +163,24 @@ fun DeviceListScreen(
text = stringResource(id = R.string.continue_login),
onClick = onContinueWithLogin,
isEnabled = state.hasTooManyDevices.not() && state.isLoading.not(),
- colors = ButtonDefaults.buttonColors(
- backgroundColor = colorResource(id = R.color.green),
- disabledBackgroundColor = colorResource(id = R.color.green40),
- disabledContentColor = colorResource(id = R.color.white80),
- contentColor = Color.White
- )
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(id = R.color.green),
+ disabledBackgroundColor = colorResource(id = R.color.green40),
+ disabledContentColor = colorResource(id = R.color.white80),
+ contentColor = Color.White
+ )
)
ActionButton(
text = stringResource(id = R.string.back),
onClick = onBackClick,
- colors = ButtonDefaults.buttonColors(
- backgroundColor = colorResource(id = R.color.blue),
- contentColor = Color.White
- ),
- modifier = Modifier
- .padding(top = 16.dp)
+ colors =
+ ButtonDefaults.buttonColors(
+ backgroundColor = colorResource(id = R.color.blue),
+ contentColor = Color.White
+ ),
+ modifier = Modifier.padding(top = 16.dp)
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
index ce92ef72aa..dcbc32befb 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
@@ -28,36 +28,32 @@ import net.mullvad.mullvadvpn.compose.state.DeviceRevokedUiState
import net.mullvad.mullvadvpn.viewmodel.DeviceRevokedViewModel
@Composable
-fun DeviceRevokedScreen(
- deviceRevokedViewModel: DeviceRevokedViewModel
-) {
+fun DeviceRevokedScreen(deviceRevokedViewModel: DeviceRevokedViewModel) {
val state = deviceRevokedViewModel.uiState.collectAsState().value
ConstraintLayout(
- modifier = Modifier
- .fillMaxHeight()
- .fillMaxWidth()
- .background(colorResource(id = R.color.darkBlue))
+ modifier =
+ Modifier.fillMaxHeight().fillMaxWidth().background(colorResource(id = R.color.darkBlue))
) {
val (icon, body, actionButtons) = createRefs()
Image(
painter = painterResource(id = R.drawable.icon_fail),
contentDescription = null, // No meaningful user info or action.
- modifier = Modifier
- .constrainAs(icon) {
- top.linkTo(parent.top, margin = 30.dp)
- start.linkTo(parent.start)
- end.linkTo(parent.end)
- }
- .padding(horizontal = 12.dp)
- .width(80.dp)
- .height(80.dp)
+ modifier =
+ Modifier.constrainAs(icon) {
+ top.linkTo(parent.top, margin = 30.dp)
+ start.linkTo(parent.start)
+ end.linkTo(parent.end)
+ }
+ .padding(horizontal = 12.dp)
+ .width(80.dp)
+ .height(80.dp)
)
Column(
- modifier = Modifier
- .constrainAs(body) {
+ modifier =
+ Modifier.constrainAs(body) {
top.linkTo(icon.bottom, margin = 22.dp)
start.linkTo(parent.start, margin = 22.dp)
end.linkTo(parent.end, margin = 22.dp)
@@ -89,8 +85,8 @@ fun DeviceRevokedScreen(
}
Column(
- modifier = Modifier
- .constrainAs(actionButtons) {
+ modifier =
+ Modifier.constrainAs(actionButtons) {
bottom.linkTo(parent.bottom, margin = 22.dp)
start.linkTo(parent.start, margin = 22.dp)
end.linkTo(parent.end, margin = 22.dp)
@@ -100,16 +96,18 @@ fun DeviceRevokedScreen(
ActionButton(
text = stringResource(id = R.string.go_to_login),
onClick = { deviceRevokedViewModel.onGoToLoginClicked() },
- colors = ButtonDefaults.buttonColors(
- contentColor = Color.White,
- backgroundColor = colorResource(
- if (state == DeviceRevokedUiState.SECURED) {
- R.color.red60
- } else {
- R.color.blue
- }
+ colors =
+ ButtonDefaults.buttonColors(
+ contentColor = Color.White,
+ backgroundColor =
+ colorResource(
+ if (state == DeviceRevokedUiState.SECURED) {
+ R.color.red60
+ } else {
+ R.color.blue
+ }
+ )
)
- )
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt
index 4869cf6e9c..0189fc4df6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoadingScreen.kt
@@ -29,9 +29,7 @@ private fun PreviewLoadingScreen() {
}
@Composable
-fun LoadingScreen(
- onSettingsCogClicked: () -> Unit
-) {
+fun LoadingScreen(onSettingsCogClicked: () -> Unit) {
val backgroundColor = colorResource(id = R.color.blue)
ScaffoldWithTopBar(
@@ -43,10 +41,8 @@ fun LoadingScreen(
content = {
Box(
contentAlignment = Alignment.Center,
- modifier = Modifier
- .background(backgroundColor)
- .padding(bottom = 64.dp)
- .fillMaxSize()
+ modifier =
+ Modifier.background(backgroundColor).padding(bottom = 64.dp).fillMaxSize()
) {
Column(
verticalArrangement = Arrangement.Center,
@@ -55,23 +51,19 @@ fun LoadingScreen(
Image(
painter = painterResource(id = R.drawable.launch_logo),
contentDescription = "",
- modifier = Modifier
- .size(120.dp)
+ modifier = Modifier.size(120.dp)
)
Image(
painter = painterResource(id = R.drawable.logo_text),
contentDescription = "",
alpha = 0.6f,
- modifier = Modifier
- .padding(top = 12.dp)
- .height(18.dp)
+ modifier = Modifier.padding(top = 12.dp).height(18.dp)
)
Text(
text = stringResource(id = R.string.connecting_to_daemon),
fontSize = 13.sp,
color = colorResource(id = R.color.white40),
- modifier = Modifier
- .padding(top = 12.dp)
+ modifier = Modifier.padding(top = 12.dp)
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt
index 8ef4f59853..7c1cfdcf1a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt
@@ -37,17 +37,15 @@ fun PrivacyDisclaimerScreen(
onAcceptClicked: () -> Unit,
) {
ConstraintLayout(
- modifier = Modifier
- .fillMaxHeight()
- .fillMaxWidth()
- .background(colorResource(id = R.color.darkBlue))
+ modifier =
+ Modifier.fillMaxHeight().fillMaxWidth().background(colorResource(id = R.color.darkBlue))
) {
val (body, actionButtons) = createRefs()
val sideMargin = dimensionResource(id = R.dimen.side_margin)
Column(
- modifier = Modifier
- .constrainAs(body) {
+ modifier =
+ Modifier.constrainAs(body) {
top.linkTo(parent.top, margin = sideMargin)
start.linkTo(parent.start, margin = sideMargin)
end.linkTo(parent.end, margin = sideMargin)
@@ -68,34 +66,33 @@ fun PrivacyDisclaimerScreen(
modifier = Modifier.padding(top = 10.dp)
)
- Row(
- modifier = Modifier.padding(top = 10.dp)
- ) {
+ Row(modifier = Modifier.padding(top = 10.dp)) {
ClickableText(
text = AnnotatedString(stringResource(id = R.string.privacy_policy_label)),
onClick = { onPrivacyPolicyLinkClicked.invoke() },
- style = TextStyle(
- fontSize = 12.sp,
- color = Color.White,
- textDecoration = TextDecoration.Underline
- )
+ style =
+ TextStyle(
+ fontSize = 12.sp,
+ color = Color.White,
+ textDecoration = TextDecoration.Underline
+ )
)
Image(
painter = painterResource(id = R.drawable.icon_extlink),
contentDescription = null,
- modifier = Modifier
- .align(Alignment.CenterVertically)
- .padding(start = 2.dp, top = 2.dp)
- .width(10.dp)
- .height(10.dp)
+ modifier =
+ Modifier.align(Alignment.CenterVertically)
+ .padding(start = 2.dp, top = 2.dp)
+ .width(10.dp)
+ .height(10.dp)
)
}
}
Column(
- modifier = Modifier
- .constrainAs(actionButtons) {
+ modifier =
+ Modifier.constrainAs(actionButtons) {
bottom.linkTo(parent.bottom, margin = sideMargin)
start.linkTo(parent.start, margin = sideMargin)
end.linkTo(parent.end, margin = sideMargin)
@@ -105,12 +102,11 @@ fun PrivacyDisclaimerScreen(
ActionButton(
text = stringResource(id = R.string.agree_and_continue),
onClick = onAcceptClicked::invoke,
- colors = ButtonDefaults.buttonColors(
- contentColor = Color.White,
- backgroundColor = colorResource(
- R.color.blue
+ colors =
+ ButtonDefaults.buttonColors(
+ contentColor = Color.White,
+ backgroundColor = colorResource(R.color.blue)
)
- )
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceListUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceListUiState.kt
index e989960301..e22aaffde2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceListUiState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/DeviceListUiState.kt
@@ -10,15 +10,9 @@ data class DeviceListUiState(
val hasTooManyDevices = deviceUiItems.count() >= 5
companion object {
- val INITIAL = DeviceListUiState(
- deviceUiItems = emptyList(),
- isLoading = true,
- stagedDevice = null
- )
+ val INITIAL =
+ DeviceListUiState(deviceUiItems = emptyList(), isLoading = true, stagedDevice = null)
}
}
-data class DeviceListItemUiState(
- val device: Device,
- val isLoading: Boolean
-)
+data class DeviceListItemUiState(val device: Device, val isLoading: Boolean)
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 3a263a6886..4535971a69 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
@@ -68,23 +68,26 @@ fun CustomTextField(
var isFocused by remember { mutableStateOf(false) }
- val textColor = when {
- isValidValue.not() -> Color.Red
- isFocused -> MullvadBlue
- else -> defaultTextColor
- }
+ val textColor =
+ when {
+ isValidValue.not() -> Color.Red
+ isFocused -> MullvadBlue
+ else -> defaultTextColor
+ }
- val placeholderTextColor = if (isFocused) {
- placeHolderColor
- } else {
- Color.White
- }
+ val placeholderTextColor =
+ if (isFocused) {
+ placeHolderColor
+ } else {
+ Color.White
+ }
- val backgroundColor = if (isFocused) {
- Color.White
- } else {
- MullvadWhite10
- }
+ val backgroundColor =
+ if (isFocused) {
+ Color.White
+ } else {
+ MullvadWhite10
+ }
fun triggerSubmit() {
keyboardController?.hide()
@@ -101,28 +104,19 @@ fun CustomTextField(
onValueChanged(input.replace(NEWLINE_STRING, EMPTY_STRING))
}
},
- textStyle = TextStyle(
- color = textColor,
- fontSize = fontSize,
- textAlign = textAlign
- ),
+ textStyle = TextStyle(color = textColor, fontSize = fontSize, textAlign = textAlign),
enabled = isEnabled,
singleLine = true,
maxLines = 1,
- keyboardOptions = KeyboardOptions(
- keyboardType = KeyboardType.Number,
- imeAction = ImeAction.Done,
- autoCorrect = false,
- ),
- keyboardActions = KeyboardActions(
- onDone = { triggerSubmit() }
- ),
+ keyboardOptions =
+ KeyboardOptions(
+ keyboardType = KeyboardType.Number,
+ imeAction = ImeAction.Done,
+ autoCorrect = false,
+ ),
+ keyboardActions = KeyboardActions(onDone = { triggerSubmit() }),
decorationBox = { decorationBox ->
- Box(
- modifier = Modifier
- .padding(PaddingValues(12.dp, 10.dp))
- .fillMaxWidth()
- ) {
+ Box(modifier = Modifier.padding(PaddingValues(12.dp, 10.dp)).fillMaxWidth()) {
if (value.isBlank()) {
Text(
text = placeholderText,
@@ -136,37 +130,38 @@ fun CustomTextField(
}
},
cursorBrush = SolidColor(MullvadBlue),
- modifier = modifier
- .background(backgroundColor)
- .clip(shape)
- .onFocusChanged { focusState ->
- isFocused = focusState.isFocused
- onFocusChange(focusState.isFocused)
- }
- .height(textFieldHeight)
- .onKeyEvent { keyEvent ->
- return@onKeyEvent when (keyEvent.nativeKeyEvent.keyCode) {
- KeyEvent.KEYCODE_ENTER -> {
- triggerSubmit()
- true
- }
- KeyEvent.KEYCODE_ESCAPE -> {
- focusManager.clearFocus(force = true)
- keyboardController?.hide()
- true
- }
- KeyEvent.KEYCODE_DPAD_DOWN -> {
- focusManager.moveFocus(FocusDirection.Down)
- true
- }
- KeyEvent.KEYCODE_DPAD_UP -> {
- focusManager.moveFocus(FocusDirection.Up)
- true
- }
- else -> {
- false
+ modifier =
+ modifier
+ .background(backgroundColor)
+ .clip(shape)
+ .onFocusChanged { focusState ->
+ isFocused = focusState.isFocused
+ onFocusChange(focusState.isFocused)
+ }
+ .height(textFieldHeight)
+ .onKeyEvent { keyEvent ->
+ return@onKeyEvent when (keyEvent.nativeKeyEvent.keyCode) {
+ KeyEvent.KEYCODE_ENTER -> {
+ triggerSubmit()
+ true
+ }
+ KeyEvent.KEYCODE_ESCAPE -> {
+ focusManager.clearFocus(force = true)
+ keyboardController?.hide()
+ true
+ }
+ KeyEvent.KEYCODE_DPAD_DOWN -> {
+ focusManager.moveFocus(FocusDirection.Down)
+ true
+ }
+ KeyEvent.KEYCODE_DPAD_UP -> {
+ focusManager.moveFocus(FocusDirection.Up)
+ true
+ }
+ else -> {
+ false
+ }
}
}
- }
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/DnsTextField.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/DnsTextField.kt
index 198bb59159..3454f48792 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/DnsTextField.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/DnsTextField.kt
@@ -9,9 +9,9 @@ fun DnsTextField(
value: String,
isValidValue: Boolean,
modifier: Modifier = Modifier,
- onValueChanged: (String) -> Unit = { },
- onFocusChanges: (Boolean) -> Unit = { },
- onSubmit: (String) -> Unit = { },
+ onValueChanged: (String) -> Unit = {},
+ onFocusChanges: (Boolean) -> Unit = {},
+ onSubmit: (String) -> Unit = {},
placeholderText: String = "",
isEnabled: Boolean = true
) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/MtuTextField.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/MtuTextField.kt
index c44c16911c..787c502908 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/MtuTextField.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/textfield/MtuTextField.kt
@@ -8,9 +8,9 @@ fun MtuTextField(
value: String,
isValidValue: Boolean,
modifier: Modifier = Modifier,
- onValueChanged: (String) -> Unit = { },
- onFocusChange: (Boolean) -> Unit = { },
- onSubmit: (String) -> Unit = { },
+ onValueChanged: (String) -> Unit = {},
+ onFocusChange: (Boolean) -> Unit = {},
+ onSubmit: (String) -> Unit = {},
isEnabled: Boolean = true,
placeholderText: String = "",
maxCharLength: Int
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/theme/Theme.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/theme/Theme.kt
index 95e6d312a0..e02626029e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/theme/Theme.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/theme/Theme.kt
@@ -7,27 +7,19 @@ import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
-private val MullvadColorPalette = lightColors(
- primary = MullvadBlue,
- primaryVariant = MullvadDarkBlue,
- secondary = MullvadRed
-)
+private val MullvadColorPalette =
+ lightColors(primary = MullvadBlue, primaryVariant = MullvadDarkBlue, secondary = MullvadRed)
-val Shapes = Shapes(
- small = RoundedCornerShape(4.dp),
- medium = RoundedCornerShape(4.dp),
- large = RoundedCornerShape(0.dp)
-)
+val Shapes =
+ Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+ )
@Composable
-fun CollapsingToolbarTheme(
- content: @Composable () -> Unit
-) {
+fun CollapsingToolbarTheme(content: @Composable () -> Unit) {
val colors = MullvadColorPalette
- MaterialTheme(
- colors = colors,
- shapes = Shapes,
- content = content
- )
+ MaterialTheme(colors = colors, shapes = Shapes, content = content)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt
index 89df8ac582..fb09846b8b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/MullvadProblemReport.kt
@@ -26,9 +26,8 @@ class MullvadProblemReport {
private val commandChannel = spawnActor()
- private val problemReportPath = GlobalScope.async(Dispatchers.Default) {
- File(logDirectory.await(), PROBLEM_REPORT_FILE)
- }
+ private val problemReportPath =
+ GlobalScope.async(Dispatchers.Default) { File(logDirectory.await(), PROBLEM_REPORT_FILE) }
private var isCollected = false
@@ -65,21 +64,21 @@ class MullvadProblemReport {
commandChannel.trySendBlocking(Command.Delete())
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- while (true) {
- val command = channel.receive()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ while (true) {
+ val command = channel.receive()
- when (command) {
- is Command.Collect -> doCollect()
- is Command.Load -> command.logs.complete(doLoad())
- is Command.Send -> command.result.complete(doSend())
- is Command.Delete -> doDelete()
+ when (command) {
+ is Command.Collect -> doCollect()
+ is Command.Load -> command.logs.complete(doLoad())
+ is Command.Send -> command.result.complete(doSend())
+ is Command.Delete -> doDelete()
+ }
}
- }
- } catch (exception: ClosedReceiveChannelException) {
+ } catch (exception: ClosedReceiveChannelException) {}
}
- }
private suspend fun doCollect() {
val logDirectoryPath = logDirectory.await().absolutePath
@@ -107,13 +106,14 @@ class MullvadProblemReport {
doCollect()
}
- val result = isCollected &&
- sendProblemReport(
- userEmail,
- userMessage,
- problemReportPath.await().absolutePath,
- cacheDirectory.await().absolutePath
- )
+ val result =
+ isCollected &&
+ sendProblemReport(
+ userEmail,
+ userMessage,
+ problemReportPath.await().absolutePath,
+ cacheDirectory.await().absolutePath
+ )
if (result) {
doDelete()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
index 4a95b2046c..8427ae0773 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
@@ -38,7 +38,6 @@ import org.koin.dsl.module
import org.koin.dsl.onClose
val uiModule = module {
-
single<SharedPreferences>(named(APP_PREFERENCES_NAME)) {
androidApplication().getSharedPreferences(APP_PREFERENCES_NAME, Context.MODE_PRIVATE)
}
@@ -73,10 +72,7 @@ val uiModule = module {
single { DeviceRepository(get()) }
single {
PrivacyDisclaimerRepository(
- androidContext().getSharedPreferences(
- APP_PREFERENCES_NAME,
- Context.MODE_PRIVATE
- )
+ androidContext().getSharedPreferences(APP_PREFERENCES_NAME, Context.MODE_PRIVATE)
)
}
single { SettingsRepository(get()) }
@@ -89,19 +85,10 @@ val uiModule = module {
viewModel { DeviceListViewModel(get(), get()) }
viewModel { LoginViewModel(get(), get()) }
viewModel {
- ChangelogViewModel(
- get(),
- BuildConfig.VERSION_CODE,
- BuildConfig.ALWAYS_SHOW_CHANGELOG
- )
+ ChangelogViewModel(get(), BuildConfig.VERSION_CODE, BuildConfig.ALWAYS_SHOW_CHANGELOG)
}
viewModel { PrivacyDisclaimerViewModel(get()) }
- viewModel {
- AdvancedSettingsViewModel(
- repository = get(),
- inetAddressValidator = get()
- )
- }
+ viewModel { AdvancedSettingsViewModel(repository = get(), inetAddressValidator = get()) }
}
const val APPS_SCOPE = "APPS_SCOPE"
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt
index 12df45f923..431023caa2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt
@@ -4,6 +4,4 @@ import androidx.core.app.NotificationManagerCompat
import org.koin.android.ext.koin.androidContext
import org.koin.dsl.module
-val vpnServiceModule = module {
- single { NotificationManagerCompat.from(androidContext()) }
-}
+val vpnServiceModule = module { single { NotificationManagerCompat.from(androidContext()) } }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt
index 93c79a1ab9..b105d2192d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt
@@ -8,19 +8,14 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.withLock
import kotlin.reflect.KClass
-class DispatchingHandler<T : Any>(
- looper: Looper,
- private val extractor: (Message) -> T?
-) : Handler(looper), MessageDispatcher<T> {
+class DispatchingHandler<T : Any>(looper: Looper, private val extractor: (Message) -> T?) :
+ Handler(looper), MessageDispatcher<T> {
private val handlers = HashMap<KClass<out T>, (T) -> Unit>()
private val lock = ReentrantReadWriteLock()
override fun <V : T> registerHandler(variant: KClass<V>, handler: (V) -> Unit) {
lock.writeLock().withLock {
- handlers.put(variant) { instance ->
- @Suppress("UNCHECKED_CAST")
- handler(instance as V)
- }
+ handlers.put(variant) { instance -> @Suppress("UNCHECKED_CAST") handler(instance as V) }
}
}
@@ -39,9 +34,7 @@ class DispatchingHandler<T : Any>(
}
fun onDestroy() {
- lock.writeLock().withLock {
- handlers.clear()
- }
+ lock.writeLock().withLock { handlers.clear() }
removeCallbacksAndMessages(null)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
index ea7ecdcd7b..99267b3363 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
@@ -21,53 +21,38 @@ import net.mullvad.mullvadvpn.model.VoucherSubmissionResult as VoucherSubmission
sealed class Event : Message.EventMessage() {
protected override val messageKey = MESSAGE_KEY
- @Parcelize
- data class AccountCreationEvent(val result: AccountCreationResult) : Event()
+ @Parcelize data class AccountCreationEvent(val result: AccountCreationResult) : Event()
- @Parcelize
- data class AccountExpiryEvent(val expiry: AccountExpiry) : Event()
+ @Parcelize data class AccountExpiryEvent(val expiry: AccountExpiry) : Event()
- @Parcelize
- data class AccountHistoryEvent(val history: AccountHistory) : Event()
+ @Parcelize data class AccountHistoryEvent(val history: AccountHistory) : Event()
- @Parcelize
- data class AppVersionInfo(val versionInfo: AppVersionInfoData?) : Event()
+ @Parcelize data class AppVersionInfo(val versionInfo: AppVersionInfoData?) : Event()
- @Parcelize
- data class AuthToken(val token: String?) : Event()
+ @Parcelize data class AuthToken(val token: String?) : Event()
- @Parcelize
- data class CurrentVersion(val version: String?) : Event()
+ @Parcelize data class CurrentVersion(val version: String?) : Event()
- @Parcelize
- data class DeviceStateEvent(val newState: DeviceState) : Event()
+ @Parcelize data class DeviceStateEvent(val newState: DeviceState) : Event()
- @Parcelize
- data class DeviceListUpdate(val event: DeviceListEvent) : Event()
+ @Parcelize data class DeviceListUpdate(val event: DeviceListEvent) : Event()
@Parcelize
data class DeviceRemovalEvent(val deviceId: String, val result: RemoveDeviceResult) : Event()
- @Parcelize
- data class ListenerReady(val connection: Messenger, val listenerId: Int) : Event()
+ @Parcelize data class ListenerReady(val connection: Messenger, val listenerId: Int) : Event()
- @Parcelize
- data class LoginEvent(val result: LoginResult) : Event()
+ @Parcelize data class LoginEvent(val result: LoginResult) : Event()
- @Parcelize
- data class NewLocation(val location: GeoIpLocation?) : Event()
+ @Parcelize data class NewLocation(val location: GeoIpLocation?) : Event()
- @Parcelize
- data class NewRelayList(val relayList: RelayList?) : Event()
+ @Parcelize data class NewRelayList(val relayList: RelayList?) : Event()
- @Parcelize
- data class SettingsUpdate(val settings: Settings?) : Event()
+ @Parcelize data class SettingsUpdate(val settings: Settings?) : Event()
- @Parcelize
- data class SplitTunnelingUpdate(val excludedApps: List<String>?) : Event()
+ @Parcelize data class SplitTunnelingUpdate(val excludedApps: List<String>?) : Event()
- @Parcelize
- data class TunnelStateChange(val tunnelState: TunnelState) : Event()
+ @Parcelize data class TunnelStateChange(val tunnelState: TunnelState) : Event()
@Parcelize
data class VoucherSubmissionResult(
@@ -75,8 +60,7 @@ sealed class Event : Message.EventMessage() {
val result: VoucherSubmissionResultData
) : Event()
- @Parcelize
- object VpnPermissionRequest : Event()
+ @Parcelize object VpnPermissionRequest : Event()
companion object {
private const val MESSAGE_KEY = "event"
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlow.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlow.kt
index de512c7cc4..b16cfe9fbd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlow.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/HandlerFlow.kt
@@ -14,14 +14,10 @@ import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.onCompletion
-class HandlerFlow<T>(
- looper: Looper,
- private val extractor: (Message) -> T
-) : Handler(looper), Flow<T> {
+class HandlerFlow<T>(looper: Looper, private val extractor: (Message) -> T) :
+ Handler(looper), Flow<T> {
private val channel = Channel<T>(Channel.UNLIMITED)
- private val flow = channel.consumeAsFlow().onCompletion {
- removeCallbacksAndMessages(null)
- }
+ private val flow = channel.consumeAsFlow().onCompletion { removeCallbacksAndMessages(null) }
@InternalCoroutinesApi
override suspend fun collect(collector: FlowCollector<T>) = flow.collect(collector)
@@ -33,7 +29,8 @@ class HandlerFlow<T>(
channel.trySendBlocking(extractedData)
} catch (exception: Exception) {
when (exception) {
- is ClosedSendChannelException, is CancellationException -> {
+ is ClosedSendChannelException,
+ is CancellationException -> {
Log.w("mullvad", "Received a message after HandlerFlow was closed", exception)
removeCallbacksAndMessages(null)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt
index 7758f6c926..cdad0a6b13 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Message.kt
@@ -11,11 +11,12 @@ sealed class Message(private val messageId: Int) : Parcelable {
protected abstract val messageKey: String
val message: RawMessage
- get() = RawMessage.obtain().also { message ->
- message.what = messageId
- message.data = Bundle()
- message.data.putParcelable(messageKey, this)
- }
+ get() =
+ RawMessage.obtain().also { message ->
+ message.what = messageId
+ message.data = Bundle()
+ message.data.putParcelable(messageKey, this)
+ }
companion object {
internal fun <T : Parcelable> fromMessage(message: RawMessage, key: String): T? {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
index 57dcd1bc98..56900e4440 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
@@ -15,59 +15,41 @@ sealed class Request : Message.RequestMessage() {
@Deprecated("Use SetDnsOptions")
data class AddCustomDnsServer(val address: InetAddress) : Request()
- @Parcelize
- object Connect : Request()
+ @Parcelize object Connect : Request()
- @Parcelize
- object CreateAccount : Request()
+ @Parcelize object CreateAccount : Request()
- @Parcelize
- object Disconnect : Request()
+ @Parcelize object Disconnect : Request()
- @Parcelize
- data class ExcludeApp(val packageName: String) : Request()
+ @Parcelize data class ExcludeApp(val packageName: String) : Request()
- @Parcelize
- object FetchAccountExpiry : Request()
+ @Parcelize object FetchAccountExpiry : Request()
- @Parcelize
- object FetchAccountHistory : Request()
+ @Parcelize object FetchAccountHistory : Request()
- @Parcelize
- object FetchAuthToken : Request()
+ @Parcelize object FetchAuthToken : Request()
- @Parcelize
- data class IncludeApp(val packageName: String) : Request()
+ @Parcelize data class IncludeApp(val packageName: String) : Request()
- @Parcelize
- data class Login(val account: String?) : Request()
+ @Parcelize data class Login(val account: String?) : Request()
- @Parcelize
- object RefreshDeviceState : Request()
+ @Parcelize object RefreshDeviceState : Request()
- @Parcelize
- object GetDevice : Request()
+ @Parcelize object GetDevice : Request()
- @Parcelize
- data class GetDeviceList(val accountToken: String) : Request()
+ @Parcelize data class GetDeviceList(val accountToken: String) : Request()
- @Parcelize
- data class RemoveDevice(val accountToken: String, val deviceId: String) : Request()
+ @Parcelize data class RemoveDevice(val accountToken: String, val deviceId: String) : Request()
- @Parcelize
- object Logout : Request()
+ @Parcelize object Logout : Request()
- @Parcelize
- object PersistExcludedApps : Request()
+ @Parcelize object PersistExcludedApps : Request()
- @Parcelize
- object Reconnect : Request()
+ @Parcelize object Reconnect : Request()
- @Parcelize
- data class RegisterListener(val listener: Messenger) : Request()
+ @Parcelize data class RegisterListener(val listener: Messenger) : Request()
- @Parcelize
- object ClearAccountHistory : Request()
+ @Parcelize object ClearAccountHistory : Request()
@Parcelize
@Deprecated("Use SetDnsOptions")
@@ -75,41 +57,30 @@ sealed class Request : Message.RequestMessage() {
@Parcelize
@Deprecated("Use SetDnsOptions")
- data class ReplaceCustomDnsServer(
- val oldAddress: InetAddress,
- val newAddress: InetAddress
- ) : Request()
+ data class ReplaceCustomDnsServer(val oldAddress: InetAddress, val newAddress: InetAddress) :
+ Request()
- @Parcelize
- data class SetAllowLan(val allow: Boolean) : Request()
+ @Parcelize data class SetAllowLan(val allow: Boolean) : Request()
- @Parcelize
- data class SetAutoConnect(val autoConnect: Boolean) : Request()
+ @Parcelize data class SetAutoConnect(val autoConnect: Boolean) : Request()
@Parcelize
@Deprecated("Use SetDnsOptions")
data class SetEnableCustomDns(val enable: Boolean) : Request()
- @Parcelize
- data class SetEnableSplitTunneling(val enable: Boolean) : Request()
+ @Parcelize data class SetEnableSplitTunneling(val enable: Boolean) : Request()
- @Parcelize
- data class SetRelayLocation(val relayLocation: LocationConstraint?) : Request()
+ @Parcelize data class SetRelayLocation(val relayLocation: LocationConstraint?) : Request()
- @Parcelize
- data class SetWireGuardMtu(val mtu: Int?) : Request()
+ @Parcelize data class SetWireGuardMtu(val mtu: Int?) : Request()
- @Parcelize
- data class SubmitVoucher(val voucher: String) : Request()
+ @Parcelize data class SubmitVoucher(val voucher: String) : Request()
- @Parcelize
- data class UnregisterListener(val listenerId: Int) : Request()
+ @Parcelize data class UnregisterListener(val listenerId: Int) : Request()
- @Parcelize
- data class VpnPermissionResponse(val isGranted: Boolean) : Request()
+ @Parcelize data class VpnPermissionResponse(val isGranted: Boolean) : Request()
- @Parcelize
- data class SetDnsOptions(val dnsOptions: DnsOptions) : Request()
+ @Parcelize data class SetDnsOptions(val dnsOptions: DnsOptions) : Request()
companion object {
private const val MESSAGE_KEY = "request"
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/ServiceConnection.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/ServiceConnection.kt
index 66ac88c91d..c58af82073 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/ServiceConnection.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/ServiceConnection.kt
@@ -46,23 +46,26 @@ class ServiceConnection(context: Context, scope: CoroutineScope) {
Channel<ServiceResult.ConnectionState>(Channel.RENDEZVOUS)
init {
- val dispatcher = handler
- .filterNotNull()
- .dispatchTo {
- listenerRegistrations = subscribeToState(Event.ListenerReady::class, scope) {
- Pair(connection, listenerId)
- }
+ val dispatcher =
+ handler.filterNotNull().dispatchTo {
+ listenerRegistrations =
+ subscribeToState(Event.ListenerReady::class, scope) {
+ Pair(connection, listenerId)
+ }
- val tunnelStateEvents = subscribeToState(
- Event.TunnelStateChange::class,
- scope,
- TunnelState.Disconnected
- ) { tunnelState }
+ val tunnelStateEvents =
+ subscribeToState(
+ Event.TunnelStateChange::class,
+ scope,
+ TunnelState.Disconnected
+ ) {
+ tunnelState
+ }
- tunnelState = tunnelStateEvents
- .combine(
- serviceConnectionStateChannel.consumeAsFlow()
- ) { tunnelState, serviceConnectionState ->
+ tunnelState =
+ tunnelStateEvents.combine(serviceConnectionStateChannel.consumeAsFlow()) {
+ tunnelState,
+ serviceConnectionState ->
tunnelState to serviceConnectionState
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountAndDevice.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountAndDevice.kt
index 1a4ed323b9..f5137ebbb7 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountAndDevice.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountAndDevice.kt
@@ -3,8 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class AccountAndDevice(
- val account_token: String,
- val device: Device
-) : Parcelable
+@Parcelize data class AccountAndDevice(val account_token: String, val device: Device) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountCreationResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountCreationResult.kt
index 23115b606d..4bb4c61384 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountCreationResult.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountCreationResult.kt
@@ -4,9 +4,7 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class AccountCreationResult : Parcelable {
- @Parcelize
- data class Success(val accountToken: String) : AccountCreationResult()
+ @Parcelize data class Success(val accountToken: String) : AccountCreationResult()
- @Parcelize
- object Failure : AccountCreationResult()
+ @Parcelize object Failure : AccountCreationResult()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountExpiry.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountExpiry.kt
index b057308192..a91ce46148 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountExpiry.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountExpiry.kt
@@ -5,11 +5,9 @@ import kotlinx.parcelize.Parcelize
import org.joda.time.DateTime
sealed class AccountExpiry : Parcelable {
- @Parcelize
- data class Available(val expiryDateTime: DateTime) : AccountExpiry()
+ @Parcelize data class Available(val expiryDateTime: DateTime) : AccountExpiry()
- @Parcelize
- object Missing : AccountExpiry()
+ @Parcelize object Missing : AccountExpiry()
fun date(): DateTime? {
return (this as? Available)?.expiryDateTime
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt
index 11e9b20604..008eb1ea7a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AccountHistory.kt
@@ -4,11 +4,9 @@ import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
sealed class AccountHistory : Parcelable {
- @Parcelize
- data class Available(val accountToken: String) : AccountHistory()
+ @Parcelize data class Available(val accountToken: String) : AccountHistory()
- @Parcelize
- object Missing : AccountHistory()
+ @Parcelize object Missing : AccountHistory()
fun accountToken() = (this as? Available)?.accountToken
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt
index cc1127d026..bbe99ce656 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/AppVersionInfo.kt
@@ -4,7 +4,4 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class AppVersionInfo(
- val supported: Boolean,
- val suggestedUpgrade: String?
-) : Parcelable
+data class AppVersionInfo(val supported: Boolean, val suggestedUpgrade: String?) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Constraint.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Constraint.kt
index 37b98298ab..c6dc2bb091 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Constraint.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Constraint.kt
@@ -8,6 +8,5 @@ sealed class Constraint<T>() : Parcelable {
@Suppress("PARCELABLE_PRIMARY_CONSTRUCTOR_IS_EMPTY")
class Any<T>() : Constraint<T>()
- @Parcelize
- data class Only<T : Parcelable>(val value: T) : Constraint<T>()
+ @Parcelize data class Only<T : Parcelable>(val value: T) : Constraint<T>()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomDnsOptions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomDnsOptions.kt
index e9e8311c26..bbf029dd4d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomDnsOptions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/CustomDnsOptions.kt
@@ -4,7 +4,4 @@ import android.os.Parcelable
import java.net.InetAddress
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class CustomDnsOptions(
- val addresses: ArrayList<InetAddress>
-) : Parcelable
+@Parcelize data class CustomDnsOptions(val addresses: ArrayList<InetAddress>) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt
index b633920e7f..c497f296ba 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Device.kt
@@ -14,8 +14,7 @@ data class Device(
val created: String
) : Parcelable {
- @IgnoredOnParcel
- val creationDate by lazy { created.parseAsDateTime() }
+ @IgnoredOnParcel val creationDate by lazy { created.parseAsDateTime() }
// Generated by Android Studio
override fun equals(other: Any?): Boolean {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt
index 3156b98833..741108612d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceEvent.kt
@@ -4,7 +4,4 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class DeviceEvent(
- val cause: DeviceEventCause,
- val newState: DeviceState
-) : Parcelable
+data class DeviceEvent(val cause: DeviceEventCause, val newState: DeviceState) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceListEvent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceListEvent.kt
index 1e0f78e985..7a2883617b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceListEvent.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceListEvent.kt
@@ -7,8 +7,7 @@ sealed class DeviceListEvent : Parcelable {
@Parcelize
data class Available(val accountToken: String, val devices: List<Device>) : DeviceListEvent()
- @Parcelize
- object Error : DeviceListEvent()
+ @Parcelize object Error : DeviceListEvent()
fun isAvailable(): Boolean {
return (this is Available)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DevicePort.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DevicePort.kt
index 1159fa1a47..e43eae3e6b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DevicePort.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DevicePort.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class DevicePort(val id: String) : Parcelable
+@Parcelize data class DevicePort(val id: String) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceState.kt
index e23f0857d1..440d03de55 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/DeviceState.kt
@@ -4,20 +4,15 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class DeviceState : Parcelable {
- @Parcelize
- object Initial : DeviceState()
+ @Parcelize object Initial : DeviceState()
- @Parcelize
- object Unknown : DeviceState()
+ @Parcelize object Unknown : DeviceState()
- @Parcelize
- data class LoggedIn(val accountAndDevice: AccountAndDevice) : DeviceState()
+ @Parcelize data class LoggedIn(val accountAndDevice: AccountAndDevice) : DeviceState()
- @Parcelize
- object LoggedOut : DeviceState()
+ @Parcelize object LoggedOut : DeviceState()
- @Parcelize
- object Revoked : DeviceState()
+ @Parcelize object Revoked : DeviceState()
fun isUnknown(): Boolean {
return this is Unknown
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ListItemData.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ListItemData.kt
index 17aa7bae51..26ea17f083 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ListItemData.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ListItemData.kt
@@ -16,22 +16,17 @@ private constructor(
val action: ItemAction? = null
) {
- @Retention
- @IntDef(DIVIDER, PLAIN, ACTION)
- annotation class ItemType
+ @Retention @IntDef(DIVIDER, PLAIN, ACTION) annotation class ItemType
class Builder(private val identifier: String) {
var text: String? = null
- @StringRes
- var textRes: Int? = null
+ @StringRes var textRes: Int? = null
- @DrawableRes
- var iconRes: Int? = null
+ @DrawableRes var iconRes: Int? = null
var isSelected: Boolean = false
- @ItemType
- var type: Int = 0
+ @ItemType var type: Int = 0
var widget: WidgetState? = null
var action: ItemAction? = null
@@ -40,8 +35,14 @@ private constructor(
throw IllegalArgumentException("ListItem should be configured with text")
return ListItemData(
- this.identifier, this.text, this.textRes, this.iconRes,
- this.isSelected, this.type, this.widget, this.action
+ this.identifier,
+ this.text,
+ this.textRes,
+ this.iconRes,
+ this.isSelected,
+ this.type,
+ this.widget,
+ this.action
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LocationConstraint.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LocationConstraint.kt
index 6734ff418e..2820a449b8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LocationConstraint.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/LocationConstraint.kt
@@ -19,11 +19,8 @@ sealed class LocationConstraint : Parcelable {
}
@Parcelize
- data class Hostname(
- val countryCode: String,
- val cityCode: String,
- val hostname: String
- ) : LocationConstraint() {
+ data class Hostname(val countryCode: String, val cityCode: String, val hostname: String) :
+ LocationConstraint() {
override val location: GeoIpLocation
get() = GeoIpLocation(null, null, countryCode, cityCode, hostname)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/PublicKey.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/PublicKey.kt
index 4ee6ad51df..169b6c3856 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/PublicKey.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/PublicKey.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class PublicKey(val key: ByteArray, val dateCreated: String) : Parcelable
+@Parcelize data class PublicKey(val key: ByteArray, val dateCreated: String) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
index dbb74b129a..b1abdc3c75 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/Relay.kt
@@ -4,11 +4,8 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class Relay(
- val hostname: String,
- val active: Boolean,
- val endpointData: RelayEndpointData
-) : Parcelable {
+data class Relay(val hostname: String, val active: Boolean, val endpointData: RelayEndpointData) :
+ Parcelable {
val isWireguardRelay
get() = endpointData is RelayEndpointData.Wireguard
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt
index cd36577dae..9b02e043ad 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraints.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class RelayConstraints(val location: Constraint<LocationConstraint>) : Parcelable
+@Parcelize data class RelayConstraints(val location: Constraint<LocationConstraint>) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayEndpointData.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayEndpointData.kt
index ecc2d4d002..86b3f0fa35 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayEndpointData.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayEndpointData.kt
@@ -4,14 +4,11 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class RelayEndpointData : Parcelable {
- @Parcelize
- object Openvpn : RelayEndpointData()
+ @Parcelize object Openvpn : RelayEndpointData()
- @Parcelize
- object Bridge : RelayEndpointData()
+ @Parcelize object Bridge : RelayEndpointData()
@Parcelize
- data class Wireguard(
- val wireguardRelayEndpointData: WireguardRelayEndpointData
- ) : RelayEndpointData()
+ data class Wireguard(val wireguardRelayEndpointData: WireguardRelayEndpointData) :
+ RelayEndpointData()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
index 08c84aad01..2d13dc9322 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayList.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class RelayList(val countries: ArrayList<RelayListCountry>) : Parcelable
+@Parcelize data class RelayList(val countries: ArrayList<RelayListCountry>) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
index 597cfb2758..2376609ced 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayListCity.kt
@@ -4,8 +4,5 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class RelayListCity(
- val name: String,
- val code: String,
- val relays: ArrayList<Relay>
-) : Parcelable
+data class RelayListCity(val name: String, val code: String, val relays: ArrayList<Relay>) :
+ Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
index 6a247997db..7832a00e77 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettings.kt
@@ -4,9 +4,7 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class RelaySettings : Parcelable {
- @Parcelize
- object CustomTunnelEndpoint : RelaySettings()
+ @Parcelize object CustomTunnelEndpoint : RelaySettings()
- @Parcelize
- class Normal(val relayConstraints: RelayConstraints) : RelaySettings()
+ @Parcelize class Normal(val relayConstraints: RelayConstraints) : RelaySettings()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt
index 94499c032a..cc6e7db2bb 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/RemoveDeviceEvent.kt
@@ -4,7 +4,5 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class RemoveDeviceEvent(
- val accountToken: String,
- val newDevices: ArrayList<Device>
-) : Parcelable
+data class RemoveDeviceEvent(val accountToken: String, val newDevices: ArrayList<Device>) :
+ Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ServiceResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ServiceResult.kt
index b1d9f5be4c..e597797e5a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ServiceResult.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/ServiceResult.kt
@@ -2,12 +2,10 @@ package net.mullvad.mullvadvpn.model
import android.os.IBinder
-data class ServiceResult(
- val binder: IBinder?
-) {
+data class ServiceResult(val binder: IBinder?) {
enum class ConnectionState {
CONNECTED,
- DISCONNECTED;
+ DISCONNECTED
}
val connectionState: ConnectionState
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelOptions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelOptions.kt
index 944a98b0b8..108fd32e04 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelOptions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelOptions.kt
@@ -4,7 +4,5 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class TunnelOptions(
- val wireguard: WireguardTunnelOptions,
- val dnsOptions: DnsOptions
-) : Parcelable
+data class TunnelOptions(val wireguard: WireguardTunnelOptions, val dnsOptions: DnsOptions) :
+ Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt
index 6edfb2dc24..c513c77d8e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt
@@ -8,28 +8,21 @@ import net.mullvad.talpid.tunnel.ErrorState
import net.mullvad.talpid.tunnel.ErrorStateCause
sealed class TunnelState() : Parcelable {
- @Parcelize
- object Disconnected : TunnelState(), Parcelable
+ @Parcelize object Disconnected : TunnelState(), Parcelable
@Parcelize
- class Connecting(
- val endpoint: TunnelEndpoint?,
- val location: GeoIpLocation?
- ) : TunnelState(), Parcelable
+ class Connecting(val endpoint: TunnelEndpoint?, val location: GeoIpLocation?) :
+ TunnelState(), Parcelable
@Parcelize
- class Connected(
- val endpoint: TunnelEndpoint,
- val location: GeoIpLocation?
- ) : TunnelState(), Parcelable
+ class Connected(val endpoint: TunnelEndpoint, val location: GeoIpLocation?) :
+ TunnelState(), Parcelable
@Parcelize
- class Disconnecting(
- val actionAfterDisconnect: ActionAfterDisconnect
- ) : TunnelState(), Parcelable
+ class Disconnecting(val actionAfterDisconnect: ActionAfterDisconnect) :
+ TunnelState(), Parcelable
- @Parcelize
- class Error(val errorState: ErrorState) : TunnelState(), Parcelable
+ @Parcelize class Error(val errorState: ErrorState) : TunnelState(), Parcelable
fun isSecured(): Boolean {
return when (this) {
@@ -66,23 +59,24 @@ sealed class TunnelState() : Parcelable {
}
}
- override fun toString(): String = when (this) {
- is TunnelState.Disconnected -> DISCONNECTED
- is TunnelState.Connecting -> CONNECTING
- is TunnelState.Connected -> CONNECTED
- is TunnelState.Disconnecting -> {
- if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) {
- RECONNECTING
- } else {
- DISCONNECTING
+ override fun toString(): String =
+ when (this) {
+ is TunnelState.Disconnected -> DISCONNECTED
+ is TunnelState.Connecting -> CONNECTING
+ is TunnelState.Connected -> CONNECTED
+ is TunnelState.Disconnecting -> {
+ if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) {
+ RECONNECTING
+ } else {
+ DISCONNECTING
+ }
}
- }
- is TunnelState.Error -> {
- if (errorState.isBlocking) {
- BLOCKING
- } else {
- ERROR
+ is TunnelState.Error -> {
+ if (errorState.isBlocking) {
+ BLOCKING
+ } else {
+ ERROR
+ }
}
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt
index bf96646516..efe05e2f5c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class VoucherSubmission(val timeAdded: Long, val newExpiry: String) : Parcelable
+@Parcelize data class VoucherSubmission(val timeAdded: Long, val newExpiry: String) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt
index b78957d5c0..4163b782d4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt
@@ -4,9 +4,7 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class VoucherSubmissionResult : Parcelable {
- @Parcelize
- data class Ok(val submission: VoucherSubmission) : VoucherSubmissionResult()
+ @Parcelize data class Ok(val submission: VoucherSubmission) : VoucherSubmissionResult()
- @Parcelize
- data class Error(val error: VoucherSubmissionError) : VoucherSubmissionResult()
+ @Parcelize data class Error(val error: VoucherSubmissionError) : VoucherSubmissionResult()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardRelayEndpointData.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardRelayEndpointData.kt
index b3ef17f98a..4a1930dd43 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardRelayEndpointData.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardRelayEndpointData.kt
@@ -3,5 +3,4 @@ package net.mullvad.mullvadvpn.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-object WireguardRelayEndpointData : Parcelable
+@Parcelize object WireguardRelayEndpointData : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardTunnelOptions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardTunnelOptions.kt
index 85a5ebc894..47c8c54a57 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardTunnelOptions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/model/WireguardTunnelOptions.kt
@@ -4,7 +4,4 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class WireguardTunnelOptions(
- val mtu: Int?,
- val quantumResistant: Boolean?
-) : Parcelable
+data class WireguardTunnelOptions(val mtu: Int?, val quantumResistant: Boolean?) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt
index 080236cff9..7afb2249d2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt
@@ -2,11 +2,8 @@ package net.mullvad.mullvadvpn.relaylist
import net.mullvad.mullvadvpn.model.LocationConstraint
-data class Relay(
- val city: RelayCity,
- override val name: String,
- override val active: Boolean
-) : RelayItem {
+data class Relay(val city: RelayCity, override val name: String, override val active: Boolean) :
+ RelayItem {
override val code = name
override val type = RelayItemType.Relay
override val location = LocationConstraint.Hostname(city.country.code, city.code, name)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
index 915e6ca181..b5aaed028a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayList.kt
@@ -7,32 +7,33 @@ class RelayList {
val countries: List<RelayCountry>
constructor(model: net.mullvad.mullvadvpn.model.RelayList) {
- var relayCountries = model.countries
- .map { country ->
- val cities = mutableListOf<RelayCity>()
- val relayCountry = RelayCountry(country.name, country.code, false, cities)
+ var relayCountries =
+ model.countries
+ .map { country ->
+ val cities = mutableListOf<RelayCity>()
+ val relayCountry = RelayCountry(country.name, country.code, false, cities)
- for (city in country.cities) {
- val relays = mutableListOf<Relay>()
- val relayCity = RelayCity(relayCountry, city.name, city.code, false, relays)
+ for (city in country.cities) {
+ val relays = mutableListOf<Relay>()
+ val relayCity = RelayCity(relayCountry, city.name, city.code, false, relays)
- val validCityRelays = city.relays.filter { relay -> relay.isWireguardRelay }
+ val validCityRelays = city.relays.filter { relay -> relay.isWireguardRelay }
- for (relay in validCityRelays) {
- relays.add(Relay(relayCity, relay.hostname, relay.active))
- }
- relays.sortWith(RelayNameComparator)
+ for (relay in validCityRelays) {
+ relays.add(Relay(relayCity, relay.hostname, relay.active))
+ }
+ relays.sortWith(RelayNameComparator)
- if (relays.isNotEmpty()) {
- cities.add(relayCity)
+ if (relays.isNotEmpty()) {
+ cities.add(relayCity)
+ }
}
- }
- cities.sortBy({ it.name })
- relayCountry
- }
- .filter { country -> country.cities.isNotEmpty() }
- .toMutableList()
+ cities.sortBy({ it.name })
+ relayCountry
+ }
+ .filter { country -> country.cities.isNotEmpty() }
+ .toMutableList()
relayCountries.sortBy({ it.name })
@@ -53,9 +54,8 @@ class RelayList {
return countries.find { country -> country.code == location.countryCode }
}
is LocationConstraint.City -> {
- val country = countries.find { country ->
- country.code == location.countryCode
- }
+ val country =
+ countries.find { country -> country.code == location.countryCode }
if (expand) {
country?.expanded = true
@@ -64,9 +64,8 @@ class RelayList {
return country?.cities?.find { city -> city.code == location.cityCode }
}
is LocationConstraint.Hostname -> {
- val country = countries.find { country ->
- country.code == location.countryCode
- }
+ val country =
+ countries.find { country -> country.code == location.countryCode }
val city = country?.cities?.find { city -> city.code == location.cityCode }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayNameComparator.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayNameComparator.kt
index 32f473b194..92a3c9c1d6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayNameComparator.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayNameComparator.kt
@@ -4,19 +4,15 @@ internal object RelayNameComparator : Comparator<Relay> {
override fun compare(o1: Relay, o2: 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)
+ 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
+ if (other.size <= index) return 1
val partsCompareResult = compareStringOrInt(other[index], s)
- if (partsCompareResult != 0)
- return partsCompareResult
+ if (partsCompareResult != 0) return partsCompareResult
}
return 0
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
index afcd6a531b..106cf9a7d9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/AccountRepository.kt
@@ -36,42 +36,37 @@ class AccountRepository(
.onEach {
_cachedCreatedAccount.value = (it as? AccountCreationResult.Success)?.accountToken
}
- .shareIn(
+ .shareIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed())
+
+ val accountExpiryState: StateFlow<AccountExpiry> =
+ serviceConnectionManager.connectionState
+ .flatMapReadyConnectionOrDefault(flowOf()) { state ->
+ state.container.accountDataSource.accountExpiry
+ }
+ .stateIn(
CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed()
+ SharingStarted.WhileSubscribed(),
+ AccountExpiry.Missing
)
- val accountExpiryState: StateFlow<AccountExpiry> = serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.accountExpiry
- }
- .stateIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed(),
- AccountExpiry.Missing
- )
-
- val accountHistoryEvents: StateFlow<AccountHistory> = serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.accountHistory
- }
- .onStart {
- fetchAccountHistory()
- }
- .stateIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed(),
- AccountHistory.Missing
- )
+ val accountHistoryEvents: StateFlow<AccountHistory> =
+ serviceConnectionManager.connectionState
+ .flatMapReadyConnectionOrDefault(flowOf()) { state ->
+ state.container.accountDataSource.accountHistory
+ }
+ .onStart { fetchAccountHistory() }
+ .stateIn(
+ CoroutineScope(dispatcher),
+ SharingStarted.WhileSubscribed(),
+ AccountHistory.Missing
+ )
- val loginEvents: SharedFlow<Event.LoginEvent> = serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- state.container.accountDataSource.loginEvents
- }
- .shareIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed()
- )
+ val loginEvents: SharedFlow<Event.LoginEvent> =
+ serviceConnectionManager.connectionState
+ .flatMapReadyConnectionOrDefault(flowOf()) { state ->
+ state.container.accountDataSource.loginEvents
+ }
+ .shareIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed())
fun createAccount() {
serviceConnectionManager.accountDataSource()?.createAccount()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/DeviceRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/DeviceRepository.kt
index 72e2d6ff31..2374f7dfe1 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/DeviceRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/DeviceRepository.kt
@@ -29,22 +29,23 @@ class DeviceRepository(
) {
private val cachedDeviceList = MutableStateFlow<DeviceList>(DeviceList.Unavailable)
- val deviceState = serviceConnectionManager.connectionState
- .flatMapLatest { state ->
- if (state is ServiceConnectionState.ConnectedReady) {
- state.container.deviceDataSource.deviceStateUpdates
- } else {
- flowOf(DeviceState.Unknown)
+ val deviceState =
+ serviceConnectionManager.connectionState
+ .flatMapLatest { state ->
+ if (state is ServiceConnectionState.ConnectedReady) {
+ state.container.deviceDataSource.deviceStateUpdates
+ } else {
+ flowOf(DeviceState.Unknown)
+ }
}
- }
- .stateIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed(),
- DeviceState.Initial
- )
+ .stateIn(
+ CoroutineScope(dispatcher),
+ SharingStarted.WhileSubscribed(),
+ DeviceState.Initial
+ )
- private val deviceListEvents = serviceConnectionManager.connectionState
- .flatMapLatest { state ->
+ private val deviceListEvents =
+ serviceConnectionManager.connectionState.flatMapLatest { state ->
if (state is ServiceConnectionState.ConnectedReady) {
state.container.deviceDataSource.deviceListUpdates
} else {
@@ -52,23 +53,21 @@ class DeviceRepository(
}
}
- val deviceList = deviceListEvents
- .map {
- if (it is DeviceListEvent.Available) {
- DeviceList.Available(it.devices)
- } else {
- DeviceList.Error
+ val deviceList =
+ deviceListEvents
+ .map {
+ if (it is DeviceListEvent.Available) {
+ DeviceList.Available(it.devices)
+ } else {
+ DeviceList.Error
+ }
}
- }
- .onStart {
- if (cachedDeviceList.value is DeviceList.Available) {
- emit(cachedDeviceList.value)
+ .onStart {
+ if (cachedDeviceList.value is DeviceList.Available) {
+ emit(cachedDeviceList.value)
+ }
}
- }
- .shareIn(
- CoroutineScope(Dispatchers.IO),
- SharingStarted.WhileSubscribed()
- )
+ .shareIn(CoroutineScope(Dispatchers.IO), SharingStarted.WhileSubscribed())
val deviceRemovalEvent: SharedFlow<Event.DeviceRemovalEvent> =
serviceConnectionManager.connectionState
@@ -79,10 +78,7 @@ class DeviceRepository(
emptyFlow()
}
}
- .shareIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed()
- )
+ .shareIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed())
fun refreshDeviceState() {
serviceConnectionManager.deviceDataSource()?.refreshDevice()
@@ -121,13 +117,12 @@ class DeviceRepository(
clearCache()
}
- val result = withTimeoutOrNull(timeoutMillis) {
- deviceListEvents
- .onStart {
- refreshDeviceList(accountToken)
- }
- .firstOrNull() ?: DeviceListEvent.Error
- } ?: DeviceListEvent.Error
+ val result =
+ withTimeoutOrNull(timeoutMillis) {
+ deviceListEvents.onStart { refreshDeviceList(accountToken) }.firstOrNull()
+ ?: DeviceListEvent.Error
+ }
+ ?: DeviceListEvent.Error
if (shouldOverrideCache) {
updateCache(result, accountToken)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/PrivacyDisclaimerRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/PrivacyDisclaimerRepository.kt
index 6096136688..db1ad220e3 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/PrivacyDisclaimerRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/PrivacyDisclaimerRepository.kt
@@ -4,9 +4,7 @@ import android.content.SharedPreferences
private const val IS_PRIVACY_DISCLOSURE_ACCEPTED_KEY = "is_privacy_disclosure_accepted"
-class PrivacyDisclaimerRepository(
- private val sharedPreferences: SharedPreferences
-) {
+class PrivacyDisclaimerRepository(private val sharedPreferences: SharedPreferences) {
fun hasAcceptedPrivacyDisclosure(): Boolean {
return sharedPreferences.getBoolean(IS_PRIVACY_DISCLOSURE_ACCEPTED_KEY, false)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt
index 59d42cf476..6eef99ecce 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt
@@ -24,28 +24,25 @@ class SettingsRepository(
private val serviceConnectionManager: ServiceConnectionManager,
dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
- val settingsUpdates: StateFlow<Settings?> = serviceConnectionManager.connectionState
- .flatMapReadyConnectionOrDefault(flowOf()) { state ->
- callbackFlowFromNotifier(state.container.settingsListener.settingsNotifier)
- }
- .onStart { serviceConnectionManager.settingsListener()?.settingsNotifier?.latestEvent }
- .stateIn(
- CoroutineScope(dispatcher),
- SharingStarted.WhileSubscribed(),
- null
- )
+ val settingsUpdates: StateFlow<Settings?> =
+ serviceConnectionManager.connectionState
+ .flatMapReadyConnectionOrDefault(flowOf()) { state ->
+ callbackFlowFromNotifier(state.container.settingsListener.settingsNotifier)
+ }
+ .onStart { serviceConnectionManager.settingsListener()?.settingsNotifier?.latestEvent }
+ .stateIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed(), null)
- fun setDnsOptions(
- isCustomDnsEnabled: Boolean,
- dnsList: List<InetAddress>
- ) {
- serviceConnectionManager.customDns()?.setDnsOptions(
- dnsOptions = DnsOptions(
- state = if (isCustomDnsEnabled) DnsState.Custom else DnsState.Default,
- customOptions = CustomDnsOptions(ArrayList(dnsList)),
- defaultOptions = DefaultDnsOptions()
+ fun setDnsOptions(isCustomDnsEnabled: Boolean, dnsList: List<InetAddress>) {
+ serviceConnectionManager
+ .customDns()
+ ?.setDnsOptions(
+ dnsOptions =
+ DnsOptions(
+ state = if (isCustomDnsEnabled) DnsState.Custom else DnsState.Default,
+ customOptions = CustomDnsOptions(ArrayList(dnsList)),
+ defaultOptions = DefaultDnsOptions()
+ )
)
- )
}
fun isLocalNetworkSharingEnabled(): Boolean {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
index 7175765e9f..fcab12c6c9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
@@ -13,9 +13,7 @@ import kotlinx.coroutines.channels.trySendBlocking
import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
import net.mullvad.mullvadvpn.util.Intermittent
-class DaemonInstance(
- private val vpnService: MullvadVpnService
-) {
+class DaemonInstance(private val vpnService: MullvadVpnService) {
sealed class Command {
data class Start(val apiEndpointConfiguration: ApiEndpointConfiguration) : Command()
object Stop : Command()
@@ -23,9 +21,8 @@ class DaemonInstance(
private val commandChannel = spawnActor()
- private var daemon by observable<MullvadDaemon?>(null) { _, oldInstance, _ ->
- oldInstance?.onDestroy()
- }
+ private var daemon by
+ observable<MullvadDaemon?>(null) { _, oldInstance, _ -> oldInstance?.onDestroy() }
val intermittentDaemon = Intermittent<MullvadDaemon>()
@@ -42,16 +39,17 @@ class DaemonInstance(
intermittentDaemon.onDestroy()
}
- private fun spawnActor() = GlobalScope.actor(Dispatchers.Default, Channel.UNLIMITED) {
- var isRunning = true
+ private fun spawnActor() =
+ GlobalScope.actor(Dispatchers.Default, Channel.UNLIMITED) {
+ var isRunning = true
- while (isRunning) {
- val startCommand = waitForCommand(channel, Command.Start::class) ?: break
- startDaemon(startCommand.apiEndpointConfiguration)
- isRunning = waitForCommand(channel, Command.Stop::class) is Command.Stop
- stopDaemon()
+ while (isRunning) {
+ val startCommand = waitForCommand(channel, Command.Start::class) ?: break
+ startDaemon(startCommand.apiEndpointConfiguration)
+ isRunning = waitForCommand(channel, Command.Stop::class) is Command.Stop
+ stopDaemon()
+ }
}
- }
private suspend fun <T : Command> waitForCommand(
channel: ReceiveChannel<Command>,
@@ -68,15 +66,14 @@ class DaemonInstance(
}
}
- private suspend fun startDaemon(
- apiEndpointConfiguration: ApiEndpointConfiguration
- ) {
- val newDaemon = MullvadDaemon(vpnService, apiEndpointConfiguration).apply {
- onDaemonStopped = {
- intermittentDaemon.spawnUpdate(null)
- daemon = null
+ private suspend fun startDaemon(apiEndpointConfiguration: ApiEndpointConfiguration) {
+ val newDaemon =
+ MullvadDaemon(vpnService, apiEndpointConfiguration).apply {
+ onDaemonStopped = {
+ intermittentDaemon.spawnUpdate(null)
+ daemon = null
+ }
}
- }
daemon = newDaemon
intermittentDaemon.update(newDaemon)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
index f7a179a35e..8fb7108619 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt
@@ -32,9 +32,8 @@ class ForegroundNotificationManager(
private val tunnelStateNotification = TunnelStateNotification(service)
- private var loggedIn by observable(false) { _, _, _ ->
- updater.trySendBlocking(UpdaterMessage.UpdateAction())
- }
+ private var loggedIn by
+ observable(false) { _, _, _ -> updater.trySendBlocking(UpdaterMessage.UpdateAction()) }
private val tunnelState
get() = connectionProxy.onStateChange.latestEvent
@@ -45,9 +44,10 @@ class ForegroundNotificationManager(
var onForeground = false
private set
- var lockedToForeground by observable(false) { _, _, _ ->
- updater.trySendBlocking(UpdaterMessage.UpdateNotification())
- }
+ var lockedToForeground by
+ observable(false) { _, _, _ ->
+ updater.trySendBlocking(UpdaterMessage.UpdateNotification())
+ }
init {
connectionProxy.onStateChange.subscribe(this) { newState ->
@@ -56,13 +56,10 @@ class ForegroundNotificationManager(
intermittentDaemon.registerListener(this) { daemon ->
jobTracker.newBackgroundJob("notificationLoggedInJob") {
- daemon?.deviceStateUpdates
- ?.onStart {
- emit(daemon.getAndEmitDeviceState())
- }
- ?.collect { deviceState ->
- loggedIn = deviceState is DeviceState.LoggedIn
- }
+ daemon
+ ?.deviceStateUpdates
+ ?.onStart { emit(daemon.getAndEmitDeviceState()) }
+ ?.collect { deviceState -> loggedIn = deviceState is DeviceState.LoggedIn }
}
}
@@ -76,21 +73,19 @@ class ForegroundNotificationManager(
updater.close()
}
- private fun runUpdater() = GlobalScope.actor<UpdaterMessage>(
- Dispatchers.Main,
- Channel.UNLIMITED
- ) {
- for (message in channel) {
- when (message) {
- is UpdaterMessage.UpdateNotification -> updateNotification()
- is UpdaterMessage.UpdateAction -> updateNotificationAction()
- is UpdaterMessage.NewTunnelState -> {
- tunnelStateNotification.tunnelState = message.newState
- updateNotification()
+ private fun runUpdater() =
+ GlobalScope.actor<UpdaterMessage>(Dispatchers.Main, Channel.UNLIMITED) {
+ for (message in channel) {
+ when (message) {
+ is UpdaterMessage.UpdateNotification -> updateNotification()
+ is UpdaterMessage.UpdateAction -> updateNotificationAction()
+ is UpdaterMessage.NewTunnelState -> {
+ tunnelStateNotification.tunnelState = message.newState
+ updateNotification()
+ }
}
}
}
- }
fun showOnForeground() {
service.startForeground(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
index e26ae28697..96630a2cec 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt
@@ -45,15 +45,17 @@ class MullvadTileService : TileService() {
delay(unlockCheckDelayMillis)
}
return@withTimeoutOrNull true
- } ?: false
+ }
+ ?: false
}
unlockAndRun {
runBlocking {
- val isUnlockStatusPropagated = isUnlockStatusPropagatedWithinTimeout(
- unlockTimeoutMillis = 1000L,
- unlockCheckDelayMillis = 100L
- )
+ val isUnlockStatusPropagated =
+ isUnlockStatusPropagatedWithinTimeout(
+ unlockTimeoutMillis = 1000L,
+ unlockCheckDelayMillis = 100L
+ )
if (isUnlockStatusPropagated) {
toggleTunnel()
@@ -73,13 +75,15 @@ class MullvadTileService : TileService() {
}
private fun toggleTunnel() {
- val intent = Intent(this, MullvadVpnService::class.java).apply {
- action = if (qsTile.state == Tile.STATE_INACTIVE) {
- MullvadVpnService.KEY_CONNECT_ACTION
- } else {
- MullvadVpnService.KEY_DISCONNECT_ACTION
+ val intent =
+ Intent(this, MullvadVpnService::class.java).apply {
+ action =
+ if (qsTile.state == Tile.STATE_INACTIVE) {
+ MullvadVpnService.KEY_CONNECT_ACTION
+ } else {
+ MullvadVpnService.KEY_DISCONNECT_ACTION
+ }
}
- }
// Always start as foreground in case tile is out-of-sync.
startForegroundService(intent)
@@ -91,9 +95,7 @@ class MullvadTileService : TileService() {
.tunnelState
.debounce(300L)
.map { (tunnelState, connectionState) -> mapToTileState(tunnelState, connectionState) }
- .collect {
- updateTileState(it)
- }
+ .collect { updateTileState(it) }
}
private fun mapToTileState(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index c35125c326..0058b09e4f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -62,11 +62,10 @@ class MullvadVpnService : TalpidVpnService() {
private lateinit var keyguardManager: KeyguardManager
private lateinit var notificationManager: ForegroundNotificationManager
- private var pendingAction by observable<PendingAction?>(null) { _, _, _ ->
- endpoint.settingsListener.settings?.let { settings ->
- handlePendingAction(settings)
+ private var pendingAction by
+ observable<PendingAction?>(null) { _, _, _ ->
+ endpoint.settingsListener.settings?.let { settings -> handlePendingAction(settings) }
}
- }
private var apiEndpointConfiguration: ApiEndpointConfiguration =
DefaultApiEndpointConfiguration()
@@ -80,12 +79,13 @@ class MullvadVpnService : TalpidVpnService() {
daemonInstance = DaemonInstance(this)
keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
- endpoint = ServiceEndpoint(
- Looper.getMainLooper(),
- daemonInstance.intermittentDaemon,
- connectivityListener,
- this
- )
+ endpoint =
+ ServiceEndpoint(
+ Looper.getMainLooper(),
+ daemonInstance.intermittentDaemon,
+ connectivityListener,
+ this
+ )
endpoint.splitTunneling.onChange.subscribe(this@MullvadVpnService) { excludedApps ->
disallowedApps = excludedApps
@@ -93,32 +93,25 @@ class MullvadVpnService : TalpidVpnService() {
connectionProxy.reconnect()
}
- notificationManager = ForegroundNotificationManager(
- this,
- connectionProxy,
- daemonInstance.intermittentDaemon
- )
+ notificationManager =
+ ForegroundNotificationManager(this, connectionProxy, daemonInstance.intermittentDaemon)
- accountExpiryNotification = AccountExpiryNotification(
- this,
- daemonInstance.intermittentDaemon,
- endpoint.accountCache
- )
+ accountExpiryNotification =
+ AccountExpiryNotification(
+ this,
+ daemonInstance.intermittentDaemon,
+ endpoint.accountCache
+ )
// Remove any leftover tunnel state persistence data
- getSharedPreferences("tunnel_state", MODE_PRIVATE)
- .edit()
- .clear()
- .commit()
+ getSharedPreferences("tunnel_state", MODE_PRIVATE).edit().clear().commit()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "Starting service")
if (BuildConfig.DEBUG) {
- intent?.getApiEndpointConfigurationExtras()?.let {
- apiEndpointConfiguration = it
- }
+ intent?.getApiEndpointConfigurationExtras()?.let { apiEndpointConfiguration = it }
}
daemonInstance.apply {
@@ -219,17 +212,18 @@ class MullvadVpnService : TalpidVpnService() {
}
}
- private fun setUpDaemon(daemon: MullvadDaemon) = GlobalScope.launch(Dispatchers.Main) {
- if (state != State.Stopped) {
- val settings = daemon.getSettings()
+ private fun setUpDaemon(daemon: MullvadDaemon) =
+ GlobalScope.launch(Dispatchers.Main) {
+ if (state != State.Stopped) {
+ val settings = daemon.getSettings()
- if (settings != null) {
- handlePendingAction(settings)
- } else {
- restart()
+ if (settings != null) {
+ handlePendingAction(settings)
+ } else {
+ restart()
+ }
}
}
- }
private fun stop() {
Log.d(TAG, "Stopping service")
@@ -270,10 +264,11 @@ class MullvadVpnService : TalpidVpnService() {
}
private fun openUi() {
- val intent = Intent(this, MainActivity::class.java).apply {
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- }
+ val intent =
+ Intent(this, MainActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ }
startActivity(intent)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
index b363dbbe5f..e33e3d028f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
@@ -48,9 +48,12 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
init {
jobTracker.newBackgroundJob("autoFetchAccountExpiry") {
daemon.await().deviceStateUpdates.collect { deviceState ->
- accountExpiry = deviceState.token()
- .also { cachedAccountToken = it }
- ?.let { fetchAccountExpiry(it) } ?: AccountExpiry.Missing
+ accountExpiry =
+ deviceState
+ .token()
+ .also { cachedAccountToken = it }
+ ?.let { fetchAccountExpiry(it) }
+ ?: AccountExpiry.Missing
}
}
@@ -58,9 +61,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
endpoint.sendEvent(Event.AccountHistoryEvent(history))
}
- onAccountExpiryChange.subscribe(this) {
- endpoint.sendEvent(Event.AccountExpiryEvent(it))
- }
+ onAccountExpiryChange.subscribe(this) { endpoint.sendEvent(Event.AccountExpiryEvent(it)) }
endpoint.dispatcher.apply {
registerHandler(Request.CreateAccount::class) { _ ->
@@ -79,8 +80,8 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
registerHandler(Request.FetchAccountExpiry::class) { _ ->
jobTracker.newBackgroundJob("fetchAccountExpiry") {
- accountExpiry = cachedAccountToken
- ?.let { fetchAccountExpiry(it) } ?: AccountExpiry.Missing
+ accountExpiry =
+ cachedAccountToken?.let { fetchAccountExpiry(it) } ?: AccountExpiry.Missing
}
}
@@ -91,9 +92,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
}
registerHandler(Request.ClearAccountHistory::class) { _ ->
- jobTracker.newBackgroundJob("clearAccountHistory") {
- clearAccountHistory()
- }
+ jobTracker.newBackgroundJob("clearAccountHistory") { clearAccountHistory() }
}
}
}
@@ -107,19 +106,20 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
commandChannel.close()
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- for (command in channel) {
- when (command) {
- is Command.CreateAccount -> doCreateAccount()
- is Command.Login -> doLogin(command.account)
- is Command.Logout -> doLogout()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ for (command in channel) {
+ when (command) {
+ is Command.CreateAccount -> doCreateAccount()
+ is Command.Login -> doLogin(command.account)
+ is Command.Logout -> doLogout()
+ }
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Command channel was closed, stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Command channel was closed, stop the actor
}
- }
private suspend fun clearAccountHistory() {
daemon.await().clearAccountHistory()
@@ -127,10 +127,10 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
}
private suspend fun doCreateAccount() {
- daemon.await().createNewAccount()
- .also { newAccountToken ->
- cachedCreatedAccountToken = newAccountToken
- }
+ daemon
+ .await()
+ .createNewAccount()
+ .also { newAccountToken -> cachedCreatedAccountToken = newAccountToken }
.let { newAccountToken ->
if (newAccountToken != null) {
AccountCreationResult.Success(newAccountToken)
@@ -138,9 +138,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
AccountCreationResult.Failure
}
}
- .also { result ->
- endpoint.sendEvent(Event.AccountCreationEvent(result))
- }
+ .also { result -> endpoint.sendEvent(Event.AccountCreationEvent(result)) }
}
private suspend fun doLogin(account: String) {
@@ -169,7 +167,8 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
if (result is GetAccountDataResult.Ok) {
result.accountData.expiry.parseAsDateTime()?.let { parsedDateTime ->
AccountExpiry.Available(parsedDateTime)
- } ?: AccountExpiry.Missing
+ }
+ ?: AccountExpiry.Missing
} else {
AccountExpiry.Missing
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt
index 0c95293ae7..596ad21a3f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt
@@ -8,14 +8,16 @@ import net.mullvad.mullvadvpn.service.MullvadDaemon
class AppVersionInfoCache(endpoint: ServiceEndpoint) {
private val daemon = endpoint.intermittentDaemon
- var appVersionInfo by observable<AppVersionInfo?>(null) { _, _, info ->
- endpoint.sendEvent(Event.AppVersionInfo(info))
- }
+ var appVersionInfo by
+ observable<AppVersionInfo?>(null) { _, _, info ->
+ endpoint.sendEvent(Event.AppVersionInfo(info))
+ }
private set
- var currentVersion by observable<String?>(null) { _, _, version ->
- endpoint.sendEvent(Event.CurrentVersion(version))
- }
+ var currentVersion by
+ observable<String?>(null) { _, _, version ->
+ endpoint.sendEvent(Event.CurrentVersion(version))
+ }
private set
init {
@@ -40,9 +42,7 @@ class AppVersionInfoCache(endpoint: ServiceEndpoint) {
private fun registerVersionInfoListener(daemon: MullvadDaemon) {
daemon.onAppVersionInfoChange = { newAppVersionInfo ->
- synchronized(this@AppVersionInfoCache) {
- appVersionInfo = newAppVersionInfo
- }
+ synchronized(this@AppVersionInfoCache) { appVersionInfo = newAppVersionInfo }
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt
index add7a7ed06..49c4d1faac 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt
@@ -20,9 +20,8 @@ class AuthTokenCache(endpoint: ServiceEndpoint) {
private val daemon = endpoint.intermittentDaemon
private val requestQueue = spawnActor()
- var authToken by observable<String?>(null) { _, _, token ->
- endpoint.sendEvent(Event.AuthToken(token))
- }
+ var authToken by
+ observable<String?>(null) { _, _, token -> endpoint.sendEvent(Event.AuthToken(token)) }
private set
init {
@@ -35,15 +34,16 @@ class AuthTokenCache(endpoint: ServiceEndpoint) {
requestQueue.close()
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- for (command in channel) {
- when (command) {
- Command.Fetch -> authToken = daemon.await().getWwwAuthToken()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ for (command in channel) {
+ when (command) {
+ Command.Fetch -> authToken = daemon.await().getWwwAuthToken()
+ }
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt
index 03808dcb94..fcdcece119 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt
@@ -63,22 +63,23 @@ class ConnectionProxy(val vpnPermission: VpnPermission, endpoint: ServiceEndpoin
daemon.unregisterListener(this)
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- while (true) {
- val command = channel.receive()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ while (true) {
+ val command = channel.receive()
- when (command) {
- Command.CONNECT -> {
- vpnPermission.request()
- daemon.await().connect()
+ when (command) {
+ Command.CONNECT -> {
+ vpnPermission.request()
+ daemon.await().connect()
+ }
+ Command.RECONNECT -> daemon.await().reconnect()
+ Command.DISCONNECT -> daemon.await().disconnect()
}
- Command.RECONNECT -> daemon.await().reconnect()
- Command.DISCONNECT -> daemon.await().disconnect()
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt
index 62943ee0cb..5a24bea643 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt
@@ -15,14 +15,11 @@ import net.mullvad.mullvadvpn.model.DnsState
class CustomDns(private val endpoint: ServiceEndpoint) {
private sealed class Command {
- @Deprecated("Use SetDnsOptions")
- class AddDnsServer(val server: InetAddress) : Command()
- @Deprecated("Use SetDnsOptions")
- class RemoveDnsServer(val server: InetAddress) : Command()
+ @Deprecated("Use SetDnsOptions") class AddDnsServer(val server: InetAddress) : Command()
+ @Deprecated("Use SetDnsOptions") class RemoveDnsServer(val server: InetAddress) : Command()
@Deprecated("Use SetDnsOptions")
class ReplaceDnsServer(val oldServer: InetAddress, val newServer: InetAddress) : Command()
- @Deprecated("Use SetDnsOptions")
- class SetEnabled(val enabled: Boolean) : Command()
+ @Deprecated("Use SetDnsOptions") class SetEnabled(val enabled: Boolean) : Command()
class SetDnsOptions(val dnsOptions: DnsOptions) : Command()
}
@@ -74,25 +71,26 @@ class CustomDns(private val endpoint: ServiceEndpoint) {
commandChannel.close()
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- while (true) {
- val command = channel.receive()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ while (true) {
+ val command = channel.receive()
- when (command) {
- is Command.AddDnsServer -> doAddDnsServer(command.server)
- is Command.RemoveDnsServer -> doRemoveDnsServer(command.server)
- is Command.ReplaceDnsServer -> {
- doReplaceDnsServer(command.oldServer, command.newServer)
+ when (command) {
+ is Command.AddDnsServer -> doAddDnsServer(command.server)
+ is Command.RemoveDnsServer -> doRemoveDnsServer(command.server)
+ is Command.ReplaceDnsServer -> {
+ doReplaceDnsServer(command.oldServer, command.newServer)
+ }
+ is Command.SetEnabled -> changeDnsOptions(command.enabled)
+ is Command.SetDnsOptions -> setDnsOptions(command.dnsOptions)
}
- is Command.SetEnabled -> changeDnsOptions(command.enabled)
- is Command.SetDnsOptions -> setDnsOptions(command.dnsOptions)
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
}
- }
private suspend fun doAddDnsServer(server: InetAddress) {
if (!dnsServers.contains(server)) {
@@ -120,11 +118,12 @@ class CustomDns(private val endpoint: ServiceEndpoint) {
}
private suspend fun changeDnsOptions(enable: Boolean) {
- val options = DnsOptions(
- state = if (enable) DnsState.Custom else DnsState.Default,
- customOptions = CustomDnsOptions(dnsServers),
- defaultOptions = DefaultDnsOptions()
- )
+ val options =
+ DnsOptions(
+ state = if (enable) DnsState.Custom else DnsState.Default,
+ customOptions = CustomDnsOptions(dnsServers),
+ defaultOptions = DefaultDnsOptions()
+ )
daemon.await().setDnsOptions(options)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt
index 9bdf30de21..8f49ba2763 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt
@@ -6,9 +6,7 @@ import net.mullvad.mullvadvpn.ipc.Request
import net.mullvad.mullvadvpn.service.MullvadDaemon
import net.mullvad.mullvadvpn.util.JobTracker
-class DaemonDeviceDataSource(
- val endpoint: ServiceEndpoint
-) {
+class DaemonDeviceDataSource(val endpoint: ServiceEndpoint) {
private val tracker = JobTracker()
init {
@@ -35,15 +33,11 @@ class DaemonDeviceDataSource(
}
endpoint.dispatcher.registerHandler(Request.GetDevice::class) {
- tracker.newBackgroundJob("getDeviceJob") {
- daemon.getAndEmitDeviceState()
- }
+ tracker.newBackgroundJob("getDeviceJob") { daemon.getAndEmitDeviceState() }
}
endpoint.dispatcher.registerHandler(Request.RefreshDeviceState::class) {
- tracker.newBackgroundJob("refreshDeviceJob") {
- daemon.refreshDevice()
- }
+ tracker.newBackgroundJob("refreshDeviceJob") { daemon.refreshDevice() }
}
endpoint.dispatcher.registerHandler(Request.RemoveDevice::class) { request ->
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt
index 4fbc1fab4b..7cc43925d7 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt
@@ -29,11 +29,12 @@ class LocationInfoCache(private val endpoint: ServiceEndpoint) {
}
}
- private val fetchRetryDelays = ExponentialBackoff().apply {
- scale = 50
- cap = 30 /* min */ * 60 /* s */ * 1000 /* ms */
- count = 17 // ceil(log2(cap / scale) + 1)
- }
+ private val fetchRetryDelays =
+ ExponentialBackoff().apply {
+ scale = 50
+ cap = 30 /* min */ * 60 /* s */ * 1000 /* ms */
+ count = 17 // ceil(log2(cap / scale) + 1)
+ }
private val fetchRequestChannel = runFetcher()
@@ -43,36 +44,34 @@ class LocationInfoCache(private val endpoint: ServiceEndpoint) {
private var lastKnownRealLocation: GeoIpLocation? = null
private var selectedRelayLocation: GeoIpLocation? = null
- var location: GeoIpLocation? by observable(null) { _, _, newLocation ->
- endpoint.sendEvent(Event.NewLocation(newLocation))
- }
+ var location: GeoIpLocation? by
+ observable(null) { _, _, newLocation -> endpoint.sendEvent(Event.NewLocation(newLocation)) }
- var state by observable<TunnelState>(TunnelState.Disconnected) { _, _, newState ->
- when (newState) {
- is TunnelState.Disconnected -> {
- location = lastKnownRealLocation
- fetchRequestChannel.trySendBlocking(RequestFetch.ForRealLocation)
- }
- is TunnelState.Connecting -> location = newState.location
- is TunnelState.Connected -> {
- location = newState.location
- fetchRequestChannel.trySendBlocking(RequestFetch.ForRelayLocation)
- }
- is TunnelState.Disconnecting -> {
- when (newState.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> location = lastKnownRealLocation
- ActionAfterDisconnect.Block -> location = null
- ActionAfterDisconnect.Reconnect -> location = selectedRelayLocation
+ var state by
+ observable<TunnelState>(TunnelState.Disconnected) { _, _, newState ->
+ when (newState) {
+ is TunnelState.Disconnected -> {
+ location = lastKnownRealLocation
+ fetchRequestChannel.trySendBlocking(RequestFetch.ForRealLocation)
}
+ is TunnelState.Connecting -> location = newState.location
+ is TunnelState.Connected -> {
+ location = newState.location
+ fetchRequestChannel.trySendBlocking(RequestFetch.ForRelayLocation)
+ }
+ is TunnelState.Disconnecting -> {
+ when (newState.actionAfterDisconnect) {
+ ActionAfterDisconnect.Nothing -> location = lastKnownRealLocation
+ ActionAfterDisconnect.Block -> location = null
+ ActionAfterDisconnect.Reconnect -> location = selectedRelayLocation
+ }
+ }
+ is TunnelState.Error -> location = null
}
- is TunnelState.Error -> location = null
}
- }
init {
- endpoint.connectionProxy.onStateChange.subscribe(this) { newState ->
- state = newState
- }
+ endpoint.connectionProxy.onStateChange.subscribe(this) { newState -> state = newState }
endpoint.connectivityListener.connectivityNotifier.subscribe(this) { isConnected ->
if (isConnected && state is TunnelState.Disconnected) {
@@ -91,18 +90,16 @@ class LocationInfoCache(private val endpoint: ServiceEndpoint) {
fetchRequestChannel.close()
}
- private fun runFetcher() = GlobalScope.actor<RequestFetch>(
- Dispatchers.Default,
- Channel.CONFLATED
- ) {
- try {
- fetcherLoop(channel)
- } catch (exception: ClosedReceiveChannelException) {
+ private fun runFetcher() =
+ GlobalScope.actor<RequestFetch>(Dispatchers.Default, Channel.CONFLATED) {
+ try {
+ fetcherLoop(channel)
+ } catch (exception: ClosedReceiveChannelException) {}
}
- }
private suspend fun fetcherLoop(channel: ReceiveChannel<RequestFetch>) {
- channel.receiveAsFlow()
+ channel
+ .receiveAsFlow()
.flatMapLatest(::fetchCurrentLocation)
.collect(::handleFetchedLocation)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
index 1f59de4074..7515bad230 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt
@@ -26,13 +26,15 @@ class RelayListListener(endpoint: ServiceEndpoint) {
private val commandChannel = spawnActor()
private val daemon = endpoint.intermittentDaemon
- private var selectedRelayLocation by observable<LocationConstraint?>(null) { _, _, _ ->
- commandChannel.trySendBlocking(Command.SetRelayLocation)
- }
+ private var selectedRelayLocation by
+ observable<LocationConstraint?>(null) { _, _, _ ->
+ commandChannel.trySendBlocking(Command.SetRelayLocation)
+ }
- var relayList by observable<RelayList?>(null) { _, _, relays ->
- endpoint.sendEvent(Event.NewRelayList(relays))
- }
+ var relayList by
+ observable<RelayList?>(null) { _, _, relays ->
+ endpoint.sendEvent(Event.NewRelayList(relays))
+ }
private set
init {
@@ -54,9 +56,7 @@ class RelayListListener(endpoint: ServiceEndpoint) {
}
private fun setUpListener(daemon: MullvadDaemon) {
- daemon.onRelayListChange = { relayLocations ->
- relayList = relayLocations
- }
+ daemon.onRelayListChange = { relayLocations -> relayList = relayLocations }
}
private fun fetchInitialRelayList(daemon: MullvadDaemon) {
@@ -67,22 +67,22 @@ class RelayListListener(endpoint: ServiceEndpoint) {
}
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.CONFLATED) {
- try {
- for (command in channel) {
- when (command) {
- Command.SetRelayLocation -> updateRelayConstraints()
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.CONFLATED) {
+ try {
+ for (command in channel) {
+ when (command) {
+ Command.SetRelayLocation -> updateRelayConstraints()
+ }
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
}
- }
private suspend fun updateRelayConstraints() {
- val constraint: Constraint<LocationConstraint> = selectedRelayLocation?.let { location ->
- Constraint.Only(location)
- } ?: Constraint.Any()
+ val constraint: Constraint<LocationConstraint> =
+ selectedRelayLocation?.let { location -> Constraint.Only(location) } ?: Constraint.Any()
val update = RelaySettingsUpdate.Normal(RelayConstraintsUpdate(constraint))
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
index 4230aa14f1..eb3bf3627a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
@@ -37,9 +37,7 @@ class ServiceEndpoint(
private val listeners = mutableMapOf<Int, Messenger>()
private val commands: SendChannel<Command> = startRegistrator()
- internal val dispatcher = DispatchingHandler(looper) { message ->
- Request.fromMessage(message)
- }
+ internal val dispatcher = DispatchingHandler(looper) { message -> Request.fromMessage(message) }
private var listenerIdCounter = 0
@@ -95,11 +93,7 @@ class ServiceEndpoint(
val deadListeners = mutableSetOf<Int>()
for ((id, listener) in listeners) {
- if (!listener.trySendEvent(
- event,
- SHOULD_LOG_DEAD_OBJECT_EXCEPTION
- )
- ) {
+ if (!listener.trySendEvent(event, SHOULD_LOG_DEAD_OBJECT_EXCEPTION)) {
deadListeners.add(id)
}
}
@@ -107,25 +101,23 @@ class ServiceEndpoint(
}
}
- private fun startRegistrator() = GlobalScope.actor<Command>(
- Dispatchers.Default,
- Channel.UNLIMITED
- ) {
- try {
- for (command in channel) {
- when (command) {
- is Command.RegisterListener -> {
- intermittentDaemon.await()
+ private fun startRegistrator() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ for (command in channel) {
+ when (command) {
+ is Command.RegisterListener -> {
+ intermittentDaemon.await()
- registerListener(command.listener)
+ registerListener(command.listener)
+ }
+ is Command.UnregisterListener -> unregisterListener(command.listenerId)
}
- is Command.UnregisterListener -> unregisterListener(command.listenerId)
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Registration queue closed; stop registrator
}
- } catch (exception: ClosedReceiveChannelException) {
- // Registration queue closed; stop registrator
}
- }
private fun registerListener(listener: Messenger) {
synchronized(this) {
@@ -133,29 +125,28 @@ class ServiceEndpoint(
listeners.put(listenerId, listener)
- val initialEvents = mutableListOf(
- Event.TunnelStateChange(connectionProxy.state),
- Event.AccountHistoryEvent(accountCache.onAccountHistoryChange.latestEvent),
- Event.SettingsUpdate(settingsListener.settings),
- Event.NewLocation(locationInfoCache.location),
- Event.SplitTunnelingUpdate(splitTunneling.onChange.latestEvent),
- Event.CurrentVersion(appVersionInfoCache.currentVersion),
- Event.AppVersionInfo(appVersionInfoCache.appVersionInfo),
- Event.NewRelayList(relayListListener.relayList),
- Event.AuthToken(authTokenCache.authToken),
- Event.ListenerReady(messenger, listenerId)
- )
+ val initialEvents =
+ mutableListOf(
+ Event.TunnelStateChange(connectionProxy.state),
+ Event.AccountHistoryEvent(accountCache.onAccountHistoryChange.latestEvent),
+ Event.SettingsUpdate(settingsListener.settings),
+ Event.NewLocation(locationInfoCache.location),
+ Event.SplitTunnelingUpdate(splitTunneling.onChange.latestEvent),
+ Event.CurrentVersion(appVersionInfoCache.currentVersion),
+ Event.AppVersionInfo(appVersionInfoCache.appVersionInfo),
+ Event.NewRelayList(relayListListener.relayList),
+ Event.AuthToken(authTokenCache.authToken),
+ Event.ListenerReady(messenger, listenerId)
+ )
if (vpnPermission.waitingForResponse) {
initialEvents.add(Event.VpnPermissionRequest)
}
- val didSuccessfullySendAllMessages = initialEvents.all { event ->
- listener.trySendEvent(
- event,
- SHOULD_LOG_DEAD_OBJECT_EXCEPTION
- )
- }
+ val didSuccessfullySendAllMessages =
+ initialEvents.all { event ->
+ listener.trySendEvent(event, SHOULD_LOG_DEAD_OBJECT_EXCEPTION)
+ }
if (didSuccessfullySendAllMessages.not()) {
listeners.remove(listenerId)
}
@@ -163,9 +154,7 @@ class ServiceEndpoint(
}
private fun unregisterListener(listenerId: Int) {
- synchronized(this) {
- listeners.remove(listenerId)
- }
+ synchronized(this) { listeners.remove(listenerId) }
}
private fun newListenerId(): Int {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt
index b44daaf0d6..772e3127b9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt
@@ -69,9 +69,7 @@ class SettingsListener(endpoint: ServiceEndpoint) {
fun subscribe(id: Any, listener: (Settings) -> Unit) {
settingsNotifier.subscribe(id) { maybeSettings ->
- maybeSettings?.let { settings ->
- listener(settings)
- }
+ maybeSettings?.let { settings -> listener(settings) }
}
}
@@ -84,9 +82,7 @@ class SettingsListener(endpoint: ServiceEndpoint) {
}
private fun fetchInitialSettings(daemon: MullvadDaemon) {
- synchronized(this) {
- handleNewSettings(daemon.getSettings())
- }
+ synchronized(this) { handleNewSettings(daemon.getSettings()) }
}
private fun handleNewSettings(newSettings: Settings?) {
@@ -105,17 +101,19 @@ class SettingsListener(endpoint: ServiceEndpoint) {
}
}
- private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- for (command in channel) {
- when (command) {
- is Command.SetAllowLan -> daemon.await().setAllowLan(command.allow)
- is Command.SetAutoConnect -> daemon.await().setAutoConnect(command.autoConnect)
- is Command.SetWireGuardMtu -> daemon.await().setWireguardMtu(command.mtu)
+ private fun spawnActor() =
+ GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ for (command in channel) {
+ when (command) {
+ is Command.SetAllowLan -> daemon.await().setAllowLan(command.allow)
+ is Command.SetAutoConnect ->
+ daemon.await().setAutoConnect(command.autoConnect)
+ is Command.SetWireGuardMtu -> daemon.await().setWireguardMtu(command.mtu)
+ }
}
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Closed sender, so stop the actor
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt
index d6455ea9a3..6ae5ce8ef4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt
@@ -9,12 +9,13 @@ import net.mullvad.talpid.util.EventNotifier
class SplitTunneling(persistence: SplitTunnelingPersistence, endpoint: ServiceEndpoint) {
private val excludedApps = persistence.excludedApps.toMutableSet()
- private var enabled by observable(persistence.enabled) { _, wasEnabled, isEnabled ->
- if (wasEnabled != isEnabled) {
- persistence.enabled = isEnabled
- update()
+ private var enabled by
+ observable(persistence.enabled) { _, wasEnabled, isEnabled ->
+ if (wasEnabled != isEnabled) {
+ persistence.enabled = isEnabled
+ update()
+ }
}
- }
val onChange = EventNotifier<List<String>?>(excludedApps.toList())
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt
index c1433b7a3c..850afa6d90 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt
@@ -25,15 +25,16 @@ class VoucherRedeemer(private val endpoint: ServiceEndpoint) {
voucherChannel.close()
}
- private fun spawnActor() = GlobalScope.actor<String>(Dispatchers.Default, Channel.UNLIMITED) {
- try {
- for (voucher in channel) {
- val result = daemon.await().submitVoucher(voucher)
+ private fun spawnActor() =
+ GlobalScope.actor<String>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ for (voucher in channel) {
+ val result = daemon.await().submitVoucher(voucher)
- endpoint.sendEvent(Event.VoucherSubmissionResult(voucher, result))
+ endpoint.sendEvent(Event.VoucherSubmissionResult(voucher, result))
+ }
+ } catch (exception: ClosedReceiveChannelException) {
+ // Voucher channel was closed, stop the actor
}
- } catch (exception: ClosedReceiveChannelException) {
- // Voucher channel was closed, stop the actor
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt
index b92dab3f98..b5b4875e04 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt
@@ -27,10 +27,11 @@ class VpnPermission(private val context: Context, private val endpoint: ServiceE
if (intent == null) {
isGranted.update(true)
} else {
- val activityIntent = Intent(context, MainActivity::class.java).apply {
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- }
+ val activityIntent =
+ Intent(context, MainActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ }
isGranted.update(null)
waitingForResponse = true
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt
index cdad8e327f..ac3fbcb139 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt
@@ -36,29 +36,27 @@ class AccountExpiryNotification(
private val buyMoreTimeUrl = resources.getString(R.string.account_url)
- private val channel = NotificationChannel(
- context,
- "mullvad_account_time",
- NotificationCompat.VISIBILITY_PRIVATE,
- R.string.account_time_notification_channel_name,
- R.string.account_time_notification_channel_description,
- NotificationManager.IMPORTANCE_HIGH,
- true,
- true
- )
+ private val channel =
+ NotificationChannel(
+ context,
+ "mullvad_account_time",
+ NotificationCompat.VISIBILITY_PRIVATE,
+ R.string.account_time_notification_channel_name,
+ R.string.account_time_notification_channel_description,
+ NotificationManager.IMPORTANCE_HIGH,
+ true,
+ true
+ )
- var accountExpiry by observable<AccountExpiry>(
- AccountExpiry.Missing
- ) { _, oldValue, newValue ->
- if (oldValue != newValue) {
- jobTracker.newUiJob("update") { update(newValue) }
+ var accountExpiry by
+ observable<AccountExpiry>(AccountExpiry.Missing) { _, oldValue, newValue ->
+ if (oldValue != newValue) {
+ jobTracker.newUiJob("update") { update(newValue) }
+ }
}
- }
init {
- accountCache.onAccountExpiryChange.subscribe(this) { expiry ->
- accountExpiry = expiry
- }
+ accountCache.onAccountExpiryChange.subscribe(this) { expiry -> accountExpiry = expiry }
}
fun onDestroy() {
@@ -95,9 +93,10 @@ class AccountExpiryNotification(
}
private suspend fun build(expiry: DateTime, remainingTime: Duration): Notification {
- val url = jobTracker.runOnBackground {
- Uri.parse("$buyMoreTimeUrl?token=${daemon.await().getWwwAuthToken()}")
- }
+ val url =
+ jobTracker.runOnBackground {
+ Uri.parse("$buyMoreTimeUrl?token=${daemon.await().getWwwAuthToken()}")
+ }
val intent = Intent(Intent.ACTION_VIEW, url)
val pendingIntent =
PendingIntent.getActivity(context, 1, intent, SdkUtils.getSupportedPendingIntentFlags())
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt
index 052866b549..de557aaf22 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt
@@ -18,9 +18,7 @@ class NotificationChannel(
isVibrationEnabled: Boolean,
isBadgeEnabled: Boolean
) {
- private val badgeColor by lazy {
- context.getColor(R.color.colorPrimary)
- }
+ private val badgeColor by lazy { context.getColor(R.color.colorPrimary) }
val notificationManager = NotificationManagerCompat.from(context)
@@ -28,12 +26,13 @@ class NotificationChannel(
val channelName = context.getString(name)
val channelDescription = context.getString(description)
- val channel = NotificationChannelCompat.Builder(id, importance)
- .setName(channelName)
- .setDescription(channelDescription)
- .setShowBadge(isBadgeEnabled)
- .setVibrationEnabled(isVibrationEnabled)
- .build()
+ val channel =
+ NotificationChannelCompat.Builder(id, importance)
+ .setName(channelName)
+ .setDescription(channelDescription)
+ .setShowBadge(isBadgeEnabled)
+ .setVibrationEnabled(isVibrationEnabled)
+ .build()
notificationManager.createNotificationChannel(channel)
}
@@ -79,20 +78,19 @@ class NotificationChannel(
deleteIntent: PendingIntent? = null,
isOngoing: Boolean = false
): Notification {
- val builder = NotificationCompat.Builder(context, id)
- .setSmallIcon(R.drawable.small_logo_black)
- .setColor(badgeColor)
- .setContentTitle(title)
- .setContentIntent(pendingIntent)
- .setVisibility(visibility)
- .setOngoing(isOngoing)
+ val builder =
+ NotificationCompat.Builder(context, id)
+ .setSmallIcon(R.drawable.small_logo_black)
+ .setColor(badgeColor)
+ .setContentTitle(title)
+ .setContentIntent(pendingIntent)
+ .setVisibility(visibility)
+ .setOngoing(isOngoing)
for (action in actions) {
builder.addAction(action)
}
- deleteIntent?.let { intent ->
- builder.setDeleteIntent(intent)
- }
+ deleteIntent?.let { intent -> builder.setDeleteIntent(intent) }
return builder.build()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt
index 06c77e5960..0a2aa186f8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt
@@ -19,68 +19,74 @@ class TunnelStateNotification(val context: Context) {
val NOTIFICATION_ID: Int = 1
}
- private val channel = NotificationChannel(
- context,
- "vpn_tunnel_status",
- NotificationCompat.VISIBILITY_SECRET,
- R.string.foreground_notification_channel_name,
- R.string.foreground_notification_channel_description,
- NotificationManager.IMPORTANCE_MIN,
- false,
- false
- )
+ private val channel =
+ NotificationChannel(
+ context,
+ "vpn_tunnel_status",
+ NotificationCompat.VISIBILITY_SECRET,
+ R.string.foreground_notification_channel_name,
+ R.string.foreground_notification_channel_description,
+ NotificationManager.IMPORTANCE_MIN,
+ false,
+ false
+ )
private val notificationText: Int
- get() = when (val state = tunnelState) {
- is TunnelState.Disconnected -> R.string.unsecured
- is TunnelState.Connecting -> {
- if (reconnecting) {
- R.string.reconnecting
- } else {
- R.string.connecting
+ get() =
+ when (val state = tunnelState) {
+ is TunnelState.Disconnected -> R.string.unsecured
+ is TunnelState.Connecting -> {
+ if (reconnecting) {
+ R.string.reconnecting
+ } else {
+ R.string.connecting
+ }
}
- }
- is TunnelState.Connected -> R.string.secured
- is TunnelState.Disconnecting -> {
- when (state.actionAfterDisconnect) {
- ActionAfterDisconnect.Reconnect -> R.string.reconnecting
- else -> R.string.disconnecting
+ is TunnelState.Connected -> R.string.secured
+ is TunnelState.Disconnecting -> {
+ when (state.actionAfterDisconnect) {
+ ActionAfterDisconnect.Reconnect -> R.string.reconnecting
+ else -> R.string.disconnecting
+ }
+ }
+ is TunnelState.Error -> {
+ state.errorState.getErrorNotificationResources(context).titleResourceId
}
}
- is TunnelState.Error -> {
- state.errorState.getErrorNotificationResources(context).titleResourceId
- }
- }
private val shouldDisplayOngoingNotification: Boolean
- get() = when (tunnelState) {
- is TunnelState.Connected -> true
- is TunnelState.Disconnected,
- is TunnelState.Connecting,
- is TunnelState.Disconnecting,
- is TunnelState.Error -> false
- }
+ get() =
+ when (tunnelState) {
+ is TunnelState.Connected -> true
+ is TunnelState.Disconnected,
+ is TunnelState.Connecting,
+ is TunnelState.Disconnecting,
+ is TunnelState.Error -> false
+ }
private var reconnecting = false
private var showingReconnecting = false
var showAction by observable(false) { _, _, _ -> update() }
- var tunnelState by observable<TunnelState>(TunnelState.Disconnected) { _, _, newState ->
- val isReconnecting = newState is TunnelState.Connecting && reconnecting
- val shouldBeginReconnecting = (newState as? TunnelState.Disconnecting)
- ?.actionAfterDisconnect == ActionAfterDisconnect.Reconnect
- reconnecting = isReconnecting || shouldBeginReconnecting
- update()
- }
-
- var visible by observable(true) { _, _, newValue ->
- if (newValue == true) {
+ var tunnelState by
+ observable<TunnelState>(TunnelState.Disconnected) { _, _, newState ->
+ val isReconnecting = newState is TunnelState.Connecting && reconnecting
+ val shouldBeginReconnecting =
+ (newState as? TunnelState.Disconnecting)?.actionAfterDisconnect ==
+ ActionAfterDisconnect.Reconnect
+ reconnecting = isReconnecting || shouldBeginReconnecting
update()
- } else {
- channel.notificationManager.cancel(NOTIFICATION_ID)
}
- }
+
+ var visible by
+ observable(true) { _, _, newValue ->
+ if (newValue == true) {
+ update()
+ } else {
+ channel.notificationManager.cancel(NOTIFICATION_ID)
+ }
+ }
private fun update() {
if (visible && (!reconnecting || !showingReconnecting)) {
@@ -89,20 +95,18 @@ class TunnelStateNotification(val context: Context) {
}
fun build(): Notification {
- val intent = Intent(context, MainActivity::class.java)
- .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
- .setAction(Intent.ACTION_MAIN)
- val pendingIntent = PendingIntent.getActivity(
- context,
- 1,
- intent,
- SdkUtils.getSupportedPendingIntentFlags()
- )
- val actions = if (showAction) {
- listOf(buildAction())
- } else {
- emptyList()
- }
+ val intent =
+ Intent(context, MainActivity::class.java)
+ .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
+ .setAction(Intent.ACTION_MAIN)
+ val pendingIntent =
+ PendingIntent.getActivity(context, 1, intent, SdkUtils.getSupportedPendingIntentFlags())
+ val actions =
+ if (showAction) {
+ listOf(buildAction())
+ } else {
+ emptyList()
+ }
return channel.buildNotification(
pendingIntent,
@@ -116,12 +120,13 @@ class TunnelStateNotification(val context: Context) {
val action = TunnelStateNotificationAction.from(tunnelState)
val label = context.getString(action.text)
val intent = Intent(action.key).setPackage("net.mullvad.mullvadvpn")
- val pendingIntent = PendingIntent.getForegroundService(
- context,
- 1,
- intent,
- SdkUtils.getSupportedPendingIntentFlags()
- )
+ val pendingIntent =
+ PendingIntent.getForegroundService(
+ context,
+ 1,
+ intent,
+ SdkUtils.getSupportedPendingIntentFlags()
+ )
return NotificationCompat.Action(action.icon, label, pendingIntent)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt
index 714264efbf..9ed9998054 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt
@@ -12,43 +12,47 @@ enum class TunnelStateNotificationAction {
Dismiss;
companion object {
- fun from(tunnelState: TunnelState) = when (tunnelState) {
- is TunnelState.Disconnected -> Connect
- is TunnelState.Connecting -> Cancel
- is TunnelState.Connected -> Disconnect
- is TunnelState.Disconnecting -> {
- when (tunnelState.actionAfterDisconnect) {
- ActionAfterDisconnect.Reconnect -> Cancel
- else -> Connect
+ fun from(tunnelState: TunnelState) =
+ when (tunnelState) {
+ is TunnelState.Disconnected -> Connect
+ is TunnelState.Connecting -> Cancel
+ is TunnelState.Connected -> Disconnect
+ is TunnelState.Disconnecting -> {
+ when (tunnelState.actionAfterDisconnect) {
+ ActionAfterDisconnect.Reconnect -> Cancel
+ else -> Connect
+ }
}
- }
- is TunnelState.Error -> {
- if (tunnelState.errorState.isBlocking) {
- Disconnect
- } else {
- Dismiss
+ is TunnelState.Error -> {
+ if (tunnelState.errorState.isBlocking) {
+ Disconnect
+ } else {
+ Dismiss
+ }
}
}
- }
}
val text
- get() = when (this) {
- Connect -> R.string.connect
- Disconnect -> R.string.disconnect
- Cancel -> R.string.cancel
- Dismiss -> R.string.dismiss
- }
+ get() =
+ when (this) {
+ Connect -> R.string.connect
+ Disconnect -> R.string.disconnect
+ Cancel -> R.string.cancel
+ Dismiss -> R.string.dismiss
+ }
val key
- get() = when (this) {
- Connect -> MullvadVpnService.KEY_CONNECT_ACTION
- else -> MullvadVpnService.KEY_DISCONNECT_ACTION
- }
+ get() =
+ when (this) {
+ Connect -> MullvadVpnService.KEY_CONNECT_ACTION
+ else -> MullvadVpnService.KEY_DISCONNECT_ACTION
+ }
val icon
- get() = when (this) {
- Connect -> R.drawable.icon_notification_connect
- else -> R.drawable.icon_notification_disconnect
- }
+ get() =
+ when (this) {
+ Connect -> R.drawable.icon_notification_connect
+ else -> R.drawable.icon_notification_disconnect
+ }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt
index 425aec8836..264304ab3f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt
@@ -15,16 +15,18 @@ class SplitTunnelingPersistence(context: Context) {
private val appListFile = File(context.filesDir, "split-tunnelling.txt")
private val preferences = context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
- var enabled by observable(preferences.getBoolean(KEY_ENABLED, false)) { _, _, isEnabled ->
- preferences.edit().apply {
- putBoolean(KEY_ENABLED, isEnabled)
- apply()
+ var enabled by
+ observable(preferences.getBoolean(KEY_ENABLED, false)) { _, _, isEnabled ->
+ preferences.edit().apply {
+ putBoolean(KEY_ENABLED, isEnabled)
+ apply()
+ }
}
- }
- var excludedApps by observable(loadExcludedApps()) { _, _, excludedAppsSet ->
- appListFile.writeText(excludedAppsSet.joinToString(separator = "\n"))
- }
+ var excludedApps by
+ observable(loadExcludedApps()) { _, _, excludedAppsSet ->
+ appListFile.writeText(excludedAppsSet.joinToString(separator = "\n"))
+ }
private fun loadExcludedApps(): Set<String> {
return when {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/BlockingController.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/BlockingController.kt
index a98394001e..9589c9474b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/BlockingController.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/BlockingController.kt
@@ -11,12 +11,13 @@ class BlockingController(val blockableView: BlockableView) {
fun action() {
if (!(job?.isActive ?: false)) {
- job = GlobalScope.launch(Dispatchers.Main) {
- blockableView.setEnabled(false)
- innerJob = blockableView.onClick()
- innerJob?.join()
- blockableView.setEnabled(true)
- }
+ job =
+ GlobalScope.launch(Dispatchers.Main) {
+ blockableView.setEnabled(false)
+ innerJob = blockableView.onClick()
+ innerJob?.join()
+ blockableView.setEnabled(true)
+ }
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt
index dcde70b923..658fd3fed3 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CollapsibleTitleController.kt
@@ -46,74 +46,80 @@ class CollapsibleTitleController(val parentView: View, scrollAreaId: Int = R.id.
private val xOffsetInterpolation = LinearInterpolation()
private val yOffsetInterpolation = LinearInterpolation()
- private val collapsedTitleLayoutListener: LayoutListener = LayoutListener() { collapsedTitle ->
- val (x, y) = calculateViewCoordinates(collapsedTitle)
+ private val collapsedTitleLayoutListener: LayoutListener =
+ LayoutListener() { collapsedTitle ->
+ val (x, y) = calculateViewCoordinates(collapsedTitle)
- collapsedTitleHeight = collapsedTitle.height.toFloat()
+ collapsedTitleHeight = collapsedTitle.height.toFloat()
- scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight)
- xOffsetInterpolation.end = x
- yOffsetInterpolation.end = y
- }
+ scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight)
+ xOffsetInterpolation.end = x
+ yOffsetInterpolation.end = y
+ }
- private val collapsedTitleView = parentView.findViewById<View>(R.id.collapsed_title).apply {
- addOnLayoutChangeListener(collapsedTitleLayoutListener)
- visibility = View.INVISIBLE
- }
+ private val collapsedTitleView =
+ parentView.findViewById<View>(R.id.collapsed_title).apply {
+ addOnLayoutChangeListener(collapsedTitleLayoutListener)
+ visibility = View.INVISIBLE
+ }
- private val expandedTitleLayoutListener: LayoutListener = LayoutListener() { expandedTitle ->
- val (x, y) = calculateViewCoordinates(expandedTitle)
+ private val expandedTitleLayoutListener: LayoutListener =
+ LayoutListener() { expandedTitle ->
+ val (x, y) = calculateViewCoordinates(expandedTitle)
- val expandedTitleMarginTop = when (val layoutParams = expandedTitle.layoutParams) {
- is MarginLayoutParams -> layoutParams.topMargin
- else -> 0
- }
+ val expandedTitleMarginTop =
+ when (val layoutParams = expandedTitle.layoutParams) {
+ is MarginLayoutParams -> layoutParams.topMargin
+ else -> 0
+ }
- expandedTitleHeight = expandedTitle.height.toFloat()
+ expandedTitleHeight = expandedTitle.height.toFloat()
- scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight)
- xOffsetInterpolation.start = x
- yOffsetInterpolation.start = y
+ scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight)
+ xOffsetInterpolation.start = x
+ yOffsetInterpolation.start = y
- scrollInterpolation.end = expandedTitleHeight + expandedTitleMarginTop
- }
+ scrollInterpolation.end = expandedTitleHeight + expandedTitleMarginTop
+ }
- private val titleLayoutListener: LayoutListener = LayoutListener() { title ->
- val (x, y) = calculateViewCoordinates(title)
+ private val titleLayoutListener: LayoutListener =
+ LayoutListener() { title ->
+ val (x, y) = calculateViewCoordinates(title)
- titleWidth = title.width.toFloat()
- titleHeight = title.height.toFloat()
+ titleWidth = title.width.toFloat()
+ titleHeight = title.height.toFloat()
- scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight)
- scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight)
- xOffsetInterpolation.reference = x
- yOffsetInterpolation.reference = y
- }
+ scaleInterpolation.start = expandedTitleHeight / maxOf(1.0f, titleHeight)
+ scaleInterpolation.end = collapsedTitleHeight / maxOf(1.0f, titleHeight)
+ xOffsetInterpolation.reference = x
+ yOffsetInterpolation.reference = y
+ }
- private val titleView = parentView.findViewById<View>(R.id.title).apply {
- addOnLayoutChangeListener(titleLayoutListener)
+ private val titleView =
+ parentView.findViewById<View>(R.id.title).apply {
+ addOnLayoutChangeListener(titleLayoutListener)
- // Setting the scale pivot point to the left corner simplifies the calculations
- pivotX = 0.0f
- pivotY = 0.0f
- }
+ // Setting the scale pivot point to the left corner simplifies the calculations
+ pivotX = 0.0f
+ pivotY = 0.0f
+ }
- private val scrollAreaLayoutListener: LayoutListener = LayoutListener() {
- scrollOffset = scrollArea.verticalScrollOffset.toFloat()
- }
+ private val scrollAreaLayoutListener: LayoutListener =
+ LayoutListener() { scrollOffset = scrollArea.verticalScrollOffset.toFloat() }
- private val scrollArea = parentView.findViewById<View>(scrollAreaId).let { view ->
- val scrollableView = view as ListenableScrollableView
+ private val scrollArea =
+ parentView.findViewById<View>(scrollAreaId).let { view ->
+ val scrollableView = view as ListenableScrollableView
- view.addOnLayoutChangeListener(scrollAreaLayoutListener)
+ view.addOnLayoutChangeListener(scrollAreaLayoutListener)
- scrollableView.onScrollListener = { _, top, _, _ ->
- scrollOffset = top.toFloat()
- update()
- }
+ scrollableView.onScrollListener = { _, top, _, _ ->
+ scrollOffset = top.toFloat()
+ update()
+ }
- scrollableView
- }
+ scrollableView
+ }
private var scrollOffsetUpdated = false
get() {
@@ -130,23 +136,25 @@ class CollapsibleTitleController(val parentView: View, scrollAreaId: Int = R.id.
private var titleWidth = 0.0f
private var titleHeight = 0.0f
- private var scrollOffset: Float by observable(0.0f) { _, old, new ->
- if (scrollOffsetUpdated == false && old != new) {
- scrollOffsetUpdated = true
+ private var scrollOffset: Float by
+ observable(0.0f) { _, old, new ->
+ if (scrollOffsetUpdated == false && old != new) {
+ scrollOffsetUpdated = true
+ }
}
- }
val fullCollapseScrollOffset: Float
get() = scrollInterpolation.end
- var expandedTitleView by observable<View?>(null) { _, oldView, newView ->
- oldView?.removeOnLayoutChangeListener(expandedTitleLayoutListener)
- newView?.apply {
- addOnLayoutChangeListener(expandedTitleLayoutListener)
- expandedTitleLayoutListener.listener(this)
- visibility = View.INVISIBLE
+ var expandedTitleView by
+ observable<View?>(null) { _, oldView, newView ->
+ oldView?.removeOnLayoutChangeListener(expandedTitleLayoutListener)
+ newView?.apply {
+ addOnLayoutChangeListener(expandedTitleLayoutListener)
+ expandedTitleLayoutListener.listener(this)
+ visibility = View.INVISIBLE
+ }
}
- }
init {
expandedTitleView = parentView.findViewById<View>(R.id.expanded_title)
@@ -170,11 +178,12 @@ class CollapsibleTitleController(val parentView: View, scrollAreaId: Int = R.id.
yOffsetInterpolation.updated
if (shouldUpdate) {
- val progress = if (expandedTitleView != null) {
- maxOf(0.0f, minOf(1.0f, scrollInterpolation.progress(scrollOffset)))
- } else {
- 1.0f
- }
+ val progress =
+ if (expandedTitleView != null) {
+ maxOf(0.0f, minOf(1.0f, scrollInterpolation.progress(scrollOffset)))
+ } else {
+ 1.0f
+ }
val scale = scaleInterpolation.interpolate(progress)
val offsetX = xOffsetInterpolation.interpolate(progress)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectActionButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectActionButton.kt
index 7fbc0875f5..664eb1bc49 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectActionButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectActionButton.kt
@@ -70,10 +70,11 @@ class ConnectActionButton(val parentView: View) {
reconnectButton.addOnLayoutChangeListener { _, left, _, right, _, _, _, _, _ ->
val width = right - left
val layoutParams = reconnectButton.layoutParams
- val leftMargin = when (layoutParams) {
- is MarginLayoutParams -> layoutParams.leftMargin
- else -> 0
- }
+ val leftMargin =
+ when (layoutParams) {
+ is MarginLayoutParams -> layoutParams.leftMargin
+ else -> 0
+ }
reconnectButtonSpace = width + leftMargin
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CustomTransformationMethod.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CustomTransformationMethod.kt
index 9ec42e3b9f..083258c62d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CustomTransformationMethod.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/CustomTransformationMethod.kt
@@ -29,7 +29,8 @@ class GroupedTransformationMethod() : TransformationMethod {
class GroupedPasswordTransformationMethod() : PasswordTransformationMethod() {
override fun getTransformation(source: CharSequence?, view: View?): CharSequence {
return if (source != null && view != null) {
- super.getTransformation(source, view)?.toString()
+ super.getTransformation(source, view)
+ ?.toString()
?.replace(DOT_CHAR, BIG_DOT_CHAR)
?.groupWithSpaces()
?: EMPTY_STRING
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemsAdapter.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemsAdapter.kt
index a97f2af3d2..4676a3532a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemsAdapter.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemsAdapter.kt
@@ -26,8 +26,10 @@ class ListItemsAdapter : RecyclerView.Adapter<ListItemsAdapter.ViewHolder>() {
fun setItems(items: List<ListItemData?>) = listDiffer.submitList(items)
- override fun onCreateViewHolder(parent: ViewGroup, @ListItemData.ItemType viewType: Int):
- ListItemsAdapter.ViewHolder {
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ @ListItemData.ItemType viewType: Int
+ ): ListItemsAdapter.ViewHolder {
return ViewHolder(
when (viewType) {
ListItemData.DIVIDER -> DividerGroupListItemView(parent.context)
@@ -36,8 +38,7 @@ class ListItemsAdapter : RecyclerView.Adapter<ListItemsAdapter.ViewHolder>() {
ListItemData.ACTION -> ActionListItemView(parent.context)
ListItemData.APPLICATION -> ApplicationListItemView(parent.context)
ListItemData.DOUBLE_ACTION -> TwoActionListItemView(parent.context)
- else ->
- throw IllegalArgumentException("View type '$viewType' is not supported")
+ else -> throw IllegalArgumentException("View type '$viewType' is not supported")
}
)
}
@@ -54,8 +55,7 @@ class ListItemsAdapter : RecyclerView.Adapter<ListItemsAdapter.ViewHolder>() {
override fun getItemCount(): Int = listDiffer.currentList.size
- @ListItemData.ItemType
- override fun getItemViewType(position: Int): Int = getItem(position).type
+ @ListItemData.ItemType override fun getItemViewType(position: Int): Int = getItem(position).type
override fun getItemId(position: Int): Long = getId(getItem(position).identifier)
@@ -109,9 +109,9 @@ class ListItemsAdapter : RecyclerView.Adapter<ListItemsAdapter.ViewHolder>() {
private val idCounter = AtomicLong(0)
private val mapIds = hashMapOf<String, Long>()
- internal fun getId(stringId: String): Long = mapIds.computeIfAbsent(stringId) {
- idCounter.decrementAndGet()
- }
+ internal fun getId(stringId: String): Long =
+ mapIds.computeIfAbsent(stringId) { idCounter.decrementAndGet() }
}
}
+
typealias DiffCallback = DiffUtil.ItemCallback<ListItemData>
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LocationInfo.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LocationInfo.kt
index f12985157c..abe52eb3cd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LocationInfo.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/LocationInfo.kt
@@ -110,10 +110,11 @@ class LocationInfo(
if (endpoint != null) {
val host = endpoint.address.address.hostAddress
val port = endpoint.address.port
- val protocol = when (endpoint.protocol) {
- TransportProtocol.Tcp -> context.getString(R.string.tcp)
- TransportProtocol.Udp -> context.getString(R.string.udp)
- }
+ val protocol =
+ when (endpoint.protocol) {
+ TransportProtocol.Tcp -> context.getString(R.string.tcp)
+ TransportProtocol.Udp -> context.getString(R.string.udp)
+ }
inAddress.text = context.getString(R.string.in_address) + " $host:$port $protocol"
} else {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
index a0fa0e613e..daef7ece5d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
@@ -90,11 +90,12 @@ open class MainActivity : FragmentActivity() {
changelogViewModel = get()
}
- requestedOrientation = if (deviceIsTv) {
- ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
- } else {
- ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
- }
+ requestedOrientation =
+ if (deviceIsTv) {
+ ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+ } else {
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ }
super.onCreate(savedInstanceState)
@@ -235,9 +236,7 @@ open class MainActivity : FragmentActivity() {
ChangelogDialog(
changesList = state.changes,
version = BuildConfig.VERSION_NAME,
- onDismiss = {
- changelogViewModel.dismissChangelogDialog()
- }
+ onDismiss = { changelogViewModel.dismissChangelogDialog() }
)
}
}
@@ -270,21 +269,22 @@ open class MainActivity : FragmentActivity() {
val isNewAccount = accountToken == accountRepository.cachedCreatedAccount.value
val isExpired = isNewAccount.not() && isExpired(LOGIN_AWAIT_EXPIRY_MILLIS)
- val fragment = when {
- isNewAccount -> WelcomeFragment()
- isExpired -> {
- if (shouldDelayLogin) {
- delay(LOGIN_DELAY_MILLIS)
+ val fragment =
+ when {
+ isNewAccount -> WelcomeFragment()
+ isExpired -> {
+ if (shouldDelayLogin) {
+ delay(LOGIN_DELAY_MILLIS)
+ }
+ OutOfTimeFragment()
}
- OutOfTimeFragment()
- }
- else -> {
- if (shouldDelayLogin) {
- delay(LOGIN_DELAY_MILLIS)
+ else -> {
+ if (shouldDelayLogin) {
+ delay(LOGIN_DELAY_MILLIS)
+ }
+ ConnectFragment()
}
- ConnectFragment()
}
- }
supportFragmentManager.beginTransaction().apply {
replace(R.id.main_fragment, fragment)
@@ -298,7 +298,8 @@ open class MainActivity : FragmentActivity() {
.filter { it is AccountExpiry.Available }
.map { it.date()?.isBeforeNow }
.first()
- } ?: false
+ }
+ ?: false
}
private fun openLoginView() {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
index ef8deeeb0e..e31b1dbf19 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PreferencesFragment.kt
@@ -34,8 +34,7 @@ class PreferencesFragment : BaseFragment() {
private lateinit var autoConnectToggle: ToggleCell
private lateinit var titleController: CollapsibleTitleController
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -53,23 +52,27 @@ class PreferencesFragment : BaseFragment() {
requireMainActivity().onBackPressed()
}
- allowLanToggle = view.findViewById<ToggleCell>(R.id.allow_lan).apply {
- listener = { state ->
- serviceConnectionManager.settingsListener()?.allowLan = when (state) {
- CellSwitch.State.ON -> true
- else -> false
+ allowLanToggle =
+ view.findViewById<ToggleCell>(R.id.allow_lan).apply {
+ listener = { state ->
+ serviceConnectionManager.settingsListener()?.allowLan =
+ when (state) {
+ CellSwitch.State.ON -> true
+ else -> false
+ }
}
}
- }
- autoConnectToggle = view.findViewById<ToggleCell>(R.id.auto_connect).apply {
- listener = { state ->
- serviceConnectionManager.settingsListener()?.autoConnect = when (state) {
- CellSwitch.State.ON -> true
- else -> false
+ autoConnectToggle =
+ view.findViewById<ToggleCell>(R.id.auto_connect).apply {
+ listener = { state ->
+ serviceConnectionManager.settingsListener()?.autoConnect =
+ when (state) {
+ CellSwitch.State.ON -> true
+ else -> false
+ }
}
}
- }
titleController = CollapsibleTitleController(view)
@@ -82,9 +85,7 @@ class PreferencesFragment : BaseFragment() {
}
private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch {
- repeatOnLifecycle(Lifecycle.State.RESUMED) {
- launchSettingsSubscription()
- }
+ repeatOnLifecycle(Lifecycle.State.RESUMED) { launchSettingsSubscription() }
}
private fun CoroutineScope.launchSettingsSubscription() = launch {
@@ -96,9 +97,7 @@ class PreferencesFragment : BaseFragment() {
emptyFlow()
}
}
- .flatMapLatest {
- callbackFlowFromNotifier(it.settingsListener.settingsNotifier)
- }
+ .flatMapLatest { callbackFlowFromNotifier(it.settingsListener.settingsNotifier) }
.collect { settings ->
if (settings != null) {
updateUi(settings)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PrivacyDisclaimerFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PrivacyDisclaimerFragment.kt
index 56d4937037..6347bd0e56 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PrivacyDisclaimerFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/PrivacyDisclaimerFragment.kt
@@ -52,10 +52,8 @@ class PrivacyDisclaimerFragment : Fragment(), StatusBarPainter, NavigationBarPai
}
private fun openPrivacyPolicy() {
- val privacyPolicyUrlIntent = Intent(
- Intent.ACTION_VIEW,
- Uri.parse(getString(R.string.faqs_and_guides_url))
- )
+ val privacyPolicyUrlIntent =
+ Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.faqs_and_guides_url)))
context?.startActivity(privacyPolicyUrlIntent)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt
index e0ef43d41e..b3396cde72 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SelectLocationFragment.kt
@@ -53,20 +53,20 @@ class SelectLocationFragment : BaseFragment(), StatusBarPainter, NavigationBarPa
private var loadingSpinner = CompletableDeferred<View>()
private var relayListState = RelayListState.Initializing
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onAttach(context: Context) {
super.onAttach(context)
- relayListAdapter = RelayListAdapter(context.resources).apply {
- onSelect = { relayItem ->
- serviceConnectionManager.relayListListener()?.selectedRelayLocation =
- relayItem?.location
- serviceConnectionManager.connectionProxy()?.connect()
- close()
+ relayListAdapter =
+ RelayListAdapter(context.resources).apply {
+ onSelect = { relayItem ->
+ serviceConnectionManager.relayListListener()?.selectedRelayLocation =
+ relayItem?.location
+ serviceConnectionManager.connectionProxy()?.connect()
+ close()
+ }
}
- }
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -88,12 +88,14 @@ class SelectLocationFragment : BaseFragment(), StatusBarPainter, NavigationBarPa
view.findViewById<CustomRecyclerView>(R.id.relay_list).apply {
layoutManager = LinearLayoutManager(requireMainActivity())
- adapter = AdapterWithHeader(relayListAdapter, R.layout.select_location_header).apply {
- onHeaderAvailable = { headerView ->
- initializeLoadingSpinner(headerView)
- titleController.expandedTitleView = headerView.findViewById(R.id.expanded_title)
+ adapter =
+ AdapterWithHeader(relayListAdapter, R.layout.select_location_header).apply {
+ onHeaderAvailable = { headerView ->
+ initializeLoadingSpinner(headerView)
+ titleController.expandedTitleView =
+ headerView.findViewById(R.id.expanded_title)
+ }
}
- }
addItemDecoration(
ListItemDividerDecoration(
@@ -137,14 +139,11 @@ class SelectLocationFragment : BaseFragment(), StatusBarPainter, NavigationBarPa
.flatMapLatest { state ->
if (state is ServiceConnectionState.ConnectedReady) {
callbackFlow {
- state.container.relayListListener.onRelayListChange =
- { list, item ->
- this.trySend(Pair(list, item))
- }
-
- awaitClose {
- state.container.relayListListener.onRelayListChange = null
+ state.container.relayListListener.onRelayListChange = { list, item ->
+ this.trySend(Pair(list, item))
}
+
+ awaitClose { state.container.relayListListener.onRelayListChange = null }
}
} else {
emptyFlow()
@@ -187,9 +186,7 @@ class SelectLocationFragment : BaseFragment(), StatusBarPainter, NavigationBarPa
// Because this method is executed inside a layout pass, hiding the spinner needs to be
// done in a new job so that it is executed after the layout pass finishes and can
// therefore schedule a new layout
- jobTracker.newUiJob("hideLoadingSpinner") {
- spinner.visibility = View.GONE
- }
+ jobTracker.newUiJob("hideLoadingSpinner") { spinner.visibility = View.GONE }
}
loadingSpinner.complete(spinner)
@@ -201,14 +198,15 @@ class SelectLocationFragment : BaseFragment(), StatusBarPainter, NavigationBarPa
selectedItem: RelayItem?
) {
val animationFinished = CompletableDeferred<Unit>()
- val animationListener = object : AnimationListener {
- override fun onAnimationEnd(animation: Animation) {
- animationFinished.complete(Unit)
- }
+ val animationListener =
+ object : AnimationListener {
+ override fun onAnimationEnd(animation: Animation) {
+ animationFinished.complete(Unit)
+ }
- override fun onAnimationStart(animation: Animation) {}
- override fun onAnimationRepeat(animation: Animation) {}
- }
+ override fun onAnimationStart(animation: Animation) {}
+ override fun onAnimationRepeat(animation: Animation) {}
+ }
val fadeOut =
AnimationUtils.loadAnimation(requireMainActivity(), R.anim.fade_out).apply {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt
index 53d7a7414e..f00ff44648 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/SettingsFragment.kt
@@ -47,8 +47,7 @@ class SettingsFragment : BaseFragment(), StatusBarPainter, NavigationBarPainter
private lateinit var advancedMenu: View
private lateinit var titleController: CollapsibleTitleController
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -62,21 +61,22 @@ class SettingsFragment : BaseFragment(), StatusBarPainter, NavigationBarPainter
): View {
val view = inflater.inflate(R.layout.settings, container, false)
- view.findViewById<ImageButton>(R.id.close).setOnClickListener {
- activity?.onBackPressed()
- }
+ view.findViewById<ImageButton>(R.id.close).setOnClickListener { activity?.onBackPressed() }
- accountMenu = view.findViewById<AccountCell>(R.id.account).apply {
- targetFragment = AccountFragment::class
- }
+ accountMenu =
+ view.findViewById<AccountCell>(R.id.account).apply {
+ targetFragment = AccountFragment::class
+ }
- preferencesMenu = view.findViewById<NavigateCell>(R.id.preferences).apply {
- targetFragment = PreferencesFragment::class
- }
+ preferencesMenu =
+ view.findViewById<NavigateCell>(R.id.preferences).apply {
+ targetFragment = PreferencesFragment::class
+ }
- advancedMenu = view.findViewById<NavigateCell>(R.id.advanced).apply {
- targetFragment = AdvancedFragment::class
- }
+ advancedMenu =
+ view.findViewById<NavigateCell>(R.id.advanced).apply {
+ targetFragment = AdvancedFragment::class
+ }
view.findViewById<NavigateCell>(R.id.report_a_problem).apply {
targetFragment = ProblemReportFragment::class
@@ -149,20 +149,14 @@ class SettingsFragment : BaseFragment(), StatusBarPainter, NavigationBarPainter
private fun CoroutineScope.luanchConfigureMenuOnDeviceChanges() = launch {
deviceRepository.deviceState
- .debounce {
- it.addDebounceForUnknownState(UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS)
- }
- .collect { device ->
- updateLoggedInStatus(device is DeviceState.LoggedIn)
- }
+ .debounce { it.addDebounceForUnknownState(UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS) }
+ .collect { device -> updateLoggedInStatus(device is DeviceState.LoggedIn) }
}
private fun CoroutineScope.launchUpdateExpiryTextOnExpiryChanges() = launch {
accountRepository.accountExpiryState
.map { state -> state.date() }
- .collect { expiryDate ->
- accountMenu.accountExpiry = expiryDate
- }
+ .collect { expiryDate -> accountMenu.accountExpiry = expiryDate }
}
private fun CoroutineScope.launchVersionInfoSubscription() = launch {
@@ -174,26 +168,23 @@ class SettingsFragment : BaseFragment(), StatusBarPainter, NavigationBarPainter
emptyFlow()
}
}
- .collect { versionInfo ->
- updateVersionInfo(versionInfo)
- }
+ .collect { versionInfo -> updateVersionInfo(versionInfo) }
}
private fun updateLoggedInStatus(loggedIn: Boolean) {
- val visibility = if (loggedIn) {
- View.VISIBLE
- } else {
- View.GONE
- }
+ val visibility =
+ if (loggedIn) {
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
accountMenu.visibility = visibility
preferencesMenu.visibility = visibility
advancedMenu.visibility = visibility
}
- private fun updateVersionInfo(
- versionInfo: VersionInfo
- ) {
+ private fun updateVersionInfo(versionInfo: VersionInfo) {
appVersionMenu.updateAvailable = versionInfo.isOutdated || !versionInfo.isSupported
appVersionMenu.version = versionInfo.currentVersion ?: ""
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/UnderNotificationBannerBehavior.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/UnderNotificationBannerBehavior.kt
index 2b28f21ff1..8abf20bb12 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/UnderNotificationBannerBehavior.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/UnderNotificationBannerBehavior.kt
@@ -8,10 +8,8 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout.Behavior
import net.mullvad.mullvadvpn.R
-class UnderNotificationBannerBehavior(
- context: Context,
- attributes: AttributeSet
-) : Behavior<ScrollView>(context, attributes) {
+class UnderNotificationBannerBehavior(context: Context, attributes: AttributeSet) :
+ Behavior<ScrollView>(context, attributes) {
override fun layoutDependsOn(parent: CoordinatorLayout, body: ScrollView, dependency: View) =
dependency.id == R.id.notification_banner
@@ -20,11 +18,12 @@ class UnderNotificationBannerBehavior(
body: ScrollView,
dependency: View
): Boolean {
- val newPaddingTop = if (dependency.visibility == View.VISIBLE) {
- dependency.height + dependency.translationY.toInt()
- } else {
- 0
- }
+ val newPaddingTop =
+ if (dependency.visibility == View.VISIBLE) {
+ dependency.height + dependency.translationY.toInt()
+ } else {
+ 0
+ }
body.getChildAt(0).apply {
if (paddingTop != newPaddingTop) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt
index 3362aef52f..ecaa995e4a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt
@@ -13,21 +13,20 @@ private const val ALWAYS_ON_VPN_APP = "always_on_vpn_app"
fun Context.openAccountPageInBrowser(authToken: String) {
startActivity(
- Intent(
- Intent.ACTION_VIEW,
- Uri.parse(getString(R.string.account_url) + "?token=$authToken")
- )
+ Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.account_url) + "?token=$authToken"))
)
}
fun Context.getAlwaysOnVpnAppName(): String? {
return resolveAlwaysOnVpnPackageName()
?.let { currentAlwaysOnVpn ->
- packageManager.getInstalledPackagesList(0)
- .singleOrNull {
- it.packageName == currentAlwaysOnVpn && it.packageName != packageName
- }
- }?.applicationInfo?.loadLabel(packageManager)?.toString()
+ packageManager.getInstalledPackagesList(0).singleOrNull {
+ it.packageName == currentAlwaysOnVpn && it.packageName != packageName
+ }
+ }
+ ?.applicationInfo
+ ?.loadLabel(packageManager)
+ ?.toString()
}
fun Fragment.requireMainActivity(): MainActivity {
@@ -44,10 +43,7 @@ fun Fragment.requireMainActivity(): MainActivity {
// Always-on VPN being disabled or not being able to read the state, NULL will be returned.
fun Context.resolveAlwaysOnVpnPackageName(): String? {
return try {
- Settings.Secure.getString(
- contentResolver,
- ALWAYS_ON_VPN_APP
- )
+ Settings.Secure.getString(contentResolver, ALWAYS_ON_VPN_APP)
} catch (ex: SecurityException) {
null
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt
index a1050273d2..c7146e941c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt
@@ -78,13 +78,15 @@ class AccountFragment : BaseFragment() {
redeemVoucherButton.setEnabled(!value)
}
- private var isAccountNumberShown by observable(false) { _, _, doShow ->
- accountNumberView.informationState = if (doShow) {
- InformationView.Masking.Show(GroupedTransformationMethod())
- } else {
- InformationView.Masking.Hide(GroupedPasswordTransformationMethod())
+ private var isAccountNumberShown by
+ observable(false) { _, _, doShow ->
+ accountNumberView.informationState =
+ if (doShow) {
+ InformationView.Masking.Show(GroupedTransformationMethod())
+ } else {
+ InformationView.Masking.Hide(GroupedPasswordTransformationMethod())
+ }
}
- }
private lateinit var accountExpiryView: InformationView
private lateinit var accountNumberView: CopyableInformationView
@@ -93,8 +95,7 @@ class AccountFragment : BaseFragment() {
private lateinit var redeemVoucherButton: RedeemVoucherButton
private lateinit var titleController: CollapsibleTitleController
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onAttach(activity: Activity) {
super.onAttach(activity)
@@ -117,33 +118,35 @@ class AccountFragment : BaseFragment() {
requireMainActivity().onBackPressed()
}
- sitePaymentButton = view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
- newAccount = false
+ sitePaymentButton =
+ view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
+ newAccount = false
- setOnClickAction("openAccountPageInBrowser", jobTracker) {
- setEnabled(false)
- serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
- context.openAccountPageInBrowser(token)
+ setOnClickAction("openAccountPageInBrowser", jobTracker) {
+ setEnabled(false)
+ serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
+ context.openAccountPageInBrowser(token)
+ }
+ setEnabled(true)
+ checkForAddedTime()
}
- setEnabled(true)
- checkForAddedTime()
}
- }
- redeemVoucherButton = view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply {
- prepare(parentFragmentManager, jobTracker)
- }
+ redeemVoucherButton =
+ view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply {
+ prepare(parentFragmentManager, jobTracker)
+ }
view.findViewById<Button>(R.id.logout).setOnClickAction("logout", jobTracker) {
accountRepository.logout()
}
- accountNumberView = view.findViewById<CopyableInformationView>(R.id.account_number).apply {
- informationState = InformationView.Masking.Hide(GroupedPasswordTransformationMethod())
- onToggleMaskingClicked = {
- isAccountNumberShown = isAccountNumberShown.not()
+ accountNumberView =
+ view.findViewById<CopyableInformationView>(R.id.account_number).apply {
+ informationState =
+ InformationView.Masking.Hide(GroupedPasswordTransformationMethod())
+ onToggleMaskingClicked = { isAccountNumberShown = isAccountNumberShown.not() }
}
- }
accountExpiryView = view.findViewById(R.id.account_expiry)
deviceNameView = view.findViewById(R.id.device_name)
@@ -184,8 +187,7 @@ class AccountFragment : BaseFragment() {
}
.collect { state ->
accountNumberView.information = state.token()
- deviceNameView.information =
- state.deviceName()?.capitalizeFirstCharOfEachWord()
+ deviceNameView.information = state.deviceName()?.capitalizeFirstCharOfEachWord()
}
}
}
@@ -206,33 +208,29 @@ class AccountFragment : BaseFragment() {
serviceConnectionManager.connectionState
.flatMapLatest { state ->
if (state is ServiceConnectionState.ConnectedReady) {
- callbackFlowFromNotifier(
- state.container.connectionProxy.onUiStateChange
- )
+ callbackFlowFromNotifier(state.container.connectionProxy.onUiStateChange)
} else {
emptyFlow()
}
}
.collect { uiState ->
- hasConnectivity = uiState is TunnelState.Connected ||
- uiState is TunnelState.Disconnected ||
- (uiState is TunnelState.Error && !uiState.errorState.isBlocking)
- isOffline = uiState is TunnelState.Error &&
- uiState.errorState.cause is ErrorStateCause.IsOffline
+ hasConnectivity =
+ uiState is TunnelState.Connected ||
+ uiState is TunnelState.Disconnected ||
+ (uiState is TunnelState.Error && !uiState.errorState.isBlocking)
+ isOffline =
+ uiState is TunnelState.Error &&
+ uiState.errorState.cause is ErrorStateCause.IsOffline
}
}
}
private fun CoroutineScope.launchRefreshDeviceStateAfterAnimation() = launch {
- transitionFinishedFlow.collect {
- deviceRepository.refreshDeviceState()
- }
+ transitionFinishedFlow.collect { deviceRepository.refreshDeviceState() }
}
private fun checkForAddedTime() {
- currentAccountExpiry?.let { expiry ->
- oldAccountExpiry = expiry
- }
+ currentAccountExpiry?.let { expiry -> oldAccountExpiry = expiry }
}
private fun updateAccountExpiry(accountExpiry: DateTime?) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt
index 506177bba1..905cc889a9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/BaseFragment.kt
@@ -12,17 +12,18 @@ import net.mullvad.mullvadvpn.util.transitionFinished
abstract class BaseFragment : Fragment {
constructor() : super()
- constructor (@LayoutRes contentLayoutId: Int) : super(contentLayoutId)
+ constructor(@LayoutRes contentLayoutId: Int) : super(contentLayoutId)
protected var transitionFinishedFlow: Flow<Unit> = emptyFlow()
private set
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
- val zAdjustment = if (animationsToAdjustZorder.contains(nextAnim)) {
- 1f
- } else {
- 0f
- }
+ val zAdjustment =
+ if (animationsToAdjustZorder.contains(nextAnim)) {
+ 1f
+ } else {
+ 0f
+ }
ViewCompat.setTranslationZ(requireView(), zAdjustment)
return if (nextAnim != 0 && enter) {
AnimationUtils.loadAnimation(context, nextAnim)?.apply {
@@ -34,11 +35,12 @@ abstract class BaseFragment : Fragment {
}
companion object {
- private val animationsToAdjustZorder = listOf(
- R.anim.fragment_enter_from_right,
- R.anim.fragment_exit_to_right,
- R.anim.fragment_enter_from_bottom,
- R.anim.fragment_exit_to_bottom
- )
+ private val animationsToAdjustZorder =
+ listOf(
+ R.anim.fragment_enter_from_right,
+ R.anim.fragment_exit_to_right,
+ R.anim.fragment_enter_from_bottom,
+ R.anim.fragment_exit_to_bottom
+ )
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConfirmNoEmailDialogFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConfirmNoEmailDialogFragment.kt
index f4bc1dade1..d31c5551b5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConfirmNoEmailDialogFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConfirmNoEmailDialogFragment.kt
@@ -33,9 +33,7 @@ class ConfirmNoEmailDialogFragment : DialogFragment() {
): View {
val view = inflater.inflate(R.layout.confirm_no_email, container, false)
- view.findViewById<Button>(R.id.back_button).setOnClickListener {
- activity?.onBackPressed()
- }
+ view.findViewById<Button>(R.id.back_button).setOnClickListener { activity?.onBackPressed() }
view.findViewById<Button>(R.id.send_button).setOnClickListener {
confirmNoEmail?.complete(true)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt
index f06f420158..68dd3a9403 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt
@@ -68,8 +68,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
private lateinit var status: ConnectionStatus
private lateinit var locationInfo: LocationInfo
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -83,9 +82,10 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
): View? {
val view = inflater.inflate(R.layout.connect, container, false)
- headerBar = view.findViewById<HeaderBar>(R.id.header_bar).apply {
- tunnelState = TunnelState.Disconnected
- }
+ headerBar =
+ view.findViewById<HeaderBar>(R.id.header_bar).apply {
+ tunnelState = TunnelState.Disconnected
+ }
accountExpiryNotification.onClick = {
serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
@@ -95,20 +95,20 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
}
}
- notificationBanner = view.findViewById<NotificationBanner>(R.id.notification_banner).apply {
- notifications.apply {
- // NOTE: The order of below notifications is significant.
- register(tunnelStateNotification)
- register(versionInfoNotification)
- register(accountExpiryNotification)
+ notificationBanner =
+ view.findViewById<NotificationBanner>(R.id.notification_banner).apply {
+ notifications.apply {
+ // NOTE: The order of below notifications is significant.
+ register(tunnelStateNotification)
+ register(versionInfoNotification)
+ register(accountExpiryNotification)
+ }
}
- }
status = ConnectionStatus(view, requireMainActivity())
- locationInfo = LocationInfo(view, requireContext()) {
- connectViewModel.toggleTunnelInfoExpansion()
- }
+ locationInfo =
+ LocationInfo(view, requireContext()) { connectViewModel.toggleTunnelInfoExpansion() }
actionButton = ConnectActionButton(view)
@@ -119,9 +119,10 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
onDisconnect = { serviceConnectionManager.connectionProxy()?.disconnect() }
}
- switchLocationButton = view.findViewById<SwitchLocationButton>(R.id.switch_location).apply {
- onClick = { openSwitchLocationScreen() }
- }
+ switchLocationButton =
+ view.findViewById<SwitchLocationButton>(R.id.switch_location).apply {
+ onClick = { openSwitchLocationScreen() }
+ }
return view
}
@@ -136,15 +137,16 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
paintNavigationBar(ContextCompat.getColor(requireContext(), R.color.blue))
}
- val shared = serviceConnectionManager.connectionState
- .flatMapLatest { state ->
- if (state is ServiceConnectionState.ConnectedReady) {
- flowOf(state.container)
- } else {
- emptyFlow()
+ val shared =
+ serviceConnectionManager.connectionState
+ .flatMapLatest { state ->
+ if (state is ServiceConnectionState.ConnectedReady) {
+ flowOf(state.container)
+ } else {
+ emptyFlow()
+ }
}
- }
- .shareIn(lifecycleScope, SharingStarted.WhileSubscribed())
+ .shareIn(lifecycleScope, SharingStarted.WhileSubscribed())
private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) {
@@ -164,9 +166,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
}
private fun LocationInfoCache.locationCallbackFlow() = callbackFlow {
- onNewLocation = {
- this.trySend(it)
- }
+ onNewLocation = { this.trySend(it) }
awaitClose { onNewLocation = null }
}
@@ -177,9 +177,7 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
}
private fun RelayListListener.relayListCallbackFlow() = callbackFlow {
- onRelayListChange = { _, item ->
- this.trySend(item)
- }
+ onRelayListChange = { _, item -> this.trySend(item) }
awaitClose { onRelayListChange = null }
}
@@ -208,17 +206,15 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
}
private fun CoroutineScope.launchAccountExpirySubscription() = launch {
- accountRepository.accountExpiryState
- .collect {
- accountExpiryNotification.updateAccountExpiry(it.date())
- }
+ accountRepository.accountExpiryState.collect {
+ accountExpiryNotification.updateAccountExpiry(it.date())
+ }
}
private fun CoroutineScope.launchTunnelInfoExpansionSubscription() = launch {
- connectViewModel.isTunnelInfoExpanded
- .collect { isExpanded ->
- locationInfo.isTunnelInfoExpanded = isExpanded
- }
+ connectViewModel.isTunnelInfoExpanded.collect { isExpanded ->
+ locationInfo.isTunnelInfoExpanded = isExpanded
+ }
}
private fun updateTunnelState(uiState: TunnelState, realState: TunnelState) {
@@ -259,7 +255,8 @@ class ConnectFragment : BaseFragment(), NavigationBarPainter {
private fun TunnelState.isTunnelErrorStateDueToExpiredAccount(): Boolean {
return ((this as? TunnelState.Error)?.errorState?.cause as? ErrorStateCause.AuthFailed)
- ?.isCausedByExpiredAccount() ?: false
+ ?.isCausedByExpiredAccount()
+ ?: false
}
companion object {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt
index 7e51e7a8e1..a382381cd8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceListFragment.kt
@@ -64,23 +64,20 @@ class DeviceListFragment : Fragment() {
private fun CoroutineScope.launchUiSubscriptionsOnResume() = launch {
deviceListViewModel.toastMessages
.flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED)
- .collect {
- Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
- }
+ .collect { Toast.makeText(context, it, Toast.LENGTH_SHORT).show() }
}
private fun openLoginView(doTriggerAutoLogin: Boolean) {
parentActivity()?.clearBackStack()
- val loginFragment = LoginFragment().apply {
- if (doTriggerAutoLogin && deviceListViewModel.accountToken != null) {
- arguments = Bundle().apply {
- putString(
- ACCOUNT_TOKEN_ARGUMENT_KEY,
- deviceListViewModel.accountToken
- )
+ val loginFragment =
+ LoginFragment().apply {
+ if (doTriggerAutoLogin && deviceListViewModel.accountToken != null) {
+ arguments =
+ Bundle().apply {
+ putString(ACCOUNT_TOKEN_ARGUMENT_KEY, deviceListViewModel.accountToken)
+ }
}
}
- }
parentFragmentManager.beginTransaction().apply {
replace(R.id.main_fragment, loginFragment)
commitAllowingStateLoss()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt
index 68eb41e9ac..f63e7d4322 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/DeviceRevokedFragment.kt
@@ -30,13 +30,14 @@ class DeviceRevokedFragment : Fragment() {
AppTheme {
val state = deviceRevokedViewModel.uiState.collectAsState().value
- val topColor = colorResource(
- if (state == DeviceRevokedUiState.SECURED) {
- R.color.green
- } else {
- R.color.red
- }
- )
+ val topColor =
+ colorResource(
+ if (state == DeviceRevokedUiState.SECURED) {
+ R.color.green
+ } else {
+ R.color.red
+ }
+ )
ScaffoldWithTopBar(
topBarColor = topColor,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt
index ed9b298ed0..3168824c92 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt
@@ -44,8 +44,7 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
private lateinit var input: AccountInput
private lateinit var createAccountButton: Button
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -66,10 +65,11 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
loggedInStatus = view.findViewById(R.id.logged_in_status)
loginFailStatus = view.findViewById(R.id.login_fail_status)
- accountLogin = view.findViewById<AccountLogin>(R.id.account_login).apply {
- onLogin = loginViewModel::login
- onClearHistory = loginViewModel::clearAccountHistory
- }
+ accountLogin =
+ view.findViewById<AccountLogin>(R.id.account_login).apply {
+ onLogin = loginViewModel::login
+ onClearHistory = loginViewModel::clearAccountHistory
+ }
createAccountButton = view.findViewById(R.id.create_account)
createAccountButton.setOnClickAction(
@@ -80,9 +80,8 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
scrollArea = view.findViewById(R.id.scroll_area)
- background = view.findViewById<View>(R.id.contents).apply {
- setOnClickListener { requestFocus() }
- }
+ background =
+ view.findViewById<View>(R.id.contents).apply { setOnClickListener { requestFocus() } }
scrollToShow(accountLogin)
@@ -102,9 +101,7 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
false
}
}
- input.onTextChanged.subscribe(this) {
- createAccountButton.isEnabled = it.isEmpty()
- }
+ input.onTextChanged.subscribe(this) { createAccountButton.isEnabled = it.isEmpty() }
}
override fun onResume() {
@@ -155,41 +152,32 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
is LoginViewModel.LoginUiState.Default -> {
showDefault()
}
-
is LoginViewModel.LoginUiState.Success -> {
// MainActivity responsible for transition to connect/out-of-time view.
showLoggedIn()
}
-
is LoginViewModel.LoginUiState.AccountCreated -> {
// MainActivity responsible for transition to welcome view.
}
-
is LoginViewModel.LoginUiState.CreatingAccount -> {
showCreatingAccount()
}
-
is LoginViewModel.LoginUiState.Loading -> {
showLoading()
}
-
is LoginViewModel.LoginUiState.InvalidAccountError -> {
loginFailure(resources.getString(R.string.login_fail_description))
}
-
is LoginViewModel.LoginUiState.TooManyDevicesError -> {
showLoading(overrideSpinnerWithErrorIcon = true)
openDeviceListFragment(uiState.accountToken)
}
-
is LoginViewModel.LoginUiState.TooManyDevicesMissingListError -> {
loginFailure(context?.getString(R.string.failed_to_fetch_devices))
}
-
is LoginViewModel.LoginUiState.UnableToCreateAccountError -> {
loginFailure(resources.getString(R.string.failed_to_create_account))
}
-
is LoginViewModel.LoginUiState.OtherError -> {
loginFailure(resources.getString(R.string.error_occurred))
}
@@ -198,9 +186,10 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
private fun openDeviceListFragment(accountToken: String) {
- val deviceFragment = DeviceListFragment().apply {
- arguments = Bundle().apply { putString(ACCOUNT_TOKEN_ARGUMENT_KEY, accountToken) }
- }
+ val deviceFragment =
+ DeviceListFragment().apply {
+ arguments = Bundle().apply { putString(ACCOUNT_TOKEN_ARGUMENT_KEY, accountToken) }
+ }
parentFragmentManager.beginTransaction().apply {
setCustomAnimations(
@@ -228,17 +217,19 @@ class LoginFragment : BaseFragment(), NavigationBarPainter {
title.setText(R.string.logging_in_title)
subtitle.setText(R.string.logging_in_description)
- loggingInStatus.visibility = if (overrideSpinnerWithErrorIcon == false) {
- View.VISIBLE
- } else {
- View.GONE
- }
+ loggingInStatus.visibility =
+ if (overrideSpinnerWithErrorIcon == false) {
+ View.VISIBLE
+ } else {
+ View.GONE
+ }
- loginFailStatus.visibility = if (overrideSpinnerWithErrorIcon == false) {
- View.GONE
- } else {
- View.VISIBLE
- }
+ loginFailStatus.visibility =
+ if (overrideSpinnerWithErrorIcon == false) {
+ View.GONE
+ } else {
+ View.VISIBLE
+ }
loggedInStatus.visibility = View.GONE
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt
index c1b4633692..8acb8e38df 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt
@@ -46,14 +46,14 @@ class OutOfTimeFragment : BaseFragment() {
private lateinit var disconnectButton: Button
private lateinit var redeemButton: RedeemVoucherButton
- private var tunnelState by observable<TunnelState>(TunnelState.Disconnected) { _, _, state ->
- updateDisconnectButton()
- updateBuyButtons()
- headerBar.tunnelState = state
- }
+ private var tunnelState by
+ observable<TunnelState>(TunnelState.Disconnected) { _, _, state ->
+ updateDisconnectButton()
+ updateBuyButtons()
+ headerBar.tunnelState = state
+ }
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -67,9 +67,10 @@ class OutOfTimeFragment : BaseFragment() {
): View? {
val view = inflater.inflate(R.layout.out_of_time, container, false)
- headerBar = view.findViewById<HeaderBar>(R.id.header_bar).apply {
- tunnelState = this@OutOfTimeFragment.tunnelState
- }
+ headerBar =
+ view.findViewById<HeaderBar>(R.id.header_bar).apply {
+ tunnelState = this@OutOfTimeFragment.tunnelState
+ }
view.findViewById<TextView>(R.id.account_credit_has_expired).text = buildString {
append(requireActivity().getString(R.string.account_credit_has_expired))
@@ -77,29 +78,32 @@ class OutOfTimeFragment : BaseFragment() {
requireActivity().getString(R.string.add_time_to_account)
}
- disconnectButton = view.findViewById<Button>(R.id.disconnect).apply {
- setOnClickAction("disconnect", jobTracker) {
- serviceConnectionManager.connectionProxy()?.disconnect()
+ disconnectButton =
+ view.findViewById<Button>(R.id.disconnect).apply {
+ setOnClickAction("disconnect", jobTracker) {
+ serviceConnectionManager.connectionProxy()?.disconnect()
+ }
}
- }
- sitePaymentButton = view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
- newAccount = false
+ sitePaymentButton =
+ view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
+ newAccount = false
- setOnClickAction("openAccountPageInBrowser", jobTracker) {
- setEnabled(false)
- serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
- context.openAccountPageInBrowser(token)
+ setOnClickAction("openAccountPageInBrowser", jobTracker) {
+ setEnabled(false)
+ serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
+ context.openAccountPageInBrowser(token)
+ }
+ setEnabled(true)
}
- setEnabled(true)
- }
- isEnabled = true
- }
+ isEnabled = true
+ }
- redeemButton = view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply {
- prepare(parentFragmentManager, jobTracker)
- }
+ redeemButton =
+ view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply {
+ prepare(parentFragmentManager, jobTracker)
+ }
return view
}
@@ -120,9 +124,7 @@ class OutOfTimeFragment : BaseFragment() {
private fun CoroutineScope.launchProceedToConnectViewIfExpiryExtended() = launch {
accountRepository.accountExpiryState
.map { state -> state.date() }
- .collect { expiryDate ->
- checkExpiry(expiryDate)
- }
+ .collect { expiryDate -> checkExpiry(expiryDate) }
}
private fun CoroutineScope.launchExpiryPolling() = launch {
@@ -136,29 +138,27 @@ class OutOfTimeFragment : BaseFragment() {
serviceConnectionManager.connectionState
.flatMapLatest { state ->
if (state is ServiceConnectionState.ConnectedReady) {
- callbackFlowFromNotifier(
- state.container.connectionProxy.onStateChange
- )
+ callbackFlowFromNotifier(state.container.connectionProxy.onStateChange)
} else {
emptyFlow()
}
}
- .collect { newState ->
- tunnelState = newState
- }
+ .collect { newState -> tunnelState = newState }
}
private fun updateDisconnectButton() {
val state = tunnelState
- val showButton = when (state) {
- is TunnelState.Disconnected -> false
- is TunnelState.Connecting, is TunnelState.Connected -> true
- is TunnelState.Disconnecting -> {
- state.actionAfterDisconnect != ActionAfterDisconnect.Nothing
+ val showButton =
+ when (state) {
+ is TunnelState.Disconnected -> false
+ is TunnelState.Connecting,
+ is TunnelState.Connected -> true
+ is TunnelState.Disconnecting -> {
+ state.actionAfterDisconnect != ActionAfterDisconnect.Nothing
+ }
+ is TunnelState.Error -> state.errorState.isBlocking
}
- is TunnelState.Error -> state.errorState.isBlocking
- }
disconnectButton.apply {
if (showButton) {
@@ -176,17 +176,16 @@ class OutOfTimeFragment : BaseFragment() {
val hasConnectivity = currentState is TunnelState.Disconnected
sitePaymentButton.setEnabled(hasConnectivity)
- val isOffline = currentState is TunnelState.Error &&
- currentState.errorState.cause is ErrorStateCause.IsOffline
+ val isOffline =
+ currentState is TunnelState.Error &&
+ currentState.errorState.cause is ErrorStateCause.IsOffline
redeemButton.setEnabled(!isOffline)
}
private fun checkExpiry(maybeExpiry: DateTime?) {
maybeExpiry?.let { expiry ->
if (expiry.isAfterNow()) {
- jobTracker.newUiJob("advanceToConnectScreen") {
- advanceToConnectScreen()
- }
+ jobTracker.newUiJob("advanceToConnectScreen") { advanceToConnectScreen() }
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt
index 0e3a52d54b..d38b905a21 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt
@@ -28,15 +28,16 @@ import net.mullvad.mullvadvpn.util.JobTracker
class ProblemReportFragment : BaseFragment() {
private val jobTracker = JobTracker()
- private var showingEmail by observable(false) { _, oldValue, newValue ->
- if (oldValue != newValue) {
- if (newValue == true) {
- parentActivity.enterSecureScreen(this)
- } else {
- parentActivity.leaveSecureScreen(this)
+ private var showingEmail by
+ observable(false) { _, oldValue, newValue ->
+ if (oldValue != newValue) {
+ if (newValue == true) {
+ parentActivity.enterSecureScreen(this)
+ } else {
+ parentActivity.leaveSecureScreen(this)
+ }
}
}
- }
private lateinit var parentActivity: MainActivity
private lateinit var problemReport: MullvadProblemReport
@@ -76,9 +77,7 @@ class ProblemReportFragment : BaseFragment() {
): View {
val view = inflater.inflate(R.layout.problem_report, container, false)
- view.findViewById<View>(R.id.back).setOnClickListener {
- activity?.onBackPressed()
- }
+ view.findViewById<View>(R.id.back).setOnClickListener { activity?.onBackPressed() }
bodyContainer = view.findViewById<ViewSwitcher>(R.id.body_container)
userEmailInput = view.findViewById<EditText>(R.id.user_email)
@@ -96,24 +95,14 @@ class ProblemReportFragment : BaseFragment() {
editMessageButton = view.findViewById<Button>(R.id.edit_message_button)
tryAgainButton = view.findViewById<Button>(R.id.try_again_button)
- view.findViewById<Button>(R.id.view_logs).setOnClickListener {
- showLogs()
- }
+ view.findViewById<Button>(R.id.view_logs).setOnClickListener { showLogs() }
- sendButton.setOnClickListener {
- jobTracker.newUiJob("sendReport") {
- sendReport(true)
- }
- }
+ sendButton.setOnClickListener { jobTracker.newUiJob("sendReport") { sendReport(true) } }
- editMessageButton.setOnClickListener {
- showForm()
- }
+ editMessageButton.setOnClickListener { showForm() }
tryAgainButton.setOnClickListener {
- jobTracker.newUiJob("sendReport") {
- sendReport(false)
- }
+ jobTracker.newUiJob("sendReport") { sendReport(false) }
}
userEmailInput.setText(problemReport.userEmail)
@@ -244,9 +233,10 @@ class ProblemReportFragment : BaseFragment() {
val colorStyle = ForegroundColorSpan(parentActivity.getColor(R.color.green))
- sendDetailsLabel.text = SpannableStringBuilder("$thanks $weWillLookIntoThis").apply {
- setSpan(colorStyle, 0, thanks.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
- }
+ sendDetailsLabel.text =
+ SpannableStringBuilder("$thanks $weWillLookIntoThis").apply {
+ setSpan(colorStyle, 0, thanks.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
sendDetailsLabel.visibility = View.VISIBLE
}
@@ -262,10 +252,11 @@ class ProblemReportFragment : BaseFragment() {
val boldStyle = StyleSpan(Typeface.BOLD)
val colorStyle = ForegroundColorSpan(parentActivity.getColor(R.color.white))
- responseMessageLabel.text = SpannableStringBuilder(responseMessage).apply {
- setSpan(boldStyle, emailStart, emailEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
- setSpan(colorStyle, emailStart, emailEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
- }
+ responseMessageLabel.text =
+ SpannableStringBuilder(responseMessage).apply {
+ setSpan(boldStyle, emailStart, emailEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
+ setSpan(colorStyle, emailStart, emailEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
responseMessageLabel.visibility = View.VISIBLE
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt
index 6efe55c118..a2c369bb15 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt
@@ -73,9 +73,10 @@ class RedeemVoucherDialogFragment : DialogFragment() {
): View {
val view = inflater.inflate(R.layout.redeem_voucher, container, false)
- voucherInput = view.findViewById<EditText>(R.id.voucher_code).apply {
- addTextChangedListener(ValidVoucherCodeChecker())
- }
+ voucherInput =
+ view.findViewById<EditText>(R.id.voucher_code).apply {
+ addTextChangedListener(ValidVoucherCodeChecker())
+ }
SegmentedInputFormatter(voucherInput, '-').apply {
allCaps = true
@@ -85,13 +86,12 @@ class RedeemVoucherDialogFragment : DialogFragment() {
}
}
- redeemButton = view.findViewById<Button>(R.id.redeem).apply {
- setEnabled(false)
+ redeemButton =
+ view.findViewById<Button>(R.id.redeem).apply {
+ setEnabled(false)
- setOnClickAction("action", jobTracker) {
- submitVoucher()
+ setOnClickAction("action", jobTracker) { submitVoucher() }
}
- }
errorMessage = view.findViewById(R.id.error)
@@ -141,7 +141,9 @@ class RedeemVoucherDialogFragment : DialogFragment() {
when (result) {
is VoucherSubmissionResult.Ok -> handleAddedTime(result.submission.timeAdded)
is VoucherSubmissionResult.Error -> showError(result.error)
- else -> { /* NOOP */ }
+ else -> {
+ /* NOOP */
+ }
}
}
@@ -152,11 +154,12 @@ class RedeemVoucherDialogFragment : DialogFragment() {
}
private fun showError(error: VoucherSubmissionError) {
- val message = when (error) {
- VoucherSubmissionError.InvalidVoucher -> R.string.invalid_voucher
- VoucherSubmissionError.VoucherAlreadyUsed -> R.string.voucher_already_used
- else -> R.string.error_occurred
- }
+ val message =
+ when (error) {
+ VoucherSubmissionError.InvalidVoucher -> R.string.invalid_voucher
+ VoucherSubmissionError.VoucherAlreadyUsed -> R.string.voucher_already_used
+ else -> R.string.error_occurred
+ }
errorMessage.apply {
setText(message)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt
index e154037ca1..27db561ee9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt
@@ -37,28 +37,28 @@ import org.koin.core.scope.Scope
class SplitTunnelingFragment : BaseFragment(R.layout.collapsed_title_layout) {
private val listItemsAdapter = ListItemsAdapter()
- private val scope: Scope = getKoin().getOrCreateScope(APPS_SCOPE, named(APPS_SCOPE))
- .also { appsScope ->
+ private val scope: Scope =
+ getKoin().getOrCreateScope(APPS_SCOPE, named(APPS_SCOPE)).also { appsScope ->
getKoin().getScopeOrNull(SERVICE_CONNECTION_SCOPE)?.let { serviceConnectionScope ->
appsScope.linkTo(serviceConnectionScope)
}
}
- private val viewModel by scope.viewModel<SplitTunnelingViewModel>(
- owner = {
- ViewModelOwner.from(this, this)
- }
- )
+ private val viewModel by
+ scope.viewModel<SplitTunnelingViewModel>(owner = { ViewModelOwner.from(this, this) })
private val toggleSystemAppsVisibility = Channel<Boolean>(Channel.CONFLATED)
private val toggleExcludeChannel = Channel<ListItemData>(Channel.BUFFERED)
- private val listItemListener = object : ListItemListener {
- override fun onItemAction(item: ListItemData) {
- when (item.widget) {
- is ImageState -> toggleExcludeChannel.trySend(item)
- is SwitchState -> toggleSystemAppsVisibility.trySend(!item.widget.isChecked)
- else -> { /* NOOP */ }
+ private val listItemListener =
+ object : ListItemListener {
+ override fun onItemAction(item: ListItemData) {
+ when (item.widget) {
+ is ImageState -> toggleExcludeChannel.trySend(item)
+ is SwitchState -> toggleSystemAppsVisibility.trySend(!item.widget.isChecked)
+ else -> {
+ /* NOOP */
+ }
+ }
}
}
- }
private var recyclerView: RecyclerView? = null
@@ -69,32 +69,24 @@ class SplitTunnelingFragment : BaseFragment(R.layout.collapsed_title_layout) {
}
listItemsAdapter.listItemListener = listItemListener
listItemsAdapter.setHasStableIds(true)
- recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView).apply {
- adapter = listItemsAdapter
- addItemDecoration(
- ListItemDividerDecoration(
- topOffset = resources.getDimensionPixelSize(R.dimen.list_item_divider)
+ recyclerView =
+ view.findViewById<RecyclerView>(R.id.recyclerView).apply {
+ adapter = listItemsAdapter
+ addItemDecoration(
+ ListItemDividerDecoration(
+ topOffset = resources.getDimensionPixelSize(R.dimen.list_item_divider)
+ )
)
- )
- tweakMargin(this)
- }
- view.findViewById<View>(R.id.back).setOnClickListener {
- requireActivity().onBackPressed()
- }
+ tweakMargin(this)
+ }
+ view.findViewById<View>(R.id.back).setOnClickListener { requireActivity().onBackPressed() }
lifecycleScope.launchWhenStarted {
- viewModel.listItems
- .onEach {
- listItemsAdapter.setItems(it)
- }
- .catch { }
- .collect()
+ viewModel.listItems.onEach { listItemsAdapter.setItems(it) }.catch {}.collect()
}
lifecycleScope.launchWhenResumed {
// pass view intent to view model
- intents()
- .onEach { viewModel.processIntent(it) }
- .collect()
+ intents().onEach { viewModel.processIntent(it) }.collect()
}
}
@@ -105,11 +97,12 @@ class SplitTunnelingFragment : BaseFragment(R.layout.collapsed_title_layout) {
super.onDestroy()
}
- private fun intents(): Flow<ViewIntent> = merge(
- transitionFinishedFlow.map { ViewIntent.ViewIsReady },
- toggleExcludeChannel.consumeAsFlow().map { ViewIntent.ChangeApplicationGroup(it) },
- toggleSystemAppsVisibility.consumeAsFlow().map { ViewIntent.ShowSystemApps(it) }
- )
+ private fun intents(): Flow<ViewIntent> =
+ merge(
+ transitionFinishedFlow.map { ViewIntent.ViewIsReady },
+ toggleExcludeChannel.consumeAsFlow().map { ViewIntent.ChangeApplicationGroup(it) },
+ toggleSystemAppsVisibility.consumeAsFlow().map { ViewIntent.ShowSystemApps(it) }
+ )
private fun tweakMargin(view: View) {
if (!hasNavigationBar()) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt
index 65f44770fb..b655c007c6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt
@@ -33,9 +33,7 @@ class ViewLogsFragment : BaseFragment() {
): View {
val view = inflater.inflate(R.layout.view_logs, container, false)
- view.findViewById<View>(R.id.back).setOnClickListener {
- activity?.onBackPressed()
- }
+ view.findViewById<View>(R.id.back).setOnClickListener { activity?.onBackPressed() }
logArea = view.findViewById<EditText>(R.id.log_area)
@@ -46,9 +44,7 @@ class ViewLogsFragment : BaseFragment() {
super.onStart()
jobTracker.newUiJob("showLogs") {
- val logs = jobTracker.runOnBackground {
- problemReport.load()
- }
+ val logs = jobTracker.runOnBackground { problemReport.load() }
logArea.setText(logs)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt
index e049afc7e5..a2176cceff 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt
@@ -49,8 +49,7 @@ class WelcomeFragment : BaseFragment() {
private lateinit var headerBar: HeaderBar
private lateinit var sitePaymentButton: SitePaymentButton
- @Deprecated("Refactor code to instead rely on Lifecycle.")
- private val jobTracker = JobTracker()
+ @Deprecated("Refactor code to instead rely on Lifecycle.") private val jobTracker = JobTracker()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -64,13 +63,15 @@ class WelcomeFragment : BaseFragment() {
): View? {
val view = inflater.inflate(R.layout.welcome, container, false)
- headerBar = view.findViewById<HeaderBar>(R.id.header_bar).apply {
- tunnelState = TunnelState.Disconnected
- }
+ headerBar =
+ view.findViewById<HeaderBar>(R.id.header_bar).apply {
+ tunnelState = TunnelState.Disconnected
+ }
- accountLabel = view.findViewById<TextView>(R.id.account_number).apply {
- setOnClickListener { copyAccountTokenToClipboard() }
- }
+ accountLabel =
+ view.findViewById<TextView>(R.id.account_number).apply {
+ setOnClickListener { copyAccountTokenToClipboard() }
+ }
view.findViewById<TextView>(R.id.pay_to_start_using).text = buildString {
append(requireActivity().getString(R.string.pay_to_start_using))
@@ -78,17 +79,18 @@ class WelcomeFragment : BaseFragment() {
append(requireActivity().getString(R.string.add_time_to_account))
}
- sitePaymentButton = view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
- newAccount = true
+ sitePaymentButton =
+ view.findViewById<SitePaymentButton>(R.id.site_payment).apply {
+ newAccount = true
- setOnClickAction("openAccountPageInBrowser", jobTracker) {
- setEnabled(false)
- serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
- context.openAccountPageInBrowser(token)
+ setOnClickAction("openAccountPageInBrowser", jobTracker) {
+ setEnabled(false)
+ serviceConnectionManager.authTokenCache()?.fetchAuthToken()?.let { token ->
+ context.openAccountPageInBrowser(token)
+ }
+ setEnabled(true)
}
- setEnabled(true)
}
- }
view.findViewById<RedeemVoucherButton>(R.id.redeem_voucher).apply {
prepare(parentFragmentManager, jobTracker)
@@ -114,15 +116,11 @@ class WelcomeFragment : BaseFragment() {
private fun CoroutineScope.launchUpdateAccountNumberOnDeviceChanges() = launch {
deviceRepository.deviceState
.debounce { it.addDebounceForUnknownState(UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS) }
- .collect { state ->
- updateAccountNumber(state.token())
- }
+ .collect { state -> updateAccountNumber(state.token()) }
}
private fun CoroutineScope.launchAdvanceToConnectViewOnExpiryExtended() = launch {
- accountRepository.accountExpiryState.collect {
- checkExpiry(it.date())
- }
+ accountRepository.accountExpiryState.collect { checkExpiry(it.date()) }
}
private fun CoroutineScope.launchExpiryPolling() = launch {
@@ -136,9 +134,7 @@ class WelcomeFragment : BaseFragment() {
serviceConnectionManager.connectionState
.flatMapLatest { state ->
if (state is ServiceConnectionState.ConnectedReady) {
- callbackFlowFromNotifier(
- state.container.connectionProxy.onStateChange
- )
+ callbackFlowFromNotifier(state.container.connectionProxy.onStateChange)
} else {
emptyFlow()
}
@@ -152,9 +148,7 @@ class WelcomeFragment : BaseFragment() {
}
private fun updateAccountNumber(rawAccountNumber: String?) {
- val accountText = rawAccountNumber?.let { account ->
- addSpacesToAccountText(account)
- }
+ val accountText = rawAccountNumber?.let { account -> addSpacesToAccountText(account) }
accountLabel.text = accountText ?: ""
accountLabel.setEnabled(accountText != null && accountText.length > 0)
@@ -168,12 +162,13 @@ class WelcomeFragment : BaseFragment() {
} else {
val numParts = (length - 1) / 4 + 1
- val parts = Array(numParts) { index ->
- val startIndex = index * 4
- val endIndex = minOf(startIndex + 4, length)
+ val parts =
+ Array(numParts) { index ->
+ val startIndex = index * 4
+ val endIndex = minOf(startIndex + 4, length)
- account.substring(startIndex, endIndex)
- }
+ account.substring(startIndex, endIndex)
+ }
return parts.joinToString(" ")
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt
index 63f19af27a..3966e0d7b9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt
@@ -11,7 +11,9 @@ import androidx.core.view.isVisible
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.model.WidgetState
-open class ActionListItemView @JvmOverloads constructor(
+open class ActionListItemView
+@JvmOverloads
+constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.actionListItemViewStyle,
@@ -24,9 +26,7 @@ open class ActionListItemView @JvmOverloads constructor(
protected val widgetContainer: ViewGroup = findViewById(R.id.widgetContainer)
protected val clickListener = OnClickListener {
- itemData.action?.let { _ ->
- listItemListener?.onItemAction(itemData)
- }
+ itemData.action?.let { _ -> listItemListener?.onItemAction(itemData) }
}
override val layoutRes: Int
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ApplicationListItemView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ApplicationListItemView.kt
index 798d812802..138e9bfb88 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ApplicationListItemView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ApplicationListItemView.kt
@@ -22,7 +22,9 @@ import org.koin.core.scope.Scope
import org.koin.core.scope.inject
@OptIn(KoinApiExtension::class)
-class ApplicationListItemView @JvmOverloads constructor(
+class ApplicationListItemView
+@JvmOverloads
+constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.applicationListItemViewStyle,
@@ -43,17 +45,11 @@ class ApplicationListItemView @JvmOverloads constructor(
override fun updateImage() {
itemIcon.isVisible = true
updateImageJob?.cancel()
- updateImageJob = viewScope.launch {
- loadImage()?.let { drawable ->
- updateImage(drawable)
- }
- }
+ updateImageJob = viewScope.launch { loadImage()?.let { drawable -> updateImage(drawable) } }
}
override fun updateText() {
- itemData.text?.let {
- itemText.text = it
- }
+ itemData.text?.let { itemText.text = it }
}
override fun onAttachedToWindow() {
@@ -67,13 +63,14 @@ class ApplicationListItemView @JvmOverloads constructor(
viewScope.coroutineContext.cancelChildren()
}
- private suspend fun loadImage(): Drawable? = withContext(Dispatchers.Default) {
- try {
- iconManager.getAppIcon(itemData.identifier)
- } catch (e: PackageManager.NameNotFoundException) {
- null
+ private suspend fun loadImage(): Drawable? =
+ withContext(Dispatchers.Default) {
+ try {
+ iconManager.getAppIcon(itemData.identifier)
+ } catch (e: PackageManager.NameNotFoundException) {
+ null
+ }
}
- }
private fun updateImage(drawable: Drawable) = itemIcon.setImageDrawable(drawable)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt
index 9baec663c5..5b8bb39b4b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt
@@ -9,27 +9,28 @@ import androidx.constraintlayout.widget.ConstraintLayout
import net.mullvad.mullvadvpn.model.ListItemData
import net.mullvad.mullvadvpn.ui.ListItemListener
-abstract class ListItemView @JvmOverloads constructor(
+abstract class ListItemView
+@JvmOverloads
+constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {
- @get:LayoutRes
- protected abstract val layoutRes: Int
+ @get:LayoutRes protected abstract val layoutRes: Int
- @get:DimenRes
- protected abstract val heightRes: Int?
+ @get:DimenRes protected abstract val heightRes: Int?
protected lateinit var itemData: ListItemData
var listItemListener: ListItemListener? = null
init {
val view = LayoutInflater.from(context).inflate(layoutRes, this, true)
- val height = if (heightRes != null) {
- resources.getDimensionPixelSize(heightRes!!)
- } else {
- LayoutParams.WRAP_CONTENT
- }
+ val height =
+ if (heightRes != null) {
+ resources.getDimensionPixelSize(heightRes!!)
+ } else {
+ LayoutParams.WRAP_CONTENT
+ }
view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, height)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt
index f1ec04bd1d..73076fbad8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt
@@ -9,8 +9,7 @@ import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.model.WidgetState
sealed class WidgetViewController<T : WidgetState>(val parent: ViewGroup) {
- @get:LayoutRes
- protected abstract val layoutRes: Int
+ @get:LayoutRes protected abstract val layoutRes: Int
init {
LayoutInflater.from(parent.context).inflate(layoutRes, parent)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotificationController.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotificationController.kt
index 1c0fb73d93..09b4947bbc 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotificationController.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotificationController.kt
@@ -12,11 +12,12 @@ class InAppNotificationController(private val onNotificationChanged: (InAppNotif
private val activeNotifications = PriorityQueue(notificationPrioritizer)
private val notifications = HashMap<InAppNotification, Int>()
- var current by observable<InAppNotification?>(null) { _, oldNotification, newNotification ->
- if (oldNotification != newNotification) {
- onNotificationChanged.invoke(newNotification)
+ var current by
+ observable<InAppNotification?>(null) { _, oldNotification, newNotification ->
+ if (oldNotification != newNotification) {
+ onNotificationChanged.invoke(newNotification)
+ }
}
- }
fun register(notification: InAppNotification) {
notification.controller = this
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/NotificationWithUrl.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/NotificationWithUrl.kt
index 8e03db6df5..c73ccd2a6b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/NotificationWithUrl.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/NotificationWithUrl.kt
@@ -5,16 +5,12 @@ import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.net.Uri
-abstract class NotificationWithUrl(
- protected val context: Context,
- urlId: Int
-) : InAppNotification() {
+abstract class NotificationWithUrl(protected val context: Context, urlId: Int) :
+ InAppNotification() {
private val url = Uri.parse(context.getString(urlId))
protected val openUrl: suspend () -> Unit = {
- val intent = Intent(Intent.ACTION_VIEW, url).apply {
- flags = FLAG_ACTIVITY_NEW_TASK
- }
+ val intent = Intent(Intent.ACTION_VIEW, url).apply { flags = FLAG_ACTIVITY_NEW_TASK }
context.startActivity(intent)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt
index d85f70ca5b..ad00489f56 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt
@@ -4,9 +4,8 @@ import android.content.Context
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.ui.VersionInfo
-class VersionInfoNotification(
- context: Context
-) : NotificationWithUrl(context, R.string.download_url) {
+class VersionInfoNotification(context: Context) :
+ NotificationWithUrl(context, R.string.download_url) {
private val unsupportedVersion = context.getString(R.string.unsupported_version)
private val updateAvailable = context.getString(R.string.update_available)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt
index b921063c24..5280ef472d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AppVersionInfoCache.kt
@@ -9,9 +9,8 @@ class AppVersionInfoCache(
eventDispatcher: EventDispatcher,
private val settingsListener: SettingsListener
) {
- private var appVersionInfo by observable<AppVersionInfo?>(null) { _, _, _ ->
- onUpdate?.invoke()
- }
+ private var appVersionInfo by
+ observable<AppVersionInfo?>(null) { _, _, _ -> onUpdate?.invoke() }
val isSupported
get() = appVersionInfo?.supported ?: true
@@ -22,15 +21,14 @@ class AppVersionInfoCache(
val upgradeVersion
get() = appVersionInfo?.suggestedUpgrade
- var onUpdate by observable<(() -> Unit)?>(null) { _, _, callback ->
- callback?.invoke()
- }
+ var onUpdate by observable<(() -> Unit)?>(null) { _, _, callback -> callback?.invoke() }
- var showBetaReleases by observable(false) { _, wasShowing, shouldShow ->
- if (shouldShow != wasShowing) {
- onUpdate?.invoke()
+ var showBetaReleases by
+ observable(false) { _, wasShowing, shouldShow ->
+ if (shouldShow != wasShowing) {
+ onUpdate?.invoke()
+ }
}
- }
private set
var version: String? = null
@@ -38,9 +36,7 @@ class AppVersionInfoCache(
init {
eventDispatcher.apply {
- registerHandler(Event.CurrentVersion::class) { event ->
- version = event.version
- }
+ registerHandler(Event.CurrentVersion::class) { event -> version = event.version }
registerHandler(Event.AppVersionInfo::class) { event ->
appVersionInfo = event.versionInfo
@@ -48,9 +44,7 @@ class AppVersionInfoCache(
}
settingsListener.settingsNotifier.subscribe(this) { maybeSettings ->
- maybeSettings?.let { settings ->
- showBetaReleases = settings.showBetaReleases
- }
+ maybeSettings?.let { settings -> showBetaReleases = settings.showBetaReleases }
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AuthTokenCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AuthTokenCache.kt
index 2078de671a..0bef217ca2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AuthTokenCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AuthTokenCache.kt
@@ -12,18 +12,14 @@ class AuthTokenCache(private val connection: Messenger, eventDispatcher: EventDi
init {
eventDispatcher.registerHandler(Event.AuthToken::class) { event ->
- synchronized(this@AuthTokenCache) {
- fetchQueue.poll()?.complete(event.token ?: "")
- }
+ synchronized(this@AuthTokenCache) { fetchQueue.poll()?.complete(event.token ?: "") }
}
}
suspend fun fetchAuthToken(): String {
val authToken = CompletableDeferred<String>()
- synchronized(this) {
- fetchQueue.offer(authToken)
- }
+ synchronized(this) { fetchQueue.offer(authToken) }
connection.send(Request.FetchAuthToken.message)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt
index fcd8565550..33a1ffb4e9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt
@@ -82,19 +82,20 @@ class ConnectionProxy(private val connection: Messenger, eventDispatcher: EventD
synchronized(this) {
val currentState = uiState
- val willReconnect = when (currentState) {
- is TunnelState.Disconnected -> false
- is TunnelState.Disconnecting -> {
- when (currentState.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> false
- ActionAfterDisconnect.Reconnect -> true
- ActionAfterDisconnect.Block -> true
+ val willReconnect =
+ when (currentState) {
+ is TunnelState.Disconnected -> false
+ is TunnelState.Disconnecting -> {
+ when (currentState.actionAfterDisconnect) {
+ ActionAfterDisconnect.Nothing -> false
+ ActionAfterDisconnect.Reconnect -> true
+ ActionAfterDisconnect.Block -> true
+ }
}
+ is TunnelState.Connecting -> true
+ is TunnelState.Connected -> true
+ is TunnelState.Error -> true
}
- is TunnelState.Connecting -> true
- is TunnelState.Connected -> true
- is TunnelState.Error -> true
- }
if (willReconnect) {
scheduleToResetAnticipatedState()
@@ -124,15 +125,16 @@ class ConnectionProxy(private val connection: Messenger, eventDispatcher: EventD
var currentJob: Job? = null
- val newJob = GlobalScope.launch(Dispatchers.Default) {
- delay(ANTICIPATED_STATE_TIMEOUT_MS)
+ val newJob =
+ GlobalScope.launch(Dispatchers.Default) {
+ delay(ANTICIPATED_STATE_TIMEOUT_MS)
- synchronized(this@ConnectionProxy) {
- if (!currentJob!!.isCancelled) {
- uiState = state
+ synchronized(this@ConnectionProxy) {
+ if (!currentJob!!.isCancelled) {
+ uiState = state
+ }
}
}
- }
currentJob = newJob
resetAnticipatedStateJob = newJob
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/LocationInfoCache.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/LocationInfoCache.kt
index 8eee6503c7..198a61cd59 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/LocationInfoCache.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/LocationInfoCache.kt
@@ -6,13 +6,13 @@ import net.mullvad.mullvadvpn.ipc.EventDispatcher
import net.mullvad.mullvadvpn.model.GeoIpLocation
class LocationInfoCache(eventDispatcher: EventDispatcher) {
- private var location: GeoIpLocation? by observable(null) { _, _, newLocation ->
- onNewLocation?.invoke(newLocation)
- }
+ private var location: GeoIpLocation? by
+ observable(null) { _, _, newLocation -> onNewLocation?.invoke(newLocation) }
- var onNewLocation by observable<((GeoIpLocation?) -> Unit)?>(null) { _, _, callback ->
- callback?.invoke(location)
- }
+ var onNewLocation by
+ observable<((GeoIpLocation?) -> Unit)?>(null) { _, _, callback ->
+ callback?.invoke(location)
+ }
init {
eventDispatcher.registerHandler(Event.NewLocation::class) { event ->
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
index aebe1f0a4f..5a92eea719 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt
@@ -48,9 +48,7 @@ class RelayListListener(
init {
eventDispatcher.registerHandler(Event.NewRelayList::class) { event ->
- event.relayList?.let { relayLocations ->
- relayListChanged(RelayList(relayLocations))
- }
+ event.relayList?.let { relayLocations -> relayListChanged(RelayList(relayLocations)) }
}
settingsListener.relaySettingsNotifier.subscribe(this) { newRelaySettings ->
@@ -67,8 +65,8 @@ class RelayListListener(
synchronized(this) {
val relayList = this.relayList
- relaySettings = newRelaySettings
- ?: RelaySettings.Normal(RelayConstraints(Constraint.Any()))
+ relaySettings =
+ newRelaySettings ?: RelaySettings.Normal(RelayConstraints(Constraint.Any()))
if (relayList != null) {
relayListChanged(relayList)
@@ -95,7 +93,9 @@ class RelayListListener(
return relayList?.findItemForLocation(location, true)
}
- else -> { /* NOOP */ }
+ else -> {
+ /* NOOP */
+ }
}
return null
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt
index 05f6740a42..ff01f20eae 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionAccountDataSource.kt
@@ -12,9 +12,7 @@ class ServiceConnectionAccountDataSource(
private val dispatcher: EventDispatcher
) {
val accountCreationResult = callbackFlow {
- val handler: (Event.AccountCreationEvent) -> Unit = { event ->
- trySend(event.result)
- }
+ val handler: (Event.AccountCreationEvent) -> Unit = { event -> trySend(event.result) }
dispatcher.registerHandler(Event.AccountCreationEvent::class, handler)
awaitClose {
// The current dispatcher doesn't support unregistration of handlers.
@@ -22,9 +20,7 @@ class ServiceConnectionAccountDataSource(
}
val accountExpiry = callbackFlow {
- val handler: (Event.AccountExpiryEvent) -> Unit = { event ->
- trySend(event.expiry)
- }
+ val handler: (Event.AccountExpiryEvent) -> Unit = { event -> trySend(event.expiry) }
dispatcher.registerHandler(Event.AccountExpiryEvent::class, handler)
connection.send(Request.FetchAccountExpiry.message)
awaitClose {
@@ -33,9 +29,7 @@ class ServiceConnectionAccountDataSource(
}
val accountHistory = callbackFlow {
- val handler: (Event.AccountHistoryEvent) -> Unit = { event ->
- trySend(event.history)
- }
+ val handler: (Event.AccountHistoryEvent) -> Unit = { event -> trySend(event.history) }
dispatcher.registerHandler(Event.AccountHistoryEvent::class, handler)
awaitClose {
// The current dispatcher doesn't support unregistration of handlers.
@@ -43,9 +37,7 @@ class ServiceConnectionAccountDataSource(
}
val loginEvents = callbackFlow {
- val handler: (Event.LoginEvent) -> Unit = { event ->
- trySend(event)
- }
+ val handler: (Event.LoginEvent) -> Unit = { event -> trySend(event) }
dispatcher.registerHandler(Event.LoginEvent::class, handler)
awaitClose {
// The current dispatcher doesn't support unregistration of handlers.
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
index 130dc1a8c9..a58db46ff7 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt
@@ -24,14 +24,11 @@ class ServiceConnectionContainer(
onServiceReady: (ServiceConnectionContainer) -> Unit,
onVpnPermissionRequest: () -> Unit
) : KoinScopeComponent {
- private val dispatcher = DispatchingHandler(Looper.getMainLooper()) { message ->
- Event.fromMessage(message)
- }
+ private val dispatcher =
+ DispatchingHandler(Looper.getMainLooper()) { message -> Event.fromMessage(message) }
- override val scope = getKoin().getOrCreateScope(
- SERVICE_CONNECTION_SCOPE,
- named(SERVICE_CONNECTION_SCOPE), this
- )
+ override val scope =
+ getKoin().getOrCreateScope(SERVICE_CONNECTION_SCOPE, named(SERVICE_CONNECTION_SCOPE), this)
val accountDataSource = ServiceConnectionAccountDataSource(connection, dispatcher)
val authTokenCache = AuthTokenCache(connection, dispatcher)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt
index 39159a1a17..2f4ee1613c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt
@@ -13,9 +13,7 @@ class ServiceConnectionDeviceDataSource(
private val dispatcher: EventDispatcher
) {
val deviceStateUpdates = callbackFlow {
- val handler: (Event.DeviceStateEvent) -> Unit = { event ->
- trySend(event.newState)
- }
+ val handler: (Event.DeviceStateEvent) -> Unit = { event -> trySend(event.newState) }
dispatcher.registerHandler(Event.DeviceStateEvent::class, handler)
connection.trySendRequest(Request.GetDevice, false)
awaitClose {
@@ -24,9 +22,7 @@ class ServiceConnectionDeviceDataSource(
}
val deviceListUpdates = callbackFlow {
- val handler: (Event.DeviceListUpdate) -> Unit = { event ->
- trySend(event.event)
- }
+ val handler: (Event.DeviceListUpdate) -> Unit = { event -> trySend(event.event) }
dispatcher.registerHandler(Event.DeviceListUpdate::class, handler)
awaitClose {
// The current dispatcher doesn't support unregistration of handlers.
@@ -34,9 +30,7 @@ class ServiceConnectionDeviceDataSource(
}
val deviceRemovalResult = callbackFlow {
- val handler: (Event.DeviceRemovalEvent) -> Unit = { event ->
- trySend(event)
- }
+ val handler: (Event.DeviceRemovalEvent) -> Unit = { event -> trySend(event) }
dispatcher.registerHandler(Event.DeviceRemovalEvent::class, handler)
awaitClose {
// The current dispatcher doesn't support unregistration of handlers.
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
index a2a6a63f03..0bbc4e71d4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
@@ -14,9 +14,7 @@ import net.mullvad.mullvadvpn.lib.endpoint.putApiEndpointConfigurationExtra
import net.mullvad.mullvadvpn.service.MullvadVpnService
import net.mullvad.talpid.util.EventNotifier
-class ServiceConnectionManager(
- private val context: Context
-) {
+class ServiceConnectionManager(private val context: Context) {
private val _connectionState =
MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
@@ -29,27 +27,28 @@ class ServiceConnectionManager(
var isBound = false
private var vpnPermissionRequestHandler: (() -> Unit)? = null
- private val serviceConnection = object : android.content.ServiceConnection {
- override fun onServiceConnected(className: ComponentName, binder: IBinder) {
- Log.d("mullvad", "UI successfully connected to the service")
+ private val serviceConnection =
+ object : android.content.ServiceConnection {
+ override fun onServiceConnected(className: ComponentName, binder: IBinder) {
+ Log.d("mullvad", "UI successfully connected to the service")
- notify(
- ServiceConnectionState.ConnectedNotReady(
- ServiceConnectionContainer(
- Messenger(binder),
- ::handleNewServiceConnection,
- ::handleVpnPermissionRequest
+ notify(
+ ServiceConnectionState.ConnectedNotReady(
+ ServiceConnectionContainer(
+ Messenger(binder),
+ ::handleNewServiceConnection,
+ ::handleVpnPermissionRequest
+ )
)
)
- )
- }
+ }
- override fun onServiceDisconnected(className: ComponentName) {
- Log.d("mullvad", "UI lost the connection to the service")
- _connectionState.value.readyContainer()?.onDestroy()
- notify(ServiceConnectionState.Disconnected)
+ override fun onServiceDisconnected(className: ComponentName) {
+ Log.d("mullvad", "UI lost the connection to the service")
+ _connectionState.value.readyContainer()?.onDestroy()
+ notify(ServiceConnectionState.Disconnected)
+ }
}
- }
fun bind(
vpnPermissionRequestHandler: () -> Unit,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
index 392b841101..1de160ffe8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt
@@ -15,8 +15,7 @@ fun ServiceConnectionManager.connectionProxy() =
fun ServiceConnectionManager.deviceDataSource() =
this.connectionState.value.readyContainer()?.deviceDataSource
-fun ServiceConnectionManager.customDns() =
- this.connectionState.value.readyContainer()?.customDns
+fun ServiceConnectionManager.customDns() = this.connectionState.value.readyContainer()?.customDns
fun ServiceConnectionManager.relayListListener() =
this.connectionState.value.readyContainer()?.relayListListener
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SplitTunneling.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SplitTunneling.kt
index 7800661b21..877d847abc 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SplitTunneling.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SplitTunneling.kt
@@ -9,11 +9,12 @@ import net.mullvad.mullvadvpn.ipc.Request
class SplitTunneling(private val connection: Messenger, eventDispatcher: EventDispatcher) {
private var excludedApps: Set<String> = emptySet()
- var enabled by observable(false) { _, wasEnabled, isEnabled ->
- if (wasEnabled != isEnabled) {
- connection.send(Request.SetEnableSplitTunneling(isEnabled).message)
+ var enabled by
+ observable(false) { _, wasEnabled, isEnabled ->
+ if (wasEnabled != isEnabled) {
+ connection.send(Request.SetEnableSplitTunneling(isEnabled).message)
+ }
}
- }
init {
eventDispatcher.registerHandler(Event.SplitTunnelingUpdate::class) { event ->
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt
index d2378100ea..bb538f3f6b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt
@@ -22,9 +22,7 @@ class VoucherRedeemer(val connection: Messenger, eventDispatcher: MessageDispatc
suspend fun submit(voucher: String): VoucherSubmissionResult {
val result = CompletableDeferred<VoucherSubmissionResult>()
- synchronized(this) {
- activeSubmissions.put(voucher, result)
- }
+ synchronized(this) { activeSubmissions.put(voucher, result) }
connection.send(Request.SubmitVoucher(voucher).message)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountCell.kt
index 8ead4f917e..4a4acf737a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountCell.kt
@@ -18,46 +18,51 @@ class AccountCell : NavigateCell {
private val expiredColor = context.getColor(R.color.red)
private val normalColor = context.getColor(R.color.white60)
- private val remainingTimeLabel = TextView(context).apply {
- layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
- gravity = Gravity.RIGHT
+ private val remainingTimeLabel =
+ TextView(context).apply {
+ layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
+ gravity = Gravity.RIGHT
- resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
- setPadding(padding, 0, padding, 0)
- }
+ resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
+ setPadding(padding, 0, padding, 0)
+ }
- setAllCaps(true)
- setTextColor(normalColor)
- setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_small))
- setTypeface(null, Typeface.BOLD)
+ setAllCaps(true)
+ setTextColor(normalColor)
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_small))
+ setTypeface(null, Typeface.BOLD)
- text = ""
- }
+ text = ""
+ }
- var accountExpiry by observable<DateTime?>(null) { _, _, expiry ->
- remainingTimeLabel.apply {
- if (expiry != null) {
- val remainingTime = Duration(DateTime.now(), expiry)
+ var accountExpiry by
+ observable<DateTime?>(null) { _, _, expiry ->
+ remainingTimeLabel.apply {
+ if (expiry != null) {
+ val remainingTime = Duration(DateTime.now(), expiry)
- if (remainingTime.isShorterThan(Duration.ZERO)) {
- setText(R.string.out_of_time)
- setTextColor(expiredColor)
+ if (remainingTime.isShorterThan(Duration.ZERO)) {
+ setText(R.string.out_of_time)
+ setTextColor(expiredColor)
+ } else {
+ setText(formatter.format(expiry, remainingTime))
+ setTextColor(normalColor)
+ }
} else {
- setText(formatter.format(expiry, remainingTime))
- setTextColor(normalColor)
+ text = ""
}
- } else {
- text = ""
}
}
- }
constructor(context: Context) : super(context)
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
cell.addView(remainingTimeLabel, cell.childCount - 1)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
index 48a05dd63e..e60d9c406f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
@@ -8,15 +8,12 @@ import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.util.SegmentedTextFormatter
class AccountHistoryAdapter : Adapter<AccountHistoryHolder>() {
- private val formatter = SegmentedTextFormatter(' ').apply {
- isValidInputCharacter = { character ->
- '0' <= character && character <= '9'
+ private val formatter =
+ SegmentedTextFormatter(' ').apply {
+ isValidInputCharacter = { character -> '0' <= character && character <= '9' }
}
- }
- var accountHistory by observable<String?>(null) { _, _, _ ->
- notifyDataSetChanged()
- }
+ var accountHistory by observable<String?>(null) { _, _, _ -> notifyDataSetChanged() }
var onSelectEntry: ((String) -> Unit)? = null
var onRemoveEntry: (() -> Unit)? = null
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryHolder.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryHolder.kt
index 4a87f4f601..20685a0ca3 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryHolder.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryHolder.kt
@@ -7,15 +7,11 @@ import kotlin.properties.Delegates.observable
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.util.SegmentedTextFormatter
-class AccountHistoryHolder(
- view: View,
- private val formatter: SegmentedTextFormatter
-) : ViewHolder(view) {
+class AccountHistoryHolder(view: View, private val formatter: SegmentedTextFormatter) :
+ ViewHolder(view) {
private val label: TextView = view.findViewById(R.id.label)
- var accountToken by observable("") { _, _, account ->
- label.text = formatter.format(account)
- }
+ var accountToken by observable("") { _, _, account -> label.text = formatter.format(account) }
var onSelect: ((String) -> Unit)? = null
var onRemove: ((String) -> Unit)? = null
@@ -23,9 +19,7 @@ class AccountHistoryHolder(
init {
view.findViewById<View>(R.id.remove).apply {
- setOnClickListener {
- onRemove?.invoke(accountToken)
- }
+ setOnClickListener { onRemove?.invoke(accountToken) }
setOnFocusChangeListener { _, hasFocus ->
onFocusChanged?.invoke(accountToken, hasFocus)
@@ -33,9 +27,7 @@ class AccountHistoryHolder(
}
label.apply {
- setOnClickListener {
- onSelect?.invoke(accountToken)
- }
+ setOnClickListener { onSelect?.invoke(accountToken) }
setOnFocusChangeListener { _, hasFocus ->
onFocusChanged?.invoke(accountToken, hasFocus)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountInput.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountInput.kt
index 1312e4ddfd..32e81a25e4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountInput.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountInput.kt
@@ -33,54 +33,62 @@ class AccountInput : LinearLayout {
inflater.inflate(R.layout.account_input, this)
}
- private val inputWatcher = object : TextWatcher {
- override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) {}
+ private val inputWatcher =
+ object : TextWatcher {
+ override fun beforeTextChanged(
+ text: CharSequence,
+ start: Int,
+ count: Int,
+ after: Int
+ ) {}
- override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {}
+ override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) {}
- override fun afterTextChanged(text: Editable) {
- removeFormattingSpans(text)
- setButtonEnabled(text.length >= MIN_ACCOUNT_TOKEN_LENGTH)
- onTextChanged.notify(text.toString())
+ override fun afterTextChanged(text: Editable) {
+ removeFormattingSpans(text)
+ setButtonEnabled(text.length >= MIN_ACCOUNT_TOKEN_LENGTH)
+ onTextChanged.notify(text.toString())
+ }
}
- }
- val input = container.findViewById<EditText>(R.id.login_input).apply {
- addTextChangedListener(inputWatcher)
- setOnEnterOrDoneAction(::login)
+ val input =
+ container.findViewById<EditText>(R.id.login_input).apply {
+ addTextChangedListener(inputWatcher)
+ setOnEnterOrDoneAction(::login)
- onFocusChangeListener = OnFocusChangeListener { view, inputHasFocus ->
- hasFocus = inputHasFocus && view.isEnabled
- }
+ onFocusChangeListener = OnFocusChangeListener { view, inputHasFocus ->
+ hasFocus = inputHasFocus && view.isEnabled
+ }
- // Manually initializing the `DigitsKeyListener` allows spaces to be used and still keeps
- // the input type as a number so that the correct software keyboard type is shown
- keyListener = DigitsKeyListener.getInstance("01234567890 ")
+ // Manually initializing the `DigitsKeyListener` allows spaces to be used and still
+ // keeps
+ // the input type as a number so that the correct software keyboard type is shown
+ keyListener = DigitsKeyListener.getInstance("01234567890 ")
- SegmentedInputFormatter(this, ' ').apply {
- isValidInputCharacter = { character ->
- '0' <= character && character <= '9'
+ SegmentedInputFormatter(this, ' ').apply {
+ isValidInputCharacter = { character -> '0' <= character && character <= '9' }
}
}
- }
- private val button = container.findViewById<ImageButton>(R.id.login_button).apply {
- setOnClickListener { login() }
- }
+ private val button =
+ container.findViewById<ImageButton>(R.id.login_button).apply {
+ setOnClickListener { login() }
+ }
val onFocusChanged = EventNotifier(false)
private var hasFocus by onFocusChanged.notifiable()
val onTextChanged = EventNotifier("")
- var loginState by observable(LoginState.Initial) { _, _, state ->
- when (state) {
- LoginState.Initial -> initialState()
- LoginState.InProgress -> loggingInState()
- LoginState.Success -> successState()
- LoginState.Failure -> failureState()
+ var loginState by
+ observable(LoginState.Initial) { _, _, state ->
+ when (state) {
+ LoginState.Initial -> initialState()
+ LoginState.InProgress -> loggingInState()
+ LoginState.Success -> successState()
+ LoginState.Failure -> failureState()
+ }
}
- }
var onLogin: ((String) -> Unit)? = null
@@ -88,8 +96,11 @@ class AccountInput : LinearLayout {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
orientation = HORIZONTAL
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
index c204445168..82dc8b6451 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
@@ -22,12 +22,13 @@ class AccountLogin : RelativeLayout {
private val MAX_ACCOUNT_HISTORY_ENTRIES = 3
}
- fun setAccountToken(accountToken: String) { input.input.setText(accountToken) }
-
- private val focusDebouncer = Debouncer(false).apply {
- listener = { hasFocus -> focused = hasFocus }
+ fun setAccountToken(accountToken: String) {
+ input.input.setText(accountToken)
}
+ private val focusDebouncer =
+ Debouncer(false).apply { listener = { hasFocus -> focused = hasFocus } }
+
private val container =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service ->
val inflater = service as LayoutInflater
@@ -39,22 +40,22 @@ class AccountLogin : RelativeLayout {
private val accountHistoryList: RecyclerView = container.findViewById(R.id.history)
private val input: AccountInput = container.findViewById(R.id.input)
- private val historyAdapter = AccountHistoryAdapter().apply {
- onSelectEntry = { account -> input.loginWith(account) }
- onChildFocusChanged = { _, hasFocus -> focusDebouncer.rawValue = hasFocus }
- }
+ private val historyAdapter =
+ AccountHistoryAdapter().apply {
+ onSelectEntry = { account -> input.loginWith(account) }
+ onChildFocusChanged = { _, hasFocus -> focusDebouncer.rawValue = hasFocus }
+ }
private val dividerHeight = resources.getDimensionPixelSize(R.dimen.account_history_divider)
private val historyEntryHeight =
resources.getDimensionPixelSize(R.dimen.account_history_entry_height)
- private val historyAnimation = ValueAnimator.ofInt(0, 0).apply {
- addUpdateListener { animation ->
- updateHeight(animation.animatedValue as Int)
- }
+ private val historyAnimation =
+ ValueAnimator.ofInt(0, 0).apply {
+ addUpdateListener { animation -> updateHeight(animation.animatedValue as Int) }
- duration = 350
- }
+ duration = 350
+ }
private val maxHeight: Int
get() = MAX_ACCOUNT_HISTORY_ENTRIES * (historyEntryHeight + dividerHeight)
@@ -62,58 +63,65 @@ class AccountLogin : RelativeLayout {
private val expandedHeight: Int
get() = collapsedHeight + (historyHeight ?: 0)
- private var historyHeight by observable<Int?>(null) { _, oldHistoryHeight, newHistoryHeight ->
- if (newHistoryHeight != oldHistoryHeight) {
- historyAnimation.setIntValues(collapsedHeight, expandedHeight)
- reposition()
+ private var historyHeight by
+ observable<Int?>(null) { _, oldHistoryHeight, newHistoryHeight ->
+ if (newHistoryHeight != oldHistoryHeight) {
+ historyAnimation.setIntValues(collapsedHeight, expandedHeight)
+ reposition()
+ }
}
- }
- private var collapsedHeight by observable(
- resources.getDimensionPixelSize(R.dimen.account_login_input_height)
- ) { _, oldCollapsedHeight, newCollapsedHeight ->
- if (newCollapsedHeight != oldCollapsedHeight) {
- historyAnimation.setIntValues(newCollapsedHeight, expandedHeight)
- reposition()
+ private var collapsedHeight by
+ observable(resources.getDimensionPixelSize(R.dimen.account_login_input_height)) {
+ _,
+ oldCollapsedHeight,
+ newCollapsedHeight ->
+ if (newCollapsedHeight != oldCollapsedHeight) {
+ historyAnimation.setIntValues(newCollapsedHeight, expandedHeight)
+ reposition()
+ }
}
- }
- private var focused by observable(false) { _, _, hasFocus ->
- updateBorder()
- shouldShowAccountHistory = hasFocus
+ private var focused by
+ observable(false) { _, _, hasFocus ->
+ updateBorder()
+ shouldShowAccountHistory = hasFocus
- if (!hasFocus) {
- hideKeyboard()
+ if (!hasFocus) {
+ hideKeyboard()
+ }
}
- }
- private var shouldShowAccountHistory by observable(false) { _, isShown, show ->
- if (isShown != show) {
- if (show) {
- historyAnimation.start()
- } else {
- historyAnimation.reverse()
+ private var shouldShowAccountHistory by
+ observable(false) { _, isShown, show ->
+ if (isShown != show) {
+ if (show) {
+ historyAnimation.start()
+ } else {
+ historyAnimation.reverse()
+ }
}
}
- }
val hasFocus
get() = focused
- var accountHistory by observable<String?>(null) { _, _, history ->
- if (history != null) {
- historyHeight = historyEntryHeight + dividerHeight
- historyAdapter.accountHistory = history
- } else {
- historyHeight = 0
+ var accountHistory by
+ observable<String?>(null) { _, _, history ->
+ if (history != null) {
+ historyHeight = historyEntryHeight + dividerHeight
+ historyAdapter.accountHistory = history
+ } else {
+ historyHeight = 0
+ }
}
- }
- var state: LoginState by observable(LoginState.Initial) { _, _, newState ->
- input.loginState = newState
+ var state: LoginState by
+ observable(LoginState.Initial) { _, _, newState ->
+ input.loginState = newState
- updateBorder()
- }
+ updateBorder()
+ }
var onLogin: ((String) -> Unit)?
get() = input.onLogin
@@ -131,16 +139,17 @@ class AccountLogin : RelativeLayout {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
border.elevation = elevation + 0.1f
input.apply {
- onFocusChanged.subscribe(this) { hasFocus ->
- focusDebouncer.rawValue = hasFocus
- }
+ onFocusChanged.subscribe(this) { hasFocus -> focusDebouncer.rawValue = hasFocus }
onTextChanged.subscribe(this) { _ ->
if (state == LoginState.Failure) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLoginBorder.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLoginBorder.kt
index 4f2a384c98..c728941264 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLoginBorder.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLoginBorder.kt
@@ -26,23 +26,26 @@ class AccountLoginBorder : RelativeLayout {
val verticalBorder: Drawable
)
- private val unfocusedDrawables = StateDrawables(
- resources.getDrawable(R.drawable.account_login_corner, null),
- resources.getDrawable(R.drawable.account_login_border, null),
- resources.getDrawable(R.drawable.account_login_border, null)
- )
+ private val unfocusedDrawables =
+ StateDrawables(
+ resources.getDrawable(R.drawable.account_login_corner, null),
+ resources.getDrawable(R.drawable.account_login_border, null),
+ resources.getDrawable(R.drawable.account_login_border, null)
+ )
- private val focusedDrawables = StateDrawables(
- resources.getDrawable(R.drawable.account_login_corner_focused, null),
- resources.getDrawable(R.drawable.account_login_border_focused, null),
- resources.getDrawable(R.drawable.account_login_border_focused, null)
- )
+ private val focusedDrawables =
+ StateDrawables(
+ resources.getDrawable(R.drawable.account_login_corner_focused, null),
+ resources.getDrawable(R.drawable.account_login_border_focused, null),
+ resources.getDrawable(R.drawable.account_login_border_focused, null)
+ )
- private val errorDrawables = StateDrawables(
- resources.getDrawable(R.drawable.account_login_corner_error, null),
- resources.getDrawable(R.drawable.account_login_border_error, null),
- resources.getDrawable(R.drawable.account_login_border_error, null)
- )
+ private val errorDrawables =
+ StateDrawables(
+ resources.getDrawable(R.drawable.account_login_corner_error, null),
+ resources.getDrawable(R.drawable.account_login_border_error, null),
+ resources.getDrawable(R.drawable.account_login_border_error, null)
+ )
private val container =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service ->
@@ -76,8 +79,11 @@ class AccountLoginBorder : RelativeLayout {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
constructor(
context: Context,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AppVersionCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AppVersionCell.kt
index 06dad0ac39..cb646a5e26 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AppVersionCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AppVersionCell.kt
@@ -12,46 +12,47 @@ import kotlin.properties.Delegates.observable
import net.mullvad.mullvadvpn.R
class AppVersionCell : UrlCell {
- private val warningIcon = ImageView(context).apply {
- val iconSize = resources.getDimensionPixelSize(R.dimen.app_version_warning_icon_size)
+ private val warningIcon =
+ ImageView(context).apply {
+ val iconSize = resources.getDimensionPixelSize(R.dimen.app_version_warning_icon_size)
- layoutParams = LayoutParams(iconSize, iconSize, 0.0f)
+ layoutParams = LayoutParams(iconSize, iconSize, 0.0f)
- resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
- setPadding(0, 0, padding, 0)
- }
+ resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
+ setPadding(0, 0, padding, 0)
+ }
- setImageResource(R.drawable.icon_alert)
- }
+ setImageResource(R.drawable.icon_alert)
+ }
- private val versionLabel = TextView(context).apply {
- layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
- gravity = Gravity.RIGHT
+ private val versionLabel =
+ TextView(context).apply {
+ layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
+ gravity = Gravity.RIGHT
- resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
- setPadding(padding, 0, padding, 0)
- }
+ resources.getDimensionPixelSize(R.dimen.cell_inner_spacing).let { padding ->
+ setPadding(padding, 0, padding, 0)
+ }
- setTextColor(context.getColor(R.color.white60))
- setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_small))
- setTypeface(null, Typeface.BOLD)
+ setTextColor(context.getColor(R.color.white60))
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_small))
+ setTypeface(null, Typeface.BOLD)
- text = ""
- }
+ text = ""
+ }
- var updateAvailable by observable(false) { _, _, updateAvailable ->
- if (updateAvailable) {
- warningIcon.visibility = VISIBLE
- footer?.visibility = VISIBLE
- } else {
- warningIcon.visibility = GONE
- footer?.visibility = GONE
+ var updateAvailable by
+ observable(false) { _, _, updateAvailable ->
+ if (updateAvailable) {
+ warningIcon.visibility = VISIBLE
+ footer?.visibility = VISIBLE
+ } else {
+ warningIcon.visibility = GONE
+ footer?.visibility = GONE
+ }
}
- }
- var version by observable("") { _, _, version ->
- versionLabel.text = version
- }
+ var version by observable("") { _, _, version -> versionLabel.text = version }
@JvmOverloads
constructor(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/BackButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/BackButton.kt
index d94fa31ec4..2bc4579c11 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/BackButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/BackButton.kt
@@ -25,8 +25,11 @@ class BackButton : LinearLayout {
loadAttributes(attributes)
}
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute) {
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute) {
loadAttributes(attributes)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt
index c2596b04d6..8a014a7ded 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt
@@ -48,11 +48,12 @@ open class Button : FrameLayout {
set(value) {
field = value
- val backgroundResource = when (value) {
- ButtonColor.Blue -> R.drawable.blue_button_background
- ButtonColor.Green -> R.drawable.green_button_background
- ButtonColor.Red -> R.drawable.red_button_background
- }
+ val backgroundResource =
+ when (value) {
+ ButtonColor.Blue -> R.drawable.blue_button_background
+ ButtonColor.Green -> R.drawable.green_button_background
+ ButtonColor.Red -> R.drawable.red_button_background
+ }
button.setBackgroundResource(backgroundResource)
}
@@ -85,8 +86,11 @@ open class Button : FrameLayout {
loadAttributes(attributes)
}
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute) {
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute) {
loadAttributes(attributes)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Cell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Cell.kt
index 54f35fd519..b78c9bc14c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Cell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Cell.kt
@@ -10,53 +10,65 @@ import android.widget.TextView
import net.mullvad.mullvadvpn.R
open class Cell : LinearLayout {
- private val label = TextView(context).apply {
- val rightPadding = resources.getDimensionPixelSize(R.dimen.cell_inner_spacing)
- val verticalPadding = resources.getDimensionPixelSize(R.dimen.cell_label_vertical_padding)
+ private val label =
+ TextView(context).apply {
+ val rightPadding = resources.getDimensionPixelSize(R.dimen.cell_inner_spacing)
+ val verticalPadding =
+ resources.getDimensionPixelSize(R.dimen.cell_label_vertical_padding)
- layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f)
- setPadding(0, verticalPadding, rightPadding, verticalPadding)
+ layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f)
+ setPadding(0, verticalPadding, rightPadding, verticalPadding)
- setTextColor(context.getColor(R.color.white))
- setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_medium_plus))
- setTypeface(null, Typeface.BOLD)
- }
+ setTextColor(context.getColor(R.color.white))
+ setTextSize(
+ TypedValue.COMPLEX_UNIT_PX,
+ resources.getDimension(R.dimen.text_medium_plus)
+ )
+ setTypeface(null, Typeface.BOLD)
+ }
protected var footer: TextView? = null
set(value) {
- field = value?.apply {
- val horizontalPadding =
- resources.getDimensionPixelSize(R.dimen.cell_footer_horizontal_padding)
- val topPadding = resources.getDimensionPixelSize(R.dimen.cell_footer_top_padding)
+ field =
+ value?.apply {
+ val horizontalPadding =
+ resources.getDimensionPixelSize(R.dimen.cell_footer_horizontal_padding)
+ val topPadding =
+ resources.getDimensionPixelSize(R.dimen.cell_footer_top_padding)
- layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
- setPadding(horizontalPadding, topPadding, horizontalPadding, 0)
+ layoutParams =
+ LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
+ setPadding(horizontalPadding, topPadding, horizontalPadding, 0)
- setTextColor(context.getColor(R.color.white60))
- setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.text_small))
- }
+ setTextColor(context.getColor(R.color.white60))
+ setTextSize(
+ TypedValue.COMPLEX_UNIT_PX,
+ resources.getDimension(R.dimen.text_small)
+ )
+ }
}
protected var cell: LinearLayout = this
set(value) {
- field = value.apply {
- val height = resources.getDimensionPixelSize(R.dimen.cell_height)
- val leftPadding = resources.getDimensionPixelSize(R.dimen.cell_left_padding)
- val rightPadding = resources.getDimensionPixelSize(R.dimen.cell_right_padding)
+ field =
+ value.apply {
+ val height = resources.getDimensionPixelSize(R.dimen.cell_height)
+ val leftPadding = resources.getDimensionPixelSize(R.dimen.cell_left_padding)
+ val rightPadding = resources.getDimensionPixelSize(R.dimen.cell_right_padding)
- setFocusable(true)
- isClickable = true
- gravity = Gravity.CENTER
- orientation = HORIZONTAL
- minimumHeight = height
+ setFocusable(true)
+ isClickable = true
+ gravity = Gravity.CENTER
+ orientation = HORIZONTAL
+ minimumHeight = height
- setBackgroundResource(R.drawable.cell_button_background)
- setPadding(leftPadding, 0, rightPadding, 0)
+ setBackgroundResource(R.drawable.cell_button_background)
+ setPadding(leftPadding, 0, rightPadding, 0)
- addView(label)
+ addView(label)
- setOnClickListener { onClickListener?.invoke() }
- }
+ setOnClickListener { onClickListener?.invoke() }
+ }
}
var onClickListener: (() -> Unit)? = null
@@ -101,9 +113,11 @@ open class Cell : LinearLayout {
private fun setUp() {
if (footer != null) {
- cell = LinearLayout(context).apply {
- layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
- }
+ cell =
+ LinearLayout(context).apply {
+ layoutParams =
+ LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
+ }
isClickable = false
orientation = VERTICAL
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CellSwitch.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CellSwitch.kt
index 8e44d72733..8c2312044a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CellSwitch.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CellSwitch.kt
@@ -21,13 +21,14 @@ class CellSwitch : LinearLayout {
OFF
}
- var state by observable(State.OFF) { _, oldState, newState ->
- animateToState()
+ var state by
+ observable(State.OFF) { _, oldState, newState ->
+ animateToState()
- if (oldState != newState) {
- listener?.invoke(newState)
+ if (oldState != newState) {
+ listener?.invoke(newState)
+ }
}
- }
var listener: ((State) -> Unit)? = null
@@ -35,19 +36,18 @@ class CellSwitch : LinearLayout {
private val offColor = context.getColor(R.color.red)
private val knobSize = resources.getDimensionPixelSize(R.dimen.cell_switch_knob_size)
- private val knobImage = ShapeDrawable(OvalShape()).apply {
- paint.apply {
- color = offColor
- style = Style.FILL
- }
+ private val knobImage =
+ ShapeDrawable(OvalShape()).apply {
+ paint.apply {
+ color = offColor
+ style = Style.FILL
+ }
- intrinsicWidth = knobSize
- intrinsicHeight = knobSize
- }
+ intrinsicWidth = knobSize
+ intrinsicHeight = knobSize
+ }
- private val knobView = ImageView(context).apply {
- setImageDrawable(knobImage)
- }
+ private val knobView = ImageView(context).apply { setImageDrawable(knobImage) }
private val knobAnimationDuration = 200L
private val knobMaxTranslation =
@@ -58,98 +58,101 @@ class CellSwitch : LinearLayout {
private var animationIsReversed = false
- private val positionAnimation = ValueAnimator.ofFloat(0f, knobMaxTranslation).apply {
- addUpdateListener { animation ->
- knobView.translationX = animation.animatedValue as Float
+ private val positionAnimation =
+ ValueAnimator.ofFloat(0f, knobMaxTranslation).apply {
+ addUpdateListener { animation ->
+ knobView.translationX = animation.animatedValue as Float
+ }
+
+ duration = knobAnimationDuration
}
- duration = knobAnimationDuration
- }
+ private val colorAnimation =
+ ValueAnimator.ofArgb(offColor, onColor).apply {
+ addUpdateListener { animation ->
+ knobImage.paint.color = animation.animatedValue as Int
+ knobImage.invalidateSelf()
+ }
- private val colorAnimation = ValueAnimator.ofArgb(offColor, onColor).apply {
- addUpdateListener { animation ->
- knobImage.paint.color = animation.animatedValue as Int
- knobImage.invalidateSelf()
+ duration = knobAnimationDuration
}
- duration = knobAnimationDuration
- }
+ private val gestureListener =
+ object : OnGestureListener {
+ private var isScrolling: Boolean = false
+ private var scrollPosition: Float = 0f
- private val gestureListener = object : OnGestureListener {
- private var isScrolling: Boolean = false
- private var scrollPosition: Float = 0f
+ override fun onDown(event: MotionEvent): Boolean {
+ scrollPosition = knobView.translationX
+ return true
+ }
- override fun onDown(event: MotionEvent): Boolean {
- scrollPosition = knobView.translationX
- return true
- }
+ override fun onFling(
+ downEvent: MotionEvent,
+ upEvent: MotionEvent,
+ velocityX: Float,
+ velocityY: Float
+ ): Boolean {
+ if (velocityX > 0f) {
+ state = State.ON
+ } else if (velocityX < 0f) {
+ state = State.OFF
+ }
- override fun onFling(
- downEvent: MotionEvent,
- upEvent: MotionEvent,
- velocityX: Float,
- velocityY: Float
- ): Boolean {
- if (velocityX > 0f) {
- state = State.ON
- } else if (velocityX < 0f) {
- state = State.OFF
+ return true
}
- return true
- }
+ override fun onLongPress(event: MotionEvent) {}
- override fun onLongPress(event: MotionEvent) {}
+ override fun onScroll(
+ downEvent: MotionEvent,
+ moveEvent: MotionEvent,
+ distanceX: Float,
+ distanceY: Float
+ ): Boolean {
+ isScrolling = true
+ scrollPosition -= distanceX
- override fun onScroll(
- downEvent: MotionEvent,
- moveEvent: MotionEvent,
- distanceX: Float,
- distanceY: Float
- ): Boolean {
- isScrolling = true
- scrollPosition -= distanceX
+ var fraction = scrollPosition / knobMaxTranslation
+ val playTime = (fraction * knobAnimationDuration).toLong()
- var fraction = scrollPosition / knobMaxTranslation
- val playTime = (fraction * knobAnimationDuration).toLong()
+ colorAnimation.pause()
+ positionAnimation.pause()
- colorAnimation.pause()
- positionAnimation.pause()
+ colorAnimation.currentPlayTime = playTime
+ positionAnimation.currentPlayTime = playTime
- colorAnimation.currentPlayTime = playTime
- positionAnimation.currentPlayTime = playTime
+ return true
+ }
- return true
- }
+ override fun onShowPress(event: MotionEvent) {}
- override fun onShowPress(event: MotionEvent) {}
+ override fun onSingleTapUp(event: MotionEvent): Boolean {
+ when (state) {
+ State.ON -> state = State.OFF
+ State.OFF -> state = State.ON
+ }
- override fun onSingleTapUp(event: MotionEvent): Boolean {
- when (state) {
- State.ON -> state = State.OFF
- State.OFF -> state = State.ON
+ return true
}
- return true
- }
-
- fun onUp(): Boolean {
- if (!isScrolling) {
- return false
- }
+ fun onUp(): Boolean {
+ if (!isScrolling) {
+ return false
+ }
- if (knobPosition <= 0.5f) {
- state = State.OFF
- } else {
- state = State.ON
- }
+ if (knobPosition <= 0.5f) {
+ state = State.OFF
+ } else {
+ state = State.ON
+ }
- isScrolling = false
- scrollPosition = 0f
+ isScrolling = false
+ scrollPosition = 0f
- return true
+ return true
+ }
}
- }
private val gestureDetector = GestureDetector(context, gestureListener)
@@ -157,8 +160,11 @@ class CellSwitch : LinearLayout {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
setBackground(resources.getDrawable(R.drawable.cell_switch_background, null))
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CopyableInformationView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CopyableInformationView.kt
index 9e5d68d585..dabc1fb218 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CopyableInformationView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CopyableInformationView.kt
@@ -20,8 +20,11 @@ class CopyableInformationView : InformationView {
loadAttributes(attributes)
}
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute) {
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute) {
loadAttributes(attributes)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CustomRecyclerView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CustomRecyclerView.kt
index 374bb3a240..902f6c6acb 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CustomRecyclerView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/CustomRecyclerView.kt
@@ -17,15 +17,19 @@ class CustomRecyclerView : RecyclerView, ListenableScrollableView {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
- itemAnimator = customItemAnimator.apply {
- onMove = { horizontalDelta, verticalDelta ->
- dispatchScrollEvent(horizontalDelta, verticalDelta)
+ itemAnimator =
+ customItemAnimator.apply {
+ onMove = { horizontalDelta, verticalDelta ->
+ dispatchScrollEvent(horizontalDelta, verticalDelta)
+ }
}
- }
}
override fun setLayoutManager(layoutManager: LayoutManager?) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt
index e1688ace21..6f7ca5e8c5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/HeaderBar.kt
@@ -14,7 +14,9 @@ import net.mullvad.mullvadvpn.ui.MainActivity
import net.mullvad.mullvadvpn.ui.StatusBarPainter
import net.mullvad.mullvadvpn.ui.paintStatusBar
-class HeaderBar @JvmOverloads constructor(
+class HeaderBar
+@JvmOverloads
+constructor(
context: Context,
attributes: AttributeSet? = null,
defStyleAttr: Int = 0,
@@ -27,18 +29,20 @@ class HeaderBar @JvmOverloads constructor(
private val securedColor = ContextCompat.getColor(context, R.color.green)
private val unsecuredColor = ContextCompat.getColor(context, R.color.red)
- var tunnelState by observable<TunnelState?>(null) { _, _, state ->
- val backgroundColor = if (state == null) {
- disabledColor
- } else if (state.isSecured()) {
- securedColor
- } else {
- unsecuredColor
- }
+ var tunnelState by
+ observable<TunnelState?>(null) { _, _, state ->
+ val backgroundColor =
+ if (state == null) {
+ disabledColor
+ } else if (state.isSecured()) {
+ securedColor
+ } else {
+ unsecuredColor
+ }
- container.setBackgroundColor(backgroundColor)
- paintStatusBar(backgroundColor)
- }
+ container.setBackgroundColor(backgroundColor)
+ paintStatusBar(backgroundColor)
+ }
init {
gravity = Gravity.CENTER_VERTICAL
@@ -46,9 +50,7 @@ class HeaderBar @JvmOverloads constructor(
settingsButton.apply {
isEnabled = true
- setOnClickListener {
- (context as? MainActivity)?.openSettings()
- }
+ setOnClickListener { (context as? MainActivity)?.openSettings() }
}
tunnelState = null
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/InformationView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/InformationView.kt
index 42f78b3b4a..b7547a8761 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/InformationView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/InformationView.kt
@@ -49,18 +49,18 @@ open class InformationView : LinearLayout {
var information by observable<String?>(null) { _, _, _ -> updateStatus() }
var errorColor by observable(context.getColor(R.color.red)) { _, _, _ -> updateStatus() }
- var informationColor by observable(context.getColor(R.color.white)) { _, _, _ ->
- updateStatus()
- }
+ var informationColor by
+ observable(context.getColor(R.color.white)) { _, _, _ -> updateStatus() }
var maxLength by observable(0) { _, _, _ -> updateStatus() }
var whenMissing by observable(WhenMissing.Nothing) { _, _, _ -> updateStatus() }
var shouldEnable by observable(false) { _, _, _ -> updateEnabled() }
- var onClick by observable<(() -> Unit)?>(null) { _, _, callback ->
- container.setFocusable(callback != null)
- }
+ var onClick by
+ observable<(() -> Unit)?>(null) { _, _, callback ->
+ container.setFocusable(callback != null)
+ }
sealed class Masking {
object None : Masking()
@@ -68,40 +68,40 @@ open class InformationView : LinearLayout {
data class Show(val transformationMethod: TransformationMethod) : Masking()
}
- var informationState by observable<Masking>(Masking.None) { _, _, newState ->
- when (newState) {
- is Masking.Hide -> {
- informationDisplay.transformationMethod = newState.transformationMethod
+ var informationState by
+ observable<Masking>(Masking.None) { _, _, newState ->
+ when (newState) {
+ is Masking.Hide -> {
+ informationDisplay.transformationMethod = newState.transformationMethod
- toggleMaskingButton.apply {
- visibility = VISIBLE
- contentDescription = context.getString(R.string.show_account_number)
- background = AppCompatResources.getDrawable(context, R.drawable.icon_show)
+ toggleMaskingButton.apply {
+ visibility = VISIBLE
+ contentDescription = context.getString(R.string.show_account_number)
+ background = AppCompatResources.getDrawable(context, R.drawable.icon_show)
+ }
}
- }
+ is Masking.Show -> {
+ informationDisplay.transformationMethod = newState.transformationMethod
- is Masking.Show -> {
- informationDisplay.transformationMethod = newState.transformationMethod
-
- toggleMaskingButton.apply {
- visibility = VISIBLE
- contentDescription = context.getString(R.string.hide_account_number)
- background = AppCompatResources.getDrawable(context, R.drawable.icon_hide)
+ toggleMaskingButton.apply {
+ visibility = VISIBLE
+ contentDescription = context.getString(R.string.hide_account_number)
+ background = AppCompatResources.getDrawable(context, R.drawable.icon_hide)
+ }
+ }
+ is Masking.None -> {
+ informationDisplay.transformationMethod = null
+ toggleMaskingButton.visibility = INVISIBLE
}
}
- is Masking.None -> {
- informationDisplay.transformationMethod = null
- toggleMaskingButton.visibility = INVISIBLE
- }
+ updateStatus()
}
- updateStatus()
- }
-
- var onToggleMaskingClicked by observable<(() -> Unit)?>(null) { _, _, callback ->
- toggleMaskingButton.setOnClickListener { callback?.invoke() }
- }
+ var onToggleMaskingClicked by
+ observable<(() -> Unit)?>(null) { _, _, callback ->
+ toggleMaskingButton.setOnClickListener { callback?.invoke() }
+ }
constructor(context: Context) : super(context) {}
@@ -109,8 +109,11 @@ open class InformationView : LinearLayout {
loadAttributes(attributes)
}
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute) {
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute) {
loadAttributes(attributes)
}
@@ -146,14 +149,11 @@ open class InformationView : LinearLayout {
errorColor = getInteger(R.styleable.InformationView_errorColor, errorColor)
maxLength = getInteger(R.styleable.InformationView_maxLength, 0)
- informationColor = getInteger(
- R.styleable.InformationView_informationColor,
- informationColor
- )
+ informationColor =
+ getInteger(R.styleable.InformationView_informationColor, informationColor)
- whenMissing = WhenMissing.fromCode(
- getInteger(R.styleable.InformationView_whenMissing, 0)
- )
+ whenMissing =
+ WhenMissing.fromCode(getInteger(R.styleable.InformationView_whenMissing, 0))
} finally {
recycle()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ListenableScrollView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ListenableScrollView.kt
index 6f2ae01b8b..683341686f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ListenableScrollView.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ListenableScrollView.kt
@@ -17,8 +17,11 @@ class ListenableScrollView : ScrollView, ListenableScrollableView {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
override fun onScrollChanged(left: Int, top: Int, oldLeft: Int, oldTop: Int) {
super.onScrollChanged(left, top, oldLeft, oldTop)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NavigateCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NavigateCell.kt
index a334618e3c..ee1901774a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NavigateCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NavigateCell.kt
@@ -9,15 +9,16 @@ import kotlin.reflect.KClass
import net.mullvad.mullvadvpn.R
open class NavigateCell : Cell {
- private val chevron = ImageView(context).apply {
- val width = resources.getDimensionPixelSize(R.dimen.chevron_width)
- val height = resources.getDimensionPixelSize(R.dimen.chevron_height)
+ private val chevron =
+ ImageView(context).apply {
+ val width = resources.getDimensionPixelSize(R.dimen.chevron_width)
+ val height = resources.getDimensionPixelSize(R.dimen.chevron_height)
- layoutParams = LayoutParams(width, height, 0.0f)
- alpha = 0.6f
+ layoutParams = LayoutParams(width, height, 0.0f)
+ alpha = 0.6f
- setImageResource(R.drawable.icon_chevron)
- }
+ setImageResource(R.drawable.icon_chevron)
+ }
var targetFragment: KClass<out Fragment>? = null
@@ -25,8 +26,11 @@ open class NavigateCell : Cell {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
cell.addView(chevron)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt
index db1c8cf43c..86073f2079 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt
@@ -22,37 +22,39 @@ import net.mullvad.mullvadvpn.util.JobTracker
class NotificationBanner : FrameLayout {
private val jobTracker = JobTracker()
- private val animationListener = object : AnimatorListener {
- override fun onAnimationCancel(animation: Animator) {}
- override fun onAnimationRepeat(animation: Animator) {}
+ private val animationListener =
+ object : AnimatorListener {
+ override fun onAnimationCancel(animation: Animator) {}
+ override fun onAnimationRepeat(animation: Animator) {}
- override fun onAnimationStart(animation: Animator) {
- visibility = View.VISIBLE
- }
+ override fun onAnimationStart(animation: Animator) {
+ visibility = View.VISIBLE
+ }
- override fun onAnimationEnd(animation: Animator) {
- synchronized(this@NotificationBanner) {
- if (reversedAnimation) {
- // Banner is now hidden
- val notification = notifications.current
+ override fun onAnimationEnd(animation: Animator) {
+ synchronized(this@NotificationBanner) {
+ if (reversedAnimation) {
+ // Banner is now hidden
+ val notification = notifications.current
- visibility = View.INVISIBLE
+ visibility = View.INVISIBLE
- if (notification != null) {
- // Notification changed, restart animation
- update(notification)
- reversedAnimation = false
- animation.start()
+ if (notification != null) {
+ // Notification changed, restart animation
+ update(notification)
+ reversedAnimation = false
+ animation.start()
+ }
}
}
}
}
- }
- private val animation = ObjectAnimator.ofFloat(this, "translationY", 0.0f).apply {
- addListener(animationListener)
- setDuration(350)
- }
+ private val animation =
+ ObjectAnimator.ofFloat(this, "translationY", 0.0f).apply {
+ addListener(animationListener)
+ setDuration(350)
+ }
private val container =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service ->
@@ -72,23 +74,22 @@ class NotificationBanner : FrameLayout {
private var reversedAnimation = false
val notifications = InAppNotificationController { _ ->
- synchronized(this@NotificationBanner) {
- animateChange()
- }
+ synchronized(this@NotificationBanner) { animateChange() }
}
constructor(context: Context) : super(context)
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
setBackgroundResource(R.color.darkBlue)
- setOnClickListener {
- jobTracker.newUiJob("click") { onClick() }
- }
+ setOnClickListener { jobTracker.newUiJob("click") { onClick() } }
visibility = View.INVISIBLE
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt
index c823a3f3b9..885fceef2a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt
@@ -11,8 +11,11 @@ class RedeemVoucherButton : Button {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
fun prepare(
fragmentManager: FragmentManager?,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SitePaymentButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SitePaymentButton.kt
index 35d0c2326f..9fbe71337e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SitePaymentButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SitePaymentButton.kt
@@ -10,14 +10,18 @@ class SitePaymentButton : UrlButton {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
- var newAccount by observable(false) { _, _, isNewAccount ->
- if (isNewAccount) {
- label = context.getString(R.string.buy_credit)
- } else {
- label = context.getString(R.string.buy_more_credit)
+ var newAccount by
+ observable(false) { _, _, isNewAccount ->
+ if (isNewAccount) {
+ label = context.getString(R.string.buy_credit)
+ } else {
+ label = context.getString(R.string.buy_more_credit)
+ }
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt
index a6a8e7dbfb..02ec153f0a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/SwitchLocationButton.kt
@@ -20,9 +20,10 @@ class SwitchLocationButton : FrameLayout {
inflater.inflate(R.layout.switch_location_button, this)
}
- private val buttonWithLabel = container.findViewById<View>(R.id.button_with_label).apply {
- setOnClickListener { onClick?.invoke() }
- }
+ private val buttonWithLabel =
+ container.findViewById<View>(R.id.button_with_label).apply {
+ setOnClickListener { onClick?.invoke() }
+ }
private val buttonWithLocation =
container.findViewById<TextView>(R.id.button_with_location).apply {
@@ -31,32 +32,37 @@ class SwitchLocationButton : FrameLayout {
var onClick: (() -> Unit)? = null
- var location by observable<RelayItem?>(null) { _, _, location ->
- buttonWithLocation.text = location?.locationName ?: ""
- }
+ var location by
+ observable<RelayItem?>(null) { _, _, location ->
+ buttonWithLocation.text = location?.locationName ?: ""
+ }
- var tunnelState by observable<TunnelState>(TunnelState.Disconnected) { _, _, state ->
- when (state) {
- is TunnelState.Disconnected -> showLocation()
- is TunnelState.Disconnecting -> {
- when (state.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> showLocation()
- ActionAfterDisconnect.Block -> showLocation()
- ActionAfterDisconnect.Reconnect -> showLabel()
+ var tunnelState by
+ observable<TunnelState>(TunnelState.Disconnected) { _, _, state ->
+ when (state) {
+ is TunnelState.Disconnected -> showLocation()
+ is TunnelState.Disconnecting -> {
+ when (state.actionAfterDisconnect) {
+ ActionAfterDisconnect.Nothing -> showLocation()
+ ActionAfterDisconnect.Block -> showLocation()
+ ActionAfterDisconnect.Reconnect -> showLabel()
+ }
}
+ is TunnelState.Connecting -> showLabel()
+ is TunnelState.Connected -> showLabel()
+ is TunnelState.Error -> showLocation()
}
- is TunnelState.Connecting -> showLabel()
- is TunnelState.Connected -> showLabel()
- is TunnelState.Error -> showLocation()
}
- }
constructor(context: Context) : super(context)
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
private fun showLabel() {
updateButton(buttonWithLabel, true)
@@ -72,11 +78,12 @@ class SwitchLocationButton : FrameLayout {
button.apply {
setEnabled(show)
- visibility = if (show) {
- View.VISIBLE
- } else {
- View.INVISIBLE
- }
+ visibility =
+ if (show) {
+ View.VISIBLE
+ } else {
+ View.INVISIBLE
+ }
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ToggleCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ToggleCell.kt
index f9ae44fd56..f47347539f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ToggleCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ToggleCell.kt
@@ -4,9 +4,10 @@ import android.content.Context
import android.util.AttributeSet
class ToggleCell : Cell {
- private val toggle = CellSwitch(context).apply {
- layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
- }
+ private val toggle =
+ CellSwitch(context).apply {
+ layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
+ }
var state
get() = toggle.state
@@ -24,8 +25,11 @@ class ToggleCell : Cell {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
onClickListener = { toggle() }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlButton.kt
index c1b700e433..db3da99270 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlButton.kt
@@ -9,8 +9,11 @@ open class UrlButton : Button {
constructor(context: Context, attributes: AttributeSet) : super(context, attributes)
- constructor(context: Context, attributes: AttributeSet, defaultStyleAttribute: Int) :
- super(context, attributes, defaultStyleAttribute)
+ constructor(
+ context: Context,
+ attributes: AttributeSet,
+ defaultStyleAttribute: Int
+ ) : super(context, attributes, defaultStyleAttribute)
init {
super.setEnabled(false)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlCell.kt
index 50727f74a6..1d263901b5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/UrlCell.kt
@@ -8,12 +8,13 @@ import android.widget.ImageView
import net.mullvad.mullvadvpn.R
open class UrlCell : Cell {
- private val externalLinkIcon = ImageView(context).apply {
- layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
- alpha = 0.6f
+ private val externalLinkIcon =
+ ImageView(context).apply {
+ layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.0f)
+ alpha = 0.6f
- setImageResource(R.drawable.icon_extlink)
- }
+ setImageResource(R.drawable.icon_extlink)
+ }
var url: Uri? = null
@@ -34,9 +35,7 @@ open class UrlCell : Cell {
private fun loadAttributes(attributes: AttributeSet?) {
context.theme.obtainStyledAttributes(attributes, R.styleable.Url, 0, 0).apply {
try {
- getString(R.styleable.Url_url)?.let { urlString ->
- url = Uri.parse(urlString)
- }
+ getString(R.styleable.Url_url)?.let { urlString -> url = Uri.parse(urlString) }
} finally {
recycle()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/AdapterWithHeader.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/AdapterWithHeader.kt
index a239a4d9c8..89b0057f63 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/AdapterWithHeader.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/AdapterWithHeader.kt
@@ -11,59 +11,63 @@ class AdapterWithHeader<H : ViewHolder>(
val adapter: RecyclerView.Adapter<H>,
val headerLayoutId: Int
) : RecyclerView.Adapter<HeaderOrHolder<H>>() {
- private val observer = object : RecyclerView.AdapterDataObserver() {
- override fun onChanged() {
- notifyDataSetChanged()
- }
+ private val observer =
+ object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ notifyDataSetChanged()
+ }
- override fun onItemRangeChanged(start: Int, count: Int) {
- notifyItemRangeChanged(start + 1, count)
- }
+ override fun onItemRangeChanged(start: Int, count: Int) {
+ notifyItemRangeChanged(start + 1, count)
+ }
- override fun onItemRangeChanged(start: Int, count: Int, payload: Any?) {
- notifyItemRangeChanged(start + 1, count, payload)
- }
+ override fun onItemRangeChanged(start: Int, count: Int, payload: Any?) {
+ notifyItemRangeChanged(start + 1, count, payload)
+ }
- override fun onItemRangeInserted(start: Int, count: Int) {
- notifyItemRangeInserted(start + 1, count)
- }
+ override fun onItemRangeInserted(start: Int, count: Int) {
+ notifyItemRangeInserted(start + 1, count)
+ }
+
+ override fun onItemRangeMoved(from: Int, to: Int, count: Int) {
+ if (from == to) {
+ notifyItemRangeChanged(from + 1, count)
+ } else {
+ val sourceStart = from + 1
+ val sourceEnd = sourceStart + count
+ val destinationStart = to + 1
+ val destinationEnd = destinationStart + count
- override fun onItemRangeMoved(from: Int, to: Int, count: Int) {
- if (from == to) {
- notifyItemRangeChanged(from + 1, count)
- } else {
- val sourceStart = from + 1
- val sourceEnd = sourceStart + count
- val destinationStart = to + 1
- val destinationEnd = destinationStart + count
+ val ascendingIndices =
+ (sourceStart..sourceEnd).zip(destinationStart..destinationEnd)
- val ascendingIndices =
- (sourceStart..sourceEnd).zip(destinationStart..destinationEnd)
+ val indices =
+ if (from < to) {
+ ascendingIndices.asReversed()
+ } else {
+ ascendingIndices
+ }
- val indices = if (from < to) {
- ascendingIndices.asReversed()
- } else {
- ascendingIndices
+ for ((source, destination) in indices) {
+ notifyItemMoved(source, destination)
+ }
}
+ }
- for ((source, destination) in indices) {
- notifyItemMoved(source, destination)
- }
+ override fun onItemRangeRemoved(start: Int, count: Int) {
+ notifyItemRangeRemoved(start + 1, count)
}
}
- override fun onItemRangeRemoved(start: Int, count: Int) {
- notifyItemRangeRemoved(start + 1, count)
+ private var headerView: View? by
+ observable<View?>(null) { _, _, newView ->
+ newView?.let { view -> onHeaderAvailable?.invoke(view) }
}
- }
- private var headerView: View? by observable<View?>(null) { _, _, newView ->
- newView?.let { view -> onHeaderAvailable?.invoke(view) }
- }
-
- var onHeaderAvailable by observable<((View) -> Unit)?>(null) { _, _, listener ->
- headerView?.let { header -> listener?.invoke(header) }
- }
+ var onHeaderAvailable by
+ observable<((View) -> Unit)?>(null) { _, _, listener ->
+ headerView?.let { header -> listener?.invoke(header) }
+ }
init {
adapter.registerAdapterDataObserver(observer)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/CacheExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/CacheExtensions.kt
index 62172231f9..ae79c1364f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/CacheExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/CacheExtensions.kt
@@ -16,7 +16,5 @@ fun AppVersionInfoCache.appVersionCallbackFlow() = callbackFlow {
)
)
}
- awaitClose {
- onUpdate = null
- }
+ awaitClose { onUpdate = null }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ChangeMonitor.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ChangeMonitor.kt
index 398177db99..c8361a36c4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ChangeMonitor.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ChangeMonitor.kt
@@ -6,11 +6,12 @@ class ChangeMonitor {
var changed = false
private set
- fun <T> monitor(initialValue: T) = observable(initialValue) { _, oldValue, newValue ->
- if (oldValue != newValue) {
- changed = true
+ fun <T> monitor(initialValue: T) =
+ observable(initialValue) { _, oldValue, newValue ->
+ if (oldValue != newValue) {
+ changed = true
+ }
}
- }
fun reset() {
changed = false
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt
index 7afb4c508f..677d981417 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt
@@ -23,17 +23,18 @@ class Debouncer<T>(initialValue: T, val intervalInMs: Long = 0) {
var debouncedValue = initialValue
private set
- var rawValue by observable(initialValue) { _, oldValue, newValue ->
- if (newValue != oldValue) {
- jobTracker.cancelJob("notifyNewValue")
+ var rawValue by
+ observable(initialValue) { _, oldValue, newValue ->
+ if (newValue != oldValue) {
+ jobTracker.cancelJob("notifyNewValue")
- if (newValue != debouncedValue) {
- jobTracker.newUiJob("notifyNewValue") {
- delay(intervalInMs)
- listener?.invoke(newValue)
- debouncedValue = newValue
+ if (newValue != debouncedValue) {
+ jobTracker.newUiJob("notifyNewValue") {
+ delay(intervalInMs)
+ listener?.invoke(newValue)
+ debouncedValue = newValue
+ }
}
}
}
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DeviceStateExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DeviceStateExtensions.kt
index d41a628bec..13b8f84599 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DeviceStateExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DeviceStateExtensions.kt
@@ -6,16 +6,12 @@ import net.mullvad.mullvadvpn.model.DeviceState
const val UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS = 2000L
private const val ZERO_DEBOUNCE_DELAY_MILLISECONDS = 0L
-fun DeviceState.addDebounceForUnknownState(
- delay: Long
-): Long {
+fun DeviceState.addDebounceForUnknownState(delay: Long): Long {
return addDebounceForStates(delay, DeviceState.Unknown::class)
}
-fun <T> DeviceState.addDebounceForStates(
- delay: Long,
- vararg states: KClass<T>
-): Long where T : DeviceState {
+fun <T> DeviceState.addDebounceForStates(delay: Long, vararg states: KClass<T>): Long where
+T : DeviceState {
val result = states.any { this::class == it }
return if (result) {
delay
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DispatchingFlow.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DispatchingFlow.kt
index af66a092ba..fc46783ab0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DispatchingFlow.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/DispatchingFlow.kt
@@ -14,10 +14,7 @@ import kotlinx.coroutines.flow.consumeAsFlow
class DispatchingFlow<T : Any>(private val upstream: Flow<T>) : Flow<T> {
private val subscribers = ConcurrentHashMap<KClass<out T>, SendChannel<T>>()
- fun <V : T> subscribe(
- variant: KClass<V>,
- capacity: Int = Channel.CONFLATED
- ): Flow<V> {
+ fun <V : T> subscribe(variant: KClass<V>, capacity: Int = Channel.CONFLATED): Flow<V> {
val channel = Channel<V>(capacity)
// This is safe because `collect` will only send to this channel if the instance class is V
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt
index 2e9c96a169..ec4091b55d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt
@@ -19,14 +19,9 @@ fun ErrorState.getErrorNotificationResources(context: Context): ErrorNotificatio
cause is ErrorStateCause.VpnPermissionDenied -> {
resolveAlwaysOnVpnErrorNotificationMessage(context.getAlwaysOnVpnAppName())
}
- isBlocking -> ErrorNotificationMessage(
- R.string.blocking_all_connections,
- cause.errorMessageId()
- )
- else -> ErrorNotificationMessage(
- R.string.critical_error,
- R.string.failed_to_block_internet
- )
+ isBlocking ->
+ ErrorNotificationMessage(R.string.blocking_all_connections, cause.errorMessageId())
+ else -> ErrorNotificationMessage(R.string.critical_error, R.string.failed_to_block_internet)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt
index 4d715a9aec..d7cc4631d0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt
@@ -23,34 +23,36 @@ fun <T> SendChannel<T>.safeOffer(element: T): Boolean {
return runCatching { trySend(element).isSuccess }.getOrDefault(false)
}
-fun Animation.transitionFinished(): Flow<Unit> = callbackFlow<Unit> {
- val transitionAnimationListener = object : Animation.AnimationListener {
- override fun onAnimationStart(animation: Animation?) {}
- override fun onAnimationEnd(animation: Animation?) {
- safeOffer(Unit)
- }
+fun Animation.transitionFinished(): Flow<Unit> =
+ callbackFlow<Unit> {
+ val transitionAnimationListener =
+ object : Animation.AnimationListener {
+ override fun onAnimationStart(animation: Animation?) {}
+ override fun onAnimationEnd(animation: Animation?) {
+ safeOffer(Unit)
+ }
- override fun onAnimationRepeat(animation: Animation?) {}
- }
- setAnimationListener(transitionAnimationListener)
- awaitClose {
- Dispatchers.Main.dispatch(EmptyCoroutineContext) {
- setAnimationListener(null)
+ override fun onAnimationRepeat(animation: Animation?) {}
+ }
+ setAnimationListener(transitionAnimationListener)
+ awaitClose {
+ Dispatchers.Main.dispatch(EmptyCoroutineContext) { setAnimationListener(null) }
+ }
}
- }
-}.take(1)
+ .take(1)
fun Context.bindServiceFlow(intent: Intent, flags: Int = 0): Flow<ServiceResult> = callbackFlow {
- val connectionCallback = object : ServiceConnection {
- override fun onServiceConnected(className: ComponentName, binder: IBinder) {
- safeOffer(ServiceResult(binder))
- }
+ val connectionCallback =
+ object : ServiceConnection {
+ override fun onServiceConnected(className: ComponentName, binder: IBinder) {
+ safeOffer(ServiceResult(binder))
+ }
- override fun onServiceDisconnected(className: ComponentName) {
- safeOffer(ServiceResult.NOT_CONNECTED)
- bindService(intent, this, flags)
+ override fun onServiceDisconnected(className: ComponentName) {
+ safeOffer(ServiceResult.NOT_CONNECTED)
+ bindService(intent, this, flags)
+ }
}
- }
bindService(intent, connectionCallback, flags)
@@ -80,8 +82,9 @@ fun <R> Flow<ServiceConnectionState>.flatMapReadyConnectionOrDefault(
}
}
-fun <T> callbackFlowFromNotifier(notifier: EventNotifier<T>) = callbackFlow<T> {
- val handler: (T) -> Unit = { value -> trySend(value) }
- notifier.subscribe(this, handler)
- awaitClose { notifier.unsubscribe(this) }
-}
+fun <T> callbackFlowFromNotifier(notifier: EventNotifier<T>) =
+ callbackFlow<T> {
+ val handler: (T) -> Unit = { value -> trySend(value) }
+ notifier.subscribe(this, handler)
+ awaitClose { notifier.unsubscribe(this) }
+ }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt
index 1fe3a60fcd..dc8ee67cf8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt
@@ -67,19 +67,18 @@ class Intermittent<T> {
synchronized(this@Intermittent) {
val previousUpdate = updateJob
- updateJob = GlobalScope.launch(Dispatchers.Default) {
- previousUpdate?.join()
- update(newValue)
- }
+ updateJob =
+ GlobalScope.launch(Dispatchers.Default) {
+ previousUpdate?.join()
+ update(newValue)
+ }
}
}
// Helper method that provides a simple way to change the wrapped value.
// The method returns a property delegate that will spawn a coroutine to update the wrapped
// value every time the property is written to.
- fun source() = observable<T?>(null) { _, _, newValue ->
- spawnUpdate(newValue)
- }
+ fun source() = observable<T?>(null) { _, _, newValue -> spawnUpdate(newValue) }
fun onDestroy() {
notifier.unsubscribeAll()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt
index 0b950d9a55..fa027af4b1 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt
@@ -26,9 +26,7 @@ class JobTracker {
GlobalScope.launch(Dispatchers.Default) {
job.join()
- synchronized(jobs) {
- jobs.remove(jobId)
- }
+ synchronized(jobs) { jobs.remove(jobId) }
}
)
@@ -65,11 +63,7 @@ class JobTracker {
}
fun cancelJob(name: String) {
- synchronized(namedJobs) {
- namedJobs.remove(name)?.let { oldJobId ->
- cancelJob(oldJobId)
- }
- }
+ synchronized(namedJobs) { namedJobs.remove(name)?.let { oldJobId -> cancelJob(oldJobId) } }
}
fun cancelJob(jobId: Long) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SdkUtils.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SdkUtils.kt
index 67491ad6fe..cb631d8af6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SdkUtils.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SdkUtils.kt
@@ -40,7 +40,6 @@ object SdkUtils {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getInstalledPackages(PackageManager.PackageInfoFlags.of(flags.toLong()))
} else {
- @Suppress("DEPRECATION")
- getInstalledPackages(flags)
+ @Suppress("DEPRECATION") getInstalledPackages(flags)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedInputFormatter.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedInputFormatter.kt
index 9154f102ef..4dd6b7bc1b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedInputFormatter.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedInputFormatter.kt
@@ -72,19 +72,16 @@ class SegmentedInputFormatter(val input: EditText, var separator: Char) : TextWa
}
private fun isValidInput(string: String): Boolean {
- return string
- .asSequence()
- .withIndex()
- .all { item ->
- val index = item.index
- val character = item.value
+ return string.asSequence().withIndex().all { item ->
+ val index = item.index
+ val character = item.value
- if ((index + 1) % separatorSkipCount == 0) {
- character == separator
- } else {
- isValidInputCharacter(character)
- }
+ if ((index + 1) % separatorSkipCount == 0) {
+ character == separator
+ } else {
+ isValidInputCharacter(character)
}
+ }
}
private fun formatInput(input: Editable) {
@@ -97,8 +94,9 @@ class SegmentedInputFormatter(val input: EditText, var separator: Char) : TextWa
val segmentEnd = index + segmentSize - 1
val separatorPosition = segmentEnd + 1
- changed = formatSegment(input, segmentStart..segmentEnd) ||
- formatSeparator(input, separatorPosition)
+ changed =
+ formatSegment(input, segmentStart..segmentEnd) ||
+ formatSeparator(input, separatorPosition)
index = separatorPosition + 1
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedTextFormatter.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedTextFormatter.kt
index 8e08f3c742..4ba6fe97e0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedTextFormatter.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SegmentedTextFormatter.kt
@@ -4,10 +4,11 @@ class SegmentedTextFormatter(var separator: Char) {
var isValidInputCharacter: (Char) -> Boolean = { _ -> true }
var segmentSize = 4
- fun format(string: String) = string
- .asSequence()
- .filter(isValidInputCharacter)
- .chunked(segmentSize)
- .map { segmentCharacters -> segmentCharacters.joinToString("") }
- .joinToString("$separator")
+ fun format(string: String) =
+ string
+ .asSequence()
+ .filter(isValidInputCharacter)
+ .chunked(segmentSize)
+ .map { segmentCharacters -> segmentCharacters.joinToString("") }
+ .joinToString("$separator")
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt
index 61050bc894..4035f5b182 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt
@@ -13,9 +13,7 @@ class SmartDeferred<T>(private val deferred: Deferred<T>) {
fun awaitThen(action: T.() -> Unit): Long? {
if (active) {
return jobTracker.newJob(
- GlobalScope.launch(Dispatchers.Default) {
- deferred.await().action()
- }
+ GlobalScope.launch(Dispatchers.Default) { deferred.await().action() }
)
} else {
return null
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt
index f2daffccaf..c0139d9d2c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt
@@ -7,9 +7,7 @@ private const val EXPIRY_FORMAT = "YYYY-MM-dd HH:mm:ss z"
fun String.capitalizeFirstCharOfEachWord(): String {
return split(" ")
- .joinToString(" ") { word ->
- word.replaceFirstChar { firstChar -> firstChar.uppercase() }
- }
+ .joinToString(" ") { word -> word.replaceFirstChar { firstChar -> firstChar.uppercase() } }
.trimEnd()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/TimeAgoFormatter.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/TimeAgoFormatter.kt
index 1136a21814..3ae5f499cd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/TimeAgoFormatter.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/TimeAgoFormatter.kt
@@ -7,9 +7,7 @@ import org.joda.time.Duration
import org.joda.time.PeriodType
class TimeAgoFormatter(val resources: Resources) {
- private val periodType = PeriodType.standard()
- .withMillisRemoved()
- .withSecondsRemoved()
+ private val periodType = PeriodType.standard().withMillisRemoved().withSecondsRemoved()
fun format(instant: DateTime): String {
val elapsedTime = Duration(instant, DateTime.now())
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt
index 7d456fb680..c29573e819 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt
@@ -29,30 +29,30 @@ class AdvancedSettingsViewModel(
private val dialogState =
MutableStateFlow<AdvancedSettingsDialogState>(AdvancedSettingsDialogState.NoDialog)
- private val vmState = combine(
- repository.settingsUpdates,
- dialogState
- ) { settings, interaction ->
- AdvancedSettingsViewModelState(
- mtuValue = settings?.mtuString() ?: "",
- isCustomDnsEnabled = settings?.isCustomDnsEnabled() ?: false,
- customDnsList = settings?.addresses()?.asStringAddressList() ?: listOf(),
- isAllowLanEnabled = settings?.allowLan ?: false,
- dialogState = interaction
- )
- }.stateIn(
- viewModelScope,
- SharingStarted.WhileSubscribed(),
- AdvancedSettingsViewModelState.default()
- )
+ private val vmState =
+ combine(repository.settingsUpdates, dialogState) { settings, interaction ->
+ AdvancedSettingsViewModelState(
+ mtuValue = settings?.mtuString() ?: "",
+ isCustomDnsEnabled = settings?.isCustomDnsEnabled() ?: false,
+ customDnsList = settings?.addresses()?.asStringAddressList() ?: listOf(),
+ isAllowLanEnabled = settings?.allowLan ?: false,
+ dialogState = interaction
+ )
+ }
+ .stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(),
+ AdvancedSettingsViewModelState.default()
+ )
- val uiState = vmState
- .map(AdvancedSettingsViewModelState::toUiState)
- .stateIn(
- viewModelScope,
- SharingStarted.WhileSubscribed(),
- AdvancedSettingsUiState.DefaultUiState()
- )
+ val uiState =
+ vmState
+ .map(AdvancedSettingsViewModelState::toUiState)
+ .stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(),
+ AdvancedSettingsUiState.DefaultUiState()
+ )
fun onMtuCellClick() {
dialogState.update { AdvancedSettingsDialogState.MtuDialog(vmState.value.mtuValue) }
@@ -62,34 +62,36 @@ class AdvancedSettingsViewModel(
dialogState.update { AdvancedSettingsDialogState.MtuDialog(value) }
}
- fun onSaveMtuClick() = viewModelScope.launch(dispatcher) {
- val dialog = dialogState.value as? AdvancedSettingsDialogState.MtuDialog
- dialog?.mtuEditValue?.toIntOrNull()?.takeIf { it.isValidMtu() }?.let { mtu ->
- repository.setWireguardMtu(mtu)
+ fun onSaveMtuClick() =
+ viewModelScope.launch(dispatcher) {
+ val dialog = dialogState.value as? AdvancedSettingsDialogState.MtuDialog
+ dialog
+ ?.mtuEditValue
+ ?.toIntOrNull()
+ ?.takeIf { it.isValidMtu() }
+ ?.let { mtu -> repository.setWireguardMtu(mtu) }
+ hideDialog()
}
- hideDialog()
- }
- fun onRestoreMtuClick() = viewModelScope.launch(dispatcher) {
- repository.setWireguardMtu(null)
- hideDialog()
- }
+ fun onRestoreMtuClick() =
+ viewModelScope.launch(dispatcher) {
+ repository.setWireguardMtu(null)
+ hideDialog()
+ }
fun onCancelDialogClick() {
hideDialog()
}
fun onDnsClick(index: Int? = null) {
- val stagedDns = if (index == null) {
- StagedDns.NewDns(CustomDnsItem.default())
- } else {
- vmState.value.customDnsList.getOrNull(index)?.let { listItem ->
- StagedDns.EditDns(
- item = listItem,
- index = index
- )
+ val stagedDns =
+ if (index == null) {
+ StagedDns.NewDns(CustomDnsItem.default())
+ } else {
+ vmState.value.customDnsList.getOrNull(index)?.let { listItem ->
+ StagedDns.EditDns(item = listItem, index = index)
+ }
}
- }
if (stagedDns != null) {
dialogState.update { AdvancedSettingsDialogState.DnsDialog(stagedDns) }
@@ -100,100 +102,101 @@ class AdvancedSettingsViewModel(
dialogState.update { state ->
val dialog = state as? AdvancedSettingsDialogState.DnsDialog ?: return
- val error = when {
- ipAddress.isBlank() || ipAddress.isValidIp().not() -> {
- StagedDns.ValidationResult.InvalidAddress
- }
- ipAddress.isDuplicateDns((state.stagedDns as? StagedDns.EditDns)?.index) -> {
- StagedDns.ValidationResult.DuplicateAddress
+ val error =
+ when {
+ ipAddress.isBlank() || ipAddress.isValidIp().not() -> {
+ StagedDns.ValidationResult.InvalidAddress
+ }
+ ipAddress.isDuplicateDns((state.stagedDns as? StagedDns.EditDns)?.index) -> {
+ StagedDns.ValidationResult.DuplicateAddress
+ }
+ else -> StagedDns.ValidationResult.Success
}
- else -> StagedDns.ValidationResult.Success
- }
return@update AdvancedSettingsDialogState.DnsDialog(
- stagedDns = if (dialog.stagedDns is StagedDns.EditDns) {
- StagedDns.EditDns(
- item = CustomDnsItem(
- address = ipAddress,
- isLocal = ipAddress.isLocalAddress()
- ),
- validationResult = error,
- index = dialog.stagedDns.index
- )
- } else {
- StagedDns.NewDns(
- item = CustomDnsItem(
- address = ipAddress,
- isLocal = ipAddress.isLocalAddress()
- ),
- validationResult = error
- )
- }
+ stagedDns =
+ if (dialog.stagedDns is StagedDns.EditDns) {
+ StagedDns.EditDns(
+ item =
+ CustomDnsItem(
+ address = ipAddress,
+ isLocal = ipAddress.isLocalAddress()
+ ),
+ validationResult = error,
+ index = dialog.stagedDns.index
+ )
+ } else {
+ StagedDns.NewDns(
+ item =
+ CustomDnsItem(
+ address = ipAddress,
+ isLocal = ipAddress.isLocalAddress()
+ ),
+ validationResult = error
+ )
+ }
)
}
}
- fun onSaveDnsClick() = viewModelScope.launch(dispatcher) {
- val dialog =
- vmState.value.dialogState as? AdvancedSettingsDialogState.DnsDialog ?: return@launch
+ fun onSaveDnsClick() =
+ viewModelScope.launch(dispatcher) {
+ val dialog =
+ vmState.value.dialogState as? AdvancedSettingsDialogState.DnsDialog ?: return@launch
- if (dialog.stagedDns.isValid().not()) return@launch
+ if (dialog.stagedDns.isValid().not()) return@launch
- val updatedList =
- vmState.value.customDnsList.toMutableList()
- .map { it.address }
- .toMutableList()
- .let { activeList ->
- if (dialog.stagedDns is StagedDns.EditDns) {
- activeList
- .apply {
- set(dialog.stagedDns.index, dialog.stagedDns.item.address)
- }
- .asInetAddressList()
- } else {
- activeList
- .apply {
- add(dialog.stagedDns.item.address)
- }
- .asInetAddressList()
+ val updatedList =
+ vmState.value.customDnsList
+ .toMutableList()
+ .map { it.address }
+ .toMutableList()
+ .let { activeList ->
+ if (dialog.stagedDns is StagedDns.EditDns) {
+ activeList
+ .apply {
+ set(dialog.stagedDns.index, dialog.stagedDns.item.address)
+ }
+ .asInetAddressList()
+ } else {
+ activeList
+ .apply { add(dialog.stagedDns.item.address) }
+ .asInetAddressList()
+ }
}
- }
- repository.setDnsOptions(
- isCustomDnsEnabled = true,
- dnsList = updatedList
- )
+ repository.setDnsOptions(isCustomDnsEnabled = true, dnsList = updatedList)
- hideDialog()
- }
+ hideDialog()
+ }
- fun onToggleDnsClick(isEnabled: Boolean) = viewModelScope.launch(dispatcher) {
- repository.setDnsOptions(
- isEnabled,
- dnsList = vmState.value.customDnsList
- .map { it.address }
- .asInetAddressList()
- )
- }
+ fun onToggleDnsClick(isEnabled: Boolean) =
+ viewModelScope.launch(dispatcher) {
+ repository.setDnsOptions(
+ isEnabled,
+ dnsList = vmState.value.customDnsList.map { it.address }.asInetAddressList()
+ )
+ }
- fun onRemoveDnsClick() = viewModelScope.launch(dispatcher) {
- val dialog = vmState.value.dialogState as? AdvancedSettingsDialogState.DnsDialog
- ?: return@launch
+ fun onRemoveDnsClick() =
+ viewModelScope.launch(dispatcher) {
+ val dialog =
+ vmState.value.dialogState as? AdvancedSettingsDialogState.DnsDialog ?: return@launch
- val updatedList = vmState.value.customDnsList.toMutableList()
- .filter {
- it.address != dialog.stagedDns.item.address
- }
- .map { it.address }
- .asInetAddressList()
+ val updatedList =
+ vmState.value.customDnsList
+ .toMutableList()
+ .filter { it.address != dialog.stagedDns.item.address }
+ .map { it.address }
+ .asInetAddressList()
- repository.setDnsOptions(
- isCustomDnsEnabled = vmState.value.isCustomDnsEnabled && updatedList.isNotEmpty(),
- dnsList = updatedList
- )
+ repository.setDnsOptions(
+ isCustomDnsEnabled = vmState.value.isCustomDnsEnabled && updatedList.isNotEmpty(),
+ dnsList = updatedList
+ )
- hideDialog()
- }
+ hideDialog()
+ }
private fun hideDialog() {
dialogState.update { AdvancedSettingsDialogState.NoDialog }
@@ -201,9 +204,7 @@ class AdvancedSettingsViewModel(
private fun String.isDuplicateDns(stagedIndex: Int? = null): Boolean {
return vmState.value.customDnsList
- .filterIndexed { index, listItem ->
- index != stagedIndex && listItem.address == this
- }
+ .filterIndexed { index, listItem -> index != stagedIndex && listItem.address == this }
.isNotEmpty()
}
@@ -218,10 +219,7 @@ class AdvancedSettingsViewModel(
private fun List<InetAddress>.asStringAddressList(): List<CustomDnsItem> {
return map {
- CustomDnsItem(
- address = it.hostAddress ?: EMPTY_STRING,
- isLocal = it.isLocalAddress()
- )
+ CustomDnsItem(address = it.hostAddress ?: EMPTY_STRING, isLocal = it.isLocalAddress())
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt
index 4db0c012fd..002d478b8f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt
@@ -11,52 +11,52 @@ data class AdvancedSettingsViewModelState(
) {
fun toUiState(): AdvancedSettingsUiState {
return when (dialogState) {
- is AdvancedSettingsDialogState.MtuDialog -> AdvancedSettingsUiState.MtuDialogUiState(
- mtu = mtuValue,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- mtuEditValue = dialogState.mtuEditValue,
- )
- is AdvancedSettingsDialogState.DnsDialog -> AdvancedSettingsUiState.DnsDialogUiState(
- mtu = mtuValue,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- stagedDns = dialogState.stagedDns,
- )
- else -> AdvancedSettingsUiState.DefaultUiState(
- mtu = mtuValue,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- )
+ is AdvancedSettingsDialogState.MtuDialog ->
+ AdvancedSettingsUiState.MtuDialogUiState(
+ mtu = mtuValue,
+ isCustomDnsEnabled = isCustomDnsEnabled,
+ isAllowLanEnabled = isAllowLanEnabled,
+ customDnsItems = customDnsList,
+ mtuEditValue = dialogState.mtuEditValue,
+ )
+ is AdvancedSettingsDialogState.DnsDialog ->
+ AdvancedSettingsUiState.DnsDialogUiState(
+ mtu = mtuValue,
+ isCustomDnsEnabled = isCustomDnsEnabled,
+ isAllowLanEnabled = isAllowLanEnabled,
+ customDnsItems = customDnsList,
+ stagedDns = dialogState.stagedDns,
+ )
+ else ->
+ AdvancedSettingsUiState.DefaultUiState(
+ mtu = mtuValue,
+ isCustomDnsEnabled = isCustomDnsEnabled,
+ isAllowLanEnabled = isAllowLanEnabled,
+ customDnsItems = customDnsList,
+ )
}
}
companion object {
private const val EMPTY_STRING = ""
- fun default() = AdvancedSettingsViewModelState(
- mtuValue = EMPTY_STRING,
- isCustomDnsEnabled = false,
- customDnsList = listOf(),
- isAllowLanEnabled = false,
- dialogState = AdvancedSettingsDialogState.NoDialog
- )
+ fun default() =
+ AdvancedSettingsViewModelState(
+ mtuValue = EMPTY_STRING,
+ isCustomDnsEnabled = false,
+ customDnsList = listOf(),
+ isAllowLanEnabled = false,
+ dialogState = AdvancedSettingsDialogState.NoDialog
+ )
}
}
sealed class AdvancedSettingsDialogState {
object NoDialog : AdvancedSettingsDialogState()
- data class MtuDialog(
- val mtuEditValue: String
- ) : AdvancedSettingsDialogState()
+ data class MtuDialog(val mtuEditValue: String) : AdvancedSettingsDialogState()
- data class DnsDialog(
- val stagedDns: StagedDns
- ) : AdvancedSettingsDialogState()
+ data class DnsDialog(val stagedDns: StagedDns) : AdvancedSettingsDialogState()
}
sealed interface StagedDns {
@@ -83,18 +83,12 @@ sealed interface StagedDns {
fun isValid() = (validationResult is ValidationResult.Success)
}
-data class CustomDnsItem(
- val address: String,
- val isLocal: Boolean
-) {
+data class CustomDnsItem(val address: String, val isLocal: Boolean) {
companion object {
private const val EMPTY_STRING = ""
fun default(): CustomDnsItem {
- return CustomDnsItem(
- address = EMPTY_STRING,
- isLocal = false
- )
+ return CustomDnsItem(address = EMPTY_STRING, isLocal = false)
}
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModel.kt
index 003eb962ad..a8255f5675 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModel.kt
@@ -15,18 +15,20 @@ class ChangelogViewModel(
val changelogDialogUiState = _changelogDialogUiState.asStateFlow()
fun refreshChangelogDialogUiState() {
- val shouldShowChangelogDialog = alwaysShowChangelog || changelogRepository
- .getVersionCodeOfMostRecentChangelogShowed() < buildVersionCode
- _changelogDialogUiState.value = if (shouldShowChangelogDialog) {
- val changelogList = changelogRepository.getLastVersionChanges()
- if (changelogList.isNotEmpty()) {
- ChangelogDialogUiState.Show(changelogList)
+ val shouldShowChangelogDialog =
+ alwaysShowChangelog ||
+ changelogRepository.getVersionCodeOfMostRecentChangelogShowed() < buildVersionCode
+ _changelogDialogUiState.value =
+ if (shouldShowChangelogDialog) {
+ val changelogList = changelogRepository.getLastVersionChanges()
+ if (changelogList.isNotEmpty()) {
+ ChangelogDialogUiState.Show(changelogList)
+ } else {
+ ChangelogDialogUiState.Hide
+ }
} else {
ChangelogDialogUiState.Hide
}
- } else {
- ChangelogDialogUiState.Hide
- }
}
fun dismissChangelogDialog() {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
index d2fc044a8e..d9a682c0c8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
@@ -41,34 +41,35 @@ class DeviceListViewModel(
var accountToken: String? = null
private var cachedDeviceList: List<Device>? = null
- val uiState = combine(
- deviceRepository.deviceList,
- _stagedDeviceId,
- _loadingDevices
- ) { deviceList, stagedDeviceId, loadingDevices ->
- val devices = if (deviceList is DeviceList.Available) {
- deviceList.devices.also { cachedDeviceList = it }
- } else {
- cachedDeviceList
- }
- val deviceUiItems = devices?.sortedBy { it.creationDate }?.map { device ->
- DeviceListItemUiState(
- device,
- loadingDevices.any { loadingDevice ->
- device.id == loadingDevice
- }
- )
- }
- val isLoading = devices == null
- val stagedDevice = devices?.firstOrNull { device ->
- device.id == stagedDeviceId
- }
- DeviceListUiState(
- deviceUiItems = deviceUiItems ?: emptyList(),
- isLoading = isLoading,
- stagedDevice = stagedDevice
- )
- }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), DeviceListUiState.INITIAL)
+ val uiState =
+ combine(deviceRepository.deviceList, _stagedDeviceId, _loadingDevices) {
+ deviceList,
+ stagedDeviceId,
+ loadingDevices ->
+ val devices =
+ if (deviceList is DeviceList.Available) {
+ deviceList.devices.also { cachedDeviceList = it }
+ } else {
+ cachedDeviceList
+ }
+ val deviceUiItems =
+ devices
+ ?.sortedBy { it.creationDate }
+ ?.map { device ->
+ DeviceListItemUiState(
+ device,
+ loadingDevices.any { loadingDevice -> device.id == loadingDevice }
+ )
+ }
+ val isLoading = devices == null
+ val stagedDevice = devices?.firstOrNull { device -> device.id == stagedDeviceId }
+ DeviceListUiState(
+ deviceUiItems = deviceUiItems ?: emptyList(),
+ isLoading = isLoading,
+ stagedDevice = stagedDevice
+ )
+ }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), DeviceListUiState.INITIAL)
fun stageDeviceForRemoval(deviceId: DeviceId) {
_stagedDeviceId.value = deviceId
@@ -85,18 +86,19 @@ class DeviceListViewModel(
if (token != null && stagedDeviceId != null) {
viewModelScope.launch {
withContext(dispatcher) {
- val result = withTimeoutOrNull(DEVICE_REMOVAL_TIMEOUT_MILLIS) {
- deviceRepository.deviceRemovalEvent
- .onSubscription {
- clearStagedDevice()
- setLoadingDevice(stagedDeviceId)
- deviceRepository.removeDevice(token, stagedDeviceId)
- }
- .filter { (deviceId, result) ->
- deviceId == stagedDeviceId && result == RemoveDeviceResult.Ok
- }
- .first()
- }
+ val result =
+ withTimeoutOrNull(DEVICE_REMOVAL_TIMEOUT_MILLIS) {
+ deviceRepository.deviceRemovalEvent
+ .onSubscription {
+ clearStagedDevice()
+ setLoadingDevice(stagedDeviceId)
+ deviceRepository.removeDevice(token, stagedDeviceId)
+ }
+ .filter { (deviceId, result) ->
+ deviceId == stagedDeviceId && result == RemoveDeviceResult.Ok
+ }
+ .first()
+ }
clearLoadingDevice(stagedDeviceId)
@@ -118,9 +120,8 @@ class DeviceListViewModel(
fun refreshDeviceState() = deviceRepository.refreshDeviceState()
- fun refreshDeviceList() = accountToken?.let { token ->
- deviceRepository.refreshDeviceList(token)
- }
+ fun refreshDeviceList() =
+ accountToken?.let { token -> deviceRepository.refreshDeviceList(token) }
private fun setLoadingDevice(deviceId: DeviceId) {
_loadingDevices.value = _loadingDevices.value.toMutableList().apply { add(deviceId) }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt
index db31c0610d..f5e9024c58 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModel.kt
@@ -23,25 +23,24 @@ class DeviceRevokedViewModel(
dispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {
- val uiState = serviceConnectionManager.connectionState
- .map { connectionState -> connectionState.readyContainer()?.connectionProxy }
- .flatMapLatest { proxy ->
- proxy?.onUiStateChange
- ?.callbackFlowFromSubscription(this)
- ?.map {
+ val uiState =
+ serviceConnectionManager.connectionState
+ .map { connectionState -> connectionState.readyContainer()?.connectionProxy }
+ .flatMapLatest { proxy ->
+ proxy?.onUiStateChange?.callbackFlowFromSubscription(this)?.map {
if (it.isSecured()) {
DeviceRevokedUiState.SECURED
} else {
DeviceRevokedUiState.UNSECURED
}
}
- ?: flowOf(DeviceRevokedUiState.UNKNOWN)
- }
- .stateIn(
- scope = CoroutineScope(dispatcher),
- started = SharingStarted.WhileSubscribed(),
- initialValue = DeviceRevokedUiState.UNKNOWN
- )
+ ?: flowOf(DeviceRevokedUiState.UNKNOWN)
+ }
+ .stateIn(
+ scope = CoroutineScope(dispatcher),
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = DeviceRevokedUiState.UNKNOWN
+ )
fun onGoToLoginClicked() {
serviceConnectionManager.connectionProxy()?.let { proxy ->
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
index 259deedc57..2f59bcb347 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt
@@ -28,9 +28,7 @@ class LoginViewModel(
sealed class LoginUiState {
object Default : LoginUiState()
object Loading : LoginUiState()
- data class Success(
- val isOutOfTime: Boolean
- ) : LoginUiState()
+ data class Success(val isOutOfTime: Boolean) : LoginUiState()
object CreatingAccount : LoginUiState()
object AccountCreated : LoginUiState()
@@ -54,20 +52,22 @@ class LoginViewModel(
fun createAccount() {
_uiState.value = LoginUiState.CreatingAccount
viewModelScope.launch(dispatcher) {
- _uiState.value = accountRepository.accountCreationEvents
- .onStart { accountRepository.createAccount() }
- .first()
- .mapToUiState()
+ _uiState.value =
+ accountRepository.accountCreationEvents
+ .onStart { accountRepository.createAccount() }
+ .first()
+ .mapToUiState()
}
}
fun login(accountToken: String) {
_uiState.value = LoginUiState.Loading
viewModelScope.launch(dispatcher) {
- _uiState.value = accountRepository.loginEvents
- .onStart { accountRepository.login(accountToken) }
- .map { it.result.mapToUiState(accountToken) }
- .first()
+ _uiState.value =
+ accountRepository.loginEvents
+ .onStart { accountRepository.login(accountToken) }
+ .map { it.result.mapToUiState(accountToken) }
+ .first()
}
}
@@ -84,12 +84,13 @@ class LoginViewModel(
LoginResult.Ok -> LoginUiState.Success(false)
LoginResult.InvalidAccount -> LoginUiState.InvalidAccountError
LoginResult.MaxDevicesReached -> {
- val refreshResult = deviceRepository.refreshAndAwaitDeviceListWithTimeout(
- accountToken = accountToken,
- shouldClearCache = true,
- shouldOverrideCache = true,
- timeoutMillis = 5000L
- )
+ val refreshResult =
+ deviceRepository.refreshAndAwaitDeviceListWithTimeout(
+ accountToken = accountToken,
+ shouldClearCache = true,
+ shouldOverrideCache = true,
+ timeoutMillis = 5000L
+ )
if (refreshResult.isAvailable()) {
LoginUiState.TooManyDevicesError(accountToken)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt
index 9537c03a82..d2f43a77f6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt
@@ -35,22 +35,23 @@ class SplitTunnelingViewModel(
private val excludedApps: MutableMap<String, AppData> = mutableMapOf()
private val notExcludedApps: MutableMap<String, AppData> = mutableMapOf()
- private val defaultListItems: List<ListItemData> = listOf(
- createTextItem(R.string.split_tunneling_description)
- // We will have search item in future
- )
+ private val defaultListItems: List<ListItemData> =
+ listOf(
+ createTextItem(R.string.split_tunneling_description)
+ // We will have search item in future
+ )
private var isSystemAppsVisible = false
init {
viewModelScope.launch(dispatcher) {
listItemsSink.emit(defaultListItems + createDivider(0) + createProgressItem())
// this will be removed after changes on native to ignore enable parameter
- if (!splitTunneling.enabled)
- splitTunneling.enabled = true
+ if (!splitTunneling.enabled) splitTunneling.enabled = true
fetchData()
}
viewModelScope.launch(dispatcher) {
- intentFlow.shareIn(viewModelScope, SharingStarted.WhileSubscribed())
+ intentFlow
+ .shareIn(viewModelScope, SharingStarted.WhileSubscribed())
.collect(::handleIntents)
}
}
@@ -97,7 +98,8 @@ class SplitTunnelingViewModel(
}
private suspend fun fetchData() {
- appsProvider.getAppsList()
+ appsProvider
+ .getAppsList()
.partition { app -> splitTunneling.isAppExcluded(app.packageName) }
.let { (excludedAppsList, notExcludedAppsList) ->
// TODO: remove potential package names from splitTunneling list
@@ -114,9 +116,10 @@ class SplitTunnelingViewModel(
if (excludedApps.isNotEmpty()) {
listItems += createDivider(0)
listItems += createMainItem(R.string.exclude_applications)
- listItems += excludedApps.values.sortedBy { it.name }.map { info ->
- createApplicationItem(info, true)
- }
+ listItems +=
+ excludedApps.values
+ .sortedBy { it.name }
+ .map { info -> createApplicationItem(info, true) }
}
val shownNotExcludedApps =
notExcludedApps.filter { app -> !app.value.isSystemApp || isSystemAppsVisible }
@@ -124,9 +127,10 @@ class SplitTunnelingViewModel(
listItems += createDivider(1)
listItems += createSwitchItem(R.string.show_system_apps, isSystemAppsVisible)
listItems += createMainItem(R.string.all_applications)
- listItems += shownNotExcludedApps.values.sortedBy { it.name }.map { info ->
- createApplicationItem(info, false)
- }
+ listItems +=
+ shownNotExcludedApps.values
+ .sortedBy { it.name }
+ .map { info -> createApplicationItem(info, false) }
}
listItemsSink.emit(listItems)
}
@@ -137,14 +141,14 @@ class SplitTunnelingViewModel(
text = appData.name
iconRes = appData.iconRes
action = ListItemData.ItemAction(appData.packageName)
- widget = WidgetState.ImageState(
- if (checked) R.drawable.ic_icons_remove else R.drawable.ic_icons_add
- )
+ widget =
+ WidgetState.ImageState(
+ if (checked) R.drawable.ic_icons_remove else R.drawable.ic_icons_add
+ )
}
- private fun createDivider(id: Int): ListItemData = ListItemData.build("space_$id") {
- type = ListItemData.DIVIDER
- }
+ private fun createDivider(id: Int): ListItemData =
+ ListItemData.build("space_$id") { type = ListItemData.DIVIDER }
private fun createMainItem(@StringRes text: Int): ListItemData =
ListItemData.build("header_$text") {
@@ -159,9 +163,8 @@ class SplitTunnelingViewModel(
action = ListItemData.ItemAction(text.toString())
}
- private fun createProgressItem(): ListItemData = ListItemData.build(identifier = "progress") {
- type = ListItemData.PROGRESS
- }
+ private fun createProgressItem(): ListItemData =
+ ListItemData.build(identifier = "progress") { type = ListItemData.PROGRESS }
private fun createSwitchItem(@StringRes text: Int, checked: Boolean): ListItemData =
ListItemData.build(identifier = "switch_$text") {
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt b/android/app/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
index 51ed63bd0a..de56ebb878 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
@@ -12,39 +12,42 @@ import net.mullvad.talpid.util.EventNotifier
class ConnectivityListener {
private val availableNetworks = HashSet<Network>()
- private val callback = object : NetworkCallback() {
- override fun onAvailable(network: Network) {
- availableNetworks.add(network)
- isConnected = true
- }
+ private val callback =
+ object : NetworkCallback() {
+ override fun onAvailable(network: Network) {
+ availableNetworks.add(network)
+ isConnected = true
+ }
- override fun onLost(network: Network) {
- availableNetworks.remove(network)
- isConnected = !availableNetworks.isEmpty()
+ override fun onLost(network: Network) {
+ availableNetworks.remove(network)
+ isConnected = !availableNetworks.isEmpty()
+ }
}
- }
private lateinit var connectivityManager: ConnectivityManager
val connectivityNotifier = EventNotifier(false)
- var isConnected by observable(false) { _, oldValue, newValue ->
- if (newValue != oldValue) {
- if (senderAddress != 0L) {
- notifyConnectivityChange(newValue, senderAddress)
- }
+ var isConnected by
+ observable(false) { _, oldValue, newValue ->
+ if (newValue != oldValue) {
+ if (senderAddress != 0L) {
+ notifyConnectivityChange(newValue, senderAddress)
+ }
- connectivityNotifier.notify(newValue)
+ connectivityNotifier.notify(newValue)
+ }
}
- }
var senderAddress = 0L
fun register(context: Context) {
- val request = NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .build()
+ val request =
+ NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+ .build()
connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/CreateTunResult.kt b/android/app/src/main/kotlin/net/mullvad/talpid/CreateTunResult.kt
index 150382bb1a..33f62026d6 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/CreateTunResult.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/CreateTunResult.kt
@@ -11,10 +11,8 @@ sealed class CreateTunResult {
get() = true
}
- class InvalidDnsServers(
- val addresses: ArrayList<InetAddress>,
- val tunFd: Int
- ) : CreateTunResult() {
+ class InvalidDnsServers(val addresses: ArrayList<InetAddress>, val tunFd: Int) :
+ CreateTunResult() {
override val isOpen
get() = true
}
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt b/android/app/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
index 4203d0b0a1..9f5e4a67a6 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
@@ -10,17 +10,19 @@ import net.mullvad.mullvadvpn.util.SdkUtils.setMeteredIfSupported
import net.mullvad.talpid.tun_provider.TunConfig
open class TalpidVpnService : VpnService() {
- private var activeTunStatus by observable<CreateTunResult?>(null) { _, oldTunStatus, _ ->
- val oldTunFd = when (oldTunStatus) {
- is CreateTunResult.Success -> oldTunStatus.tunFd
- is CreateTunResult.InvalidDnsServers -> oldTunStatus.tunFd
- else -> null
- }
+ private var activeTunStatus by
+ observable<CreateTunResult?>(null) { _, oldTunStatus, _ ->
+ val oldTunFd =
+ when (oldTunStatus) {
+ is CreateTunResult.Success -> oldTunStatus.tunFd
+ is CreateTunResult.InvalidDnsServers -> oldTunStatus.tunFd
+ else -> null
+ }
- if (oldTunFd != null) {
- ParcelFileDescriptor.adoptFd(oldTunFd).close()
+ if (oldTunFd != null) {
+ ParcelFileDescriptor.adoptFd(oldTunFd).close()
+ }
}
- }
private val tunIsOpen
get() = activeTunStatus?.isOpen ?: false
@@ -59,9 +61,7 @@ open class TalpidVpnService : VpnService() {
}
fun createTun() {
- synchronized(this) {
- activeTunStatus = createTun(currentTunConfig)
- }
+ synchronized(this) { activeTunStatus = createTun(currentTunConfig) }
}
fun recreateTunIfOpen(config: TunConfig) {
@@ -74,15 +74,11 @@ open class TalpidVpnService : VpnService() {
}
fun closeTun() {
- synchronized(this) {
- activeTunStatus = null
- }
+ synchronized(this) { activeTunStatus = null }
}
fun markTunAsStale() {
- synchronized(this) {
- tunIsStale = true
- }
+ synchronized(this) { tunIsStale = true }
}
private fun createTun(config: TunConfig): CreateTunResult {
@@ -93,32 +89,33 @@ open class TalpidVpnService : VpnService() {
var invalidDnsServerAddresses = ArrayList<InetAddress>()
- val builder = Builder().apply {
- for (address in config.addresses) {
- addAddress(address, prefixForAddress(address))
- }
+ val builder =
+ Builder().apply {
+ for (address in config.addresses) {
+ addAddress(address, prefixForAddress(address))
+ }
- for (dnsServer in config.dnsServers) {
- try {
- addDnsServer(dnsServer)
- } catch (exception: IllegalArgumentException) {
- invalidDnsServerAddresses.add(dnsServer)
+ for (dnsServer in config.dnsServers) {
+ try {
+ addDnsServer(dnsServer)
+ } catch (exception: IllegalArgumentException) {
+ invalidDnsServerAddresses.add(dnsServer)
+ }
}
- }
- for (route in config.routes) {
- addRoute(route.address, route.prefixLength.toInt())
- }
+ for (route in config.routes) {
+ addRoute(route.address, route.prefixLength.toInt())
+ }
- disallowedApps?.let { apps ->
- for (app in apps) {
- addDisallowedApplication(app)
+ disallowedApps?.let { apps ->
+ for (app in apps) {
+ addDisallowedApplication(app)
+ }
}
+ setMtu(config.mtu)
+ setBlocking(false)
+ setMeteredIfSupported(false)
}
- setMtu(config.mtu)
- setBlocking(false)
- setMeteredIfSupported(false)
- }
val vpnInterface = builder.establish()
val tunFd = vpnInterface?.detachFd()
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt b/android/app/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
index 5efb1bcb1c..89fdedaba1 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/net/TransportProtocol.kt
@@ -5,5 +5,6 @@ import kotlinx.parcelize.Parcelize
@Parcelize
enum class TransportProtocol : Parcelable {
- Tcp, Udp
+ Tcp,
+ Udp
}
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt b/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt
index 5c081b392e..7bb9eb2530 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/net/TunnelEndpoint.kt
@@ -4,7 +4,4 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
-data class TunnelEndpoint(
- val endpoint: Endpoint,
- val quantumResistant: Boolean
-) : Parcelable
+data class TunnelEndpoint(val endpoint: Endpoint, val quantumResistant: Boolean) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
index 365ac0811b..a62abaacd0 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ActionAfterDisconnect.kt
@@ -5,5 +5,7 @@ import kotlinx.parcelize.Parcelize
@Parcelize
enum class ActionAfterDisconnect : Parcelable {
- Nothing, Block, Reconnect
+ Nothing,
+ Block,
+ Reconnect
}
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorState.kt b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorState.kt
index 2c5ba00bf5..070d190beb 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorState.kt
@@ -3,5 +3,4 @@ package net.mullvad.talpid.tunnel
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
-@Parcelize
-data class ErrorState(val cause: ErrorStateCause, val isBlocking: Boolean) : Parcelable
+@Parcelize data class ErrorState(val cause: ErrorStateCause, val isBlocking: Boolean) : Parcelable
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorStateCause.kt b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorStateCause.kt
index b31f71f1fb..5096e5c693 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorStateCause.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ErrorStateCause.kt
@@ -14,27 +14,19 @@ sealed class ErrorStateCause : Parcelable {
}
}
- @Parcelize
- object Ipv6Unavailable : ErrorStateCause()
+ @Parcelize object Ipv6Unavailable : ErrorStateCause()
- @Parcelize
- object SetFirewallPolicyError : ErrorStateCause()
+ @Parcelize object SetFirewallPolicyError : ErrorStateCause()
- @Parcelize
- object SetDnsError : ErrorStateCause()
+ @Parcelize object SetDnsError : ErrorStateCause()
- @Parcelize
- class InvalidDnsServers(val addresses: ArrayList<InetAddress>) : ErrorStateCause()
+ @Parcelize class InvalidDnsServers(val addresses: ArrayList<InetAddress>) : ErrorStateCause()
- @Parcelize
- object StartTunnelError : ErrorStateCause()
+ @Parcelize object StartTunnelError : ErrorStateCause()
- @Parcelize
- class TunnelParameterError(val error: ParameterGenerationError) : ErrorStateCause()
+ @Parcelize class TunnelParameterError(val error: ParameterGenerationError) : ErrorStateCause()
- @Parcelize
- object IsOffline : ErrorStateCause()
+ @Parcelize object IsOffline : ErrorStateCause()
- @Parcelize
- object VpnPermissionDenied : ErrorStateCause()
+ @Parcelize object VpnPermissionDenied : ErrorStateCause()
}
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
index 51fa8ac461..b1504c676f 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/tunnel/ParameterGenerationError.kt
@@ -1,5 +1,8 @@
package net.mullvad.talpid.tunnel
enum class ParameterGenerationError {
- NoMatchingRelay, NoMatchingBridgeRelay, NoWireguardKey, CustomTunnelHostResultionError
+ NoMatchingRelay,
+ NoMatchingBridgeRelay,
+ NoWireguardKey,
+ CustomTunnelHostResultionError
}
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifier.kt b/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifier.kt
index fb038f1243..148b56eb45 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifier.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifier.kt
@@ -52,20 +52,14 @@ class EventNotifier<T>(private val initialValue: T) {
}
fun unsubscribe(id: Any) {
- synchronized(this) {
- listeners.remove(id)
- }
+ synchronized(this) { listeners.remove(id) }
}
fun unsubscribeAll() {
- synchronized(this) {
- listeners.clear()
- }
+ synchronized(this) { listeners.clear() }
}
- fun notifiable() = observable(latestEvent) { _, _, newValue ->
- notify(newValue)
- }
+ fun notifiable() = observable(latestEvent) { _, _, newValue -> notify(newValue) }
}
fun <T> autoSubscribable(id: Any, fallback: T, listener: (T) -> Unit) =
diff --git a/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifierExtensions.kt b/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifierExtensions.kt
index 454cae6133..add362fcb1 100644
--- a/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifierExtensions.kt
+++ b/android/app/src/main/kotlin/net/mullvad/talpid/util/EventNotifierExtensions.kt
@@ -4,10 +4,6 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
fun <T> EventNotifier<T>.callbackFlowFromSubscription(id: Any) = callbackFlow {
- this@callbackFlowFromSubscription.subscribe(id) {
- this.trySend(it)
- }
- awaitClose {
- this@callbackFlowFromSubscription.unsubscribe(id)
- }
+ this@callbackFlowFromSubscription.subscribe(id) { this.trySend(it) }
+ awaitClose { this@callbackFlowFromSubscription.unsubscribe(id) }
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestCoroutineRule.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestCoroutineRule.kt
index 1acdf9e577..1f84171e3d 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestCoroutineRule.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestCoroutineRule.kt
@@ -7,9 +7,8 @@ import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description
-class TestCoroutineRule(
- val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()
-) : TestWatcher() {
+class TestCoroutineRule(val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) :
+ TestWatcher() {
override fun starting(description: Description?) {
super.starting(description)
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestUtils.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestUtils.kt
index 4c4f043c06..59e1c70c6c 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestUtils.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/TestUtils.kt
@@ -2,10 +2,15 @@ package net.mullvad.mullvadvpn
import kotlin.test.assertTrue
-fun <T> assertLists(expected: List<T>, actual: List<T>, message: String? = null) = assertTrue(
- expected.size == actual.size && expected.containsAll(actual) && actual.containsAll(expected),
- message ?: """Expected list should have same size and contains same items.
+fun <T> assertLists(expected: List<T>, actual: List<T>, message: String? = null) =
+ assertTrue(
+ expected.size == actual.size &&
+ expected.containsAll(actual) &&
+ actual.containsAll(expected),
+ message
+ ?: """Expected list should have same size and contains same items.
| Expected(${expected.size}): $expected
| Actual(${actual.size}) : $actual
- """.trimMargin()
-)
+ """
+ .trimMargin()
+ )
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsIconManagerTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsIconManagerTest.kt
index e6d43621a1..8db700f452 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsIconManagerTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/applist/ApplicationsIconManagerTest.kt
@@ -58,12 +58,8 @@ class ApplicationsIconManagerTest {
assertEquals(mockedDrawable, result)
assertEquals(mockedDrawable, result2)
- verify(exactly = 2) {
- mockedMainLooper.isCurrentThread
- }
- verify(exactly = 1) {
- mockedPackageManager.getApplicationIcon(testPackageName)
- }
+ verify(exactly = 2) { mockedMainLooper.isCurrentThread }
+ verify(exactly = 1) { mockedPackageManager.getApplicationIcon(testPackageName) }
}
@Test
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 e1a9e37ac4..3f2534798d 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
@@ -34,26 +34,41 @@ class ApplicationsProviderTest {
every {
mockedPackageManager.getInstalledApplications(PackageManager.GET_META_DATA)
- } returns listOf(
- createApplicationInfo(launchWithInternetPackageName, launch = true, internet = true),
- createApplicationInfo(launchWithoutInternetPackageName, launch = true),
- createApplicationInfo(nonLaunchWithInternetPackageName, internet = true),
- createApplicationInfo(nonLaunchWithoutInternetPackageName),
- createApplicationInfo(
- leanbackLaunchWithInternetPackageName,
- leanback = true,
- internet = true
- ),
- createApplicationInfo(leanbackLaunchWithoutInternetPackageName, leanback = true),
- createApplicationInfo(selfPackageName, internet = true, launch = true)
- )
+ } returns
+ listOf(
+ createApplicationInfo(
+ launchWithInternetPackageName,
+ launch = true,
+ internet = true
+ ),
+ createApplicationInfo(launchWithoutInternetPackageName, launch = true),
+ createApplicationInfo(nonLaunchWithInternetPackageName, internet = true),
+ createApplicationInfo(nonLaunchWithoutInternetPackageName),
+ createApplicationInfo(
+ leanbackLaunchWithInternetPackageName,
+ leanback = true,
+ internet = true
+ ),
+ createApplicationInfo(leanbackLaunchWithoutInternetPackageName, leanback = true),
+ createApplicationInfo(selfPackageName, internet = true, launch = true)
+ )
val result = testSubject.getAppsList()
- val expected = listOf(
- AppData(launchWithInternetPackageName, 0, launchWithInternetPackageName),
- AppData(nonLaunchWithInternetPackageName, 0, nonLaunchWithInternetPackageName, true),
- AppData(leanbackLaunchWithInternetPackageName, 0, leanbackLaunchWithInternetPackageName)
- )
+ val expected =
+ listOf(
+ AppData(launchWithInternetPackageName, 0, launchWithInternetPackageName),
+ AppData(
+ nonLaunchWithInternetPackageName,
+ 0,
+ nonLaunchWithInternetPackageName,
+ true
+ ),
+ AppData(
+ leanbackLaunchWithInternetPackageName,
+ 0,
+ leanbackLaunchWithInternetPackageName
+ )
+ )
assertLists(expected, result)
@@ -61,31 +76,34 @@ class ApplicationsProviderTest {
mockedPackageManager.getInstalledApplications(PackageManager.GET_META_DATA)
listOf(
- launchWithInternetPackageName,
- launchWithoutInternetPackageName,
- nonLaunchWithInternetPackageName,
- nonLaunchWithoutInternetPackageName,
- leanbackLaunchWithInternetPackageName,
- leanbackLaunchWithoutInternetPackageName,
- selfPackageName
- ).forEach { packageName ->
- mockedPackageManager.checkPermission(internet, packageName)
- }
+ launchWithInternetPackageName,
+ launchWithoutInternetPackageName,
+ nonLaunchWithInternetPackageName,
+ nonLaunchWithoutInternetPackageName,
+ leanbackLaunchWithInternetPackageName,
+ leanbackLaunchWithoutInternetPackageName,
+ selfPackageName
+ )
+ .forEach { packageName ->
+ mockedPackageManager.checkPermission(internet, packageName)
+ }
listOf(
- launchWithInternetPackageName,
- nonLaunchWithInternetPackageName,
- leanbackLaunchWithInternetPackageName
- ).forEach { packageName ->
- mockedPackageManager.getLaunchIntentForPackage(packageName)
- }
+ launchWithInternetPackageName,
+ nonLaunchWithInternetPackageName,
+ leanbackLaunchWithInternetPackageName
+ )
+ .forEach { packageName ->
+ mockedPackageManager.getLaunchIntentForPackage(packageName)
+ }
listOf(
- nonLaunchWithInternetPackageName,
- leanbackLaunchWithInternetPackageName,
- ).forEach { packageName ->
- mockedPackageManager.getLeanbackLaunchIntentForPackage(packageName)
- }
+ nonLaunchWithInternetPackageName,
+ leanbackLaunchWithInternetPackageName,
+ )
+ .forEach { packageName ->
+ mockedPackageManager.getLeanbackLaunchIntentForPackage(packageName)
+ }
}
}
@@ -103,26 +121,16 @@ class ApplicationsProviderTest {
every { mockApplicationInfo.loadLabel(mockedPackageManager) } returns packageName
- every {
- mockedPackageManager.getLaunchIntentForPackage(packageName)
- } returns if (launch || systemApp)
- mockk()
- else
- null
+ every { mockedPackageManager.getLaunchIntentForPackage(packageName) } returns
+ if (launch || systemApp) mockk() else null
- every {
- mockedPackageManager.getLeanbackLaunchIntentForPackage(packageName)
- } returns if (leanback || systemApp)
- mockk()
- else
- null
+ every { mockedPackageManager.getLeanbackLaunchIntentForPackage(packageName) } returns
+ if (leanback || systemApp) mockk() else null
every {
mockedPackageManager.checkPermission(Manifest.permission.INTERNET, packageName)
- } returns if (internet)
- PackageManager.PERMISSION_GRANTED
- else
- PackageManager.PERMISSION_DENIED
+ } returns
+ if (internet) PackageManager.PERMISSION_GRANTED else PackageManager.PERMISSION_DENIED
return mockApplicationInfo
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt
index 92ffd792a0..01b1807d42 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt
@@ -18,10 +18,7 @@ import org.koin.test.KoinTestRule
class UiModuleTest : KoinTest {
- @get:Rule
- val koinTestRule = KoinTestRule.create {
- modules(uiModule)
- }
+ @get:Rule val koinTestRule = KoinTestRule.create { modules(uiModule) }
@After
fun tearDown() {
@@ -31,18 +28,17 @@ class UiModuleTest : KoinTest {
@Test
fun test_scope_linking() {
val appsScope: Scope = getKoin().createScope(APPS_SCOPE, named(APPS_SCOPE))
- val serviceConnectionScope = getKoin().createScope(
- SERVICE_CONNECTION_SCOPE,
- named(SERVICE_CONNECTION_SCOPE)
- )
+ val serviceConnectionScope =
+ getKoin().createScope(SERVICE_CONNECTION_SCOPE, named(SERVICE_CONNECTION_SCOPE))
appsScope.linkTo(serviceConnectionScope)
val mockedMessenger = mockk<Messenger>()
val mockedEventMessageHandler = mockk<MessageDispatcher<Event>>(relaxed = true)
- val serviceConnectionSplitTunneling = serviceConnectionScope.get<SplitTunneling>(
- parameters = { parametersOf(mockedMessenger, mockedEventMessageHandler) }
- )
+ val serviceConnectionSplitTunneling =
+ serviceConnectionScope.get<SplitTunneling>(
+ parameters = { parametersOf(mockedMessenger, mockedEventMessageHandler) }
+ )
assertEquals(appsScope.get<SplitTunneling>(), serviceConnectionSplitTunneling)
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt
index 44ccdf013b..ff10770540 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt
@@ -26,14 +26,11 @@ import org.junit.Test
class ConnectionProxyTest {
- @MockK
- private lateinit var mockedMainLooper: Looper
+ @MockK private lateinit var mockedMainLooper: Looper
- @MockK
- private lateinit var connection: Messenger
+ @MockK private lateinit var connection: Messenger
- @MockK
- private lateinit var mockedDispatchingHandler: EventDispatcher
+ @MockK private lateinit var mockedDispatchingHandler: EventDispatcher
lateinit var connectionProxy: ConnectionProxy
@Before
@@ -57,9 +54,7 @@ class ConnectionProxyTest {
fun test_initialize_connection_proxy() {
// Arrange
val eventType = slot<KClass<Event.TunnelStateChange>>()
- every {
- mockedDispatchingHandler.registerHandler(capture(eventType), any())
- } just Runs
+ every { mockedDispatchingHandler.registerHandler(capture(eventType), any()) } just Runs
// Create ConnectionProxy instance and assert initial Event type
connectionProxy = ConnectionProxy(connection, mockedDispatchingHandler)
assertEquals(Event.TunnelStateChange::class, eventType.captured.java.kotlin)
@@ -69,9 +64,7 @@ class ConnectionProxyTest {
fun test_tunnel_normal_connect_disconnect() {
// Arrange
every { connection.send(any()) } just Runs
- every {
- mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any())
- } just Runs
+ every { mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any()) } just Runs
// Act and Assert no crashes
connectionProxy = ConnectionProxy(connection, mockedDispatchingHandler)
connectionProxy.connect()
@@ -82,9 +75,7 @@ class ConnectionProxyTest {
fun test_tunnel_handle_crash_on_connect() {
// Arrange
every { connection.send(any()) } throws DeadObjectException()
- every {
- mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any())
- } just Runs
+ every { mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any()) } just Runs
// Act and Assert no crashes
connectionProxy = ConnectionProxy(connection, mockedDispatchingHandler)
connectionProxy.connect()
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt
index 8b737cba69..81633c89be 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt
@@ -25,14 +25,11 @@ import org.junit.Test
class ServiceConnectionDeviceDataSourceTest {
private val tracker = JobTracker()
- @MockK
- private lateinit var mockedMainLooper: Looper
+ @MockK private lateinit var mockedMainLooper: Looper
- @MockK
- private lateinit var mockedDispatchingHandler: EventDispatcher
+ @MockK private lateinit var mockedDispatchingHandler: EventDispatcher
- @MockK
- private lateinit var connection: Messenger
+ @MockK private lateinit var connection: Messenger
lateinit var serviceConnectionDeviceDataSource: ServiceConnectionDeviceDataSource
@@ -57,9 +54,7 @@ class ServiceConnectionDeviceDataSourceTest {
fun test_get_devices_list() {
// Arrange
every { connection.send(any()) } just Runs
- every {
- mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any())
- } just Runs
+ every { mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any()) } just Runs
// Act and Assert no crashes
serviceConnectionDeviceDataSource =
ServiceConnectionDeviceDataSource(connection, mockedDispatchingHandler)
@@ -70,9 +65,7 @@ class ServiceConnectionDeviceDataSourceTest {
fun test_catch_exception_on_devices_list() {
// Arrange
every { connection.send(any()) } throws DeadObjectException()
- every {
- mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any())
- } just Runs
+ every { mockedDispatchingHandler.registerHandler(any<KClass<Event>>(), any()) } just Runs
// Act and Assert no crashes
serviceConnectionDeviceDataSource =
ServiceConnectionDeviceDataSource(connection, mockedDispatchingHandler)
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
index eafac23bfc..3547b92065 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
@@ -19,8 +19,7 @@ import org.junit.Test
class ChangelogViewModelTest {
- @MockK
- private lateinit var mockedChangelogRepository: ChangelogRepository
+ @MockK private lateinit var mockedChangelogRepository: ChangelogRepository
private lateinit var viewModel: ChangelogViewModel
@@ -28,9 +27,8 @@ class ChangelogViewModelTest {
fun setup() {
MockKAnnotations.init(this)
mockkStatic(EVENT_NOTIFIER_EXTENSION_CLASS)
- every {
- mockedChangelogRepository.setVersionCodeOfMostRecentChangelogShowed(any())
- } just Runs
+ every { mockedChangelogRepository.setVersionCodeOfMostRecentChangelogShowed(any()) } just
+ Runs
viewModel = ChangelogViewModel(mockedChangelogRepository, 1, false)
}
@@ -52,9 +50,8 @@ class ChangelogViewModelTest {
viewModel.changelogDialogUiState.test {
// Arrange
val fakeList = listOf("test")
- every {
- mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed()
- } returns -1
+ every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns
+ -1
every { mockedChangelogRepository.getLastVersionChanges() } returns fakeList
// Assert initial ui state
@@ -76,9 +73,8 @@ class ChangelogViewModelTest {
viewModel.changelogDialogUiState.test {
// Arrange
val fakeEmptyList = emptyList<String>()
- every {
- mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed()
- } returns -1
+ every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns
+ -1
every { mockedChangelogRepository.getLastVersionChanges() } returns fakeEmptyList
// Assert initial ui state
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt
index c3be82c1e1..32cce31136 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceRevokedViewModelTest.kt
@@ -30,11 +30,9 @@ import org.junit.Test
class DeviceRevokedViewModelTest {
- @MockK
- private lateinit var mockedAccountRepository: AccountRepository
+ @MockK private lateinit var mockedAccountRepository: AccountRepository
- @MockK
- private lateinit var mockedServiceConnectionManager: ServiceConnectionManager
+ @MockK private lateinit var mockedServiceConnectionManager: ServiceConnectionManager
private val serviceConnectionState =
MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
@@ -46,11 +44,12 @@ class DeviceRevokedViewModelTest {
MockKAnnotations.init(this)
mockkStatic(EVENT_NOTIFIER_EXTENSION_CLASS)
every { mockedServiceConnectionManager.connectionState } returns serviceConnectionState
- viewModel = DeviceRevokedViewModel(
- mockedServiceConnectionManager,
- mockedAccountRepository,
- TestCoroutineDispatcher()
- )
+ viewModel =
+ DeviceRevokedViewModel(
+ mockedServiceConnectionManager,
+ mockedAccountRepository,
+ TestCoroutineDispatcher()
+ )
}
@After
@@ -79,17 +78,19 @@ class DeviceRevokedViewModelTest {
@Test
fun testUiStateWhenServiceConnectedAndReady() = runBlockingTest {
// Arrange
- val mockedContainer = mockk<ServiceConnectionContainer>().apply {
- val eventNotifierMock = mockk<EventNotifier<TunnelState>>().apply {
- every { callbackFlowFromSubscription(any()) } returns MutableStateFlow(
- TunnelState.Connected(mockk(), mockk())
- )
+ val mockedContainer =
+ mockk<ServiceConnectionContainer>().apply {
+ val eventNotifierMock =
+ mockk<EventNotifier<TunnelState>>().apply {
+ every { callbackFlowFromSubscription(any()) } returns
+ MutableStateFlow(TunnelState.Connected(mockk(), mockk()))
+ }
+ val mockedConnectionProxy =
+ mockk<ConnectionProxy>().apply {
+ every { onUiStateChange } returns eventNotifierMock
+ }
+ every { connectionProxy } returns mockedConnectionProxy
}
- val mockedConnectionProxy = mockk<ConnectionProxy>().apply {
- every { onUiStateChange } returns eventNotifierMock
- }
- every { connectionProxy } returns mockedConnectionProxy
- }
// Act, Assert
viewModel.uiState.test {
@@ -102,30 +103,30 @@ class DeviceRevokedViewModelTest {
@Test
fun testGoToLoginWhenDisconnected() {
// Arrange
- val mockedContainer = mockk<ServiceConnectionContainer>().also {
- every { it.connectionProxy.state } returns TunnelState.Disconnected
- every { it.connectionProxy.disconnect() } just Runs
- every { mockedAccountRepository.logout() } just Runs
- }
+ val mockedContainer =
+ mockk<ServiceConnectionContainer>().also {
+ every { it.connectionProxy.state } returns TunnelState.Disconnected
+ every { it.connectionProxy.disconnect() } just Runs
+ every { mockedAccountRepository.logout() } just Runs
+ }
serviceConnectionState.value = ServiceConnectionState.ConnectedReady(mockedContainer)
// Act
viewModel.onGoToLoginClicked()
// Assert
- verify {
- mockedAccountRepository.logout()
- }
+ verify { mockedAccountRepository.logout() }
}
@Test
fun testGoToLoginWhenConnected() {
// Arrange
- val mockedContainer = mockk<ServiceConnectionContainer>().also {
- every { it.connectionProxy.state } returns TunnelState.Connected(mockk(), mockk())
- every { it.connectionProxy.disconnect() } just Runs
- every { mockedAccountRepository.logout() } just Runs
- }
+ val mockedContainer =
+ mockk<ServiceConnectionContainer>().also {
+ every { it.connectionProxy.state } returns TunnelState.Connected(mockk(), mockk())
+ every { it.connectionProxy.disconnect() } just Runs
+ every { mockedAccountRepository.logout() } just Runs
+ }
serviceConnectionState.value = ServiceConnectionState.ConnectedReady(mockedContainer)
// Act
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
index ea35dd7c6c..0531342cc4 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
@@ -28,14 +28,11 @@ import org.junit.Test
class LoginViewModelTest {
- @MockK
- private lateinit var mockedAccountRepository: AccountRepository
+ @MockK private lateinit var mockedAccountRepository: AccountRepository
- @MockK
- private lateinit var mockedDeviceRepository: DeviceRepository
+ @MockK private lateinit var mockedDeviceRepository: DeviceRepository
- @MockK
- private lateinit var mockedServiceConnectionContainer: ServiceConnectionContainer
+ @MockK private lateinit var mockedServiceConnectionContainer: ServiceConnectionContainer
private lateinit var loginViewModel: LoginViewModel
@@ -58,11 +55,12 @@ class LoginViewModelTest {
serviceConnectionState.value =
ServiceConnectionState.ConnectedReady(mockedServiceConnectionContainer)
- loginViewModel = LoginViewModel(
- mockedAccountRepository,
- mockedDeviceRepository,
- TestCoroutineDispatcher()
- )
+ loginViewModel =
+ LoginViewModel(
+ mockedAccountRepository,
+ mockedDeviceRepository,
+ TestCoroutineDispatcher()
+ )
}
@Test
@@ -109,15 +107,8 @@ class LoginViewModelTest {
@Test
fun testLoginWithTooManyDevicesError() = runBlockingTest {
coEvery {
- mockedDeviceRepository.refreshAndAwaitDeviceListWithTimeout(
- any(),
- any(),
- any(),
- any()
- )
- } returns DeviceListEvent.Available(
- DUMMY_ACCOUNT_TOKEN, listOf()
- )
+ mockedDeviceRepository.refreshAndAwaitDeviceListWithTimeout(any(), any(), any(), any())
+ } returns DeviceListEvent.Available(DUMMY_ACCOUNT_TOKEN, listOf())
loginViewModel.uiState.test {
skipDefaultItem()
@@ -125,7 +116,8 @@ class LoginViewModelTest {
assertEquals(LoginViewModel.LoginUiState.Loading, awaitItem())
loginTestEvents.emit(Event.LoginEvent(LoginResult.MaxDevicesReached))
assertEquals(
- LoginViewModel.LoginUiState.TooManyDevicesError(DUMMY_ACCOUNT_TOKEN), awaitItem()
+ LoginViewModel.LoginUiState.TooManyDevicesError(DUMMY_ACCOUNT_TOKEN),
+ awaitItem()
)
}
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt
index ac229ba3fb..9fa0e9ea88 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt
@@ -29,11 +29,9 @@ import org.junit.Test
import org.junit.rules.Timeout
class SplitTunnelingViewModelTest {
- @get:Rule
- val testCoroutineRule = TestCoroutineRule()
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
- @get:Rule
- val timeout = Timeout(3000L, TimeUnit.MILLISECONDS)
+ @get:Rule val timeout = Timeout(3000L, TimeUnit.MILLISECONDS)
private val mockedApplicationsProvider = mockk<ApplicationsProvider>()
private val mockedSplitTunneling = mockk<SplitTunneling>()
private lateinit var testSubject: SplitTunnelingViewModel
@@ -50,166 +48,174 @@ class SplitTunnelingViewModelTest {
}
@Test
- fun test_has_progress_on_start() = runBlockingTest(testCoroutineRule.testDispatcher) {
- initTestSubject(emptyList())
- val actualList: List<ListItemData> = testSubject.listItems.first()
+ fun test_has_progress_on_start() =
+ runBlockingTest(testCoroutineRule.testDispatcher) {
+ initTestSubject(emptyList())
+ val actualList: List<ListItemData> = testSubject.listItems.first()
- val initialExpectedList = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(0),
- createProgressItem()
- )
+ val initialExpectedList =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(0),
+ createProgressItem()
+ )
- assertLists(initialExpectedList, actualList)
+ assertLists(initialExpectedList, actualList)
- verify(exactly = 1) {
- mockedApplicationsProvider.getAppsList()
+ verify(exactly = 1) { mockedApplicationsProvider.getAppsList() }
}
- }
@Test
- fun test_empty_app_list() = runBlockingTest(testCoroutineRule.testDispatcher) {
- initTestSubject(emptyList())
- testSubject.processIntent(ViewIntent.ViewIsReady)
- val actualList = testSubject.listItems.first()
- val expectedList = listOf(createTextItem(R.string.split_tunneling_description))
- assertLists(expectedList, actualList)
- }
+ fun test_empty_app_list() =
+ runBlockingTest(testCoroutineRule.testDispatcher) {
+ initTestSubject(emptyList())
+ testSubject.processIntent(ViewIntent.ViewIsReady)
+ val actualList = testSubject.listItems.first()
+ val expectedList = listOf(createTextItem(R.string.split_tunneling_description))
+ assertLists(expectedList, actualList)
+ }
@Test
- fun test_apps_list_delivered() = runBlockingTest(testCoroutineRule.testDispatcher) {
- val appExcluded = AppData("test.excluded", 0, "testName1")
- val appNotExcluded = AppData("test.not.excluded", 0, "testName2")
- every { mockedSplitTunneling.isAppExcluded(appExcluded.packageName) } returns true
- every { mockedSplitTunneling.isAppExcluded(appNotExcluded.packageName) } returns false
+ fun test_apps_list_delivered() =
+ runBlockingTest(testCoroutineRule.testDispatcher) {
+ val appExcluded = AppData("test.excluded", 0, "testName1")
+ val appNotExcluded = AppData("test.not.excluded", 0, "testName2")
+ every { mockedSplitTunneling.isAppExcluded(appExcluded.packageName) } returns true
+ every { mockedSplitTunneling.isAppExcluded(appNotExcluded.packageName) } returns false
- initTestSubject(listOf(appExcluded, appNotExcluded))
- testSubject.processIntent(ViewIntent.ViewIsReady)
+ initTestSubject(listOf(appExcluded, appNotExcluded))
+ testSubject.processIntent(ViewIntent.ViewIsReady)
- val actualList = testSubject.listItems.first()
- val expectedList = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(0),
- createMainItem(R.string.exclude_applications),
- createApplicationItem(appExcluded, true),
- createDivider(1),
- createSwitchItem(R.string.show_system_apps, false),
- createMainItem(R.string.all_applications),
- createApplicationItem(appNotExcluded, false),
- )
+ val actualList = testSubject.listItems.first()
+ val expectedList =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(0),
+ createMainItem(R.string.exclude_applications),
+ createApplicationItem(appExcluded, true),
+ createDivider(1),
+ createSwitchItem(R.string.show_system_apps, false),
+ createMainItem(R.string.all_applications),
+ createApplicationItem(appNotExcluded, false),
+ )
- assertLists(expectedList, actualList)
- verifyAll {
- mockedSplitTunneling.enabled
- mockedSplitTunneling.isAppExcluded(appExcluded.packageName)
- mockedSplitTunneling.isAppExcluded(appNotExcluded.packageName)
+ assertLists(expectedList, actualList)
+ verifyAll {
+ mockedSplitTunneling.enabled
+ mockedSplitTunneling.isAppExcluded(appExcluded.packageName)
+ mockedSplitTunneling.isAppExcluded(appNotExcluded.packageName)
+ }
}
- }
@Test
- fun test_remove_app_from_excluded() = runBlockingTest(testCoroutineRule.testDispatcher) {
- val app = AppData("test", 0, "testName")
- every { mockedSplitTunneling.isAppExcluded(app.packageName) } returns true
- every { mockedSplitTunneling.includeApp(app.packageName) } just Runs
+ fun test_remove_app_from_excluded() =
+ runBlockingTest(testCoroutineRule.testDispatcher) {
+ val app = AppData("test", 0, "testName")
+ every { mockedSplitTunneling.isAppExcluded(app.packageName) } returns true
+ every { mockedSplitTunneling.includeApp(app.packageName) } just Runs
- initTestSubject(listOf(app))
- testSubject.processIntent(ViewIntent.ViewIsReady)
+ initTestSubject(listOf(app))
+ testSubject.processIntent(ViewIntent.ViewIsReady)
- val listBeforeAction = testSubject.listItems.first()
- val expectedListBeforeAction = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(0),
- createMainItem(R.string.exclude_applications),
- createApplicationItem(app, true),
- )
+ val listBeforeAction = testSubject.listItems.first()
+ val expectedListBeforeAction =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(0),
+ createMainItem(R.string.exclude_applications),
+ createApplicationItem(app, true),
+ )
- assertLists(expectedListBeforeAction, listBeforeAction)
+ assertLists(expectedListBeforeAction, listBeforeAction)
- val item = listBeforeAction.first { it.identifier == app.packageName }
- testSubject.processIntent(ViewIntent.ChangeApplicationGroup(item))
+ val item = listBeforeAction.first { it.identifier == app.packageName }
+ testSubject.processIntent(ViewIntent.ChangeApplicationGroup(item))
- val itemsAfterAction = testSubject.listItems.first()
- val expectedList = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(1),
- createSwitchItem(R.string.show_system_apps, false),
- createMainItem(R.string.all_applications),
- createApplicationItem(app, false),
- )
+ val itemsAfterAction = testSubject.listItems.first()
+ val expectedList =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(1),
+ createSwitchItem(R.string.show_system_apps, false),
+ createMainItem(R.string.all_applications),
+ createApplicationItem(app, false),
+ )
- assertLists(expectedList, itemsAfterAction)
+ assertLists(expectedList, itemsAfterAction)
- verifyAll {
- mockedSplitTunneling.enabled
- mockedSplitTunneling.isAppExcluded(app.packageName)
- mockedSplitTunneling.includeApp(app.packageName)
+ verifyAll {
+ mockedSplitTunneling.enabled
+ mockedSplitTunneling.isAppExcluded(app.packageName)
+ mockedSplitTunneling.includeApp(app.packageName)
+ }
}
- }
@Test
- fun test_add_app_to_excluded() = runBlockingTest(testCoroutineRule.testDispatcher) {
- val app = AppData("test", 0, "testName")
- every { mockedSplitTunneling.isAppExcluded(app.packageName) } returns false
- every { mockedSplitTunneling.excludeApp(app.packageName) } just Runs
- initTestSubject(listOf(app))
- testSubject.processIntent(ViewIntent.ViewIsReady)
+ fun test_add_app_to_excluded() =
+ runBlockingTest(testCoroutineRule.testDispatcher) {
+ val app = AppData("test", 0, "testName")
+ every { mockedSplitTunneling.isAppExcluded(app.packageName) } returns false
+ every { mockedSplitTunneling.excludeApp(app.packageName) } just Runs
+ initTestSubject(listOf(app))
+ testSubject.processIntent(ViewIntent.ViewIsReady)
- val listBeforeAction = testSubject.listItems.first()
- val expectedListBeforeAction = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(1),
- createSwitchItem(R.string.show_system_apps, false),
- createMainItem(R.string.all_applications),
- createApplicationItem(app, false),
- )
+ val listBeforeAction = testSubject.listItems.first()
+ val expectedListBeforeAction =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(1),
+ createSwitchItem(R.string.show_system_apps, false),
+ createMainItem(R.string.all_applications),
+ createApplicationItem(app, false),
+ )
- assertLists(expectedListBeforeAction, listBeforeAction)
+ assertLists(expectedListBeforeAction, listBeforeAction)
- val item = listBeforeAction.first { it.identifier == app.packageName }
- testSubject.processIntent(ViewIntent.ChangeApplicationGroup(item))
+ val item = listBeforeAction.first { it.identifier == app.packageName }
+ testSubject.processIntent(ViewIntent.ChangeApplicationGroup(item))
- val itemsAfterAction = testSubject.listItems.first()
- val expectedList = listOf(
- createTextItem(R.string.split_tunneling_description),
- createDivider(0),
- createMainItem(R.string.exclude_applications),
- createApplicationItem(app, true),
- )
+ val itemsAfterAction = testSubject.listItems.first()
+ val expectedList =
+ listOf(
+ createTextItem(R.string.split_tunneling_description),
+ createDivider(0),
+ createMainItem(R.string.exclude_applications),
+ createApplicationItem(app, true),
+ )
- assertLists(expectedList, itemsAfterAction)
+ assertLists(expectedList, itemsAfterAction)
- verifyAll {
- mockedSplitTunneling.enabled
- mockedSplitTunneling.isAppExcluded(app.packageName)
- mockedSplitTunneling.excludeApp(app.packageName)
+ verifyAll {
+ mockedSplitTunneling.enabled
+ mockedSplitTunneling.isAppExcluded(app.packageName)
+ mockedSplitTunneling.excludeApp(app.packageName)
+ }
}
- }
private fun initTestSubject(appList: List<AppData>) {
every { mockedApplicationsProvider.getAppsList() } returns appList
- testSubject = SplitTunnelingViewModel(
- mockedApplicationsProvider,
- mockedSplitTunneling,
- testCoroutineRule.testDispatcher
- )
+ testSubject =
+ SplitTunnelingViewModel(
+ mockedApplicationsProvider,
+ mockedSplitTunneling,
+ testCoroutineRule.testDispatcher
+ )
}
- private fun createApplicationItem(
- appData: AppData,
- checked: Boolean
- ): ListItemData = ListItemData.build(appData.packageName) {
- type = ListItemData.APPLICATION
- text = appData.name
- iconRes = appData.iconRes
- action = ListItemData.ItemAction(appData.packageName)
- widget = WidgetState.ImageState(
- if (checked) R.drawable.ic_icons_remove else R.drawable.ic_icons_add
- )
- }
+ private fun createApplicationItem(appData: AppData, checked: Boolean): ListItemData =
+ ListItemData.build(appData.packageName) {
+ type = ListItemData.APPLICATION
+ text = appData.name
+ iconRes = appData.iconRes
+ action = ListItemData.ItemAction(appData.packageName)
+ widget =
+ WidgetState.ImageState(
+ if (checked) R.drawable.ic_icons_remove else R.drawable.ic_icons_add
+ )
+ }
- private fun createDivider(id: Int): ListItemData = ListItemData.build("space_$id") {
- type = ListItemData.DIVIDER
- }
+ private fun createDivider(id: Int): ListItemData =
+ ListItemData.build("space_$id") { type = ListItemData.DIVIDER }
private fun createMainItem(@StringRes text: Int): ListItemData =
ListItemData.build("header_$text") {
@@ -224,9 +230,8 @@ class SplitTunnelingViewModelTest {
action = ListItemData.ItemAction(text.toString())
}
- private fun createProgressItem(): ListItemData = ListItemData.build(identifier = "progress") {
- type = ListItemData.PROGRESS
- }
+ private fun createProgressItem(): ListItemData =
+ ListItemData.build(identifier = "progress") { type = ListItemData.PROGRESS }
private fun createSwitchItem(@StringRes text: Int, checked: Boolean): ListItemData =
ListItemData.build(identifier = "switch_$text") {
diff --git a/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt b/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt
index b3a00c809c..5fb8db5fe1 100644
--- a/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt
+++ b/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt
@@ -3,8 +3,6 @@ package net.mullvad.mullvadvpn.lib.endpoint
import kotlinx.parcelize.Parcelize
@Parcelize
-data class CustomApiEndpointConfiguration(
- val apiEndpoint: ApiEndpoint
-) : ApiEndpointConfiguration {
+data class CustomApiEndpointConfiguration(val apiEndpoint: ApiEndpoint) : ApiEndpointConfiguration {
override fun apiEndpoint() = apiEndpoint
}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
index 59905d72e2..19cc5a8b93 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt
@@ -22,10 +22,7 @@ fun UiDevice.findObjectWithTimeout(
timeout: Long = DEFAULT_INTERACTION_TIMEOUT
): UiObject2 {
- wait(
- Until.hasObject(selector),
- timeout
- )
+ wait(Until.hasObject(selector), timeout)
return try {
findObject(selector)
@@ -50,10 +47,7 @@ fun UiDevice.clickAllowOnNotificationPermissionPromptIfApiLevel31AndAbove(
val selector = By.text("Allow")
- wait(
- Until.hasObject(selector),
- timeout
- )
+ wait(Until.hasObject(selector), timeout)
try {
findObjectWithTimeout(selector).click()
@@ -69,10 +63,7 @@ fun UiObject2.findObjectWithTimeout(
timeout: Long = DEFAULT_INTERACTION_TIMEOUT
): UiObject2 {
- wait(
- Until.hasObject(selector),
- timeout
- )
+ wait(Until.hasObject(selector), timeout)
return try {
findObject(selector)
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
index d3b2abe7ae..d5a2e5176b 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/interactor/AppInteractor.kt
@@ -20,10 +20,7 @@ import net.mullvad.mullvadvpn.test.common.extension.clickAgreeOnPrivacyDisclaime
import net.mullvad.mullvadvpn.test.common.extension.clickAllowOnNotificationPermissionPromptIfApiLevel31AndAbove
import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout
-class AppInteractor(
- private val device: UiDevice,
- private val targetContext: Context
-) {
+class AppInteractor(private val device: UiDevice, private val targetContext: Context) {
fun launch(customApiEndpointConfiguration: CustomApiEndpointConfiguration? = null) {
device.pressHome()
// Wait for launcher
@@ -41,10 +38,7 @@ class AppInteractor(
}
}
targetContext.startActivity(intent)
- device.wait(
- Until.hasObject(By.pkg(MULLVAD_PACKAGE).depth(0)),
- APP_LAUNCH_TIMEOUT
- )
+ device.wait(Until.hasObject(By.pkg(MULLVAD_PACKAGE).depth(0)), APP_LAUNCH_TIMEOUT)
}
fun launchAndEnsureLoggedIn(accountToken: String) {
@@ -56,8 +50,10 @@ class AppInteractor(
}
fun attemptLogin(accountToken: String) {
- val loginObject = device.findObjectWithTimeout(By.clazz("android.widget.EditText"))
- .apply { text = accountToken }
+ val loginObject =
+ device.findObjectWithTimeout(By.clazz("android.widget.EditText")).apply {
+ text = accountToken
+ }
loginObject.parent.findObject(By.clazz(ImageButton::class.java)).click()
}
@@ -67,10 +63,10 @@ class AppInteractor(
fun extractIpAddress(): String {
device.findObjectWithTimeout(By.res(TUNNEL_INFO_ID)).click()
- return device.findObjectWithTimeout(
- By.res(TUNNEL_OUT_ADDRESS_ID),
- CONNECTION_TIMEOUT
- ).text.extractIpAddress()
+ return device
+ .findObjectWithTimeout(By.res(TUNNEL_OUT_ADDRESS_ID), CONNECTION_TIMEOUT)
+ .text
+ .extractIpAddress()
}
fun clickSettingsCog() {
@@ -85,9 +81,7 @@ class AppInteractor(
device.findObjectWithTimeout(By.text(text)).click()
}
- fun waitForLoginPrompt(
- timeout: Long = LOGIN_PROMPT_TIMEOUT
- ) {
+ fun waitForLoginPrompt(timeout: Long = LOGIN_PROMPT_TIMEOUT) {
device.findObjectWithTimeout(By.text("Login"), timeout)
}
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/CaptureScreenshotOnFailedTestRule.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/CaptureScreenshotOnFailedTestRule.kt
index 138d09cc28..c7b8992292 100644
--- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/CaptureScreenshotOnFailedTestRule.kt
+++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/rule/CaptureScreenshotOnFailedTestRule.kt
@@ -60,10 +60,7 @@ class CaptureScreenshotOnFailedTestRule(private val testTag: String) : TestWatch
) {
contentValues.apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
- put(
- MediaStore.Images.Media.RELATIVE_PATH,
- "$DIRECTORY_PICTURES/$baseDir"
- )
+ put(MediaStore.Images.Media.RELATIVE_PATH, "$DIRECTORY_PICTURES/$baseDir")
}
val uri =
@@ -89,14 +86,17 @@ class CaptureScreenshotOnFailedTestRule(private val testTag: String) : TestWatch
baseDir: String,
filename: String
) {
- val screenshotBaseDirectory = Paths.get(
- Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES).path,
- baseDir,
- ).toFile().apply {
- if (exists().not()) {
- mkdirs()
- }
- }
+ val screenshotBaseDirectory =
+ Paths.get(
+ Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES).path,
+ baseDir,
+ )
+ .toFile()
+ .apply {
+ if (exists().not()) {
+ mkdirs()
+ }
+ }
FileOutputStream(File(screenshotBaseDirectory, filename)).use { outputStream ->
try {
this.compress(Bitmap.CompressFormat.JPEG, 50, outputStream)
@@ -107,8 +107,9 @@ class CaptureScreenshotOnFailedTestRule(private val testTag: String) : TestWatch
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
}
- private fun createBaseScreenshotContentValues() = ContentValues().apply {
- put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
- put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
- }
+ private fun createBaseScreenshotContentValues() =
+ ContentValues().apply {
+ put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
+ put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
+ }
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
index 8f72fef0be..488162b08c 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/ConnectionTest.kt
@@ -12,13 +12,9 @@ import org.junit.Test
class ConnectionTest : EndToEndTest() {
- @Rule
- @JvmField
- val cleanupAccountTestRule = CleanupAccountTestRule()
+ @Rule @JvmField val cleanupAccountTestRule = CleanupAccountTestRule()
- @Rule
- @JvmField
- val forgetAllVpnAppsInSettingsTestRule = ForgetAllVpnAppsInSettingsTestRule()
+ @Rule @JvmField val forgetAllVpnAppsInSettingsTestRule = ForgetAllVpnAppsInSettingsTestRule()
@Test
fun testConnectAndVerifyWithConnectionCheck() {
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
index f8f5bb8f6c..3514405dd9 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/EndToEndTest.kt
@@ -19,16 +19,15 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
abstract class EndToEndTest {
- @Rule
- @JvmField
- val rule = CaptureScreenshotOnFailedTestRule(LOG_TAG)
+ @Rule @JvmField val rule = CaptureScreenshotOnFailedTestRule(LOG_TAG)
@Rule
@JvmField
- val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Manifest.permission.READ_EXTERNAL_STORAGE
- )
+ val permissionRule: GrantPermissionRule =
+ GrantPermissionRule.grant(
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.READ_EXTERNAL_STORAGE
+ )
lateinit var device: UiDevice
lateinit var targetContext: Context
@@ -41,14 +40,13 @@ abstract class EndToEndTest {
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
targetContext = InstrumentationRegistry.getInstrumentation().targetContext
- validTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
- invalidTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(INVALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
+ validTestAccountToken =
+ InstrumentationRegistry.getArguments()
+ .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
+ invalidTestAccountToken =
+ InstrumentationRegistry.getArguments()
+ .getRequiredArgument(INVALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
- app = AppInteractor(
- device,
- targetContext
- )
+ app = AppInteractor(device, targetContext)
}
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt
index 9cec30d872..646af7a18e 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/LoginTest.kt
@@ -15,9 +15,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class LoginTest : EndToEndTest() {
- @Rule
- @JvmField
- val cleanupAccountTestRule = CleanupAccountTestRule()
+ @Rule @JvmField val cleanupAccountTestRule = CleanupAccountTestRule()
@Test
fun testLoginWithInvalidCredentials() {
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/interactor/SystemSettingsInteractor.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/interactor/SystemSettingsInteractor.kt
index 9e5f0aa665..bcf4adcc9e 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/interactor/SystemSettingsInteractor.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/interactor/SystemSettingsInteractor.kt
@@ -7,18 +7,15 @@ import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import net.mullvad.mullvadvpn.test.common.extension.findObjectByCaseInsensitiveText
-class SystemSettingsInteractor(
- private val uiDevice: UiDevice,
- private val context: Context
-) {
+class SystemSettingsInteractor(private val uiDevice: UiDevice, private val context: Context) {
fun openVpnSettings() {
- val intent = Intent("com.intent.MAIN").apply {
- addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- intent.component = ComponentName.unflattenFromString(
- "com.android.settings/.Settings\$VpnSettingsActivity"
- )
+ val intent =
+ Intent("com.intent.MAIN").apply {
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ intent.component =
+ ComponentName.unflattenFromString("com.android.settings/.Settings\$VpnSettingsActivity")
context.startActivity(intent)
Thread.sleep(1000)
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/CleanupAccountTestRule.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/CleanupAccountTestRule.kt
index 2b69436f6d..2e19cb42fe 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/CleanupAccountTestRule.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/CleanupAccountTestRule.kt
@@ -13,8 +13,9 @@ class CleanupAccountTestRule : TestWatcher() {
override fun starting(description: Description) {
Log.d(LOG_TAG, "Cleaning up account before test: ${description.methodName}")
val targetContext = InstrumentationRegistry.getInstrumentation().targetContext
- val validTestAccountToken = InstrumentationRegistry.getArguments()
- .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
+ val validTestAccountToken =
+ InstrumentationRegistry.getArguments()
+ .getRequiredArgument(VALID_TEST_ACCOUNT_TOKEN_ARGUMENT_KEY)
MullvadAccountInteractor(SimpleMullvadHttpClient(targetContext), validTestAccountToken)
.cleanupAccount()
}
diff --git a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ConnCheckState.kt b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ConnCheckState.kt
index 744e80124e..75004270a4 100644
--- a/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ConnCheckState.kt
+++ b/android/test/e2e/src/main/kotlin/net/mullvad/mullvadvpn/test/e2e/misc/ConnCheckState.kt
@@ -1,6 +1,3 @@
package net.mullvad.mullvadvpn.test.e2e.misc
-data class ConnCheckState(
- val isConnected: Boolean,
- val ipAddress: String
-)
+data class ConnCheckState(val isConnected: Boolean, val ipAddress: String)
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 bc56737b04..b97fb28f45 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
@@ -23,17 +23,13 @@ class SimpleMullvadHttpClient(context: Context) {
Log.v(LOG_TAG, "Remove all devices")
val token = login(accountToken)
val devices = getDeviceList(token)
- devices.forEach {
- removeDevice(token, it)
- }
+ devices.forEach { removeDevice(token, it) }
Log.v(LOG_TAG, "All devices removed")
}
fun login(accountToken: String): String {
Log.v(LOG_TAG, "Attempt login with account token: $accountToken")
- val json = JSONObject().apply {
- put("account_number", accountToken)
- }
+ val json = JSONObject().apply { put("account_number", accountToken) }
return sendSimpleSynchronousRequest(Request.Method.POST, AUTH_URL, json)!!.let { response ->
response.getString("access_token").also { accessToken ->
Log.v(LOG_TAG, "Successfully logged in and received access token: $accessToken")
@@ -44,21 +40,20 @@ class SimpleMullvadHttpClient(context: Context) {
fun getDeviceList(accessToken: String): List<String> {
Log.v(LOG_TAG, "Get devices")
- val response = sendSimpleSynchronousRequestArray(
- Request.Method.GET,
- DEVICE_LIST_URL,
- token = accessToken
- )
+ val response =
+ sendSimpleSynchronousRequestArray(
+ Request.Method.GET,
+ DEVICE_LIST_URL,
+ token = accessToken
+ )
- return response!!.iterator<JSONObject>().asSequence().toList()
+ return response!!
+ .iterator<JSONObject>()
+ .asSequence()
+ .toList()
.also {
- it
- .map { jsonObject ->
- jsonObject.getString("name")
- }
- .also { deviceNames ->
- Log.v(LOG_TAG, "Devices received: $deviceNames")
- }
+ it.map { jsonObject -> jsonObject.getString("name") }
+ .also { deviceNames -> Log.v(LOG_TAG, "Devices received: $deviceNames") }
}
.map { it.getString("id") }
.toList()
@@ -74,13 +69,8 @@ class SimpleMullvadHttpClient(context: Context) {
}
fun runConnectionCheck(): ConnCheckState? {
- return sendSimpleSynchronousRequestString(
- Request.Method.GET,
- CONN_CHECK_URL
- )
- ?.let { respose ->
- JSONObject(respose)
- }
+ return sendSimpleSynchronousRequestString(Request.Method.GET, CONN_CHECK_URL)
+ ?.let { respose -> JSONObject(respose) }
?.let { json ->
ConnCheckState(
isConnected = json.getBoolean("mullvad_exit_ip"),
@@ -96,24 +86,19 @@ class SimpleMullvadHttpClient(context: Context) {
token: String? = null
): JSONObject? {
val future = RequestFuture.newFuture<JSONObject>()
- val request = object : JsonObjectRequest(
- method,
- url,
- body,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- if (body != null) {
- headers.put("Content-Type", "application/json")
- }
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
+ val request =
+ object : JsonObjectRequest(method, url, body, future, future) {
+ override fun getHeaders(): MutableMap<String, String> {
+ val headers = HashMap<String, String>()
+ if (body != null) {
+ headers.put("Content-Type", "application/json")
+ }
+ if (token != null) {
+ headers.put("Authorization", "Bearer $token")
+ }
+ return headers
}
- return headers
}
- }
queue.add(request)
return try {
future.get().also { response ->
@@ -132,28 +117,22 @@ class SimpleMullvadHttpClient(context: Context) {
token: String? = null
): String? {
val future = RequestFuture.newFuture<String>()
- val request = object : StringRequest(
- method,
- url,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- if (body != null) {
- headers.put("Content-Type", "application/json")
- }
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
+ val request =
+ object : StringRequest(method, url, future, future) {
+ override fun getHeaders(): MutableMap<String, String> {
+ val headers = HashMap<String, String>()
+ if (body != null) {
+ headers.put("Content-Type", "application/json")
+ }
+ if (token != null) {
+ headers.put("Authorization", "Bearer $token")
+ }
+ return headers
}
- return headers
}
- }
queue.add(request)
return try {
- future.get().also { response ->
- Log.v(LOG_TAG, "String request response: $response")
- }
+ future.get().also { response -> Log.v(LOG_TAG, "String request response: $response") }
} catch (e: Exception) {
Log.v(LOG_TAG, "String request error: ${e.message}")
throw TestEventException(REQUEST_ERROR_MESSAGE)
@@ -167,22 +146,17 @@ class SimpleMullvadHttpClient(context: Context) {
token: String? = null
): JSONArray? {
val future = RequestFuture.newFuture<JSONArray>()
- val request = object : JsonArrayRequest(
- method,
- url,
- null,
- future,
- future
- ) {
- override fun getHeaders(): MutableMap<String, String> {
- val headers = HashMap<String, String>()
- headers.put("Content-Type", "application/json")
- if (token != null) {
- headers.put("Authorization", "Bearer $token")
+ val request =
+ object : JsonArrayRequest(method, url, null, future, future) {
+ override fun getHeaders(): MutableMap<String, String> {
+ val headers = HashMap<String, String>()
+ headers.put("Content-Type", "application/json")
+ if (token != null) {
+ headers.put("Authorization", "Bearer $token")
+ }
+ return headers
}
- return headers
}
- }
queue.add(request)
return try {
future.get().also { response ->
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 e3708a47f1..06f7164034 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
@@ -29,8 +29,10 @@ class MockApiDispatcher : Dispatcher() {
AUTH_TOKEN_URL_PATH -> handleLoginRequest(request.body)
DEVICES_URL_PATH -> {
when (request.method) {
- "get", "GET" -> handleDeviceListRequest()
- "post", "POST" -> handleDeviceCreationRequest(request.body)
+ "get",
+ "GET" -> handleDeviceListRequest()
+ "post",
+ "POST" -> handleDeviceCreationRequest(request.body)
else -> MockResponse().setResponseCode(404)
}
}
@@ -51,9 +53,10 @@ class MockApiDispatcher : Dispatcher() {
.addJsonHeader()
.setBody(
accessTokenJsonResponse(
- accessToken = DUMMY_ACCESS_TOKEN,
- expiry = currentUtcTimeWithOffsetZero().plusDays(1)
- ).toString()
+ accessToken = DUMMY_ACCESS_TOKEN,
+ expiry = currentUtcTimeWithOffsetZero().plusDays(1)
+ )
+ .toString()
)
} else {
Log.e(
@@ -69,13 +72,9 @@ class MockApiDispatcher : Dispatcher() {
MockResponse()
.setResponseCode(200)
.addJsonHeader()
- .setBody(
- accountInfoJson(
- id = DUMMY_ID,
- expiry = expiry
- ).toString()
- )
- } ?: MockResponse().setResponseCode(400)
+ .setBody(accountInfoJson(id = DUMMY_ID, expiry = expiry).toString())
+ }
+ ?: MockResponse().setResponseCode(400)
}
private fun handleDeviceInfoRequest(): MockResponse {
@@ -85,33 +84,36 @@ class MockApiDispatcher : Dispatcher() {
.addJsonHeader()
.setBody(
deviceJson(
- id = DUMMY_ID,
- name = DUMMY_DEVICE_NAME,
- publicKey = cachedKey,
- creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
- ).toString()
+ id = DUMMY_ID,
+ name = DUMMY_DEVICE_NAME,
+ publicKey = cachedKey,
+ creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
+ )
+ .toString()
)
- } ?: MockResponse().setResponseCode(400)
+ }
+ ?: MockResponse().setResponseCode(400)
}
private fun handleDeviceCreationRequest(body: Buffer): MockResponse {
- return body.getPubKey()
- .also { newKey ->
- cachedPubKeyFromAppUnderTest = newKey
- }
+ return body
+ .getPubKey()
+ .also { newKey -> cachedPubKeyFromAppUnderTest = newKey }
?.let { newKey ->
MockResponse()
.setResponseCode(201)
.addJsonHeader()
.setBody(
deviceJson(
- id = DUMMY_ID,
- name = DUMMY_DEVICE_NAME,
- publicKey = newKey,
- creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
- ).toString()
+ id = DUMMY_ID,
+ name = DUMMY_DEVICE_NAME,
+ publicKey = newKey,
+ creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
+ )
+ .toString()
)
- } ?: MockResponse().setResponseCode(400)
+ }
+ ?: MockResponse().setResponseCode(400)
}
private fun handleDeviceListRequest(): MockResponse {
@@ -120,15 +122,18 @@ class MockApiDispatcher : Dispatcher() {
.setResponseCode(200)
.addJsonHeader()
.setBody(
- JSONArray().put(
- deviceJson(
- id = DUMMY_ID,
- name = DUMMY_DEVICE_NAME,
- publicKey = cachedKey,
- creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
+ JSONArray()
+ .put(
+ deviceJson(
+ id = DUMMY_ID,
+ name = DUMMY_DEVICE_NAME,
+ publicKey = cachedKey,
+ creationDate = currentUtcTimeWithOffsetZero().minusDays(1)
+ )
)
- ).toString()
+ .toString()
)
- } ?: MockResponse().setResponseCode(400)
+ }
+ ?: MockResponse().setResponseCode(400)
}
}
diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt
index ba5ba01810..bb5c20eebb 100644
--- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt
+++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt
@@ -24,21 +24,15 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
abstract class MockApiTest {
- @Rule
- @JvmField
- val rule = CaptureScreenshotOnFailedTestRule(LOG_TAG)
+ @Rule @JvmField val rule = CaptureScreenshotOnFailedTestRule(LOG_TAG)
@Rule
@JvmField
- val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(
- WRITE_EXTERNAL_STORAGE,
- READ_EXTERNAL_STORAGE
- )
+ val permissionRule: GrantPermissionRule =
+ GrantPermissionRule.grant(WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE)
protected val apiDispatcher = MockApiDispatcher()
- private val mockWebServer = MockWebServer().apply {
- dispatcher = apiDispatcher
- }
+ private val mockWebServer = MockWebServer().apply { dispatcher = apiDispatcher }
lateinit var device: UiDevice
lateinit var targetContext: Context
@@ -50,10 +44,7 @@ abstract class MockApiTest {
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
targetContext = InstrumentationRegistry.getInstrumentation().targetContext
- app = AppInteractor(
- device,
- targetContext
- )
+ app = AppInteractor(device, targetContext)
mockWebServer.start()
Log.d(LOG_TAG, "Mocked web server started using port: ${mockWebServer.port}")
@@ -66,16 +57,14 @@ abstract class MockApiTest {
}
private fun createEndpoint(port: Int): CustomApiEndpointConfiguration {
- val mockApiSocket = InetSocketAddress(
- InetAddress.getLocalHost(),
- port
- )
- val api = ApiEndpoint(
- address = mockApiSocket,
- disableAddressCache = true,
- disableTls = true,
- forceDirectConnection = true
- )
+ val mockApiSocket = InetSocketAddress(InetAddress.getLocalHost(), port)
+ val api =
+ ApiEndpoint(
+ address = mockApiSocket,
+ disableAddressCache = true,
+ disableTls = true,
+ forceDirectConnection = true
+ )
return CustomApiEndpointConfiguration(api)
}
}
diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt
index 145cbafbd2..b76c4d4278 100644
--- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt
+++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt
@@ -5,38 +5,30 @@ import org.joda.time.DateTime
import org.json.JSONArray
import org.json.JSONObject
-fun accountInfoJson(
- id: String,
- expiry: DateTime
-) = JSONObject().apply {
- put("id", id)
- put("expiry", expiry.formatStrictlyAccordingToIso8601AndRfc3339())
- put("max_ports", 5)
- put("can_add_ports", true)
- put("max_devices", 5)
- put("can_add_devices", true)
-}
+fun accountInfoJson(id: String, expiry: DateTime) =
+ JSONObject().apply {
+ put("id", id)
+ put("expiry", expiry.formatStrictlyAccordingToIso8601AndRfc3339())
+ put("max_ports", 5)
+ put("can_add_ports", true)
+ put("max_devices", 5)
+ put("can_add_devices", true)
+ }
-fun deviceJson(
- id: String,
- name: String,
- publicKey: String,
- creationDate: DateTime
-) = JSONObject().apply {
- put("id", id)
- put("name", name)
- put("pubkey", publicKey)
- put("hijack_dns", true)
- put("created", creationDate.formatStrictlyAccordingToIso8601AndRfc3339())
- put("ipv4_address", "127.0.0.1/32")
- put("ipv6_address", "fc00::1/128")
- put("ports", JSONArray())
-}
+fun deviceJson(id: String, name: String, publicKey: String, creationDate: DateTime) =
+ JSONObject().apply {
+ put("id", id)
+ put("name", name)
+ put("pubkey", publicKey)
+ put("hijack_dns", true)
+ put("created", creationDate.formatStrictlyAccordingToIso8601AndRfc3339())
+ put("ipv4_address", "127.0.0.1/32")
+ put("ipv6_address", "fc00::1/128")
+ put("ports", JSONArray())
+ }
-fun accessTokenJsonResponse(
- accessToken: String,
- expiry: DateTime
-) = JSONObject().apply {
- put("access_token", accessToken)
- put("expiry", expiry.formatStrictlyAccordingToIso8601AndRfc3339())
-}
+fun accessTokenJsonResponse(accessToken: String, expiry: DateTime) =
+ JSONObject().apply {
+ put("access_token", accessToken)
+ put("expiry", expiry.formatStrictlyAccordingToIso8601AndRfc3339())
+ }