1 /* 2 * Copyright (C) 2016 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.applications; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.ComponentInfo; 24 import android.content.pm.IPackageManager; 25 import android.content.pm.PackageManager; 26 import android.content.pm.ResolveInfo; 27 import android.content.pm.UserInfo; 28 import android.location.LocationManager; 29 import android.os.RemoteException; 30 import android.os.UserManager; 31 import android.telecom.DefaultDialerManager; 32 import android.text.TextUtils; 33 import android.util.ArraySet; 34 35 import com.android.internal.telephony.SmsApplication; 36 import com.android.settings.R; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Set; 41 42 public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvider { 43 44 protected final Context mContext; 45 private final PackageManager mPm; 46 private final IPackageManager mPms; 47 private final DevicePolicyManager mDpm; 48 private final UserManager mUm; 49 ApplicationFeatureProviderImpl(Context context, PackageManager pm, IPackageManager pms, DevicePolicyManager dpm)50 public ApplicationFeatureProviderImpl(Context context, PackageManager pm, 51 IPackageManager pms, DevicePolicyManager dpm) { 52 mContext = context.getApplicationContext(); 53 mPm = pm; 54 mPms = pms; 55 mDpm = dpm; 56 mUm = UserManager.get(mContext); 57 } 58 59 @Override calculateNumberOfPolicyInstalledApps(boolean async, NumberOfAppsCallback callback)60 public void calculateNumberOfPolicyInstalledApps(boolean async, NumberOfAppsCallback callback) { 61 final CurrentUserAndManagedProfilePolicyInstalledAppCounter counter = 62 new CurrentUserAndManagedProfilePolicyInstalledAppCounter(mContext, mPm, callback); 63 if (async) { 64 counter.execute(); 65 } else { 66 counter.executeInForeground(); 67 } 68 } 69 70 @Override listPolicyInstalledApps(ListOfAppsCallback callback)71 public void listPolicyInstalledApps(ListOfAppsCallback callback) { 72 final CurrentUserPolicyInstalledAppLister lister = 73 new CurrentUserPolicyInstalledAppLister(mPm, mUm, callback); 74 lister.execute(); 75 } 76 77 @Override calculateNumberOfAppsWithAdminGrantedPermissions(String[] permissions, boolean async, NumberOfAppsCallback callback)78 public void calculateNumberOfAppsWithAdminGrantedPermissions(String[] permissions, 79 boolean async, NumberOfAppsCallback callback) { 80 final CurrentUserAndManagedProfileAppWithAdminGrantedPermissionsCounter counter = 81 new CurrentUserAndManagedProfileAppWithAdminGrantedPermissionsCounter(mContext, 82 permissions, mPm, mPms, mDpm, callback); 83 if (async) { 84 counter.execute(); 85 } else { 86 counter.executeInForeground(); 87 } 88 } 89 90 @Override listAppsWithAdminGrantedPermissions(String[] permissions, ListOfAppsCallback callback)91 public void listAppsWithAdminGrantedPermissions(String[] permissions, 92 ListOfAppsCallback callback) { 93 final CurrentUserAppWithAdminGrantedPermissionsLister lister = 94 new CurrentUserAppWithAdminGrantedPermissionsLister(permissions, mPm, mPms, mDpm, 95 mUm, callback); 96 lister.execute(); 97 } 98 99 @Override findPersistentPreferredActivities(int userId, Intent[] intents)100 public List<UserAppInfo> findPersistentPreferredActivities(int userId, Intent[] intents) { 101 final List<UserAppInfo> preferredActivities = new ArrayList<>(); 102 final Set<UserAppInfo> uniqueApps = new ArraySet<>(); 103 final UserInfo userInfo = mUm.getUserInfo(userId); 104 for (final Intent intent : intents) { 105 try { 106 final ResolveInfo resolveInfo = 107 mPms.findPersistentPreferredActivity(intent, userId); 108 if (resolveInfo != null) { 109 ComponentInfo componentInfo = null; 110 if (resolveInfo.activityInfo != null) { 111 componentInfo = resolveInfo.activityInfo; 112 } else if (resolveInfo.serviceInfo != null) { 113 componentInfo = resolveInfo.serviceInfo; 114 } else if (resolveInfo.providerInfo != null) { 115 componentInfo = resolveInfo.providerInfo; 116 } 117 if (componentInfo != null) { 118 UserAppInfo info = new UserAppInfo(userInfo, componentInfo.applicationInfo); 119 if (uniqueApps.add(info)) { 120 preferredActivities.add(info); 121 } 122 } 123 } 124 } catch (RemoteException exception) { 125 } 126 } 127 return preferredActivities; 128 } 129 130 @Override getKeepEnabledPackages()131 public Set<String> getKeepEnabledPackages() { 132 // Find current default phone/sms app. We should keep them enabled. 133 final Set<String> keepEnabledPackages = new ArraySet<>(); 134 final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mContext); 135 if (!TextUtils.isEmpty(defaultDialer)) { 136 keepEnabledPackages.add(defaultDialer); 137 } 138 final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication( 139 mContext, true /* updateIfNeeded */); 140 if (defaultSms != null) { 141 keepEnabledPackages.add(defaultSms.getPackageName()); 142 } 143 144 keepEnabledPackages.addAll(getEnabledPackageWhitelist()); 145 146 final LocationManager locationManager = 147 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 148 final String locationHistoryPackage = locationManager.getExtraLocationControllerPackage(); 149 if (locationHistoryPackage != null) { 150 keepEnabledPackages.add(locationHistoryPackage); 151 } 152 return keepEnabledPackages; 153 } 154 getEnabledPackageWhitelist()155 private Set<String> getEnabledPackageWhitelist() { 156 final Set<String> keepEnabledPackages = new ArraySet<>(); 157 158 // Keep Settings intelligence enabled, otherwise search feature will be disabled. 159 keepEnabledPackages.add( 160 mContext.getString(R.string.config_settingsintelligence_package_name)); 161 162 // Keep Package Installer enabled. 163 keepEnabledPackages.add(mContext.getString(R.string.config_package_installer_package_name)); 164 165 return keepEnabledPackages; 166 } 167 168 private static class CurrentUserAndManagedProfilePolicyInstalledAppCounter 169 extends InstalledAppCounter { 170 private NumberOfAppsCallback mCallback; 171 CurrentUserAndManagedProfilePolicyInstalledAppCounter(Context context, PackageManager packageManager, NumberOfAppsCallback callback)172 CurrentUserAndManagedProfilePolicyInstalledAppCounter(Context context, 173 PackageManager packageManager, NumberOfAppsCallback callback) { 174 super(context, PackageManager.INSTALL_REASON_POLICY, packageManager); 175 mCallback = callback; 176 } 177 178 @Override onCountComplete(int num)179 protected void onCountComplete(int num) { 180 mCallback.onNumberOfAppsResult(num); 181 } 182 } 183 184 private static class CurrentUserAndManagedProfileAppWithAdminGrantedPermissionsCounter 185 extends AppWithAdminGrantedPermissionsCounter { 186 private NumberOfAppsCallback mCallback; 187 CurrentUserAndManagedProfileAppWithAdminGrantedPermissionsCounter(Context context, String[] permissions, PackageManager packageManager, IPackageManager packageManagerService, DevicePolicyManager devicePolicyManager, NumberOfAppsCallback callback)188 CurrentUserAndManagedProfileAppWithAdminGrantedPermissionsCounter(Context context, 189 String[] permissions, PackageManager packageManager, 190 IPackageManager packageManagerService, 191 DevicePolicyManager devicePolicyManager, NumberOfAppsCallback callback) { 192 super(context, permissions, packageManager, packageManagerService, devicePolicyManager); 193 mCallback = callback; 194 } 195 196 @Override onCountComplete(int num)197 protected void onCountComplete(int num) { 198 mCallback.onNumberOfAppsResult(num); 199 } 200 } 201 202 private static class CurrentUserPolicyInstalledAppLister extends InstalledAppLister { 203 private ListOfAppsCallback mCallback; 204 CurrentUserPolicyInstalledAppLister(PackageManager packageManager, UserManager userManager, ListOfAppsCallback callback)205 CurrentUserPolicyInstalledAppLister(PackageManager packageManager, 206 UserManager userManager, ListOfAppsCallback callback) { 207 super(packageManager, userManager); 208 mCallback = callback; 209 } 210 211 @Override onAppListBuilt(List<UserAppInfo> list)212 protected void onAppListBuilt(List<UserAppInfo> list) { 213 mCallback.onListOfAppsResult(list); 214 } 215 } 216 217 private static class CurrentUserAppWithAdminGrantedPermissionsLister extends 218 AppWithAdminGrantedPermissionsLister { 219 private ListOfAppsCallback mCallback; 220 CurrentUserAppWithAdminGrantedPermissionsLister(String[] permissions, PackageManager packageManager, IPackageManager packageManagerService, DevicePolicyManager devicePolicyManager, UserManager userManager, ListOfAppsCallback callback)221 CurrentUserAppWithAdminGrantedPermissionsLister(String[] permissions, 222 PackageManager packageManager, IPackageManager packageManagerService, 223 DevicePolicyManager devicePolicyManager, UserManager userManager, 224 ListOfAppsCallback callback) { 225 super(permissions, packageManager, packageManagerService, devicePolicyManager, 226 userManager); 227 mCallback = callback; 228 } 229 230 @Override onAppListBuilt(List<UserAppInfo> list)231 protected void onAppListBuilt(List<UserAppInfo> list) { 232 mCallback.onListOfAppsResult(list); 233 } 234 } 235 } 236