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 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 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 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 118 public void maybeTakeSystemAppsSnapshot(int userId) { 119 if (shouldDeleteSystemApps(userId)) { 120 mSnapshot.takeNewSnapshot(userId); 121 } 122 } 123 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 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