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