1 /*
2  * Copyright (C) 2023 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 android.car.builtin.keyguard;
18 
19 import android.car.builtin.util.Slogf;
20 import android.os.RemoteException;
21 
22 import com.android.internal.policy.IKeyguardService;
23 import com.android.internal.policy.IKeyguardStateCallback;
24 
25 import java.io.PrintWriter;
26 
27 /**
28  * Maintains a cached copy of Keyguard's state.
29  */
30 final class KeyguardStateMonitor {
31     private static final String TAG = "KeyguardStateMonitor";
32     private final int mCurrentUserId;
33     private final StateCallback mCallback;
34 
35     // These cache the current state of Keyguard to improve performance and avoid deadlock. After
36     // Keyguard changes its state, it always triggers a layout in window manager. Because
37     // IKeyguardStateCallback is synchronous and because these states are declared volatile, it's
38     // guaranteed that the new state is always picked up in the layout caused by the state change
39     // of Keyguard. To be extra safe, assume most restrictive values until Keyguard tells us the
40     // actual value.
41     private volatile boolean mIsShowing = true;
42 
43     private final IKeyguardStateCallback.Stub mKeyguardStateCallback =
44             new IKeyguardStateCallback.Stub() {
45                 @Override
46                 public void onShowingStateChanged(boolean showing, int userId) {
47                     if (userId != mCurrentUserId) return;
48                     mIsShowing = showing;
49 
50                     mCallback.onShowingChanged(showing);
51                 }
52 
53                 @Override
54                 public void onSimSecureStateChanged(boolean simSecure) {
55                 }
56 
57                 @Override
58                 public void onInputRestrictedStateChanged(boolean inputRestricted) {
59                 }
60 
61                 @Override
62                 public void onTrustedChanged(boolean trusted) {
63                 }
64             };
65 
KeyguardStateMonitor(IKeyguardService service, int userId, StateCallback callback)66     KeyguardStateMonitor(IKeyguardService service, int userId, StateCallback callback) {
67         mCurrentUserId = userId;
68         mCallback = callback;
69 
70         try {
71             service.addStateMonitorCallback(mKeyguardStateCallback);
72         } catch (RemoteException e) {
73             Slogf.w(TAG, "Remote Exception", e);
74         }
75     }
76 
isShowing()77     boolean isShowing() {
78         return mIsShowing;
79     }
80 
81     /**
82      * Dump KeyguardStateMonitor.
83      */
dump(PrintWriter writer)84     void dump(PrintWriter writer) {
85         writer.println("*KeyguardStateMonitor*");
86         writer.println("mIsShowing=" + mIsShowing);
87     }
88 
89     interface StateCallback {
onShowingChanged(boolean showing)90         void onShowingChanged(boolean showing);
91     }
92 }
93