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