1 /* 2 * Copyright (C) 2012 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.wm; 18 19 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 20 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 21 22 import android.app.admin.DevicePolicyCache; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.Context; 25 import android.os.Handler; 26 import android.os.IBinder; 27 import android.os.Process; 28 import android.os.UserHandle; 29 import android.os.UserManagerInternal; 30 31 import com.android.internal.annotations.VisibleForTesting; 32 import com.android.server.LocalServices; 33 import com.android.server.policy.WindowManagerPolicy; 34 import com.android.server.utils.UserTokenWatcher; 35 import com.android.server.wm.LockTaskController.LockTaskToken; 36 37 class KeyguardDisableHandler { 38 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardDisableHandler" : TAG_WM; 39 40 private final UserTokenWatcher mAppTokenWatcher; 41 private final UserTokenWatcher mSystemTokenWatcher; 42 43 private int mCurrentUser = UserHandle.USER_SYSTEM; 44 private Injector mInjector; 45 46 @VisibleForTesting KeyguardDisableHandler(Injector injector, Handler handler)47 KeyguardDisableHandler(Injector injector, Handler handler) { 48 mInjector = injector; 49 mAppTokenWatcher = new UserTokenWatcher(mCallback, handler, TAG); 50 mSystemTokenWatcher = new UserTokenWatcher(mCallback, handler, TAG); 51 } 52 setCurrentUser(int user)53 public void setCurrentUser(int user) { 54 synchronized (this) { 55 mCurrentUser = user; 56 updateKeyguardEnabledLocked(UserHandle.USER_ALL); 57 } 58 } 59 updateKeyguardEnabled(int userId)60 void updateKeyguardEnabled(int userId) { 61 synchronized (this) { 62 updateKeyguardEnabledLocked(userId); 63 } 64 } 65 updateKeyguardEnabledLocked(int userId)66 private void updateKeyguardEnabledLocked(int userId) { 67 if (mCurrentUser == userId || userId == UserHandle.USER_ALL) { 68 mInjector.enableKeyguard(shouldKeyguardBeEnabled(mCurrentUser)); 69 } 70 } 71 disableKeyguard(IBinder token, String tag, int callingUid, int userId)72 void disableKeyguard(IBinder token, String tag, int callingUid, int userId) { 73 UserTokenWatcher watcherForCaller = watcherForCallingUid(token, callingUid); 74 watcherForCaller.acquire(token, tag, mInjector.getProfileParentId(userId)); 75 } 76 reenableKeyguard(IBinder token, int callingUid, int userId)77 void reenableKeyguard(IBinder token, int callingUid, int userId) { 78 UserTokenWatcher watcherForCaller = watcherForCallingUid(token, callingUid); 79 watcherForCaller.release(token, mInjector.getProfileParentId(userId)); 80 } 81 watcherForCallingUid(IBinder token, int callingUid)82 private UserTokenWatcher watcherForCallingUid(IBinder token, int callingUid) { 83 if (Process.isApplicationUid(callingUid)) { 84 return mAppTokenWatcher; 85 } else if (callingUid == Process.SYSTEM_UID && token instanceof LockTaskToken) { 86 // We allow the lock task token here as a legacy case, because it enforces its own 87 // security guarantees. 88 // NOTE: DO NOT add new usages of this API in system server. It is deprecated and 89 // easily misused. 90 return mSystemTokenWatcher; 91 } else { 92 throw new UnsupportedOperationException("Only apps can use the KeyguardLock API"); 93 } 94 } 95 shouldKeyguardBeEnabled(int userId)96 private boolean shouldKeyguardBeEnabled(int userId) { 97 final boolean dpmRequiresPassword = mInjector.dpmRequiresPassword(mCurrentUser); 98 final boolean keyguardSecure = mInjector.isKeyguardSecure(mCurrentUser); 99 100 final boolean allowedFromApps = !dpmRequiresPassword && !keyguardSecure; 101 // The system can disable the keyguard for lock task mode even if the keyguard is secure, 102 // because it enforces its own security guarantees. 103 final boolean allowedFromSystem = !dpmRequiresPassword; 104 105 final boolean shouldBeDisabled = allowedFromApps && mAppTokenWatcher.isAcquired(userId) 106 || allowedFromSystem && mSystemTokenWatcher.isAcquired(userId); 107 return !shouldBeDisabled; 108 } 109 110 // Callback happens on mHandler thread. 111 private final UserTokenWatcher.Callback mCallback = new UserTokenWatcher.Callback() { 112 @Override 113 public void acquired(int userId) { 114 updateKeyguardEnabled(userId); 115 } 116 117 @Override 118 public void released(int userId) { 119 updateKeyguardEnabled(userId); 120 } 121 }; 122 create(Context context, WindowManagerPolicy policy, Handler handler)123 static KeyguardDisableHandler create(Context context, WindowManagerPolicy policy, 124 Handler handler) { 125 final UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class); 126 return new KeyguardDisableHandler(new Injector() { 127 @Override 128 public boolean dpmRequiresPassword(int userId) { 129 return DevicePolicyCache.getInstance().getPasswordQuality(userId) 130 != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 131 } 132 133 @Override 134 public boolean isKeyguardSecure(int userId) { 135 return policy.isKeyguardSecure(userId); 136 } 137 138 @Override 139 public int getProfileParentId(int userId) { 140 return userManager.getProfileParentId(userId); 141 } 142 143 @Override 144 public void enableKeyguard(boolean enabled) { 145 policy.enableKeyguard(enabled); 146 } 147 }, handler); 148 } 149 150 interface Injector { 151 boolean dpmRequiresPassword(int userId); 152 153 boolean isKeyguardSecure(int userId); 154 155 int getProfileParentId(int userId); 156 157 void enableKeyguard(boolean enabled); 158 } 159 } 160