1 /* <lambda>null2 * Copyright (C) 2024 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.picker.category.data.repository 18 19 import android.content.Context 20 import android.util.Log 21 import com.android.wallpaper.config.BaseFlags 22 import com.android.wallpaper.model.Category 23 import com.android.wallpaper.picker.category.client.DefaultWallpaperCategoryClient 24 import com.android.wallpaper.picker.data.category.CategoryModel 25 import com.android.wallpaper.picker.di.modules.BackgroundDispatcher 26 import com.android.wallpaper.util.converter.category.CategoryFactory 27 import dagger.hilt.android.qualifiers.ApplicationContext 28 import javax.inject.Inject 29 import javax.inject.Singleton 30 import kotlinx.coroutines.CoroutineScope 31 import kotlinx.coroutines.flow.MutableStateFlow 32 import kotlinx.coroutines.flow.StateFlow 33 import kotlinx.coroutines.flow.asStateFlow 34 import kotlinx.coroutines.launch 35 36 @Singleton 37 open class DefaultWallpaperCategoryRepository 38 @Inject 39 constructor( 40 @ApplicationContext val context: Context, 41 private val defaultWallpaperClient: DefaultWallpaperCategoryClient, 42 private val categoryFactory: CategoryFactory, 43 @BackgroundDispatcher private val backgroundScope: CoroutineScope, 44 ) : WallpaperCategoryRepository { 45 46 private var myPhotosFetchedCategory: Category? = null 47 private var onDeviceFetchedCategory: Category? = null 48 private var thirdPartyFetchedCategory: List<Category> = emptyList() 49 private var systemFetchedCategories: List<Category> = emptyList() 50 private var thirdPartyLiveWallpaperFetchedCategories: List<Category> = emptyList() 51 52 override fun getMyPhotosFetchedCategory(): Category? { 53 return myPhotosFetchedCategory 54 } 55 56 override fun getOnDeviceFetchedCategories(): Category? { 57 return onDeviceFetchedCategory 58 } 59 60 override fun getThirdPartyFetchedCategories(): List<Category> { 61 return thirdPartyFetchedCategory 62 } 63 64 override fun getSystemFetchedCategories(): List<Category> { 65 return systemFetchedCategories 66 } 67 68 override fun getThirdPartyLiveWallpaperFetchedCategories(): List<Category> { 69 return thirdPartyLiveWallpaperFetchedCategories 70 } 71 72 private val _systemCategories = MutableStateFlow<List<CategoryModel>>(emptyList()) 73 override val systemCategories: StateFlow<List<CategoryModel>> = _systemCategories.asStateFlow() 74 75 private val _myPhotosCategory = MutableStateFlow<CategoryModel?>(null) 76 override val myPhotosCategory: StateFlow<CategoryModel?> = _myPhotosCategory.asStateFlow() 77 78 private val _onDeviceCategory = MutableStateFlow<CategoryModel?>(null) 79 override val onDeviceCategory: StateFlow<CategoryModel?> = _onDeviceCategory.asStateFlow() 80 81 private val _thirdPartyAppCategory = MutableStateFlow<List<CategoryModel>>(emptyList()) 82 override val thirdPartyAppCategory: StateFlow<List<CategoryModel>> = 83 _thirdPartyAppCategory.asStateFlow() 84 85 private val _thirdPartyLiveWallpaperCategory = 86 MutableStateFlow<List<CategoryModel>>(emptyList()) 87 override val thirdPartyLiveWallpaperCategory: StateFlow<List<CategoryModel>> = 88 _thirdPartyLiveWallpaperCategory.asStateFlow() 89 90 private val _isDefaultCategoriesFetched = MutableStateFlow(false) 91 override val isDefaultCategoriesFetched: StateFlow<Boolean> = 92 _isDefaultCategoriesFetched.asStateFlow() 93 94 init { 95 if (BaseFlags.get().isWallpaperCategoryRefactoringEnabled()) { 96 backgroundScope.launch { fetchAllCategories() } 97 } 98 } 99 100 private suspend fun fetchAllCategories() { 101 try { 102 fetchSystemCategories() 103 fetchMyPhotosCategory() 104 fetchOnDeviceCategory() 105 fetchThirdPartyAppCategory() 106 fetchThirdPartyLiveWallpaperCategory() 107 } catch (e: Exception) { 108 Log.e(TAG, "Error fetching default categories", e) 109 } finally { 110 _isDefaultCategoriesFetched.value = true 111 } 112 } 113 114 private suspend fun fetchThirdPartyLiveWallpaperCategory() { 115 try { 116 val excludedPackageNames = defaultWallpaperClient.getExcludedLiveWallpaperPackageNames() 117 thirdPartyLiveWallpaperFetchedCategories = 118 defaultWallpaperClient.getThirdPartyLiveWallpaperCategory(excludedPackageNames) 119 val processedCategories = 120 thirdPartyLiveWallpaperFetchedCategories.map { 121 categoryFactory.getCategoryModel(it) 122 } 123 _thirdPartyLiveWallpaperCategory.value = processedCategories 124 } catch (e: Exception) { 125 Log.e(TAG, "Error fetching third party live wallpaper categories", e) 126 } 127 } 128 129 private suspend fun fetchSystemCategories() { 130 try { 131 systemFetchedCategories = defaultWallpaperClient.getSystemCategories() 132 val processedCategories = 133 systemFetchedCategories.map { categoryFactory.getCategoryModel(it) } 134 _systemCategories.value = processedCategories 135 } catch (e: Exception) { 136 Log.e(TAG, "Error fetching system categories", e) 137 } 138 } 139 140 override suspend fun fetchMyPhotosCategory() { 141 try { 142 myPhotosFetchedCategory = defaultWallpaperClient.getMyPhotosCategory() 143 myPhotosFetchedCategory.let { category -> 144 _myPhotosCategory.value = category?.let { categoryFactory.getCategoryModel(it) } 145 } 146 } catch (e: Exception) { 147 Log.e(TAG, "Error fetching My Photos category", e) 148 } 149 } 150 151 override suspend fun refreshNetworkCategories() {} 152 153 override suspend fun refreshThirdPartyAppCategories() { 154 _isDefaultCategoriesFetched.value = false 155 fetchThirdPartyAppCategory() 156 _isDefaultCategoriesFetched.value = true 157 } 158 159 override suspend fun refreshThirdPartyLiveWallpaperCategories() { 160 _isDefaultCategoriesFetched.value = false 161 fetchThirdPartyLiveWallpaperCategory() 162 _isDefaultCategoriesFetched.value = true 163 } 164 165 private suspend fun fetchOnDeviceCategory() { 166 try { 167 onDeviceFetchedCategory = 168 (defaultWallpaperClient as? DefaultWallpaperCategoryClient)?.getOnDeviceCategory() 169 _onDeviceCategory.value = 170 onDeviceFetchedCategory?.let { categoryFactory.getCategoryModel(it) } 171 } catch (e: Exception) { 172 Log.e(TAG, "Error fetching On Device category", e) 173 } 174 } 175 176 private suspend fun fetchThirdPartyAppCategory() { 177 try { 178 val excludedPackageNames = defaultWallpaperClient.getExcludedThirdPartyPackageNames() 179 thirdPartyFetchedCategory = 180 defaultWallpaperClient.getThirdPartyCategory(excludedPackageNames) 181 val processedCategories = 182 thirdPartyFetchedCategory.map { category -> 183 categoryFactory.getCategoryModel(category) 184 } 185 _thirdPartyAppCategory.value = processedCategories 186 } catch (e: Exception) { 187 Log.e(TAG, "Error fetching third party app categories", e) 188 } 189 } 190 191 companion object { 192 private const val TAG = "DefaultWallpaperCategoryRepository" 193 } 194 } 195