1 /* 2 * Copyright 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.managedprovisioning.task.nonrequiredapps; 18 19 import static com.android.internal.util.Preconditions.checkNotNull; 20 21 import android.annotation.IntDef; 22 import android.app.AppGlobals; 23 import android.content.Context; 24 import android.content.pm.IPackageManager; 25 import android.content.pm.PackageManager; 26 27 import com.android.internal.annotations.VisibleForTesting; 28 import com.android.managedprovisioning.common.Utils; 29 import com.android.managedprovisioning.model.ProvisioningParams; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.Collections; 34 import java.util.Set; 35 36 /** 37 * Logic that calculates which system apps should be removed during profile creation and subsequent 38 * OTAs. It also decides whether a snapshot should be taken or not. 39 */ 40 public class NonRequiredAppsLogic { 41 42 @IntDef({ 43 Case.OTA_LEAVE_APPS, 44 Case.OTA_REMOVE_APPS, 45 Case.NEW_PROFILE_LEAVE_APPS, 46 Case.NEW_PROFILE_REMOVE_APPS 47 }) 48 @Retention(RetentionPolicy.SOURCE) 49 private @interface Case { 50 int OTA_LEAVE_APPS = 0; 51 int OTA_REMOVE_APPS = 1; 52 int NEW_PROFILE_LEAVE_APPS = 2; 53 int NEW_PROFILE_REMOVE_APPS = 3; 54 } 55 56 private final PackageManager mPackageManager; 57 private final IPackageManager mIPackageManager; 58 private final boolean mNewProfile; 59 private final ProvisioningParams mParams; 60 private final SystemAppsSnapshot mSnapshot; 61 private final OverlayPackagesProvider mProvider; 62 private final Utils mUtils; 63 NonRequiredAppsLogic( Context context, boolean newProfile, ProvisioningParams params)64 public NonRequiredAppsLogic( 65 Context context, 66 boolean newProfile, 67 ProvisioningParams params) { 68 this( 69 context.getPackageManager(), 70 AppGlobals.getPackageManager(), 71 newProfile, 72 params, 73 new SystemAppsSnapshot(context), 74 new OverlayPackagesProvider(context, params), 75 new Utils()); 76 } 77 78 @VisibleForTesting NonRequiredAppsLogic( PackageManager packageManager, IPackageManager iPackageManager, boolean newProfile, ProvisioningParams params, SystemAppsSnapshot snapshot, OverlayPackagesProvider provider, Utils utils)79 NonRequiredAppsLogic( 80 PackageManager packageManager, 81 IPackageManager iPackageManager, 82 boolean newProfile, 83 ProvisioningParams params, 84 SystemAppsSnapshot snapshot, 85 OverlayPackagesProvider provider, 86 Utils utils) { 87 mPackageManager = checkNotNull(packageManager); 88 mIPackageManager = checkNotNull(iPackageManager); 89 mNewProfile = newProfile; 90 mParams = checkNotNull(params); 91 mSnapshot = checkNotNull(snapshot); 92 mProvider = checkNotNull(provider); 93 mUtils = checkNotNull(utils); 94 } 95 getSystemAppsToRemove(int userId)96 public Set<String> getSystemAppsToRemove(int userId) { 97 if (!shouldDeleteSystemApps(userId)) { 98 return Collections.emptySet(); 99 } 100 101 // Start with all system apps 102 Set<String> newSystemApps = mUtils.getCurrentSystemApps(mIPackageManager, userId); 103 104 // Remove the ones that were already present in the last snapshot only when OTA 105 if (!mNewProfile) { 106 newSystemApps.removeAll(mSnapshot.getSnapshot(userId)); 107 } 108 109 // Get the packages from the black/white lists 110 Set<String> packagesToDelete = mProvider.getNonRequiredApps(userId); 111 112 // Retain only new system apps 113 packagesToDelete.retainAll(newSystemApps); 114 115 return packagesToDelete; 116 } 117 maybeTakeSystemAppsSnapshot(int userId)118 public void maybeTakeSystemAppsSnapshot(int userId) { 119 if (shouldDeleteSystemApps(userId)) { 120 mSnapshot.takeNewSnapshot(userId); 121 } 122 } 123 shouldDeleteSystemApps(int userId)124 private boolean shouldDeleteSystemApps(int userId) { 125 @Case int which = getCase(userId); 126 return (Case.NEW_PROFILE_REMOVE_APPS == which) || (Case.OTA_REMOVE_APPS == which); 127 } 128 getCase(int userId)129 private @Case int getCase(int userId) { 130 if (mNewProfile) { 131 if (mParams.leaveAllSystemAppsEnabled) { 132 return Case.NEW_PROFILE_LEAVE_APPS; 133 } else { 134 return Case.NEW_PROFILE_REMOVE_APPS; 135 } 136 } else { 137 if (mSnapshot.hasSnapshot(userId)) { 138 return Case.OTA_REMOVE_APPS; 139 } else { 140 return Case.OTA_LEAVE_APPS; 141 } 142 } 143 } 144 } 145