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 com.android.systemui.qs.external.CustomTile 22 23 /** 24 * Container for the spec that identifies a tile. 25 * 26 * A tile's [spec] is one of two options: 27 * * `custom(<componentName>)`: A [ComponentName] surrounded by [CustomTile.PREFIX] and terminated 28 * by `)`, represents a tile provided by an app, corresponding to a `TileService`. 29 * * a string not starting with [CustomTile.PREFIX], representing a tile provided by SystemUI. 30 */ 31 sealed class TileSpec private constructor(open val spec: String) { 32 33 /** Represents a spec that couldn't be parsed into a valid type of tile. */ 34 data object Invalid : TileSpec("") 35 36 /** Container for the spec of a tile provided by SystemUI. */ 37 data class PlatformTileSpec 38 internal constructor( 39 override val spec: String, 40 ) : TileSpec(spec) { toStringnull41 override fun toString(): String { 42 return "P($spec)" 43 } 44 } 45 46 /** 47 * Container for the spec of a tile provided by an app. 48 * 49 * [componentName] indicates the associated `TileService`. 50 */ 51 data class CustomTileSpec 52 internal constructor( 53 override val spec: String, 54 val componentName: ComponentName, 55 ) : TileSpec(spec) { toStringnull56 override fun toString(): String { 57 return "C(${componentName.flattenToShortString()})" 58 } 59 } 60 61 companion object { 62 /** Create a [TileSpec] from the string [spec]. */ 63 @JvmStatic createnull64 fun create(spec: String): TileSpec { 65 return if (TextUtils.isEmpty(spec)) { 66 Invalid 67 } else if (!spec.isCustomTileSpec) { 68 PlatformTileSpec(spec) 69 } else { 70 spec.componentName?.let { CustomTileSpec(spec, it) } ?: Invalid 71 } 72 } 73 createnull74 fun create(component: ComponentName): CustomTileSpec { 75 return CustomTileSpec(CustomTile.toSpec(component), component) 76 } 77 78 private val String.isCustomTileSpec: Boolean 79 get() = startsWith(CustomTile.PREFIX) 80 81 private val String.componentName: ComponentName? 82 get() = 83 if (!isCustomTileSpec) { 84 null 85 } else { 86 if (endsWith(")")) { 87 val extracted = substring(CustomTile.PREFIX.length, length - 1) 88 ComponentName.unflattenFromString(extracted) 89 } else { 90 null 91 } 92 } 93 } 94 } 95