blob: c9173a6430cca122d77ae1ff865da4b30a05bd14 [file] [log] [blame]
Craig Mautner5642a482012-08-23 12:16:53 -07001/*
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
17package com.android.server.wm;
18
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080019import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
20import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
21
Craig Mautner5642a482012-08-23 12:16:53 -070022import android.app.admin.DevicePolicyManager;
23import android.content.Context;
24import android.os.Handler;
25import android.os.IBinder;
Adrian Roos1c8e3c02018-11-20 20:07:55 +010026import android.os.Process;
27import android.os.UserHandle;
28import android.os.UserManagerInternal;
Adrian Roose99bc052017-11-20 17:55:31 +010029
Adrian Roos1c8e3c02018-11-20 20:07:55 +010030import com.android.internal.annotations.VisibleForTesting;
31import com.android.server.LocalServices;
Adrian Roose99bc052017-11-20 17:55:31 +010032import com.android.server.policy.WindowManagerPolicy;
Adrian Roos1c8e3c02018-11-20 20:07:55 +010033import com.android.server.utils.UserTokenWatcher;
34import com.android.server.wm.LockTaskController.LockTaskToken;
Craig Mautner5642a482012-08-23 12:16:53 -070035
Adrian Roos1c8e3c02018-11-20 20:07:55 +010036class KeyguardDisableHandler {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080037 private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardDisableHandler" : TAG_WM;
Craig Mautner5642a482012-08-23 12:16:53 -070038
Adrian Roos1c8e3c02018-11-20 20:07:55 +010039 private final UserTokenWatcher mAppTokenWatcher;
40 private final UserTokenWatcher mSystemTokenWatcher;
Craig Mautner5642a482012-08-23 12:16:53 -070041
Adrian Roos1c8e3c02018-11-20 20:07:55 +010042 private int mCurrentUser = UserHandle.USER_SYSTEM;
43 private Injector mInjector;
Craig Mautner5642a482012-08-23 12:16:53 -070044
Adrian Roos1c8e3c02018-11-20 20:07:55 +010045 @VisibleForTesting
46 KeyguardDisableHandler(Injector injector, Handler handler) {
47 mInjector = injector;
48 mAppTokenWatcher = new UserTokenWatcher(mCallback, handler, TAG);
49 mSystemTokenWatcher = new UserTokenWatcher(mCallback, handler, TAG);
Craig Mautner5642a482012-08-23 12:16:53 -070050 }
51
Adrian Roos1c8e3c02018-11-20 20:07:55 +010052 public void setCurrentUser(int user) {
53 synchronized (this) {
54 mCurrentUser = user;
55 updateKeyguardEnabledLocked(UserHandle.USER_ALL);
Craig Mautner5642a482012-08-23 12:16:53 -070056 }
57 }
58
Adrian Roos1c8e3c02018-11-20 20:07:55 +010059 void updateKeyguardEnabled(int userId) {
60 synchronized (this) {
61 updateKeyguardEnabledLocked(userId);
Craig Mautner5642a482012-08-23 12:16:53 -070062 }
Adrian Roos1c8e3c02018-11-20 20:07:55 +010063 }
Craig Mautner5642a482012-08-23 12:16:53 -070064
Adrian Roos1c8e3c02018-11-20 20:07:55 +010065 private void updateKeyguardEnabledLocked(int userId) {
66 if (mCurrentUser == userId || userId == UserHandle.USER_ALL) {
67 mInjector.enableKeyguard(shouldKeyguardBeEnabled(mCurrentUser));
68 }
69 }
70
71 void disableKeyguard(IBinder token, String tag, int callingUid, int userId) {
72 UserTokenWatcher watcherForCaller = watcherForCallingUid(token, callingUid);
73 watcherForCaller.acquire(token, tag, mInjector.getProfileParentId(userId));
74 }
75
76 void reenableKeyguard(IBinder token, int callingUid, int userId) {
77 UserTokenWatcher watcherForCaller = watcherForCallingUid(token, callingUid);
78 watcherForCaller.release(token, mInjector.getProfileParentId(userId));
79 }
80
81 private UserTokenWatcher watcherForCallingUid(IBinder token, int callingUid) {
82 if (Process.isApplicationUid(callingUid)) {
83 return mAppTokenWatcher;
84 } else if (callingUid == Process.SYSTEM_UID && token instanceof LockTaskToken) {
85 // We allow the lock task token here as a legacy case, because it enforces its own
86 // security guarantees.
87 // NOTE: DO NOT add new usages of this API in system server. It is deprecated and
88 // easily misused.
89 return mSystemTokenWatcher;
90 } else {
91 throw new UnsupportedOperationException("Only apps can use the KeyguardLock API");
92 }
93 }
94
95 private boolean shouldKeyguardBeEnabled(int userId) {
96 final boolean dpmRequiresPassword = mInjector.dpmRequiresPassword(mCurrentUser);
97 final boolean keyguardSecure = mInjector.isKeyguardSecure(mCurrentUser);
98
99 final boolean allowedFromApps = !dpmRequiresPassword && !keyguardSecure;
100 // The system can disable the keyguard for lock task mode even if the keyguard is secure,
101 // because it enforces its own security guarantees.
102 final boolean allowedFromSystem = !dpmRequiresPassword;
103
104 final boolean shouldBeDisabled = allowedFromApps && mAppTokenWatcher.isAcquired(userId)
105 || allowedFromSystem && mSystemTokenWatcher.isAcquired(userId);
106 return !shouldBeDisabled;
107 }
108
109 // Callback happens on mHandler thread.
110 private final UserTokenWatcher.Callback mCallback = new UserTokenWatcher.Callback() {
111 @Override
112 public void acquired(int userId) {
113 updateKeyguardEnabled(userId);
Jason Monk4a3daac2014-12-09 14:32:02 -0500114 }
115
116 @Override
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100117 public void released(int userId) {
118 updateKeyguardEnabled(userId);
Craig Mautner5642a482012-08-23 12:16:53 -0700119 }
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100120 };
Craig Mautner5642a482012-08-23 12:16:53 -0700121
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100122 static KeyguardDisableHandler create(Context context, WindowManagerPolicy policy,
123 Handler handler) {
124 final UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);
125 return new KeyguardDisableHandler(new Injector() {
126 @Override
127 public boolean dpmRequiresPassword(int userId) {
128 DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
129 Context.DEVICE_POLICY_SERVICE);
130 return dpm == null || dpm.getPasswordQuality(null, userId)
131 != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
132 }
133
134 @Override
135 public boolean isKeyguardSecure(int userId) {
136 return policy.isKeyguardSecure(userId);
137 }
138
139 @Override
140 public int getProfileParentId(int userId) {
141 return userManager.getProfileParentId(userId);
142 }
143
144 @Override
145 public void enableKeyguard(boolean enabled) {
146 policy.enableKeyguard(enabled);
147 }
148 }, handler);
149 }
150
151 interface Injector {
152 boolean dpmRequiresPassword(int userId);
153
154 boolean isKeyguardSecure(int userId);
155
156 int getProfileParentId(int userId);
157
158 void enableKeyguard(boolean enabled);
Craig Mautner5642a482012-08-23 12:16:53 -0700159 }
160}