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