From e85dfda01853d51a37b2dbee53026fdfa1696a77 Mon Sep 17 00:00:00 2001
From: Fabian-K <fabian.kajzar@sap.com>
Date: Thu, 2 Jul 2020 15:46:36 +0200
Subject: [PATCH] Background Priority Service (#800)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: Ic0905f66e03544c549ee6bf0edde3707c528215c

* Translation branch update (#127)

* Implement submission done fragment (#20)

* Added submission done fragment (currently dangling in nav graph)

* fixed leftover javadoc

* Moved QR code scan and registration fragment to submission package (#21)

* Dependency Updates and Gradle Fixes (#34)

* Bump up Gradle to 4.0.0 / 6.1.1

* Bump up NDK

* Bump Up SQLite

* adapt circle config

* Fix #23: Typo in onboarding screen (#31)

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Submission UI Additions (#25)

* Moved camera permission check to dispatcher fragment

* Added illustrations for test result screen

* Updated result fragment to match new design

* Added constraints to status card

* Integrated submission result positive other warning fragment in ui flow

* Added submission done fragment to nav graph

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added ability to dialog helper to create dialog without negative button

* Switched from AlertDialog.Builder to DIalogHelper

* Enable diagnosis key upload to backend (#35)

* Moved camera permission check to dispatcher fragment

* Added illustrations for test result screen

* Updated result fragment to match new design

* Added constraints to status card

* Integrated submission result positive other warning fragment in ui flow

* add TAN fetching to the key submission transaction

* remove unneeded function

* Fix log message for fetching TAN

* Added submission done fragment to nav graph

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added ability to dialog helper to create dialog without negative button

* Switched from AlertDialog.Builder to DIalogHelper

* use actual TAN (authCode) for key submission

set the TAN in the corresponding header field
fixes #8

* request permission to retrieve diagnosis keys

* permission needs to be requested again after dialog has been presented to the users
* trigger transaction to retrieve TAN and upload keys

Co-authored-by: Kolya Opahle <k.opahle@sap.com>

* Removed ExposureNotificationIntentService, the functionality is handled by NotificationHelper (#40)

* Fixing tele tan registration (#45)

* Fixed teleTAN based device registration

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* allowed excluded tan chars for testing

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Revert "allowed excluded tan chars for testing"

This reverts commit 253ede4ea9c8ba2b5e6dd324680eed0f8f7e74c1.

* Release/0.5.5 (#48)

* Release/0.5.5

* Hotfix for resetting Gradle Version (internal pipeline confirmation) (#52)

* Gradle Reset to 0.5.4 (#53)

* Release/0.5.5 (#48)

* Hotfix for resetting Gradle Version (internal pipeline confirmation) (#52)

* Minify and Shrink Disabled (#56)

* Release/0.5.5

* Gradle Reset to 0.5.4 (#53)

* Release/0.5.5 (#48)

* Hotfix for resetting Gradle Version (internal pipeline confirmation) (#52)

* Disable minify / shrink

* Dont obfuscate

* 0.5.6

* Update known issues and fixing typo in readme (#44)

* added strings wip to known issues

* updated readme

Co-authored-by: Muschko <marc.muschko@sap.com>

* Updated strings, introduced more details on app-information screens (#88)

* updated strings for risk card and risk card details; plural strings are todo when finalized

* updated more strings on main / details

* added comments

* added strings for information about, information technical hotline; changed technical hotline layout

* removed hotline test icon

* fixed build issues

* Cleanup pull_request_template.md (#54)

* Update pull_request_template.md

* Removed Link to Contribution Guidelines (added by Github on the right hand side, anyhow)
* Removed Link to issue #41 from title example (this has been linked quite a lot...)

* 0.5.6

* Fix typo

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: marcmuschko <marc.muschko@sap.com>

* Add Support for lower case characters in the teleTAN screen (#66)

* added support for lower case input in teleTan fragment

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Removed notice of case insensitivity from temporary strings.xml

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>

* Correct typos in architecture overview (#67)

Co-authored-by: marcmuschko <marc.muschko@sap.com>

* Bluetooth & connection card (#97)

* introduced settings navigation helper

* added connection and bluetooth stati to main and tracing settings

* moved strings

* removed unnecessary backgroundTint

Co-authored-by: marcmuschko <marc.muschko@sap.com>

* Fix typo in class documentation (#71)

* 0.5.6

* fix typo

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: marcmuschko <marc.muschko@sap.com>

* spelling fixes (#87)

* 0.5.6

* spelling fixes

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: klemens <ka7@github.com>
Co-authored-by: marcmuschko <marc.muschko@sap.com>

* Moves creation of notification channel to app startup (#32)

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Tracing start/stop fix due to missing handling inside tracing (#99)

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Switch the DB Password to use the KeyStore MasterKey (#98)

Signed-off-by: d067928 <jakob.moeller@sap.com>

* Shared prefs ktx shorthand (#38)

* closes #33

* Add Commit Flag to ensure synchronous consistent Updates to Disk

Signed-off-by: d067928 <jakob.moeller@sap.com>

* Add persistance of timestamp and whether user is allowed to submit keys (#74)

* Store timestamp of receiving registration token

* also reset this timestamp when deleting the registration token

* use correct timestamp for display of test time

* replace tracing activation time by test result reception time

* rename TAN request to match context

* set isAllowedToSubmitDiagnosisKeys properly

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* set "enabled" for include_settings_switch_row in notifications settings, fixes wrong binding and removed clickable rows (#101)

Co-authored-by: marcmuschko <marc.muschko@sap.com>

* fix #82 (#94)

* fix #82

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Add ShareHelper (#85)

* Add ShareHelper

* Use ShareHelper in MainShareFragment

* Replace the current exposure status with a positive result card when test result is positive (#79)

* Made submission status card style more cross device friendly

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added the positive result submission status card

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* lint fix

* Updated main fragment documentation

* Added icon for sharing risk status

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Updated positive result home screen card text and icons

Signed-off-by: Kolya Opahle <k.opahle@sap.com>

* Added loading indicator to test result fragment (#100)

Co-authored-by: marcmuschko <marc.muschko@sap.com>
Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>

* Adjusted onboarding flow, adjusted contribution file, small fixes in settings (#106)

* changed permission dialog logic for onboarding tracing fragment and onboarding notification fragment

* adjusted contributing file

* added settings notification handling to display value in settings overview

* fixed app crash during bluetooth settings navigation

* corrected wrong value from view model in tracing settings text

* Submission Contact Fragment & StepView Custom View (#102)

* - submission-contact fragment added
- StepEntry custom view added to unify various step entry views
- SimpleStepEntry as a simple implementation of a StepEntry with title and text added

* - apply naming conventions for ids
- use CallHelper to trigger a call
- access views using kotlinx.android.synthetic

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>

* Notifications when risk value has changed between low and high. (#76)

* Notifications when risk value has changed between low and high.

* Notifications when risk value has changed between low and high.
Fixed wildcard imports.

* Fixed formatting, ktlint issue.

* app foreground/background checking. Notifications are not sent when app is in background

* update comments

* initialize foreground flag as false(valid for background threads before ui starts)

* comments

* included UNDERTERMINED as a low, for initialisation

* fixed icon

* fixed tests

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* added onboarding strings (#109)

* disable colored output for ktlint (#105)

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Limit number of keys to be uploaded to server (#107)

* limit the number of keys to be uploaded to 14

* fix spaces

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>

* Fix white space, informal language and spelling of Docker in Readme (#78)

* 0.5.6

* Fix spelling gonna and docker

* Add missing "to"

Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: marcmuschko <marc.muschko@sap.com>

* Update build.gradle (#111)

* Build.Gradle Conflict Resolving (0.8.0) (#112)

* Minify and proguard fix (#113)

Commented out -dontobfuscate

* Circle progress bar (#96)

* circle progress bar impl

* ktlint format

* added new ui

* added circle to contact tracing without binding

* added binding and final icon

* added circle progress to risk card

* added comments

* changed default value for disableText

* adapted views order to designs

* removed testing value

Co-authored-by: Kirill <kirill.sergeev@sap.com>

* TracingStatusHelper unit test (#114)

* TracingStatusHelper unit test

* removed duplicate

* Prevent screenshot of the app for all activities (#108)

* Prevent screenshot of the app for all activities

* fix ktlint

* code smell fix

Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>

* Feature: Bluetooth callback (#115)

* bluetooth callback added

* bound bluetooth callback to the ui

Co-authored-by: Kirill <kirill.sergeev@sap.com>

* Added main overview page to main menu (#120)

* added overview fragment baseline

* main overview draft version completed with build fixes

* checked some final strings again

* Fixed screen orientation to portrait (#121)

* added restriction to portrait and reversed portrait orientation only

* suppress SourceLockedOrientationActivity lint error

* changed local config that a high match can be generated via QR code, integrated it with the UI (#125)

* Feature: Translation preparation (#126)

* renamed old strings and reordered

* app information strings translation tags

* updated translation tags for long texts

* added translation comments to strings

* fixed naming error

* removed empty comment

Co-authored-by: Muschko <marc.muschko@sap.com>

Co-authored-by: Kolya Opahle <k.opahle@sap.com>
Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: Michael Keppler <bananeweizen@gmx.de>
Co-authored-by: Thomas Klingbeil <64434904+tklingbeil@users.noreply.github.com>
Co-authored-by: Hee Tatt Ooi <64406309+HeeTattSap@users.noreply.github.com>
Co-authored-by: Muschko <marc.muschko@sap.com>
Co-authored-by: Thomas Kowark <thomas.kowark@sap.com>
Co-authored-by: Robert Scheck <robert-scheck@users.noreply.github.com>
Co-authored-by: Volkmar Vogel <volkmar@vogel.app>
Co-authored-by: ka7 <ka7@la-evento.com>
Co-authored-by: klemens <ka7@github.com>
Co-authored-by: Tim Brüggenthies <tim.brueggenthies@outlook.de>
Co-authored-by: mseele <mseele@gmail.com>
Co-authored-by: Janik Steegmüller <janik.steegmueller@gmail.com>
Co-authored-by: Fabian-K <fabian.kajzar@sap.com>
Co-authored-by: Hee Tatt Ooi <hee.tatt.ooi@sap.com>
Co-authored-by: Matthias Küch <mail@matthias-kuech.de>
Co-authored-by: oemerb <66002424+oemerb@users.noreply.github.com>
Co-authored-by: AlexanderAlferov <64849422+AlexanderAlferov@users.noreply.github.com>
Co-authored-by: Kirill <kirill.sergeev@sap.com>
Co-authored-by: Philipp Woessner <64482866+pwoessner@users.noreply.github.com>

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: Ic0905f66e03544c549ee6bf0edde3707c528215c

* Remove values-2Q

Signed-off-by: d067928 <jakob.moeller@sap.com>

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: Idf52dece137fdc6e314ed752a8ef6b79b08683b0

* deleted 2Q

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I63afce1d7307c912b034728d8b78d437974f818d

* excluded translation from lint for dev

* fixed quickBuild errors

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I0b2e12f977b0a4bf37716d85e527d8d05168120f

* fixed local issues

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: Ied4c086215e1392cb4ac061c9e82760f4757d5b2

* fixes

* resolved merge conflicts

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I0dbb47c30c1f19b7533e953e349a3145694db366

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: If73a3358a2939902b8df4e491fb7b3beb626f8fc

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I101e87820c63ecb7c40b044ac0bc2e05331b352b

* changed default value for strings

* added https to english faq links

* fixed error during merge

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I8b27c238c3387741363b0dc353711994217801b6

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I9bc5d20688a11bfd5fd4a481b3c36143d4caba64

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: Ib3f20898335ded0101af92c452c766c329946611

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I9b5bbd9b5b5d44029f694b7afca8f7251b48e86a

* added privacy, technical and terms html file with english content

* include Turkish translation (#792)

I added Turkish to resConfigs for properly including the new translation into the build.

* replaced NOTR tag with XTXT to make "main_about_link" translatable

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I01f4b04ec61a334e0b25815b03e2953e5031e0d9

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I71fcec61630c5d99e009eeb1341fd37bdd0c55e9

* string placeholders required for background priority added (#797)

* additional strings for explanatory card added (#798)

* add turkish privacy & terms

* [INTERNAL] Translation delivery: commit by LX Lab

Change-Id: I3708d2af77b48642eee7a6562cffd935327ed875

* Implementation of "Background Priority Service (1592)"
- new permission REQUEST_IGNORE_BATTERY_OPTIMIZATIONS added
- settings entry to enable background priority

* replaced turkish faq link with the old one

* extract PowerManagementHelper.kt from Repository

* update style for static code analysis...

* ktlint format

Co-authored-by: service-tip-git <tmsatsls@gmail.com>
Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: Kolya Opahle <k.opahle@sap.com>
Co-authored-by: Jakob Möller <jakob.moeller@sap.com>
Co-authored-by: Michael Keppler <bananeweizen@gmx.de>
Co-authored-by: Thomas Klingbeil <64434904+tklingbeil@users.noreply.github.com>
Co-authored-by: Hee Tatt Ooi <64406309+HeeTattSap@users.noreply.github.com>
Co-authored-by: Muschko <marc.muschko@sap.com>
Co-authored-by: Thomas Kowark <thomas.kowark@sap.com>
Co-authored-by: Robert Scheck <robert-scheck@users.noreply.github.com>
Co-authored-by: Volkmar Vogel <volkmar@vogel.app>
Co-authored-by: ka7 <ka7@la-evento.com>
Co-authored-by: klemens <ka7@github.com>
Co-authored-by: Tim Brüggenthies <tim.brueggenthies@outlook.de>
Co-authored-by: mseele <mseele@gmail.com>
Co-authored-by: Janik Steegmüller <janik.steegmueller@gmail.com>
Co-authored-by: Hee Tatt Ooi <hee.tatt.ooi@sap.com>
Co-authored-by: Matthias Küch <mail@matthias-kuech.de>
Co-authored-by: oemerb <66002424+oemerb@users.noreply.github.com>
Co-authored-by: AlexanderAlferov <64849422+AlexanderAlferov@users.noreply.github.com>
Co-authored-by: Kirill <kirill.sergeev@sap.com>
Co-authored-by: Philipp Woessner <64482866+pwoessner@users.noreply.github.com>
Co-authored-by: Luka Harambasic <luka.harambasic@sap.com>
Co-authored-by: Karina Jung <66269900+kaluju@users.noreply.github.com>
Co-authored-by: service-tip-git <tmsatsls+github.com_service-tip-git@sap.com>
Co-authored-by: duchampdev <duchampdev@outlook.com>
---
 .../res/navigation/nav_graph.xml              |   9 ++
 Corona-Warn-App/src/main/AndroidManifest.xml  |   2 +
 .../storage/SettingsRepository.kt             |  10 ++
 .../SettingsBackgroundPriorityFragment.kt     |  84 ++++++++++++++
 .../ui/settings/SettingsFragment.kt           |   7 ++
 .../ui/viewmodel/SettingsViewModel.kt         |   7 ++
 .../util/ExternalActionHelper.kt              |  29 +++++
 .../util/PowerManagementHelper.kt             |  14 +++
 .../util/formatter/FormatterSettingsHelper.kt |  23 ++++
 ..._settings_background_priority_disabled.xml |  12 ++
 ...c_settings_background_priority_enabled.xml |  12 ++
 .../src/main/res/layout/fragment_settings.xml |  18 ++-
 .../fragment_settings_background_priority.xml | 106 ++++++++++++++++++
 .../src/main/res/navigation/nav_graph.xml     |   9 ++
 .../util/ExternalActionHelperTest.kt          |  15 +++
 .../formatter/FormatterSettingsHelperTest.kt  |  50 +++++++++
 16 files changed, 406 insertions(+), 1 deletion(-)
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt
 create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/PowerManagementHelper.kt
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_disabled.xml
 create mode 100644 Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_enabled.xml
 create mode 100644 Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml

diff --git a/Corona-Warn-App/src/deviceForTesters/res/navigation/nav_graph.xml b/Corona-Warn-App/src/deviceForTesters/res/navigation/nav_graph.xml
index 178330347..58d6e0bd7 100644
--- a/Corona-Warn-App/src/deviceForTesters/res/navigation/nav_graph.xml
+++ b/Corona-Warn-App/src/deviceForTesters/res/navigation/nav_graph.xml
@@ -76,6 +76,9 @@
         <action
             android:id="@+id/action_settingsFragment_to_settingsNotificationFragment"
             app:destination="@id/settingsNotificationFragment" />
+        <action
+            android:id="@+id/action_settingsFragment_to_settingsBackgroundPriorityFragment"
+            app:destination="@id/settingsBackgroundPriorityFragment" />
     </fragment>
 
     <fragment
@@ -90,6 +93,12 @@
         android:label="SettingsNotificationFragment"
         tools:layout="@layout/fragment_settings_notifications" />
 
+    <fragment
+        android:id="@+id/settingsBackgroundPriorityFragment"
+        android:name="de.rki.coronawarnapp.ui.settings.SettingsBackgroundPriorityFragment"
+        android:label="SettingsBackgroundPriorityFragment"
+        tools:layout="@layout/fragment_settings_background_priority" />
+
     <fragment
         android:id="@+id/settingsResetFragment"
         android:name="de.rki.coronawarnapp.ui.settings.SettingsResetFragment"
diff --git a/Corona-Warn-App/src/main/AndroidManifest.xml b/Corona-Warn-App/src/main/AndroidManifest.xml
index 7a6b385e4..c0208b74d 100644
--- a/Corona-Warn-App/src/main/AndroidManifest.xml
+++ b/Corona-Warn-App/src/main/AndroidManifest.xml
@@ -18,6 +18,8 @@
         android:name="android.permission.INTERNET"
         android:required="true" />
 
+    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
+
     <application
         android:name="de.rki.coronawarnapp.CoronaWarnApplication"
         android:allowBackup="false"
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
index 77b7402d3..5cf13c062 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SettingsRepository.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import androidx.core.app.NotificationManagerCompat
 import androidx.lifecycle.MutableLiveData
 import de.rki.coronawarnapp.util.ConnectivityHelper
+import de.rki.coronawarnapp.util.PowerManagementHelper
 
 /**
  * The Settings Repository maps all setting states from different sources to MutableLiveData.
@@ -25,6 +26,7 @@ object SettingsRepository {
     val isConnectionEnabled = MutableLiveData(true)
     val isBluetoothEnabled = MutableLiveData(true)
     val isBackgroundJobEnabled = MutableLiveData(true)
+    val isBackgroundPriorityEnabled = MutableLiveData(false)
     val manualKeyRetrievalTime = MutableLiveData<Long>()
 
     /**
@@ -115,4 +117,12 @@ object SettingsRepository {
     fun updateManualKeyRetrievalTime(value: Long) {
         manualKeyRetrievalTime.postValue(value)
     }
+
+    /**
+     * Refresh the current background priority state.
+     */
+    fun refreshBackgroundPriorityEnabled(context: Context) {
+        isBackgroundPriorityEnabled.value =
+            PowerManagementHelper.isIgnoringBatteryOptimizations(context)
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt
new file mode 100644
index 000000000..b5d465e9f
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsBackgroundPriorityFragment.kt
@@ -0,0 +1,84 @@
+package de.rki.coronawarnapp.ui.settings
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.accessibility.AccessibilityEvent
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import de.rki.coronawarnapp.databinding.FragmentSettingsBackgroundPriorityBinding
+import de.rki.coronawarnapp.ui.main.MainActivity
+import de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel
+import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel
+import de.rki.coronawarnapp.util.ExternalActionHelper
+
+/**
+ * This is the setting background priority page. Here the user sees the background priority setting status.
+ * If background priority is disabled it can be activated.
+ *
+ * @see TracingViewModel
+ * @see SettingsViewModel
+ */
+class SettingsBackgroundPriorityFragment : Fragment() {
+    companion object {
+        private val TAG: String? = SettingsBackgroundPriorityFragment::class.simpleName
+    }
+
+    private val settingsViewModel: SettingsViewModel by activityViewModels()
+    private var _binding: FragmentSettingsBackgroundPriorityBinding? = null
+    private val binding: FragmentSettingsBackgroundPriorityBinding get() = _binding!!
+
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        _binding = FragmentSettingsBackgroundPriorityBinding.inflate(inflater)
+        binding.settingsViewModel = settingsViewModel
+        binding.lifecycleOwner = this
+        return binding.root
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+        setButtonOnClickListener()
+    }
+
+    override fun onResume() {
+        super.onResume()
+        binding.settingsBackgroundPriorityContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
+        // refresh required data
+        settingsViewModel.refreshBackgroundPriorityEnabled(requireContext())
+    }
+
+    private fun setButtonOnClickListener() {
+        val switch = binding.settingsSwitchRowBackgroundPriority.settingsSwitchRowSwitch
+        val switchRow = binding.settingsSwitchRowBackgroundPriority.settingsSwitchRow
+
+        // enable background priority
+        setOf(switch, switchRow).forEach {
+            it.setOnClickListener {
+                val isPriorityEnabled = settingsViewModel.isBackgroundPriorityEnabled.value == true
+
+                if (!isPriorityEnabled)
+                    ExternalActionHelper.disableBatteryOptimizations(requireContext())
+            }
+        }
+
+        // explanatory card
+        binding.settingsTracingStatusConnection.tracingStatusCardButton.setOnClickListener {
+            ExternalActionHelper.toBatteryOptimizationSettings(requireContext())
+        }
+
+        // back navigation
+        binding.settingsBackgroundPriorityHeader.headerButtonBack.buttonIcon.setOnClickListener {
+            (activity as MainActivity).goBack()
+        }
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt
index 3c7e49013..258db57c5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsFragment.kt
@@ -60,6 +60,7 @@ class SettingsFragment : Fragment() {
         settingsViewModel.refreshNotificationsEnabled(requireContext())
         settingsViewModel.refreshNotificationsRiskEnabled()
         settingsViewModel.refreshNotificationsTestEnabled()
+        settingsViewModel.refreshBackgroundPriorityEnabled(requireContext())
 
         binding.settingsContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
     }
@@ -67,6 +68,7 @@ class SettingsFragment : Fragment() {
     private fun setButtonOnClickListener() {
         val tracingRow = binding.settingsTracing.settingsRow
         val notificationRow = binding.settingsNotifications.settingsRow
+        val backgroundPriorityRow = binding.settingsBackgroundPriority.settingsRow
         val resetRow = binding.settingsReset
         val goBack = binding.settingsHeader.headerButtonBack.buttonIcon
         resetRow.setOnClickListener {
@@ -84,6 +86,11 @@ class SettingsFragment : Fragment() {
                 SettingsFragmentDirections.actionSettingsFragmentToSettingsNotificationFragment()
             )
         }
+        backgroundPriorityRow.setOnClickListener {
+            findNavController().doNavigate(
+                SettingsFragmentDirections.actionSettingsFragmentToSettingsBackgroundPriorityFragment()
+            )
+        }
         goBack.setOnClickListener {
             (activity as MainActivity).goBack()
         }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
index 179afc711..c3e32a21d 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SettingsViewModel.kt
@@ -25,6 +25,9 @@ class SettingsViewModel : ViewModel() {
     // Will impact UI if background activity is not permitted, persistent storing is not necessary
     val isBackgroundJobEnabled: LiveData<Boolean> = SettingsRepository.isBackgroundJobEnabled
 
+    val isBackgroundPriorityEnabled: LiveData<Boolean> =
+        SettingsRepository.isBackgroundPriorityEnabled
+
     /**
      * Is manual key retrieval enabled
      * Used for "Update" button on the Risk Card and in the Risk Details
@@ -114,4 +117,8 @@ class SettingsViewModel : ViewModel() {
     fun updateManualKeyRetrievalEnabled(value: Boolean) {
         SettingsRepository.updateManualKeyRetrievalEnabled(value)
     }
+
+    fun refreshBackgroundPriorityEnabled(context: Context) {
+        SettingsRepository.refreshBackgroundPriorityEnabled(context)
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ExternalActionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ExternalActionHelper.kt
index e200dadb0..7afb041b8 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ExternalActionHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ExternalActionHelper.kt
@@ -155,4 +155,33 @@ object ExternalActionHelper {
             )
         }
     }
+
+    fun disableBatteryOptimizations(context: Context) {
+        try {
+            val intent = Intent(
+                Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
+                Uri.parse("package:" + context.packageName)
+            )
+            context.startActivity(intent)
+        } catch (exception: Exception) {
+            // catch generic exception on settings navigation
+            // most likely due to device / rom specific intent issue
+            ExternalActionException(exception).report(
+                ExceptionCategory.UI
+            )
+        }
+    }
+
+    fun toBatteryOptimizationSettings(context: Context) {
+        try {
+            val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
+            context.startActivity(intent)
+        } catch (exception: Exception) {
+            // catch generic exception on settings navigation
+            // most likely due to device / rom specific intent issue
+            ExternalActionException(exception).report(
+                ExceptionCategory.UI
+            )
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/PowerManagementHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/PowerManagementHelper.kt
new file mode 100644
index 000000000..a7c142914
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/PowerManagementHelper.kt
@@ -0,0 +1,14 @@
+package de.rki.coronawarnapp.util
+
+import android.content.Context
+import android.os.PowerManager
+
+object PowerManagementHelper {
+    /**
+     * Checks if app is excluded from battery optimizations
+     */
+    fun isIgnoringBatteryOptimizations(context: Context): Boolean {
+        val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+        return powerManager.isIgnoringBatteryOptimizations(context.packageName)
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelper.kt
index 038e11a18..d1decae43 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelper.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelper.kt
@@ -267,6 +267,29 @@ fun formatSettingsTracingIcon(
     }
 }
 
+/**
+ * Formats the settings icon for background priority
+ */
+fun formatSettingsBackgroundPriorityIcon(
+    enabled: Boolean
+): Drawable? = formatDrawable(
+    enabled,
+    R.drawable.ic_settings_background_priority_enabled,
+    R.drawable.ic_settings_background_priority_disabled
+)
+
+/**
+ * Formats the settings icon color for background priority
+ */
+fun formatSettingsBackgroundPriorityIconColor(
+    enabled: Boolean
+): Int =
+    formatColor(
+        enabled,
+        R.color.colorAccentTintIcon,
+        R.color.colorTextSemanticRed
+    )
+
 /**
  * Formats the tracing switch status based on the tracing status
  *
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_disabled.xml b/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_disabled.xml
new file mode 100644
index 000000000..6107eb6fd
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_disabled.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="40dp"
+    android:height="40dp"
+    android:viewportWidth="40"
+    android:viewportHeight="40">
+  <path
+      android:pathData="M17.44,25.7C18.59,26.51 19.99,27 21.5,27C22.9375,27 24.2729,26.5681 25.3838,25.8269L26.8184,27.2609C25.3284,28.3542 23.4895,29 21.5,29C19.44,29 17.54,28.3 16.02,27.14L16.02,27.14ZM13.943,11.398L14.0095,11.4567L29.3036,26.7509C29.5792,27.0265 29.5792,27.4735 29.3036,27.7491C29.0491,28.0036 28.6487,28.0232 28.3718,27.8079L28.3053,27.7491L13.0112,12.455C12.7355,12.1794 12.7355,11.7324 13.0112,11.4567C13.2657,11.2023 13.666,11.1827 13.943,11.398ZM21.5,11C26.47,11 30.5,15.03 30.5,20C30.5,21.9619 29.872,23.7773 28.8062,25.2561L27.3697,23.8189C28.0847,22.7211 28.5,21.4097 28.5,20C28.5,16.13 25.37,13 21.5,13C20.0903,13 18.7789,13.4153 17.6811,14.1303L16.2439,12.6938C17.7227,11.628 19.5381,11 21.5,11ZM14.2391,14.6816L15.6731,16.1162C14.9319,17.2271 14.5,18.5625 14.5,20L14.5,20L17.5,20L13.5,24L9.5,20L12.5,20C12.5,18.0105 13.1458,16.1716 14.2391,14.6816Z"
+      android:strokeWidth="1"
+      android:fillColor="#C00F2D"
+      android:fillType="nonZero"
+      android:strokeColor="#00000000"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_enabled.xml b/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_enabled.xml
new file mode 100644
index 000000000..ef4ebe1ae
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/drawable/ic_settings_background_priority_enabled.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="40dp"
+    android:height="40dp"
+    android:viewportWidth="40"
+    android:viewportHeight="40">
+  <path
+      android:pathData="M23.5,20C23.5,18.9 22.6,18 21.5,18C20.4,18 19.5,18.9 19.5,20C19.5,21.1 20.4,22 21.5,22C22.6,22 23.5,21.1 23.5,20ZM21.5,11C16.53,11 12.5,15.03 12.5,20L9.5,20L13.5,24L17.5,20L14.5,20C14.5,16.13 17.63,13 21.5,13C25.37,13 28.5,16.13 28.5,20C28.5,23.87 25.37,27 21.5,27C19.99,27 18.59,26.51 17.44,25.7L16.02,27.14C17.54,28.3 19.44,29 21.5,29C26.47,29 30.5,24.97 30.5,20C30.5,15.03 26.47,11 21.5,11Z"
+      android:strokeWidth="1"
+      android:fillColor="#007FAD"
+      android:fillType="nonZero"
+      android:strokeColor="#00000000"/>
+</vector>
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_settings.xml b/Corona-Warn-App/src/main/res/layout/fragment_settings.xml
index 49b89205e..3051209a2 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_settings.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_settings.xml
@@ -80,6 +80,22 @@
                     app:subtitle="@{@string/settings_notifications_title}"
                     app:tracingViewModel="@{tracingViewModel}" />
 
+                <include
+                    android:id="@+id/settings_background_priority"
+                    layout="@layout/include_setting_row"
+                    android:layout_width="@dimen/match_constraint"
+                    android:layout_height="wrap_content"
+                    app:body="@{@string/settings_background_priority_body_description}"
+                    app:color="@{FormatterSettingsHelper.formatSettingsBackgroundPriorityIconColor(settingsViewModel.isBackgroundPriorityEnabled())}"
+                    app:icon="@{FormatterSettingsHelper.formatSettingsBackgroundPriorityIcon(settingsViewModel.isBackgroundPriorityEnabled())}"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@+id/settings_notifications"
+                    app:showDivider="@{true}"
+                    app:statusText="@{FormatterSettingsHelper.formatStatus(settingsViewModel.isBackgroundPriorityEnabled())}"
+                    app:subtitle="@{@string/settings_background_priority_title}"
+                    app:tracingViewModel="@{tracingViewModel}" />
+
                 <androidx.constraintlayout.widget.ConstraintLayout
                     android:id="@+id/settings_reset"
                     style="@style/row"
@@ -87,7 +103,7 @@
                     android:layout_height="wrap_content"
                     app:layout_constraintEnd_toEndOf="parent"
                     app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toBottomOf="@+id/settings_notifications">
+                    app:layout_constraintTop_toBottomOf="@+id/settings_background_priority">
 
                     <androidx.constraintlayout.widget.ConstraintLayout
                         android:layout_width="0dp"
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml b/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml
new file mode 100644
index 000000000..fba3d512d
--- /dev/null
+++ b/Corona-Warn-App/src/main/res/layout/fragment_settings_background_priority.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <data>
+
+        <import type="de.rki.coronawarnapp.util.formatter.FormatterHelper" />
+
+        <import type="de.rki.coronawarnapp.util.formatter.FormatterSettingsHelper" />
+
+        <variable
+            name="settingsViewModel"
+            type="de.rki.coronawarnapp.ui.viewmodel.SettingsViewModel" />
+    </data>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/settings_background_priority_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:contentDescription="@string/settings_background_priority_title"
+        android:focusable="true">
+
+        <include
+            android:id="@+id/settings_background_priority_header"
+            layout="@layout/include_header"
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="wrap_content"
+            app:icon="@{@drawable/ic_back}"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:title="@{@string/settings_background_priority_title}" />
+
+        <ScrollView
+            android:layout_width="@dimen/match_constraint"
+            android:layout_height="@dimen/match_constraint"
+            android:fillViewport="true"
+            app:layout_constraintBottom_toBottomOf="@+id/guideline_bottom"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/settings_background_priority_header">
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <include
+                    android:id="@+id/settings_background_priority_header_details"
+                    layout="@layout/include_information_details"
+                    android:layout_width="@dimen/match_constraint"
+                    android:layout_height="wrap_content"
+                    app:body="@{@string/settings_background_priority_body}"
+                    app:headline="@{@string/settings_background_priority_headline}"
+                    app:illustration="@{@drawable/ic_settings_illustration_reset}"
+                    app:illustrationDescription="@{@string/settings_background_priority_illustration_description}"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+                <include
+                    android:id="@+id/settings_switch_row_background_priority"
+                    layout="@layout/include_settings_switch_row"
+                    android:layout_width="@dimen/match_constraint"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/spacing_small"
+                    app:enabled="@{!settingsViewModel.isBackgroundPriorityEnabled()}"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@+id/settings_background_priority_header_details"
+                    app:showDivider="@{true}"
+                    app:status="@{settingsViewModel.isBackgroundPriorityEnabled()}"
+                    app:statusText="@{FormatterSettingsHelper.formatStatus(settingsViewModel.isBackgroundPriorityEnabled())}"
+                    app:subtitle="@{@string/settings_background_priority_title}" />
+
+                <include
+                    android:id="@+id/settings_tracing_status_connection"
+                    layout="@layout/include_tracing_status_card"
+                    android:layout_width="@dimen/match_constraint"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="@dimen/spacing_small"
+                    android:visibility="@{FormatterHelper.formatVisibility(settingsViewModel.isBackgroundPriorityEnabled())}"
+                    app:body="@{@string/settings_background_priority_card_body}"
+                    app:buttonText="@{@string/settings_background_priority_card_button}"
+                    app:headline="@{@string/settings_background_priority_card_headline}"
+                    app:layout_constraintEnd_toStartOf="@+id/guideline_card_end"
+                    app:layout_constraintStart_toStartOf="@+id/guideline_card_start"
+                    app:layout_constraintTop_toBottomOf="@id/settings_switch_row_background_priority" />
+
+                <include layout="@layout/merge_guidelines_side" />
+
+                <include layout="@layout/merge_guidelines_card" />
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+        </ScrollView>
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline_bottom"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            app:layout_constraintGuide_end="@dimen/guideline_bottom" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</layout>
\ No newline at end of file
diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
index da14ba42c..13ffd4246 100644
--- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
+++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml
@@ -73,6 +73,9 @@
         <action
             android:id="@+id/action_settingsFragment_to_settingsNotificationFragment"
             app:destination="@id/settingsNotificationFragment" />
+        <action
+            android:id="@+id/action_settingsFragment_to_settingsBackgroundPriorityFragment"
+            app:destination="@id/settingsBackgroundPriorityFragment" />
     </fragment>
 
     <fragment
@@ -87,6 +90,12 @@
         android:label="SettingsNotificationFragment"
         tools:layout="@layout/fragment_settings_notifications" />
 
+    <fragment
+        android:id="@+id/settingsBackgroundPriorityFragment"
+        android:name="de.rki.coronawarnapp.ui.settings.SettingsBackgroundPriorityFragment"
+        android:label="SettingsBackgroundPriorityFragment"
+        tools:layout="@layout/fragment_settings_background_priority" />
+
     <fragment
         android:id="@+id/settingsResetFragment"
         android:name="de.rki.coronawarnapp.ui.settings.SettingsResetFragment"
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/ExternalActionHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/ExternalActionHelperTest.kt
index 0ca6efe8c..2ed543620 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/ExternalActionHelperTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/ExternalActionHelperTest.kt
@@ -79,6 +79,21 @@ class ExternalActionHelperTest {
         verify(exactly = 1) { fragment.startActivity(any()) }
     }
 
+    @Test
+    fun disableBatteryOptimizations() {
+        every { context.packageName } returns "package_name"
+        every { context.startActivity(any()) } just Runs
+        ExternalActionHelper.disableBatteryOptimizations(context)
+        verify(exactly = 1) { context.startActivity(any()) }
+    }
+
+    @Test
+    fun toBatteryOptimizationSettings() {
+        every { context.startActivity(any()) } just Runs
+        ExternalActionHelper.toBatteryOptimizationSettings(context)
+        verify(exactly = 1) { context.startActivity(any()) }
+    }
+
     @After
     fun cleanUp() {
         unmockkAll()
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelperTest.kt
index e52f804ed..cb6f079b1 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelperTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/formatter/FormatterSettingsHelperTest.kt
@@ -6,6 +6,7 @@ import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.R
 import io.mockk.MockKAnnotations
 import io.mockk.every
+import io.mockk.mockk
 import io.mockk.impl.annotations.MockK
 import io.mockk.mockkObject
 import io.mockk.unmockkAll
@@ -855,6 +856,55 @@ class FormatterSettingsHelperTest {
         formatNotificationImageBase(bNotifications = false)
     }
 
+    @Test
+    fun formatSettingsBackgroundPriorityIconColor() {
+        formatSettingsBackgroundPriorityIconColorBase(true, R.color.colorAccentTintIcon)
+        formatSettingsBackgroundPriorityIconColorBase(false, R.color.colorTextSemanticRed)
+    }
+
+    private fun formatSettingsBackgroundPriorityIconColorBase(
+        enabled: Boolean,
+        expectedColor: Int
+    ) {
+        every { context.getColor(R.color.colorAccentTintIcon) } returns R.color.colorAccentTintIcon
+        every { context.getColor(R.color.colorTextSemanticRed) } returns R.color.colorTextSemanticRed
+
+        val result =
+            formatSettingsBackgroundPriorityIconColor(enabled)
+        assertThat(
+            result, `is`(context.getColor(expectedColor))
+        )
+    }
+
+    @Test
+    fun formatSettingsBackgroundPriorityIcon() {
+        formatSettingsBackgroundPriorityIconBase(
+            true,
+            R.drawable.ic_settings_background_priority_enabled
+        )
+        formatSettingsBackgroundPriorityIconBase(
+            false,
+            R.drawable.ic_settings_background_priority_disabled
+        )
+    }
+
+    private fun formatSettingsBackgroundPriorityIconBase(
+        enabled: Boolean,
+        expectedDrawable: Int
+    ) {
+        val drawableA = mockk<Drawable>()
+        val drawableB = mockk<Drawable>()
+
+        every { context.getDrawable(R.drawable.ic_settings_background_priority_enabled) } returns drawableA
+        every { context.getDrawable(R.drawable.ic_settings_background_priority_disabled) } returns drawableB
+
+        val result =
+            formatSettingsBackgroundPriorityIcon(enabled)
+        assertThat(
+            result, `is`(context.getDrawable(expectedDrawable))
+        )
+    }
+
     @After
     fun cleanUp() {
         unmockkAll()
-- 
GitLab