1 /* <lambda>null2 * Copyright (C) 2022 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.settings.spa.app.appinfo 18 19 import android.app.ActivityManager 20 import android.content.ComponentName 21 import android.content.Context 22 import android.content.pm.ApplicationInfo 23 import android.content.pm.PackageManager 24 import android.content.pm.ResolveInfo 25 import com.android.settingslib.RestrictedLockUtils 26 import com.android.settingslib.RestrictedLockUtilsInternal 27 import com.android.settingslib.Utils 28 import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager 29 import com.android.settingslib.spaprivileged.model.app.isDisallowControl 30 import com.android.settingslib.spaprivileged.model.app.userId 31 32 class AppButtonRepository(private val context: Context) { 33 private val packageManager = context.packageManager 34 private val devicePolicyManager = context.devicePolicyManager 35 36 /** 37 * Checks whether the given application is disallowed from modifying. 38 */ 39 fun isDisallowControl(app: ApplicationInfo): Boolean = when { 40 // Not allow to control the device provisioning package. 41 Utils.isDeviceProvisioningPackage(context.resources, app.packageName) -> true 42 43 // If the uninstallation intent is already queued, disable the button. 44 devicePolicyManager.isUninstallInQueue(app.packageName) -> true 45 46 else -> app.isDisallowControl(context) 47 } 48 49 /** 50 * Checks whether uninstall is blocked by admin. 51 */ 52 fun isUninstallBlockedByAdmin(app: ApplicationInfo): Boolean = 53 RestrictedLockUtilsInternal.checkIfUninstallBlocked(context, app.packageName, app.userId) 54 ?.let { admin -> 55 RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) 56 true 57 } ?: false 58 59 fun getHomePackageInfo(): HomePackages { 60 val homePackages = mutableSetOf<String>() 61 val homeActivities = ArrayList<ResolveInfo>() 62 val currentDefaultHome = packageManager.getHomeActivities(homeActivities) 63 homeActivities.mapNotNull { it.activityInfo }.forEach { activityInfo -> 64 homePackages.add(activityInfo.packageName) 65 // Also make sure to include anything proxying for the home app 66 activityInfo.metaData?.getString(ActivityManager.META_HOME_ALTERNATE) 67 ?.takeIf { signaturesMatch(it, activityInfo.packageName) } 68 ?.let { homePackages.add(it) } 69 } 70 return HomePackages(homePackages, currentDefaultHome) 71 } 72 73 private fun signaturesMatch(packageName1: String, packageName2: String): Boolean = try { 74 packageManager.checkSignatures(packageName1, packageName2) >= PackageManager.SIGNATURE_MATCH 75 } catch (e: Exception) { 76 // e.g. named alternate package not found during lookup; this is an expected case sometimes 77 false 78 } 79 80 data class HomePackages( 81 val homePackages: Set<String>, 82 val currentDefaultHome: ComponentName?, 83 ) 84 } 85