• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.qs.pipeline.shared
18 
19 import android.content.ComponentName
20 import android.text.TextUtils
21 import androidx.compose.runtime.Stable
22 import com.android.systemui.qs.external.CustomTile
23 
24 /**
25  * Container for the spec that identifies a tile.
26  *
27  * A tile's [spec] is one of two options:
28  * * `custom(<componentName>)`: A [ComponentName] surrounded by [CustomTile.PREFIX] and terminated
29  *   by `)`, represents a tile provided by an app, corresponding to a `TileService`.
30  * * a string not starting with [CustomTile.PREFIX], representing a tile provided by SystemUI.
31  */
32 sealed class TileSpec private constructor(open val spec: String) {
33 
34     /** Represents a spec that couldn't be parsed into a valid type of tile. */
35     data object Invalid : TileSpec("")
36 
37     /** Container for the spec of a tile provided by SystemUI. */
38     @Stable
39     data class PlatformTileSpec internal constructor(override val spec: String) : TileSpec(spec) {
toStringnull40         override fun toString(): String {
41             return "P($spec)"
42         }
43     }
44 
45     /**
46      * Container for the spec of a tile provided by an app.
47      *
48      * [componentName] indicates the associated `TileService`.
49      */
50     @Stable
51     data class CustomTileSpec
52     internal constructor(override val spec: String, val componentName: ComponentName) :
53         TileSpec(spec) {
toStringnull54         override fun toString(): String {
55             return "C(${componentName.flattenToShortString()})"
56         }
57     }
58 
59     companion object {
60         /** Create a [TileSpec] from the string [spec]. */
61         @JvmStatic
createnull62         fun create(spec: String): TileSpec {
63             return if (TextUtils.isEmpty(spec)) {
64                 Invalid
65             } else if (!spec.isCustomTileSpec) {
66                 PlatformTileSpec(spec)
67             } else {
68                 spec.componentName?.let { CustomTileSpec(spec, it) } ?: Invalid
69             }
70         }
71 
createnull72         fun create(component: ComponentName): CustomTileSpec {
73             return CustomTileSpec(CustomTile.toSpec(component), component)
74         }
75 
76         private val String.isCustomTileSpec: Boolean
77             get() = startsWith(CustomTile.PREFIX)
78 
79         private val String.componentName: ComponentName?
80             get() =
81                 if (!isCustomTileSpec) {
82                     null
83                 } else {
84                     if (endsWith(")")) {
85                         val extracted = substring(CustomTile.PREFIX.length, length - 1)
86                         ComponentName.unflattenFromString(extracted)
87                     } else {
88                         null
89                     }
90                 }
91     }
92 }
93 
94 val TileSpec.metricSpec
95     get() =
96         when (this) {
97             is TileSpec.Invalid -> ""
98             is TileSpec.PlatformTileSpec -> spec
99             is TileSpec.CustomTileSpec -> componentName.packageName
100         }
101