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.communal.domain.model 18 19 import android.appwidget.AppWidgetProviderInfo 20 import android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_RECONFIGURABLE 21 import android.content.pm.ApplicationInfo 22 import android.graphics.Bitmap 23 import android.widget.RemoteViews 24 import com.android.systemui.communal.shared.model.CommunalContentSize 25 import com.android.systemui.communal.widgets.CommunalAppWidgetHost 26 import java.util.UUID 27 28 /** Encapsulates data for a communal content. */ 29 sealed interface CommunalContentModel { 30 /** Unique key across all types of content models. */ 31 val key: String 32 33 /** Size to be rendered in the grid. */ 34 val size: CommunalContentSize 35 36 /** 37 * A type of communal content is ongoing / live / ephemeral, and can be sized and ordered 38 * dynamically. 39 */ 40 sealed interface Ongoing : CommunalContentModel { 41 override var size: CommunalContentSize 42 43 /** Timestamp in milliseconds of when the content was created. */ 44 val createdTimestampMillis: Long 45 } 46 47 sealed interface WidgetContent : CommunalContentModel { 48 val appWidgetId: Int 49 50 data class Widget( 51 override val appWidgetId: Int, 52 val providerInfo: AppWidgetProviderInfo, 53 val appWidgetHost: CommunalAppWidgetHost, 54 val inQuietMode: Boolean, 55 ) : WidgetContent { 56 override val key = KEY.widget(appWidgetId) 57 // Widget size is always half. 58 override val size = CommunalContentSize.HALF 59 60 /** Whether this widget can be reconfigured after it has already been added. */ 61 val reconfigurable: Boolean 62 get() = 63 (providerInfo.widgetFeatures and WIDGET_FEATURE_RECONFIGURABLE != 0) && 64 providerInfo.configure != null 65 } 66 67 data class DisabledWidget( 68 override val appWidgetId: Int, 69 val providerInfo: AppWidgetProviderInfo 70 ) : WidgetContent { 71 override val key = KEY.disabledWidget(appWidgetId) 72 // Widget size is always half. 73 override val size = CommunalContentSize.HALF 74 75 val appInfo: ApplicationInfo? 76 get() = providerInfo.providerInfo?.applicationInfo 77 } 78 79 data class PendingWidget( 80 override val appWidgetId: Int, 81 val packageName: String, 82 val icon: Bitmap? = null, 83 ) : WidgetContent { 84 override val key = KEY.pendingWidget(appWidgetId) 85 // Widget size is always half. 86 override val size = CommunalContentSize.HALF 87 } 88 } 89 90 /** A placeholder item representing a new widget being added */ 91 class WidgetPlaceholder : CommunalContentModel { 92 override val key: String = KEY.widgetPlaceholder() 93 // Same as widget size. 94 override val size = CommunalContentSize.HALF 95 } 96 97 /** A CTA tile in the glanceable hub view mode which can be dismissed. */ 98 class CtaTileInViewMode : CommunalContentModel { 99 override val key: String = KEY.CTA_TILE_IN_VIEW_MODE_KEY 100 // Same as widget size. 101 override val size = CommunalContentSize.HALF 102 } 103 104 class Tutorial( 105 id: Int, 106 override var size: CommunalContentSize, 107 ) : CommunalContentModel { 108 override val key = KEY.tutorial(id) 109 } 110 111 class Smartspace( 112 smartspaceTargetId: String, 113 val remoteViews: RemoteViews, 114 override val createdTimestampMillis: Long, 115 override var size: CommunalContentSize = CommunalContentSize.HALF, 116 ) : Ongoing { 117 override val key = KEY.smartspace(smartspaceTargetId) 118 } 119 120 class Umo( 121 override val createdTimestampMillis: Long, 122 override var size: CommunalContentSize = CommunalContentSize.HALF, 123 ) : Ongoing { 124 override val key = KEY.umo() 125 } 126 127 class KEY { 128 companion object { 129 const val CTA_TILE_IN_VIEW_MODE_KEY = "cta_tile_in_view_mode" 130 const val CTA_TILE_IN_EDIT_MODE_KEY = "cta_tile_in_edit_mode" 131 widgetnull132 fun widget(id: Int): String { 133 return "widget_$id" 134 } 135 disabledWidgetnull136 fun disabledWidget(id: Int): String { 137 return "disabled_widget_$id" 138 } 139 pendingWidgetnull140 fun pendingWidget(id: Int): String { 141 return "pending_widget_$id" 142 } 143 widgetPlaceholdernull144 fun widgetPlaceholder(): String { 145 return "widget_placeholder_${UUID.randomUUID()}" 146 } 147 tutorialnull148 fun tutorial(id: Int): String { 149 return "tutorial_$id" 150 } 151 smartspacenull152 fun smartspace(id: String): String { 153 return "smartspace_$id" 154 } 155 umonull156 fun umo(): String { 157 return "umo" 158 } 159 } 160 } 161 isWidgetContentnull162 fun isWidgetContent() = this is WidgetContent 163 164 fun isLiveContent() = this is Smartspace || this is Umo 165 } 166