1 /* 2 * Copyright (C) 2017 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; 18 19 import android.Manifest; 20 import android.annotation.Nullable; 21 import android.app.ActivityManager; 22 import android.content.Context; 23 import android.os.Binder; 24 import android.os.IBinder; 25 import android.os.UserHandle; 26 import android.os.UserManager; 27 import android.service.oemlock.IOemLockService; 28 import android.service.persistentdata.PersistentDataBlockManager; 29 30 /** 31 * Service for managing the OEM lock state of the device. 32 * 33 * The current implementation is a wrapper around the previous implementation of OEM lock. 34 * - the DISALLOW_OEM_UNLOCK user restriction was set if the carrier disallowed unlock 35 * - the user allows unlock in settings which calls PDBM.setOemUnlockEnabled() 36 */ 37 public class OemLockService extends SystemService { 38 private Context mContext; 39 40 public OemLockService(Context context) { 41 super(context); 42 mContext = context; 43 } 44 45 @Override 46 public void onStart() { 47 publishBinderService(Context.OEM_LOCK_SERVICE, mService); 48 } 49 50 private boolean doIsOemUnlockAllowedByCarrier() { 51 return !UserManager.get(mContext).hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK); 52 } 53 54 private boolean doIsOemUnlockAllowedByUser() { 55 final PersistentDataBlockManager pdbm = (PersistentDataBlockManager) 56 mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 57 58 final long token = Binder.clearCallingIdentity(); 59 try { 60 return pdbm.getOemUnlockEnabled(); 61 } finally { 62 Binder.restoreCallingIdentity(token); 63 } 64 } 65 66 /** 67 * Implements the binder interface for the service. 68 */ 69 private final IBinder mService = new IOemLockService.Stub() { 70 @Override 71 public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) { 72 enforceManageCarrierOemUnlockPermission(); 73 enforceUserIsAdmin(); 74 75 // Note: this implementation does not require a signature 76 77 // Continue using user restriction for backwards compatibility 78 final UserHandle userHandle = UserHandle.of(UserHandle.getCallingUserId()); 79 final long token = Binder.clearCallingIdentity(); 80 try { 81 UserManager.get(mContext) 82 .setUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, !allowed, userHandle); 83 } finally { 84 Binder.restoreCallingIdentity(token); 85 } 86 } 87 88 @Override 89 public boolean isOemUnlockAllowedByCarrier() { 90 enforceManageCarrierOemUnlockPermission(); 91 return doIsOemUnlockAllowedByCarrier(); 92 } 93 94 @Override 95 public void setOemUnlockAllowedByUser(boolean allowedByUser) { 96 if (ActivityManager.isUserAMonkey()) { 97 // Prevent a monkey from changing this 98 return; 99 } 100 101 enforceManageUserOemUnlockPermission(); 102 enforceUserIsAdmin(); 103 104 final PersistentDataBlockManager pdbm = (PersistentDataBlockManager) 105 mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE); 106 107 final long token = Binder.clearCallingIdentity(); 108 try { 109 // The method name is misleading as it really just means whether or not the device 110 // can be unlocked but doesn't actually do any unlocking. 111 pdbm.setOemUnlockEnabled(allowedByUser); 112 } finally { 113 Binder.restoreCallingIdentity(token); 114 } 115 } 116 117 @Override 118 public boolean isOemUnlockAllowedByUser() { 119 enforceManageUserOemUnlockPermission(); 120 return doIsOemUnlockAllowedByUser(); 121 } 122 }; 123 124 private void enforceManageCarrierOemUnlockPermission() { 125 mContext.enforceCallingOrSelfPermission( 126 Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE, 127 "Can't manage OEM unlock allowed by carrier"); 128 } 129 130 private void enforceManageUserOemUnlockPermission() { 131 mContext.enforceCallingOrSelfPermission( 132 Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE, 133 "Can't manage OEM unlock allowed by user"); 134 } 135 136 private void enforceUserIsAdmin() { 137 final int userId = UserHandle.getCallingUserId(); 138 final long token = Binder.clearCallingIdentity(); 139 try { 140 if (!UserManager.get(mContext).isUserAdmin(userId)) { 141 throw new SecurityException("Must be an admin user"); 142 } 143 } finally { 144 Binder.restoreCallingIdentity(token); 145 } 146 } 147 } 148