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.wallpaper.util.converter
18 
19 import android.app.WallpaperManager
20 import android.content.ComponentName
21 import android.content.Context
22 import android.util.Log
23 import com.android.wallpaper.effects.EffectsController
24 import com.android.wallpaper.model.CreativeWallpaperInfo
25 import com.android.wallpaper.model.CurrentWallpaperInfo
26 import com.android.wallpaper.model.ImageWallpaperInfo
27 import com.android.wallpaper.model.LiveWallpaperInfo
28 import com.android.wallpaper.model.WallpaperInfo
29 import com.android.wallpaper.picker.data.ColorInfo
30 import com.android.wallpaper.picker.data.CommonWallpaperData
31 import com.android.wallpaper.picker.data.CreativeWallpaperData
32 import com.android.wallpaper.picker.data.CreativeWallpaperEffectsData
33 import com.android.wallpaper.picker.data.Destination
34 import com.android.wallpaper.picker.data.ImageWallpaperData
35 import com.android.wallpaper.picker.data.LiveWallpaperData
36 import com.android.wallpaper.picker.data.WallpaperId
37 import com.android.wallpaper.picker.data.WallpaperModel
38 
39 /** This class creates an instance of [WallpaperModel] from a given [WallpaperInfo] object. */
40 interface WallpaperModelFactory {
41 
getWallpaperModelnull42     fun getWallpaperModel(context: Context, wallpaperInfo: WallpaperInfo): WallpaperModel
43 
44     companion object {
45 
46         const val STATIC_WALLPAPER_PACKAGE = "StaticWallpaperPackage"
47         const val STATIC_WALLPAPER_CLASS = "StaticWallpaperClass"
48 
49         private const val TAG = "WallpaperModelFactory"
50         private const val UNKNOWN_COLLECTION_ID = "unknown_collection_id"
51 
52         fun WallpaperInfo.getCommonWallpaperData(context: Context): CommonWallpaperData {
53             var wallpaperDestination = Destination.NOT_APPLIED
54             if (this is CurrentWallpaperInfo) {
55                 wallpaperDestination =
56                     when (wallpaperManagerFlag) {
57                         WallpaperManager.FLAG_SYSTEM -> Destination.APPLIED_TO_SYSTEM
58                         WallpaperManager.FLAG_LOCK -> Destination.APPLIED_TO_LOCK
59                         WallpaperManager.FLAG_LOCK and WallpaperManager.FLAG_SYSTEM ->
60                             Destination.APPLIED_TO_SYSTEM_LOCK
61                         else -> {
62                             Log.w(
63                                 TAG,
64                                 "Invalid value for wallpaperManagerFlag: $wallpaperManagerFlag"
65                             )
66                             Destination.NOT_APPLIED
67                         }
68                     }
69             }
70 
71             // componentName is a valid value for liveWallpapers, for other types of wallpapers
72             // (which are static) we can have a constant value
73             val componentName =
74                 if (this is LiveWallpaperInfo) {
75                     wallpaperComponent.component
76                 } else {
77                     ComponentName(STATIC_WALLPAPER_PACKAGE, STATIC_WALLPAPER_CLASS)
78                 }
79 
80             val wallpaperId =
81                 WallpaperId(
82                     componentName = componentName,
83                     uniqueId =
84                         if (this is ImageWallpaperInfo && getWallpaperId() == null)
85                             "${uri.hashCode()}"
86                         else wallpaperId,
87                     // TODO(b/308800470): Figure out the use of collection ID
88                     collectionId = getCollectionId(context) ?: UNKNOWN_COLLECTION_ID,
89                 )
90 
91             val colorInfoOfWallpaper =
92                 ColorInfo(colorInfo.wallpaperColors, colorInfo.placeholderColor)
93 
94             return CommonWallpaperData(
95                 id = wallpaperId,
96                 title = getTitle(context),
97                 attributions = getAttributions(context),
98                 exploreActionUrl = getActionUrl(context),
99                 thumbAsset = getThumbAsset(context),
100                 placeholderColorInfo = colorInfoOfWallpaper,
101                 destination = wallpaperDestination,
102             )
103         }
104 
105         fun LiveWallpaperInfo.getLiveWallpaperData(
106             context: Context,
107             effectsController: EffectsController? = null
108         ): LiveWallpaperData {
109             val groupNameOfWallpaper = (this as? CreativeWallpaperInfo)?.groupName ?: ""
110             val wallpaperManager = WallpaperManager.getInstance(context)
111             val currentHomeWallpaper =
112                 wallpaperManager.getWallpaperInfo(WallpaperManager.FLAG_SYSTEM)
113             val currentLockWallpaper = wallpaperManager.getWallpaperInfo(WallpaperManager.FLAG_LOCK)
114             return LiveWallpaperData(
115                 groupName = groupNameOfWallpaper,
116                 systemWallpaperInfo = info,
117                 isTitleVisible = isVisibleTitle,
118                 isApplied = isApplied(currentHomeWallpaper, currentLockWallpaper),
119                 // TODO (331227828): don't relay on effectNames to determine if this is an effect
120                 // live wallpaper
121                 isEffectWallpaper = effectsController?.isEffectsWallpaper(info)
122                         ?: (effectNames != null),
123                 effectNames = effectNames,
124             )
125         }
126 
127         fun CreativeWallpaperInfo.getCreativeWallpaperData(): CreativeWallpaperData {
128             return CreativeWallpaperData(
129                 configPreviewUri = configPreviewUri,
130                 cleanPreviewUri = cleanPreviewUri,
131                 deleteUri = deleteUri,
132                 thumbnailUri = thumbnailUri,
133                 shareUri = shareUri,
134                 author = author ?: "",
135                 description = description ?: "",
136                 contentDescription = contentDescription,
137                 isCurrent = isCurrent,
138                 creativeWallpaperEffectsData = getCreativeWallpaperEffectData(),
139             )
140         }
141 
142         private fun CreativeWallpaperInfo.getCreativeWallpaperEffectData():
143             CreativeWallpaperEffectsData? {
144             val effectsBottomSheetTitle =
145                 effectsBottomSheetTitle.takeUnless { it.isNullOrEmpty() } ?: return null
146             val effectsBottomSheetSubtitle =
147                 effectsBottomSheetSubtitle.takeUnless { it.isNullOrEmpty() } ?: return null
148             val clearActionsUri =
149                 clearActionsUri.takeUnless { it?.scheme.isNullOrEmpty() } ?: return null
150             val effectsUri = effectsUri.takeUnless { it?.scheme.isNullOrEmpty() } ?: return null
151             return CreativeWallpaperEffectsData(
152                 effectsBottomSheetTitle = effectsBottomSheetTitle,
153                 effectsBottomSheetSubtitle = effectsBottomSheetSubtitle,
154                 currentEffectId = currentlyAppliedEffectId ?: "",
155                 clearActionUri = clearActionsUri,
156                 effectsUri = effectsUri,
157             )
158         }
159 
160         fun ImageWallpaperInfo.getImageWallpaperData(): ImageWallpaperData {
161             return ImageWallpaperData(uri)
162         }
163     }
164 }
165