diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e31ef4cff..c757ed114 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -400,11 +400,9 @@
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:exported="true">
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile13Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile13Service.kt
new file mode 100644
index 000000000..db5fb25db
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile13Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile13Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_13"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile14Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile14Service.kt
new file mode 100644
index 000000000..bf979abd3
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile14Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile14Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_14"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile15Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile15Service.kt
new file mode 100644
index 000000000..f47a5098e
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile15Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile15Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_15"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile16Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile16Service.kt
new file mode 100644
index 000000000..b94432c02
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile16Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile16Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_16"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile17Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile17Service.kt
new file mode 100644
index 000000000..9e291f587
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile17Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile17Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_17"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile18Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile18Service.kt
new file mode 100644
index 000000000..75dfd514b
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile18Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile18Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_18"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile19Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile19Service.kt
new file mode 100644
index 000000000..ce35c4c82
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile19Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile19Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_19"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile20Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile20Service.kt
new file mode 100644
index 000000000..b065d0b80
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile20Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile20Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_20"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile21Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile21Service.kt
new file mode 100644
index 000000000..c013bdb1c
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile21Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile21Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_21"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile22Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile22Service.kt
new file mode 100644
index 000000000..ad656535c
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile22Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile22Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_22"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile23Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile23Service.kt
new file mode 100644
index 000000000..ae8cc6d6f
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile23Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile23Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_23"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile24Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile24Service.kt
new file mode 100644
index 000000000..825d9a8c6
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile24Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile24Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_24"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile25Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile25Service.kt
new file mode 100644
index 000000000..2ca487e72
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile25Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile25Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_25"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile26Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile26Service.kt
new file mode 100644
index 000000000..5a9fb94c1
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile26Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile26Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_26"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile27Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile27Service.kt
new file mode 100644
index 000000000..d2908017c
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile27Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile27Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_27"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile28Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile28Service.kt
new file mode 100644
index 000000000..0af716c08
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile28Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile28Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_28"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile29Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile29Service.kt
new file mode 100644
index 000000000..0e7785ff2
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile29Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile29Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_29"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile30Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile30Service.kt
new file mode 100644
index 000000000..e051c470d
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile30Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile30Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_30"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile31Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile31Service.kt
new file mode 100644
index 000000000..64bfaa153
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile31Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile31Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_31"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile32Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile32Service.kt
new file mode 100644
index 000000000..c806d1601
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile32Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile32Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_32"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile33Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile33Service.kt
new file mode 100644
index 000000000..9d427da53
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile33Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile33Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_33"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile34Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile34Service.kt
new file mode 100644
index 000000000..29ad8d2a6
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile34Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile34Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_34"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile35Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile35Service.kt
new file mode 100644
index 000000000..e835d4f4b
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile35Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile35Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_35"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile36Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile36Service.kt
new file mode 100644
index 000000000..324b9ecbc
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile36Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile36Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_36"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile37Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile37Service.kt
new file mode 100644
index 000000000..82325da18
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile37Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile37Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_37"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile38Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile38Service.kt
new file mode 100644
index 000000000..2aa92cad2
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile38Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile38Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_38"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile39Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile39Service.kt
new file mode 100644
index 000000000..e8674ae18
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile39Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile39Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_39"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/Tile40Service.kt b/app/src/main/java/io/homeassistant/companion/android/qs/Tile40Service.kt
new file mode 100644
index 000000000..6637a9c57
--- /dev/null
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/Tile40Service.kt
@@ -0,0 +1,24 @@
+package io.homeassistant.companion.android.qs
+
+import android.os.Build
+import android.service.quicksettings.Tile
+import androidx.annotation.RequiresApi
+
+@RequiresApi(Build.VERSION_CODES.N)
+class Tile40Service : TileExtensions() {
+
+ companion object {
+ const val TILE_ID = "tile_40"
+ }
+
+ override fun getTile(): Tile? {
+ return if (qsTile != null)
+ qsTile
+ else
+ null
+ }
+
+ override fun getTileId(): String {
+ return TILE_ID
+ }
+}
diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt b/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt
index 89fa651b3..50d12ae4f 100755
--- a/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt
+++ b/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt
@@ -30,13 +30,17 @@ import io.homeassistant.companion.android.common.data.integration.IntegrationRep
import io.homeassistant.companion.android.common.data.integration.getIcon
import io.homeassistant.companion.android.database.qs.TileDao
import io.homeassistant.companion.android.database.qs.TileEntity
+import io.homeassistant.companion.android.database.qs.getHighestInUse
import io.homeassistant.companion.android.database.qs.isSetup
+import io.homeassistant.companion.android.database.qs.numberedId
import io.homeassistant.companion.android.settings.SettingsActivity
+import io.homeassistant.companion.android.settings.qs.updateActiveTileServices
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import javax.inject.Inject
import io.homeassistant.companion.android.common.R as commonR
@@ -87,7 +91,7 @@ abstract class TileExtensions : TileService() {
super.onTileRemoved()
Log.d(TAG, "Tile: ${getTileId()} removed")
handleInject()
- mainScope.launch {
+ runBlocking {
setTileAdded(getTileId(), false)
}
}
@@ -279,6 +283,10 @@ abstract class TileExtensions : TileService() {
)
} // else if it doesn't exist and is removed we don't have to save anything
}
+
+ val highestInUse = tileDao.getHighestInUse()?.numberedId ?: 0
+ Log.d(TAG, "Highest tile in use: $highestInUse")
+ updateActiveTileServices(highestInUse, applicationContext)
}
private fun getTileIcon(tileIconId: Int?, entity: Entity<*>?, context: Context): Bitmap? {
diff --git a/app/src/main/java/io/homeassistant/companion/android/settings/qs/ManageTilesViewModel.kt b/app/src/main/java/io/homeassistant/companion/android/settings/qs/ManageTilesViewModel.kt
index fc221d130..3ab1d6811 100755
--- a/app/src/main/java/io/homeassistant/companion/android/settings/qs/ManageTilesViewModel.kt
+++ b/app/src/main/java/io/homeassistant/companion/android/settings/qs/ManageTilesViewModel.kt
@@ -1,5 +1,6 @@
package io.homeassistant.companion.android.settings.qs
+import android.annotation.SuppressLint
import android.app.Application
import android.app.StatusBarManager
import android.content.ComponentName
@@ -28,13 +29,43 @@ import io.homeassistant.companion.android.common.data.integration.domain
import io.homeassistant.companion.android.common.data.integration.getIcon
import io.homeassistant.companion.android.database.qs.TileDao
import io.homeassistant.companion.android.database.qs.TileEntity
+import io.homeassistant.companion.android.database.qs.getHighestInUse
import io.homeassistant.companion.android.database.qs.isSetup
+import io.homeassistant.companion.android.database.qs.numberedId
import io.homeassistant.companion.android.qs.Tile10Service
import io.homeassistant.companion.android.qs.Tile11Service
import io.homeassistant.companion.android.qs.Tile12Service
+import io.homeassistant.companion.android.qs.Tile13Service
+import io.homeassistant.companion.android.qs.Tile14Service
+import io.homeassistant.companion.android.qs.Tile15Service
+import io.homeassistant.companion.android.qs.Tile16Service
+import io.homeassistant.companion.android.qs.Tile17Service
+import io.homeassistant.companion.android.qs.Tile18Service
+import io.homeassistant.companion.android.qs.Tile19Service
import io.homeassistant.companion.android.qs.Tile1Service
+import io.homeassistant.companion.android.qs.Tile20Service
+import io.homeassistant.companion.android.qs.Tile21Service
+import io.homeassistant.companion.android.qs.Tile22Service
+import io.homeassistant.companion.android.qs.Tile23Service
+import io.homeassistant.companion.android.qs.Tile24Service
+import io.homeassistant.companion.android.qs.Tile25Service
+import io.homeassistant.companion.android.qs.Tile26Service
+import io.homeassistant.companion.android.qs.Tile27Service
+import io.homeassistant.companion.android.qs.Tile28Service
+import io.homeassistant.companion.android.qs.Tile29Service
import io.homeassistant.companion.android.qs.Tile2Service
+import io.homeassistant.companion.android.qs.Tile30Service
+import io.homeassistant.companion.android.qs.Tile31Service
+import io.homeassistant.companion.android.qs.Tile32Service
+import io.homeassistant.companion.android.qs.Tile33Service
+import io.homeassistant.companion.android.qs.Tile34Service
+import io.homeassistant.companion.android.qs.Tile35Service
+import io.homeassistant.companion.android.qs.Tile36Service
+import io.homeassistant.companion.android.qs.Tile37Service
+import io.homeassistant.companion.android.qs.Tile38Service
+import io.homeassistant.companion.android.qs.Tile39Service
import io.homeassistant.companion.android.qs.Tile3Service
+import io.homeassistant.companion.android.qs.Tile40Service
import io.homeassistant.companion.android.qs.Tile4Service
import io.homeassistant.companion.android.qs.Tile5Service
import io.homeassistant.companion.android.qs.Tile6Service
@@ -60,6 +91,50 @@ class ManageTilesViewModel @Inject constructor(
companion object {
private const val TAG = "ManageTilesViewModel"
+
+ @SuppressLint("InlinedApi", "NewApi")
+ val idToTileService = mapOf(
+ Tile1Service.TILE_ID to Tile1Service::class.java,
+ Tile2Service.TILE_ID to Tile2Service::class.java,
+ Tile3Service.TILE_ID to Tile3Service::class.java,
+ Tile4Service.TILE_ID to Tile4Service::class.java,
+ Tile5Service.TILE_ID to Tile5Service::class.java,
+ Tile6Service.TILE_ID to Tile6Service::class.java,
+ Tile7Service.TILE_ID to Tile7Service::class.java,
+ Tile8Service.TILE_ID to Tile8Service::class.java,
+ Tile9Service.TILE_ID to Tile9Service::class.java,
+ Tile10Service.TILE_ID to Tile10Service::class.java,
+ Tile11Service.TILE_ID to Tile11Service::class.java,
+ Tile12Service.TILE_ID to Tile12Service::class.java,
+ Tile13Service.TILE_ID to Tile13Service::class.java,
+ Tile14Service.TILE_ID to Tile14Service::class.java,
+ Tile15Service.TILE_ID to Tile15Service::class.java,
+ Tile16Service.TILE_ID to Tile16Service::class.java,
+ Tile17Service.TILE_ID to Tile17Service::class.java,
+ Tile18Service.TILE_ID to Tile18Service::class.java,
+ Tile19Service.TILE_ID to Tile19Service::class.java,
+ Tile20Service.TILE_ID to Tile20Service::class.java,
+ Tile21Service.TILE_ID to Tile21Service::class.java,
+ Tile22Service.TILE_ID to Tile22Service::class.java,
+ Tile23Service.TILE_ID to Tile23Service::class.java,
+ Tile24Service.TILE_ID to Tile24Service::class.java,
+ Tile25Service.TILE_ID to Tile25Service::class.java,
+ Tile26Service.TILE_ID to Tile26Service::class.java,
+ Tile27Service.TILE_ID to Tile27Service::class.java,
+ Tile28Service.TILE_ID to Tile28Service::class.java,
+ Tile29Service.TILE_ID to Tile29Service::class.java,
+ Tile30Service.TILE_ID to Tile30Service::class.java,
+ Tile31Service.TILE_ID to Tile31Service::class.java,
+ Tile32Service.TILE_ID to Tile32Service::class.java,
+ Tile33Service.TILE_ID to Tile33Service::class.java,
+ Tile34Service.TILE_ID to Tile34Service::class.java,
+ Tile35Service.TILE_ID to Tile35Service::class.java,
+ Tile36Service.TILE_ID to Tile36Service::class.java,
+ Tile37Service.TILE_ID to Tile37Service::class.java,
+ Tile38Service.TILE_ID to Tile38Service::class.java,
+ Tile39Service.TILE_ID to Tile39Service::class.java,
+ Tile40Service.TILE_ID to Tile40Service::class.java
+ )
}
lateinit var iconPack: IconPack
@@ -188,22 +263,12 @@ class ManageTilesViewModel @Inject constructor(
)
tileDao.add(tileData)
+ val highestInUse = tileDao.getHighestInUse()?.numberedId ?: 0
+ updateActiveTileServices(highestInUse, app)
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !selectedTileAdded) {
val statusBarManager = app.getSystemService()
- val service = when (selectedTile.id) {
- Tile2Service.TILE_ID -> Tile2Service::class.java
- Tile3Service.TILE_ID -> Tile3Service::class.java
- Tile4Service.TILE_ID -> Tile4Service::class.java
- Tile5Service.TILE_ID -> Tile5Service::class.java
- Tile6Service.TILE_ID -> Tile6Service::class.java
- Tile7Service.TILE_ID -> Tile7Service::class.java
- Tile8Service.TILE_ID -> Tile8Service::class.java
- Tile9Service.TILE_ID -> Tile9Service::class.java
- Tile10Service.TILE_ID -> Tile10Service::class.java
- Tile11Service.TILE_ID -> Tile11Service::class.java
- Tile12Service.TILE_ID -> Tile12Service::class.java
- else -> Tile1Service::class.java
- }
+ val service = idToTileService[selectedTile.id] ?: Tile1Service::class.java
val icon = selectedIconDrawable?.let {
it.toBitmapOrNull(it.intrinsicWidth, it.intrinsicHeight)?.let { bitmap ->
android.graphics.drawable.Icon.createWithBitmap(bitmap)
diff --git a/app/src/main/java/io/homeassistant/companion/android/settings/qs/TileSlot.kt b/app/src/main/java/io/homeassistant/companion/android/settings/qs/TileSlot.kt
index f2e15d2e8..487ce571c 100644
--- a/app/src/main/java/io/homeassistant/companion/android/settings/qs/TileSlot.kt
+++ b/app/src/main/java/io/homeassistant/companion/android/settings/qs/TileSlot.kt
@@ -1,6 +1,10 @@
package io.homeassistant.companion.android.settings.qs
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
import android.content.res.Resources
+import kotlin.math.min
import io.homeassistant.companion.android.R as commonR
data class TileSlot(
@@ -17,3 +21,24 @@ fun loadTileSlots(resources: Resources): List {
val tileNameArray = resources.getStringArray(commonR.array.tile_name)
return tileIdArray.zip(tileNameArray).map { (id, name) -> TileSlot(id, name) }
}
+
+/**
+ * Enables/disables services for tiles to ensure that only the required number of tiles + a few more
+ * are available, instead of all possible tiles.
+ */
+fun updateActiveTileServices(highestInUse: Int, context: Context) {
+ val tileIdArray = context.resources.getStringArray(commonR.array.tile_ids)
+ val packageManager = context.packageManager
+ val activeTilesRequired = min(tileIdArray.size, highestInUse + 4)
+ ManageTilesViewModel.idToTileService.toList().forEachIndexed { index, (_, service) ->
+ packageManager.setComponentEnabledSetting(
+ ComponentName(context, service),
+ if (index < activeTilesRequired) {
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ } else {
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ },
+ PackageManager.DONT_KILL_APP
+ )
+ }
+}
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 0a163d5bf..90ab28c5c 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -23,6 +23,34 @@
- tile_10
- tile_11
- tile_12
+ - tile_13
+ - tile_14
+ - tile_15
+ - tile_16
+ - tile_17
+ - tile_18
+ - tile_19
+ - tile_20
+ - tile_21
+ - tile_22
+ - tile_23
+ - tile_24
+ - tile_25
+ - tile_26
+ - tile_27
+ - tile_28
+ - tile_29
+ - tile_30
+ - tile_31
+ - tile_32
+ - tile_33
+ - tile_34
+ - tile_35
+ - tile_36
+ - tile_37
+ - tile_38
+ - tile_39
+ - tile_40
- @string/tile_1
@@ -37,5 +65,33 @@
- @string/tile_10
- @string/tile_11
- @string/tile_12
+ - @string/tile_13
+ - @string/tile_14
+ - @string/tile_15
+ - @string/tile_16
+ - @string/tile_17
+ - @string/tile_18
+ - @string/tile_19
+ - @string/tile_20
+ - @string/tile_21
+ - @string/tile_22
+ - @string/tile_23
+ - @string/tile_24
+ - @string/tile_25
+ - @string/tile_26
+ - @string/tile_27
+ - @string/tile_28
+ - @string/tile_29
+ - @string/tile_30
+ - @string/tile_31
+ - @string/tile_32
+ - @string/tile_33
+ - @string/tile_34
+ - @string/tile_35
+ - @string/tile_36
+ - @string/tile_37
+ - @string/tile_38
+ - @string/tile_39
+ - @string/tile_40
\ No newline at end of file
diff --git a/common/src/main/java/io/homeassistant/companion/android/database/qs/TileDao.kt b/common/src/main/java/io/homeassistant/companion/android/database/qs/TileDao.kt
index 11709dd30..7e3e783e6 100755
--- a/common/src/main/java/io/homeassistant/companion/android/database/qs/TileDao.kt
+++ b/common/src/main/java/io/homeassistant/companion/android/database/qs/TileDao.kt
@@ -11,6 +11,16 @@ interface TileDao {
@Query("SELECT * FROM qs_tiles WHERE tileId = :tileId")
suspend fun get(tileId: String): TileEntity?
+ @Query("SELECT * FROM qs_tiles")
+ suspend fun getAll(): List
+
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun add(tileEntity: TileEntity)
}
+
+suspend fun TileDao.getHighestInUse(): TileEntity? {
+ return getAll()
+ .filter { it.added || it.isSetup }
+ .sortedByDescending { it.tileId.split("_")[1].toInt() }
+ .getOrNull(0)
+}
diff --git a/common/src/main/java/io/homeassistant/companion/android/database/qs/TileEntity.kt b/common/src/main/java/io/homeassistant/companion/android/database/qs/TileEntity.kt
index ab49afd13..4bfd5fac6 100755
--- a/common/src/main/java/io/homeassistant/companion/android/database/qs/TileEntity.kt
+++ b/common/src/main/java/io/homeassistant/companion/android/database/qs/TileEntity.kt
@@ -26,3 +26,6 @@ data class TileEntity(
val TileEntity.isSetup: Boolean
get() = this.label.isNotBlank() && this.entityId.isNotBlank()
+
+val TileEntity.numberedId: Int
+ get() = this.tileId.split("_")[1].toInt()
diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml
index 4e72a3345..9699cc468 100644
--- a/common/src/main/res/values/strings.xml
+++ b/common/src/main/res/values/strings.xml
@@ -744,9 +744,37 @@
Tile 10
Tile 11
Tile 12
+ Tile 13
+ Tile 14
+ Tile 15
+ Tile 16
+ Tile 17
+ Tile 18
+ Tile 19
Tile 2
+ Tile 20
+ Tile 21
+ Tile 22
+ Tile 23
+ Tile 24
+ Tile 25
+ Tile 26
+ Tile 27
+ Tile 28
+ Tile 29
Tile 3
+ Tile 30
+ Tile 31
+ Tile 32
+ Tile 33
+ Tile 34
+ Tile 35
+ Tile 36
+ Tile 37
+ Tile 38
+ Tile 39
Tile 4
+ Tile 40
Tile 5
Tile 6
Tile 7