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.ota; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; 22 23 import static com.android.internal.util.Preconditions.checkNotNull; 24 25 import android.app.admin.DevicePolicyManager; 26 import android.content.ComponentName; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.content.pm.ResolveInfo; 31 import android.content.pm.UserInfo; 32 import android.os.UserHandle; 33 import android.os.UserManager; 34 import android.util.ArraySet; 35 import android.view.inputmethod.InputMethod; 36 37 import com.android.internal.annotations.VisibleForTesting; 38 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 39 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 40 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 41 import com.android.managedprovisioning.common.ProvisionLogger; 42 import com.android.managedprovisioning.common.SettingsFacade; 43 import com.android.managedprovisioning.model.ProvisioningParams; 44 import com.android.managedprovisioning.task.CrossProfileIntentFiltersSetter; 45 import com.android.managedprovisioning.task.DeleteNonRequiredAppsTask; 46 import com.android.managedprovisioning.task.DisableInstallShortcutListenersTask; 47 import com.android.managedprovisioning.task.DisallowAddUserTask; 48 import com.android.managedprovisioning.task.InstallExistingPackageTask; 49 import com.android.managedprovisioning.task.MigrateSystemAppsSnapshotTask; 50 import com.android.managedprovisioning.task.UpdateInteractAcrossProfilesAppOpTask; 51 52 import java.util.List; 53 import java.util.function.IntFunction; 54 55 /** 56 * After a system update, this class resets the cross-profile intent filters and performs any 57 * tasks necessary to bring the system up to date. 58 */ 59 public class OtaController { 60 61 private static final String TELECOM_PACKAGE = "com.android.server.telecom"; 62 63 private final Context mContext; 64 private final TaskExecutor mTaskExecutor; 65 private final CrossProfileIntentFiltersSetter mCrossProfileIntentFiltersSetter; 66 67 private final UserManager mUserManager; 68 private final DevicePolicyManager mDevicePolicyManager; 69 70 private final IntFunction<ArraySet<String>> mMissingSystemImeProvider; 71 private final ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker; 72 OtaController(Context context)73 public OtaController(Context context) { 74 this(context, new TaskExecutor(), new CrossProfileIntentFiltersSetter(context), 75 userId -> getMissingSystemImePackages(context, UserHandle.of(userId)), 76 new ProvisioningAnalyticsTracker( 77 MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()), 78 new ManagedProvisioningSharedPreferences(context))); 79 } 80 81 @VisibleForTesting OtaController(Context context, TaskExecutor taskExecutor, CrossProfileIntentFiltersSetter crossProfileIntentFiltersSetter, IntFunction<ArraySet<String>> missingSystemImeProvider, ProvisioningAnalyticsTracker provisioningAnalyticsTracker)82 OtaController(Context context, TaskExecutor taskExecutor, 83 CrossProfileIntentFiltersSetter crossProfileIntentFiltersSetter, 84 IntFunction<ArraySet<String>> missingSystemImeProvider, 85 ProvisioningAnalyticsTracker provisioningAnalyticsTracker) { 86 mContext = checkNotNull(context); 87 mTaskExecutor = checkNotNull(taskExecutor); 88 mCrossProfileIntentFiltersSetter = checkNotNull(crossProfileIntentFiltersSetter); 89 mProvisioningAnalyticsTracker = checkNotNull(provisioningAnalyticsTracker); 90 91 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 92 mDevicePolicyManager = (DevicePolicyManager) context.getSystemService( 93 Context.DEVICE_POLICY_SERVICE); 94 95 mMissingSystemImeProvider = missingSystemImeProvider; 96 } 97 run()98 public void run() { 99 if (mContext.getUserId() != UserHandle.USER_SYSTEM) { 100 return; 101 } 102 // Migrate snapshot files to use user serial number as file name. 103 mTaskExecutor.execute( 104 UserHandle.USER_SYSTEM, new MigrateSystemAppsSnapshotTask( 105 mContext, mTaskExecutor, mProvisioningAnalyticsTracker)); 106 107 // Check for device owner. 108 final int deviceOwnerUserId = mDevicePolicyManager.getDeviceOwnerUserId(); 109 if (deviceOwnerUserId != UserHandle.USER_NULL) { 110 addDeviceOwnerTasks(deviceOwnerUserId, mContext); 111 } 112 113 for (UserInfo userInfo : mUserManager.getUsers()) { 114 if (userInfo.isManagedProfile()) { 115 addManagedProfileTasks(userInfo.id, mContext); 116 } else if (mDevicePolicyManager.getProfileOwnerAsUser(userInfo.id) != null) { 117 addManagedUserTasks(userInfo.id, mContext); 118 } else { 119 // if this user has managed profiles, reset the cross-profile intent filters between 120 // this user and its managed profiles. 121 mCrossProfileIntentFiltersSetter.resetFilters(userInfo.id); 122 } 123 } 124 125 mTaskExecutor.execute(mContext.getUserId(), new UpdateInteractAcrossProfilesAppOpTask( 126 mContext, 127 /* params= */ null, 128 mTaskExecutor, 129 mProvisioningAnalyticsTracker 130 )); 131 } 132 addDeviceOwnerTasks(final int userId, Context context)133 void addDeviceOwnerTasks(final int userId, Context context) { 134 ComponentName deviceOwner = mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser(); 135 if (deviceOwner == null) { 136 // Shouldn't happen 137 ProvisionLogger.loge("No device owner found."); 138 return; 139 } 140 141 // Build a set of fake params to be able to run the tasks 142 ProvisioningParams fakeParams = new ProvisioningParams.Builder() 143 .setDeviceAdminComponentName(deviceOwner) 144 .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE) 145 .build(); 146 147 mTaskExecutor.execute(userId, 148 new DeleteNonRequiredAppsTask(false, context, fakeParams, mTaskExecutor, 149 mProvisioningAnalyticsTracker)); 150 mTaskExecutor.execute(userId, 151 new DisallowAddUserTask(UserManager.isSplitSystemUser(), context, fakeParams, 152 mTaskExecutor, mProvisioningAnalyticsTracker)); 153 } 154 addManagedProfileTasks(final int userId, Context context)155 void addManagedProfileTasks(final int userId, Context context) { 156 mUserManager.setUserRestriction(UserManager.DISALLOW_WALLPAPER, true, 157 UserHandle.of(userId)); 158 // Enabling telecom package as it supports managed profiles from N. 159 mTaskExecutor.execute(userId, 160 new InstallExistingPackageTask(TELECOM_PACKAGE, context, null, mTaskExecutor, 161 mProvisioningAnalyticsTracker)); 162 163 ComponentName profileOwner = mDevicePolicyManager.getProfileOwnerAsUser(userId); 164 if (profileOwner == null) { 165 // Shouldn't happen. 166 ProvisionLogger.loge("No profile owner on managed profile " + userId); 167 return; 168 } 169 170 // Build a set of fake params to be able to run the tasks 171 ProvisioningParams fakeParams = new ProvisioningParams.Builder() 172 .setDeviceAdminComponentName(profileOwner) 173 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 174 .build(); 175 mTaskExecutor.execute(userId, 176 new DisableInstallShortcutListenersTask(context, fakeParams, mTaskExecutor, 177 mProvisioningAnalyticsTracker)); 178 mTaskExecutor.execute(userId, 179 new DeleteNonRequiredAppsTask(false, context, fakeParams, mTaskExecutor, 180 mProvisioningAnalyticsTracker)); 181 182 // Copying missing system IMEs if necessary. 183 mMissingSystemImeProvider.apply(userId).forEach(packageName -> mTaskExecutor.execute(userId, 184 new InstallExistingPackageTask(packageName, context, fakeParams, mTaskExecutor, 185 mProvisioningAnalyticsTracker))); 186 } 187 addManagedUserTasks(final int userId, Context context)188 void addManagedUserTasks(final int userId, Context context) { 189 ComponentName profileOwner = mDevicePolicyManager.getProfileOwnerAsUser(userId); 190 if (profileOwner == null) { 191 // Shouldn't happen. 192 ProvisionLogger.loge("No profile owner on managed user " + userId); 193 return; 194 } 195 196 // Build a set of fake params to be able to run the tasks 197 ProvisioningParams fakeParams = new ProvisioningParams.Builder() 198 .setDeviceAdminComponentName(profileOwner) 199 .setProvisioningAction(ACTION_PROVISION_MANAGED_USER) 200 .build(); 201 mTaskExecutor.execute(userId, 202 new DeleteNonRequiredAppsTask(false, context, fakeParams, mTaskExecutor, 203 mProvisioningAnalyticsTracker)); 204 } 205 206 /** 207 * Returns IME packages that can be installed from the profile parent user. 208 * 209 * @param context {@link Context} of the caller. 210 * @param userHandle {@link UserHandle} that specifies the user. 211 * @return A set of IME package names that can be installed from the profile parent user. 212 */ getMissingSystemImePackages(Context context, UserHandle userHandle)213 private static ArraySet<String> getMissingSystemImePackages(Context context, 214 UserHandle userHandle) { 215 ArraySet<String> profileParentSystemImes = getInstalledSystemImePackages(context, 216 context.getSystemService(UserManager.class).getProfileParent(userHandle)); 217 ArraySet<String> installedSystemImes = getInstalledSystemImePackages(context, userHandle); 218 profileParentSystemImes.removeAll(installedSystemImes); 219 return profileParentSystemImes; 220 } 221 222 /** 223 * Returns a set of the installed IME package names for the given user. 224 * 225 * @param context {@link Context} of the caller. 226 * @param userHandle {@link UserHandle} that specifies the user. 227 * @return A set of IME package names. 228 */ getInstalledSystemImePackages(Context context, UserHandle userHandle)229 private static ArraySet<String> getInstalledSystemImePackages(Context context, 230 UserHandle userHandle) { 231 PackageManager packageManager; 232 try { 233 packageManager = context 234 .createPackageContextAsUser("android", 0, userHandle) 235 .getPackageManager(); 236 } catch (PackageManager.NameNotFoundException e) { 237 return new ArraySet<>(); 238 } 239 List<ResolveInfo> resolveInfoList = packageManager.queryIntentServices( 240 new Intent(InputMethod.SERVICE_INTERFACE), 241 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DISABLED_COMPONENTS); 242 ArraySet<String> result = new ArraySet<>(); 243 for (ResolveInfo resolveInfo : resolveInfoList) { 244 result.add(resolveInfo.serviceInfo.packageName); 245 } 246 return result; 247 } 248 } 249