blob: cc87735c7485d8d5c42df496badf903a4b6f2c15 [file] [log] [blame]
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001/*
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
17package com.android.systemui.keyguard;
18
19import com.android.internal.policy.IKeyguardExitCallback;
20import com.android.internal.policy.IKeyguardService;
21import com.android.internal.policy.IKeyguardServiceConstants;
22import com.android.internal.policy.IKeyguardShowCallback;
23import com.android.systemui.statusbar.CommandQueue;
24
25import android.app.ActivityManagerNative;
26import android.app.Service;
27import android.app.StatusBarManager;
28import android.content.Context;
29import android.content.Intent;
30import android.os.Binder;
31import android.os.Bundle;
32import android.os.Debug;
33import android.os.IBinder;
34import android.os.RemoteException;
35import android.util.Log;
36import android.view.MotionEvent;
37
38import static android.content.pm.PackageManager.PERMISSION_GRANTED;
39
40public class KeyguardService extends Service {
41 static final String TAG = "KeyguardService";
42 static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
43
44 public static final String ACTION_STATUS_BAR_BIND = "action.status_bar_bind";
45
46 private CommandQueue mCommandQueue;
47 private StatusBarManager mStatusBarManager;
48
49 @Override
50 public void onCreate() {
51 }
52
53 @Override
54 public IBinder onBind(Intent intent) {
55 if (ACTION_STATUS_BAR_BIND.equals(intent.getAction())) {
56 return mKeyguardStatusBarBinder;
57 } else {
58 return mBinder;
59 }
60 }
61
62 void checkPermission() {
63 if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
64 Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
65 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
66 + ", must have permission " + PERMISSION);
67 }
68 }
69
70 private final KeyguardStatusBarBinder mKeyguardStatusBarBinder =
71 new KeyguardStatusBarBinder() {
72
73 @Override
74 public void register(CommandQueue commandQueue) {
75 mCommandQueue = commandQueue;
76 }
77
78 @Override
79 public void dismissKeyguard() {
80 try {
81 mBinder.dismiss();
82 } catch (RemoteException e) {
83 Log.e(TAG, "Could not dismiss keyguard", e);
84 }
85 }
86 };
87
88 private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
89
90 /** Whether the Keyguard is visible. */
91 private boolean mShowing;
92
93 /**
94 * Whether the Keyguard is hidden by a window with
95 * {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}. So mShowing might
96 * be true, but also mHidden. So in the end, the Keyguard would not be visible.
97 */
98 private boolean mHidden;
99 private boolean mShowingDream;
100
101 @Override
102 public synchronized boolean isShowing() {
103 return mShowing;
104 }
105
106 @Override
107 public synchronized boolean isSecure() {
108 return true;
109 }
110
111 @Override
112 public synchronized boolean isShowingAndNotHidden() {
113 return mShowing && !mHidden;
114 }
115
116 @Override
117 public synchronized boolean isInputRestricted() {
118 return false;
119 }
120
121 @Override
122 public synchronized void verifyUnlock(IKeyguardExitCallback callback) {
123 }
124
125 @Override
126 public synchronized void keyguardDone(boolean authenticated, boolean wakeup) {
127 checkPermission();
128 mShowing = false;
129 adjustStatusBarLocked();
130 if (mCommandQueue != null) {
131 mCommandQueue.setKeyguardShown(false, null, true);
132 }
133 }
134
135 @Override
136 public synchronized int setHidden(boolean isHidden) {
137 checkPermission();
138 if (mHidden == isHidden) {
139 return IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_NONE;
140 }
141 mHidden = isHidden;
142 try {
143 ActivityManagerNative.getDefault().setLockScreenShown(mShowing && !mHidden
144 || mShowingDream);
145 } catch (RemoteException e) {
146 Log.e(TAG, "Could not update activity manager lock screen state", e);
147 }
148 adjustStatusBarLocked();
149 if (mCommandQueue != null) {
150 mCommandQueue.setKeyguardShown(!isHidden, null, false);
151 }
152 return isShowingAndNotHidden()
153 ? IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_SET_FLAGS
154 : IKeyguardServiceConstants.KEYGUARD_SERVICE_HIDE_RESULT_UNSET_FLAGS;
155 }
156
157 @Override
158 public synchronized void dismiss() {
159 checkPermission();
160 mShowing = false;
161 adjustStatusBarLocked();
162 if (mCommandQueue != null) {
163 mCommandQueue.setKeyguardShown(false, null, true);
164 }
165 }
166
167 @Override
168 public synchronized void onDreamingStarted() {
169 checkPermission();
170 mShowingDream = true;
171 }
172
173 @Override
174 public synchronized void onDreamingStopped() {
175 checkPermission();
176 mShowingDream = false;
177 }
178
179 @Override
180 public synchronized void onScreenTurnedOff(int reason) {
181 checkPermission();
182 }
183
184 @Override
185 public synchronized void onScreenTurnedOn(IKeyguardShowCallback callback) {
186 checkPermission();
187 mShowing = true;
188 adjustStatusBarLocked();
189 if (mCommandQueue != null) {
190 mCommandQueue.setKeyguardShown(isShowingAndNotHidden(), callback, true);
191 }
192 }
193
194 @Override
195 public synchronized void setKeyguardEnabled(boolean enabled) {
196 checkPermission();
197 }
198
199 @Override
200 public synchronized boolean isDismissable() {
201 return !isSecure();
202 }
203
204 @Override
205 public synchronized void onSystemReady() {
206 checkPermission();
207 }
208
209 @Override
210 public synchronized void doKeyguardTimeout(Bundle options) {
211 checkPermission();
212 }
213
214 @Override
215 public synchronized void setCurrentUser(int userId) {
216 checkPermission();
217 }
218
219 @Override
220 public synchronized void showAssistant() {
221 checkPermission();
222 }
223
224 @Override
225 public synchronized void dispatch(MotionEvent event) {
226 checkPermission();
227 }
228
229 @Override
230 public synchronized void launchCamera() {
231 checkPermission();
232 }
233
234 @Override
235 public synchronized void onBootCompleted() {
236 checkPermission();
237 onScreenTurnedOn(null);
238 }
239
240 private void adjustStatusBarLocked() {
241 if (mStatusBarManager == null) {
242 mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
243 }
244 if (mStatusBarManager == null) {
245 Log.w(TAG, "Could not get status bar manager");
246 } else {
247 // Disable aspects of the system/status/navigation bars that must not be re-enabled by
248 // windows that appear on top, ever
249 int flags = StatusBarManager.DISABLE_NONE;
250 if (isShowing()) {
251 // Permanently disable components not available when keyguard is enabled
252 // (like recents). Temporary enable/disable (e.g. the "back" button) are
253 // done in KeyguardHostView.
254 flags |= StatusBarManager.DISABLE_RECENT;
255 if (isSecure()) {
256 // showing secure lockscreen; disable ticker and switch private notifications
257 // to show their public versions, if available.
258 flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS;
259 }
260 if (false) {
261 flags |= StatusBarManager.DISABLE_SEARCH;
262 }
263 }
264 if (isShowingAndNotHidden()) {
265 flags |= StatusBarManager.DISABLE_HOME;
266 }
267 mStatusBarManager.disable(flags);
268 }
269 }
270 };
271}
272