15f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot/* 25f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Copyright 2014, The Android Open Source Project 35f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * 45f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Licensed under the Apache License, Version 2.0 (the "License"); 55f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * you may not use this file except in compliance with the License. 65f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * You may obtain a copy of the License at 75f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * 85f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * http://www.apache.org/licenses/LICENSE-2.0 95f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * 105f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * Unless required by applicable law or agreed to in writing, software 115f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * distributed under the License is distributed on an "AS IS" BASIS, 125f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * See the License for the specific language governing permissions and 145f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot * limitations under the License. 155f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot */ 165f22bf5fcf695d794e3de83c03ab88e4b21808fdNicolas Prevot 172818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnsepackage com.android.managedprovisioning.task; 182818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 193b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport android.content.BroadcastReceiver; 20c319f8de1ccf824a1c40997f3f0a71d47099b616Nicolas Prevotimport android.content.ComponentName; 212818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.content.Context; 222818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.content.Intent; 233b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport android.content.pm.ApplicationInfo; 24b20503c00736a21c24cfdf45ae72e3f7a264b4b6Nicolas Prevotimport android.content.pm.ComponentInfo; 25012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connorsimport android.content.pm.IPackageDeleteObserver; 262818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.content.pm.IPackageManager; 27089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnseimport android.content.pm.PackageInfo; 283b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport android.content.pm.PackageManager.NameNotFoundException; 292818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.content.pm.PackageManager; 302818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.content.pm.ResolveInfo; 31089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnseimport android.content.res.Resources; 322818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.os.RemoteException; 332818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport android.os.ServiceManager; 343b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport android.util.Xml; 353d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shankaimport android.view.inputmethod.InputMethodInfo; 363d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shankaimport android.view.inputmethod.InputMethodManager; 372818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 383b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport com.android.internal.util.FastXmlSerializer; 392818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport com.android.managedprovisioning.ProvisionLogger; 402818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport com.android.managedprovisioning.R; 41d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport com.android.managedprovisioning.Utils; 422818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 433b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport java.io.File; 443b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport java.io.FileInputStream; 453b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport java.io.FileOutputStream; 463b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport java.io.IOException; 473b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 48b20503c00736a21c24cfdf45ae72e3f7a264b4b6Nicolas Prevotimport java.util.ArrayList; 492818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport java.util.Arrays; 50d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnseimport java.util.Collections; 512818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport java.util.HashSet; 522818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport java.util.List; 532818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnseimport java.util.Set; 54012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connorsimport java.util.concurrent.atomic.AtomicInteger; 552818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 563b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport org.xmlpull.v1.XmlPullParser; 573b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport org.xmlpull.v1.XmlPullParserException; 583b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevotimport org.xmlpull.v1.XmlSerializer; 593b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 602818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse/** 61d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Deletes all system apps with a launcher that are not in the required set of packages. 62089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * Furthermore deletes all disallowed apps. 63089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * 64089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * Note: If an app is mistakenly listed as both required and disallowed, it will be treated as 65089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * required. 66d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * 67d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * This task may be run when a profile (both for managed device and managed profile) is created. 68d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * In that case the newProfile flag should be true. 69d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * 70d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * It should also be run after a system update with newProfile false, if 71d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * {@link #shouldDeleteNonRequiredApps} returns true. Note that only newly installed system apps 72d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * will be deleted. 732818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse */ 742818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnsepublic class DeleteNonRequiredAppsTask { 7528bffd6424a3d9f2dbefe6c7d6144f3a4edee3bcSander Alewijnse private final Callback mCallback; 762818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse private final Context mContext; 77089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final String mMdmPackageName; 782818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse private final IPackageManager mIpm; 792818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse private final PackageManager mPm; 80089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final List<String> mRequiredAppsList; 81089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final List<String> mDisallowedAppsList; 82089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final List<String> mVendorRequiredAppsList; 83089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final List<String> mVendorDisallowedAppsList; 842818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse private final int mUserId; 853d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka private final int mProvisioningType; 86089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private final boolean mNewProfile; // If we are provisioning a new managed profile/device. 87ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds private final boolean mLeaveAllSystemAppsEnabled; 883b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 89418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot private static final String TAG_SYSTEM_APPS = "system-apps"; 903b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot private static final String TAG_PACKAGE_LIST_ITEM = "item"; 913b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot private static final String ATTR_VALUE = "value"; 922818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 93089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse public static final int DEVICE_OWNER = 0; 94089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse public static final int PROFILE_OWNER = 1; 95d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 96089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse /** 97089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * Provisioning type should be either {@link #DEVICE_OWNER} or {@link #PROFILE_OWNER}. 98089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse **/ 99089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse public DeleteNonRequiredAppsTask(Context context, String mdmPackageName, int provisioningType, 100ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds boolean newProfile, int userId, boolean leaveAllSystemAppsEnabled, Callback callback) { 101089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 1022818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse mCallback = callback; 1032818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse mContext = context; 104089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mMdmPackageName = mdmPackageName; 1053d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka mProvisioningType = provisioningType; 1062818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse mUserId = userId; 107418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot mNewProfile = newProfile; 108ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds mLeaveAllSystemAppsEnabled = leaveAllSystemAppsEnabled; 109089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mIpm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); 110089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mPm = context.getPackageManager(); 111089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 112089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse int requiredAppsListArray; 113089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse int vendorRequiredAppsListArray; 114089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse int disallowedAppsListArray; 115089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse int vendorDisallowedAppsListArray; 1163d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka if (mProvisioningType == DEVICE_OWNER) { 117089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse requiredAppsListArray = R.array.required_apps_managed_device; 118089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse disallowedAppsListArray = R.array.disallowed_apps_managed_device; 119089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse vendorRequiredAppsListArray = R.array.vendor_required_apps_managed_device; 120089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse vendorDisallowedAppsListArray = R.array.vendor_disallowed_apps_managed_device; 1213d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka } else if (mProvisioningType == PROFILE_OWNER) { 122089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse requiredAppsListArray = R.array.required_apps_managed_profile; 123089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse disallowedAppsListArray = R.array.disallowed_apps_managed_profile; 124089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse vendorRequiredAppsListArray = R.array.vendor_required_apps_managed_profile; 125089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse vendorDisallowedAppsListArray = R.array.vendor_disallowed_apps_managed_profile; 126089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } else { 1273d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka throw new IllegalArgumentException("Provisioning type " + mProvisioningType + 128089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse " not supported."); 129089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } 130089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 131089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse Resources resources = mContext.getResources(); 132089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mRequiredAppsList = Arrays.asList(resources.getStringArray(requiredAppsListArray)); 133089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mDisallowedAppsList = Arrays.asList(resources.getStringArray(disallowedAppsListArray)); 134089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mVendorRequiredAppsList = Arrays.asList( 135089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse resources.getStringArray(vendorRequiredAppsListArray)); 136089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse mVendorDisallowedAppsList = Arrays.asList( 137089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse resources.getStringArray(vendorDisallowedAppsListArray)); 1382818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 1392818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 1402818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse public void run() { 141ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds if (mLeaveAllSystemAppsEnabled) { 142ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds ProvisionLogger.logd("Not deleting non-required apps."); 143ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds mCallback.onSuccess(); 144ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds return; 145ccd60165065172486fff32b581a0fb4d724b2991Julia Reynolds } 1463b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot ProvisionLogger.logd("Deleting non required apps."); 1473b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 1487d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot File systemAppsFile = getSystemAppsFile(mContext, mUserId); 1497d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot systemAppsFile.getParentFile().mkdirs(); // Creating the folder if it does not exist 1503b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 151d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse Set<String> currentApps = Utils.getCurrentSystemApps(mUserId); 152418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot Set<String> previousApps; 153418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot if (mNewProfile) { 1547d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot // Provisioning case. 155418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot previousApps = new HashSet<String>(); 156418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot } else { 1577d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot // OTA case. 1587d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot if (!systemAppsFile.exists()) { 159d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse ProvisionLogger.loge("Could not find the system apps file " + 160d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse systemAppsFile.getAbsolutePath()); 1617d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot mCallback.onError(); 162418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot return; 163418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot } 1647d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot previousApps = readSystemApps(systemAppsFile); 165418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot } 166d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 1677d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot writeSystemApps(currentApps, systemAppsFile); 1683b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot Set<String> newApps = currentApps; 1693b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot newApps.removeAll(previousApps); 1703b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 171089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse // Newly installed system apps are uninstalled when they are not required and are either 172089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse // disallowed or have a launcher icon. 1733b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot Set<String> packagesToDelete = newApps; 174089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse packagesToDelete.removeAll(getRequiredApps()); 175089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse Set<String> packagesToRetain = getCurrentAppsWithLauncher(); 1763d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka // Don't delete the system input method packages in case of Device owner provisioning. 1773d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka if (mProvisioningType == DEVICE_OWNER) { 1783d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka packagesToRetain.removeAll(getSystemInputMethods()); 1793d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka } 180089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse packagesToRetain.addAll(getDisallowedApps()); 181089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse packagesToDelete.retainAll(packagesToRetain); 182089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 1837d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot if (packagesToDelete.isEmpty()) { 1847d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot mCallback.onSuccess(); 1857d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot return; 1867d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot } 187089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse removeNonInstalledPackages(packagesToDelete); 188089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 1897d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot PackageDeleteObserver packageDeleteObserver = 1907d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot new PackageDeleteObserver(packagesToDelete.size()); 1917d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot for (String packageName : packagesToDelete) { 1927d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot try { 1937d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot mIpm.deletePackageAsUser(packageName, packageDeleteObserver, mUserId, 1947d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot PackageManager.DELETE_SYSTEM_APP); 1957d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot } catch (RemoteException neverThrown) { 196089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse // Never thrown, as we are making local calls. 197089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse ProvisionLogger.loge("This should not happen.", neverThrown); 198089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } 199089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } 200089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } 201089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse 202089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse /** 203089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse * Remove all packages from the set that are not installed. 204089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse */ 205089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private void removeNonInstalledPackages(Set<String> packages) { 206089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse Set<String> toBeRemoved = new HashSet<String>(); 207089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse for (String packageName : packages) { 208089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse try { 209089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse PackageInfo info = mIpm.getPackageInfo(packageName, 0 /* default flags */, mUserId); 210089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse if (info == null) { 211089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse toBeRemoved.add(packageName); 212089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } 213089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse } catch (RemoteException neverThrown) { 214089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse // Never thrown, as we are making local calls. 2157d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot ProvisionLogger.loge("This should not happen.", neverThrown); 2163b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2173b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 218089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse packages.removeAll(toBeRemoved); 2193b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 220b20503c00736a21c24cfdf45ae72e3f7a264b4b6Nicolas Prevot 2217d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot /** 222d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * Returns if this task should be run on OTA. 223d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse * This is indicated by the presence of the system apps file. 2247d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot */ 225d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse public static boolean shouldDeleteNonRequiredApps(Context context, int userId) { 226d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse return getSystemAppsFile(context, userId).exists(); 2273b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2282818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 229d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse static File getSystemAppsFile(Context context, int userId) { 230d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse return new File(context.getFilesDir() + File.separator + "system_apps" 231d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse + File.separator + "user" + userId + ".xml"); 2323b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2333b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 2343b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot private Set<String> getCurrentAppsWithLauncher() { 2352818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse Intent launcherIntent = new Intent(Intent.ACTION_MAIN); 2362818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER); 2373b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot List<ResolveInfo> resolveInfos = mPm.queryIntentActivitiesAsUser(launcherIntent, 2383bcd298ae1efa3c3ee78ecc4f114d498fcac2685Nicolas Prevot PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS, 2393bcd298ae1efa3c3ee78ecc4f114d498fcac2685Nicolas Prevot mUserId); 2403b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot Set<String> apps = new HashSet<String>(); 2413b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot for (ResolveInfo resolveInfo : resolveInfos) { 2423b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot apps.add(resolveInfo.activityInfo.packageName); 2433b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2443b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot return apps; 2453b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2462818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 2473d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka private Set<String> getSystemInputMethods() { 2483d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka final InputMethodManager inputMethodManager = 2493d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 2503d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka List<InputMethodInfo> inputMethods = inputMethodManager.getInputMethodList(); 2513d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka Set<String> systemInputMethods = new HashSet<String>(); 2523d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka for (InputMethodInfo inputMethodInfo : inputMethods) { 2533d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka ApplicationInfo applicationInfo = inputMethodInfo.getServiceInfo().applicationInfo; 2543d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 2553d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka systemInputMethods.add(inputMethodInfo.getPackageName()); 2563d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka } 2573d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka } 2583d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka return systemInputMethods; 2593d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka } 2603d24d0966fbbb4b67ceb06fe373db147a1b793bfSudheer Shanka 2617d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot private void writeSystemApps(Set<String> packageNames, File systemAppsFile) { 2623b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot try { 2637d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot FileOutputStream stream = new FileOutputStream(systemAppsFile, false); 2643b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot XmlSerializer serializer = new FastXmlSerializer(); 2653b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.setOutput(stream, "utf-8"); 2663b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.startDocument(null, true); 267418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot serializer.startTag(null, TAG_SYSTEM_APPS); 2683b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot for (String packageName : packageNames) { 2693b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.startTag(null, TAG_PACKAGE_LIST_ITEM); 2703b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.attribute(null, ATTR_VALUE, packageName); 2713b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.endTag(null, TAG_PACKAGE_LIST_ITEM); 2722818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 273418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot serializer.endTag(null, TAG_SYSTEM_APPS); 2743b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot serializer.endDocument(); 2753b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot stream.close(); 2763b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } catch (IOException e) { 277418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot ProvisionLogger.loge("IOException trying to write the system apps", e); 2782818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 2793b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2802818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 2817d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot private Set<String> readSystemApps(File systemAppsFile) { 2823b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot Set<String> result = new HashSet<String>(); 2837d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot if (!systemAppsFile.exists()) { 2843b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot return result; 2853b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2863b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot try { 2877d56b9097cf040afa85bfc93f78a30436754eaf8Nicolas Prevot FileInputStream stream = new FileInputStream(systemAppsFile); 2883b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 2893b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot XmlPullParser parser = Xml.newPullParser(); 2903b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot parser.setInput(stream, null); 2913b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot 2923b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot int type = parser.next(); 2933b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot int outerDepth = parser.getDepth(); 2943b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 2953b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2963b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 2973b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot continue; 2983b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 2993b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot String tag = parser.getName(); 3003b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot if (tag.equals(TAG_PACKAGE_LIST_ITEM)) { 3013b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot result.add(parser.getAttributeValue(null, ATTR_VALUE)); 3023b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } else { 3033b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot ProvisionLogger.loge("Unknown tag: " + tag); 3043b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } 3052818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 3063b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot stream.close(); 3073b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } catch (IOException e) { 308418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot ProvisionLogger.loge("IOException trying to read the system apps", e); 3093b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot } catch (XmlPullParserException e) { 310418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot ProvisionLogger.loge("XmlPullParserException trying to read the system apps", e); 3112818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 3123b76f0d34ed293c310605a66711cf3aba42f09e6Nicolas Prevot return result; 3132818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 3142818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 315089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse protected Set<String> getRequiredApps() { 316089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse HashSet<String> requiredApps = new HashSet<String>(); 317089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse requiredApps.addAll(mRequiredAppsList); 318089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse requiredApps.addAll(mVendorRequiredAppsList); 319089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse requiredApps.add(mMdmPackageName); 3202818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse return requiredApps; 3212818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 3222818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse 323089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse private Set<String> getDisallowedApps() { 324089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse HashSet<String> disallowedApps = new HashSet<String>(); 325089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse disallowedApps.addAll(mDisallowedAppsList); 326089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse disallowedApps.addAll(mVendorDisallowedAppsList); 327089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse return disallowedApps; 328d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse } 329d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse 330012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors /** 331012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors * Runs the next task when all packages have been deleted or shuts down the activity if package 332012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors * deletion fails. 333012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors */ 334012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors class PackageDeleteObserver extends IPackageDeleteObserver.Stub { 335012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors private final AtomicInteger mPackageCount = new AtomicInteger(0); 336012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors 337012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors public PackageDeleteObserver(int packageCount) { 338012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors this.mPackageCount.set(packageCount); 339012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors } 340012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors 341012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors @Override 342012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors public void packageDeleted(String packageName, int returnCode) { 343012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors if (returnCode != PackageManager.DELETE_SUCCEEDED) { 344012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors ProvisionLogger.logw( 345418aaf4c4ff54e5f890bff004e120d8d5e5af755Nicolas Prevot "Could not finish the provisioning: package deletion failed"); 346012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors mCallback.onError(); 347d5e4c42542dd96d8940912cc20dff20fa48da0d9Sander Alewijnse return; 348012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors } 349012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors int currentPackageCount = mPackageCount.decrementAndGet(); 350012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors if (currentPackageCount == 0) { 351089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse ProvisionLogger.logi("All non-required system apps with launcher icon, " 352089a4fada683bf5e6415e0fa8b2b62ecb333f9c7Sander Alewijnse + "and all disallowed apps have been uninstalled."); 353012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors mCallback.onSuccess(); 354012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors } 355012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors } 356012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors } 357012c9bbe972e78cc7341000c3ec517ccfc27d22aAdam Connors 3582818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse public abstract static class Callback { 3592818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse public abstract void onSuccess(); 3602818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse public abstract void onError(); 3612818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse } 3622818d32aa494363a59d3b0f47695e317f47b689bSander Alewijnse} 363