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.client 18 19 import android.content.Context 20 import android.content.Intent 21 import android.content.pm.ApplicationInfo 22 import android.content.pm.PackageManager 23 import android.content.pm.ResolveInfo 24 import android.service.wallpaper.WallpaperService 25 import android.util.Log 26 import com.android.wallpaper.model.WallpaperInfo 27 import com.android.wallpaper.module.InjectorProvider 28 import dagger.hilt.android.qualifiers.ApplicationContext 29 import org.xmlpull.v1.XmlPullParserException 30 import java.io.IOException 31 import java.text.Collator 32 import javax.inject.Inject 33 import javax.inject.Singleton 34 35 /** 36 * Defines methods related to handling of live wallpapers. 37 */ 38 @Singleton 39 class LiveWallpapersClientImpl @Inject constructor(@ApplicationContext val context: Context): 40 LiveWallpapersClient { 41 42 override fun getAll( 43 excludedPackageNames: Set<String?>? 44 ): List<WallpaperInfo> { 45 val resolveInfos = getAllOnDevice() 46 val wallpaperInfos: MutableList<WallpaperInfo> = mutableListOf() 47 val factory = 48 InjectorProvider.getInjector().getLiveWallpaperInfoFactory(context) 49 50 resolveInfos.forEach { resolveInfo -> 51 val wallpaperInfo: android.app.WallpaperInfo 52 try { 53 wallpaperInfo = android.app.WallpaperInfo(context, resolveInfo) 54 } catch (e: XmlPullParserException) { 55 Log.w(TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e) 56 return@forEach 57 } catch (e: IOException) { 58 Log.w(TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e) 59 return@forEach 60 } 61 if (excludedPackageNames != null 62 && excludedPackageNames.contains(wallpaperInfo.packageName)) { 63 return@forEach 64 } 65 wallpaperInfos.add(factory.getLiveWallpaperInfo(wallpaperInfo)) 66 } 67 68 return wallpaperInfos 69 } 70 71 /** 72 * Returns ResolveInfo objects for all live wallpaper services installed on the device. System 73 * wallpapers are listed first, unsorted, with other installed wallpapers following sorted 74 * in alphabetical order. 75 */ 76 fun getAllOnDevice(): List<ResolveInfo> { 77 val pm = context.packageManager 78 val packageName = context.packageName 79 80 val resolveInfos = pm.queryIntentServices( 81 Intent(WallpaperService.SERVICE_INTERFACE), 82 PackageManager.GET_META_DATA 83 ) 84 85 val wallpaperInfos: MutableList<ResolveInfo> = mutableListOf() 86 87 // Remove the "Rotating Image Wallpaper" live wallpaper, which is owned by this package, 88 // and separate system wallpapers to sort only non-system ones. 89 val iter = resolveInfos.iterator() 90 while (iter.hasNext()) { 91 val resolveInfo = iter.next() 92 if (packageName == resolveInfo.serviceInfo.packageName) { 93 iter.remove() 94 } else if (isSystemApp(resolveInfo.serviceInfo.applicationInfo)) { 95 wallpaperInfos.add(resolveInfo) 96 iter.remove() 97 } 98 } 99 100 if (resolveInfos.isEmpty()) { 101 return wallpaperInfos 102 } 103 104 // Sort non-system wallpapers alphabetically and append them to system ones 105 val collator = Collator.getInstance() 106 resolveInfos.sortWith(compareBy(collator) { it.loadLabel(pm).toString() }) 107 108 wallpaperInfos.addAll(resolveInfos) 109 110 return wallpaperInfos 111 } 112 113 private fun isSystemApp(appInfo: ApplicationInfo): Boolean { 114 return (appInfo.flags and (ApplicationInfo.FLAG_SYSTEM 115 or ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0 } 116 117 companion object { 118 private const val TAG = "LiveWallpapersClient" 119 } 120 }