1 /* 2 * Copyright (C) 2014 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.server.devicepolicy; 18 19 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; 20 21 import android.annotation.Nullable; 22 import android.app.ActivityManagerInternal; 23 import android.app.AppOpsManagerInternal; 24 import android.app.admin.DevicePolicyManager.DeviceOwnerType; 25 import android.app.admin.SystemUpdateInfo; 26 import android.app.admin.SystemUpdatePolicy; 27 import android.content.ComponentName; 28 import android.content.pm.PackageManager; 29 import android.content.pm.PackageManagerInternal; 30 import android.os.Binder; 31 import android.os.Process; 32 import android.os.UserHandle; 33 import android.os.UserManager; 34 import android.util.ArraySet; 35 import android.util.IndentingPrintWriter; 36 import android.util.Pair; 37 import android.util.Slog; 38 import android.util.SparseArray; 39 import android.util.SparseIntArray; 40 41 import com.android.internal.annotations.GuardedBy; 42 import com.android.internal.annotations.VisibleForTesting; 43 import com.android.server.LocalServices; 44 import com.android.server.devicepolicy.OwnersData.OwnerInfo; 45 import com.android.server.pm.UserManagerInternal; 46 import com.android.server.wm.ActivityTaskManagerInternal; 47 48 import java.io.File; 49 import java.time.LocalDate; 50 import java.util.ArrayList; 51 import java.util.List; 52 import java.util.Objects; 53 import java.util.Set; 54 55 /** 56 * Stores and restores state for the Device and Profile owners and related device-wide information. 57 * By definition there can be only one device owner, but there may be a profile owner for each user. 58 * 59 * <p>This class is thread safe, so individual methods can safely be called without locking. 60 * However, caller must still synchronize on their side to ensure integrity between multiple calls. 61 */ 62 class Owners { 63 private static final String TAG = "DevicePolicyManagerService"; 64 65 private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE 66 67 private final UserManager mUserManager; 68 private final UserManagerInternal mUserManagerInternal; 69 private final PackageManagerInternal mPackageManagerInternal; 70 private final ActivityTaskManagerInternal mActivityTaskManagerInternal; 71 private final ActivityManagerInternal mActivityManagerInternal; 72 73 @GuardedBy("mData") 74 private final OwnersData mData; 75 76 private boolean mSystemReady; 77 78 @VisibleForTesting Owners(UserManager userManager, UserManagerInternal userManagerInternal, PackageManagerInternal packageManagerInternal, ActivityTaskManagerInternal activityTaskManagerInternal, ActivityManagerInternal activityManagerInternal, PolicyPathProvider pathProvider)79 Owners(UserManager userManager, 80 UserManagerInternal userManagerInternal, 81 PackageManagerInternal packageManagerInternal, 82 ActivityTaskManagerInternal activityTaskManagerInternal, 83 ActivityManagerInternal activityManagerInternal, 84 PolicyPathProvider pathProvider) { 85 mUserManager = userManager; 86 mUserManagerInternal = userManagerInternal; 87 mPackageManagerInternal = packageManagerInternal; 88 mActivityTaskManagerInternal = activityTaskManagerInternal; 89 mActivityManagerInternal = activityManagerInternal; 90 mData = new OwnersData(pathProvider); 91 } 92 93 /** 94 * Load configuration from the disk. 95 */ load()96 void load() { 97 synchronized (mData) { 98 int[] usersIds = 99 mUserManager.getAliveUsers().stream().mapToInt(u -> u.id).toArray(); 100 mData.load(usersIds); 101 102 mUserManagerInternal.setDeviceManaged(hasDeviceOwner()); 103 for (int userId : usersIds) { 104 mUserManagerInternal.setUserManaged(userId, hasProfileOwner(userId)); 105 } 106 107 notifyChangeLocked(); 108 pushToActivityTaskManagerLocked(); 109 } 110 } 111 112 // Notify interested parties that things have changed. This does not notify the 113 // ActivityTaskManager. 114 @GuardedBy("mData") notifyChangeLocked()115 private void notifyChangeLocked() { 116 pushToDevicePolicyManager(); 117 pushToPackageManagerLocked(); 118 pushToActivityManagerLocked(); 119 pushToAppOpsLocked(); 120 } 121 pushToDevicePolicyManager()122 private void pushToDevicePolicyManager() { 123 // Not every change here must invalidate the DPM caches, but there is no harm in 124 // invalidating the caches unnecessarily, provided the invalidation is infrequent. 125 DevicePolicyManagerService.invalidateBinderCaches(); 126 } 127 128 @GuardedBy("mData") pushToPackageManagerLocked()129 private void pushToPackageManagerLocked() { 130 final SparseArray<String> po = new SparseArray<>(); 131 for (int i = mData.mProfileOwners.size() - 1; i >= 0; i--) { 132 po.put(mData.mProfileOwners.keyAt(i), mData.mProfileOwners.valueAt(i).packageName); 133 } 134 final String doPackage = mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null; 135 mPackageManagerInternal.setDeviceAndProfileOwnerPackages( 136 mData.mDeviceOwnerUserId, doPackage, po); 137 } 138 139 @GuardedBy("mData") pushToActivityTaskManagerLocked()140 private void pushToActivityTaskManagerLocked() { 141 mActivityTaskManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked()); 142 } 143 144 @GuardedBy("mData") pushToActivityManagerLocked()145 private void pushToActivityManagerLocked() { 146 mActivityManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked()); 147 148 final ArraySet<Integer> profileOwners = new ArraySet<>(); 149 for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) { 150 final int userId = mData.mProfileOwners.keyAt(poi); 151 final int profileOwnerUid = mPackageManagerInternal.getPackageUid( 152 mData.mProfileOwners.valueAt(poi).packageName, 153 PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES, 154 userId); 155 if (profileOwnerUid >= 0) { 156 profileOwners.add(profileOwnerUid); 157 } 158 } 159 mActivityManagerInternal.setProfileOwnerUid(profileOwners); 160 } 161 162 @GuardedBy("mData") getDeviceOwnerUidLocked()163 int getDeviceOwnerUidLocked() { 164 if (mData.mDeviceOwner != null) { 165 return mPackageManagerInternal.getPackageUid(mData.mDeviceOwner.packageName, 166 PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES, 167 mData.mDeviceOwnerUserId); 168 } else { 169 return Process.INVALID_UID; 170 } 171 } 172 getDeviceOwnerPackageName()173 String getDeviceOwnerPackageName() { 174 synchronized (mData) { 175 return mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null; 176 } 177 } 178 getDeviceOwnerUserId()179 int getDeviceOwnerUserId() { 180 synchronized (mData) { 181 return mData.mDeviceOwnerUserId; 182 } 183 } 184 185 @Nullable getDeviceOwnerUserIdAndComponent()186 Pair<Integer, ComponentName> getDeviceOwnerUserIdAndComponent() { 187 synchronized (mData) { 188 if (mData.mDeviceOwner == null) { 189 return null; 190 } else { 191 return Pair.create(mData.mDeviceOwnerUserId, mData.mDeviceOwner.admin); 192 } 193 } 194 } 195 getDeviceOwnerName()196 String getDeviceOwnerName() { 197 synchronized (mData) { 198 return mData.mDeviceOwner != null ? mData.mDeviceOwner.name : null; 199 } 200 } 201 getDeviceOwnerComponent()202 ComponentName getDeviceOwnerComponent() { 203 synchronized (mData) { 204 return mData.mDeviceOwner != null ? mData.mDeviceOwner.admin : null; 205 } 206 } 207 getDeviceOwnerRemoteBugreportUri()208 String getDeviceOwnerRemoteBugreportUri() { 209 synchronized (mData) { 210 return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportUri : null; 211 } 212 } 213 getDeviceOwnerRemoteBugreportHash()214 String getDeviceOwnerRemoteBugreportHash() { 215 synchronized (mData) { 216 return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportHash : null; 217 } 218 } 219 setDeviceOwner(ComponentName admin, String ownerName, int userId)220 void setDeviceOwner(ComponentName admin, String ownerName, int userId) { 221 if (userId < 0) { 222 Slog.e(TAG, "Invalid user id for device owner user: " + userId); 223 return; 224 } 225 synchronized (mData) { 226 // A device owner is allowed to access device identifiers. Even though this flag 227 // is not currently checked for device owner, it is set to true here so that it is 228 // semantically compatible with the meaning of this flag. 229 mData.mDeviceOwner = new OwnerInfo(ownerName, admin, /* remoteBugreportUri =*/ null, 230 /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true); 231 mData.mDeviceOwnerUserId = userId; 232 233 mUserManagerInternal.setDeviceManaged(true); 234 notifyChangeLocked(); 235 pushToActivityTaskManagerLocked(); 236 } 237 } 238 clearDeviceOwner()239 void clearDeviceOwner() { 240 synchronized (mData) { 241 mData.mDeviceOwnerTypes.remove(mData.mDeviceOwner.packageName); 242 mData.mDeviceOwner = null; 243 mData.mDeviceOwnerUserId = UserHandle.USER_NULL; 244 245 mUserManagerInternal.setDeviceManaged(false); 246 notifyChangeLocked(); 247 pushToActivityTaskManagerLocked(); 248 } 249 } 250 setProfileOwner(ComponentName admin, String ownerName, int userId)251 void setProfileOwner(ComponentName admin, String ownerName, int userId) { 252 synchronized (mData) { 253 // For a newly set PO, there's no need for migration. 254 mData.mProfileOwners.put(userId, new OwnerInfo(ownerName, admin, 255 /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null, 256 /* isOrganizationOwnedDevice =*/ false)); 257 mUserManagerInternal.setUserManaged(userId, true); 258 notifyChangeLocked(); 259 } 260 } 261 removeProfileOwner(int userId)262 void removeProfileOwner(int userId) { 263 synchronized (mData) { 264 mData.mProfileOwners.remove(userId); 265 mUserManagerInternal.setUserManaged(userId, false); 266 notifyChangeLocked(); 267 } 268 } 269 transferProfileOwner(ComponentName target, int userId)270 void transferProfileOwner(ComponentName target, int userId) { 271 synchronized (mData) { 272 final OwnerInfo ownerInfo = mData.mProfileOwners.get(userId); 273 final OwnerInfo newOwnerInfo = new OwnerInfo(target.getPackageName(), target, 274 ownerInfo.remoteBugreportUri, ownerInfo.remoteBugreportHash, 275 ownerInfo.isOrganizationOwnedDevice); 276 mData.mProfileOwners.put(userId, newOwnerInfo); 277 notifyChangeLocked(); 278 } 279 } 280 transferDeviceOwnership(ComponentName target)281 void transferDeviceOwnership(ComponentName target) { 282 synchronized (mData) { 283 Integer previousDeviceOwnerType = mData.mDeviceOwnerTypes.remove( 284 mData.mDeviceOwner.packageName); 285 // We don't set a name because it's not used anyway. 286 // See DevicePolicyManagerService#getDeviceOwnerName 287 mData.mDeviceOwner = new OwnerInfo(null, target, 288 mData.mDeviceOwner.remoteBugreportUri, 289 mData.mDeviceOwner.remoteBugreportHash, 290 mData.mDeviceOwner.isOrganizationOwnedDevice); 291 292 if (previousDeviceOwnerType != null) { 293 mData.mDeviceOwnerTypes.put( 294 mData.mDeviceOwner.packageName, previousDeviceOwnerType); 295 } 296 notifyChangeLocked(); 297 pushToActivityTaskManagerLocked(); 298 } 299 } 300 getProfileOwnerComponent(int userId)301 ComponentName getProfileOwnerComponent(int userId) { 302 synchronized (mData) { 303 OwnerInfo profileOwner = mData.mProfileOwners.get(userId); 304 return profileOwner != null ? profileOwner.admin : null; 305 } 306 } 307 getProfileOwnerName(int userId)308 String getProfileOwnerName(int userId) { 309 synchronized (mData) { 310 OwnerInfo profileOwner = mData.mProfileOwners.get(userId); 311 return profileOwner != null ? profileOwner.name : null; 312 } 313 } 314 getProfileOwnerPackage(int userId)315 String getProfileOwnerPackage(int userId) { 316 synchronized (mData) { 317 OwnerInfo profileOwner = mData.mProfileOwners.get(userId); 318 return profileOwner != null ? profileOwner.packageName : null; 319 } 320 } 321 322 /** 323 * Returns true if {@code userId} has a profile owner and that profile owner is on an 324 * organization-owned device, as indicated by the provisioning flow. 325 */ isProfileOwnerOfOrganizationOwnedDevice(int userId)326 boolean isProfileOwnerOfOrganizationOwnedDevice(int userId) { 327 synchronized (mData) { 328 OwnerInfo profileOwner = mData.mProfileOwners.get(userId); 329 return profileOwner != null ? profileOwner.isOrganizationOwnedDevice : false; 330 } 331 } 332 getProfileOwnerKeys()333 Set<Integer> getProfileOwnerKeys() { 334 synchronized (mData) { 335 return mData.mProfileOwners.keySet(); 336 } 337 } 338 listAllOwners()339 List<OwnerShellData> listAllOwners() { 340 List<OwnerShellData> owners = new ArrayList<>(); 341 synchronized (mData) { 342 if (mData.mDeviceOwner != null) { 343 owners.add(OwnerShellData.forDeviceOwner(mData.mDeviceOwnerUserId, 344 mData.mDeviceOwner.admin)); 345 } 346 for (int i = 0; i < mData.mProfileOwners.size(); i++) { 347 int userId = mData.mProfileOwners.keyAt(i); 348 OwnerInfo info = mData.mProfileOwners.valueAt(i); 349 owners.add(OwnerShellData.forUserProfileOwner(userId, info.admin)); 350 } 351 } 352 return owners; 353 } 354 355 getSystemUpdatePolicy()356 SystemUpdatePolicy getSystemUpdatePolicy() { 357 synchronized (mData) { 358 return mData.mSystemUpdatePolicy; 359 } 360 } 361 setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy)362 void setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy) { 363 synchronized (mData) { 364 mData.mSystemUpdatePolicy = systemUpdatePolicy; 365 } 366 } 367 clearSystemUpdatePolicy()368 void clearSystemUpdatePolicy() { 369 synchronized (mData) { 370 mData.mSystemUpdatePolicy = null; 371 } 372 } 373 getSystemUpdateFreezePeriodRecord()374 Pair<LocalDate, LocalDate> getSystemUpdateFreezePeriodRecord() { 375 synchronized (mData) { 376 return new Pair<>(mData.mSystemUpdateFreezeStart, 377 mData.mSystemUpdateFreezeEnd); 378 } 379 } 380 getSystemUpdateFreezePeriodRecordAsString()381 String getSystemUpdateFreezePeriodRecordAsString() { 382 synchronized (mData) { 383 return mData.getSystemUpdateFreezePeriodRecordAsString(); 384 } 385 } 386 387 /** 388 * Returns {@code true} if the freeze period record is changed, {@code false} otherwise. 389 */ setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end)390 boolean setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end) { 391 boolean changed = false; 392 synchronized (mData) { 393 if (!Objects.equals(mData.mSystemUpdateFreezeStart, start)) { 394 mData.mSystemUpdateFreezeStart = start; 395 changed = true; 396 } 397 if (!Objects.equals(mData.mSystemUpdateFreezeEnd, end)) { 398 mData.mSystemUpdateFreezeEnd = end; 399 changed = true; 400 } 401 } 402 return changed; 403 } 404 hasDeviceOwner()405 boolean hasDeviceOwner() { 406 synchronized (mData) { 407 return mData.mDeviceOwner != null; 408 } 409 } 410 isDeviceOwnerUserId(int userId)411 boolean isDeviceOwnerUserId(int userId) { 412 synchronized (mData) { 413 return mData.mDeviceOwner != null && mData.mDeviceOwnerUserId == userId; 414 } 415 } 416 hasProfileOwner(int userId)417 boolean hasProfileOwner(int userId) { 418 synchronized (mData) { 419 return getProfileOwnerComponent(userId) != null; 420 } 421 } 422 423 /** Sets the remote bugreport uri and hash, and also writes to the file. */ setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri, String remoteBugreportHash)424 void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri, 425 String remoteBugreportHash) { 426 synchronized (mData) { 427 if (mData.mDeviceOwner != null) { 428 mData.mDeviceOwner.remoteBugreportUri = remoteBugreportUri; 429 mData.mDeviceOwner.remoteBugreportHash = remoteBugreportHash; 430 } 431 writeDeviceOwner(); 432 } 433 } 434 435 /** Set whether the profile owner manages an organization-owned device, then write to file. */ setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice)436 void setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice) { 437 synchronized (mData) { 438 OwnerInfo profileOwner = mData.mProfileOwners.get(userId); 439 if (profileOwner != null) { 440 profileOwner.isOrganizationOwnedDevice = isOrganizationOwnedDevice; 441 } else { 442 Slog.e(TAG, String.format( 443 "No profile owner for user %d to set org-owned flag.", userId)); 444 } 445 writeProfileOwner(userId); 446 } 447 } 448 setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType, boolean isAdminTestOnly)449 void setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType, 450 boolean isAdminTestOnly) { 451 synchronized (mData) { 452 if (!hasDeviceOwner()) { 453 Slog.e(TAG, "Attempting to set a device owner type when there is no device owner"); 454 return; 455 } else if (!isAdminTestOnly && isDeviceOwnerTypeSetForDeviceOwner(packageName)) { 456 Slog.e(TAG, "Setting the device owner type more than once is only allowed" 457 + " for test only admins"); 458 return; 459 } 460 461 mData.mDeviceOwnerTypes.put(packageName, deviceOwnerType); 462 writeDeviceOwner(); 463 } 464 } 465 466 @DeviceOwnerType getDeviceOwnerType(String packageName)467 int getDeviceOwnerType(String packageName) { 468 synchronized (mData) { 469 if (isDeviceOwnerTypeSetForDeviceOwner(packageName)) { 470 return mData.mDeviceOwnerTypes.get(packageName); 471 } 472 return DEVICE_OWNER_TYPE_DEFAULT; 473 } 474 } 475 isDeviceOwnerTypeSetForDeviceOwner(String packageName)476 boolean isDeviceOwnerTypeSetForDeviceOwner(String packageName) { 477 synchronized (mData) { 478 return !mData.mDeviceOwnerTypes.isEmpty() 479 && mData.mDeviceOwnerTypes.containsKey(packageName); 480 } 481 } 482 writeDeviceOwner()483 void writeDeviceOwner() { 484 synchronized (mData) { 485 pushToDevicePolicyManager(); 486 mData.writeDeviceOwner(); 487 } 488 } 489 writeProfileOwner(int userId)490 void writeProfileOwner(int userId) { 491 synchronized (mData) { 492 pushToDevicePolicyManager(); 493 mData.writeProfileOwner(userId); 494 } 495 } 496 497 /** 498 * Saves the given {@link SystemUpdateInfo} if it is different from the existing one, or if 499 * none exists. 500 * 501 * @return Whether the saved system update information has changed. 502 */ saveSystemUpdateInfo(@ullable SystemUpdateInfo newInfo)503 boolean saveSystemUpdateInfo(@Nullable SystemUpdateInfo newInfo) { 504 synchronized (mData) { 505 // Check if we already have the same update information. 506 if (Objects.equals(newInfo, mData.mSystemUpdateInfo)) { 507 return false; 508 } 509 510 mData.mSystemUpdateInfo = newInfo; 511 mData.writeDeviceOwner(); 512 return true; 513 } 514 } 515 516 @Nullable getSystemUpdateInfo()517 public SystemUpdateInfo getSystemUpdateInfo() { 518 synchronized (mData) { 519 return mData.mSystemUpdateInfo; 520 } 521 } 522 523 @GuardedBy("mData") pushToAppOpsLocked()524 void pushToAppOpsLocked() { 525 if (!mSystemReady) { 526 return; 527 } 528 final long ident = Binder.clearCallingIdentity(); 529 try { 530 final SparseIntArray owners = new SparseIntArray(); 531 if (mData.mDeviceOwner != null) { 532 final int uid = getDeviceOwnerUidLocked(); 533 if (uid >= 0) { 534 owners.put(mData.mDeviceOwnerUserId, uid); 535 } 536 } 537 if (mData.mProfileOwners != null) { 538 for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) { 539 final int uid = mPackageManagerInternal.getPackageUid( 540 mData.mProfileOwners.valueAt(poi).packageName, 541 PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES, 542 mData.mProfileOwners.keyAt(poi)); 543 if (uid >= 0) { 544 owners.put(mData.mProfileOwners.keyAt(poi), uid); 545 } 546 } 547 } 548 AppOpsManagerInternal appops = LocalServices.getService(AppOpsManagerInternal.class); 549 if (appops != null) { 550 appops.setDeviceAndProfileOwners(owners.size() > 0 ? owners : null); 551 } 552 } finally { 553 Binder.restoreCallingIdentity(ident); 554 } 555 } 556 systemReady()557 public void systemReady() { 558 synchronized (mData) { 559 mSystemReady = true; 560 pushToActivityManagerLocked(); 561 pushToAppOpsLocked(); 562 } 563 } 564 dump(IndentingPrintWriter pw)565 public void dump(IndentingPrintWriter pw) { 566 synchronized (mData) { 567 mData.dump(pw); 568 } 569 } 570 571 @VisibleForTesting getDeviceOwnerFile()572 File getDeviceOwnerFile() { 573 return mData.getDeviceOwnerFile(); 574 } 575 576 @VisibleForTesting getProfileOwnerFile(int userId)577 File getProfileOwnerFile(int userId) { 578 return mData.getProfileOwnerFile(userId); 579 } 580 } 581