• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.server.devicelock;
18 
19 import android.annotation.IntDef;
20 import android.os.OutcomeReceiver;
21 
22 import com.android.devicelock.flags.Flags;
23 import com.android.internal.annotations.GuardedBy;
24 
25 import java.lang.annotation.ElementType;
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.lang.annotation.Target;
29 
30 /**
31  * Stub implementation of the connector that is used when the device has had its restrictions
32  * cleared so that we don't try to bind to a disabled package.
33  */
34 public class DeviceLockControllerConnectorStub implements DeviceLockControllerConnector {
35     // Pseudo states used for CTS conformance when a device is finalized.
36     @Target(ElementType.TYPE_USE)
37     @Retention(RetentionPolicy.SOURCE)
38     @IntDef({
39             DevicePseudoState.UNDEFINED,
40             DevicePseudoState.LOCKED,
41             DevicePseudoState.UNLOCKED,
42             DevicePseudoState.CLEARED,
43     })
44     private @interface DevicePseudoState {
45         int UNDEFINED = 0;
46         int UNLOCKED = 1;
47         int LOCKED = 2;
48         int CLEARED = 3;
49     }
50 
51     @GuardedBy("this")
52     private @DevicePseudoState int mPseudoState = DevicePseudoState.UNDEFINED;
53 
54     @Override
unbind()55     public void unbind() {}
56 
57     @Override
lockDevice(OutcomeReceiver<Void, Exception> callback)58     public void lockDevice(OutcomeReceiver<Void, Exception> callback) {
59         synchronized (this) {
60             if (setExceptionIfDeviceIsCleared(callback)) {
61                 return;
62             }
63 
64             mPseudoState = DevicePseudoState.LOCKED;
65         }
66         callback.onResult(/* result= */ null);
67     }
68 
69     @Override
unlockDevice(OutcomeReceiver<Void, Exception> callback)70     public void unlockDevice(OutcomeReceiver<Void, Exception> callback) {
71         synchronized (this) {
72             if (setExceptionIfDeviceIsCleared(callback)) {
73                 return;
74             }
75 
76             mPseudoState = DevicePseudoState.UNLOCKED;
77         }
78         callback.onResult(/* result= */ null);
79     }
80 
81     @Override
isDeviceLocked(OutcomeReceiver<Boolean, Exception> callback)82     public void isDeviceLocked(OutcomeReceiver<Boolean, Exception> callback) {
83         boolean isLocked;
84 
85         synchronized (this) {
86             if (setExceptionIfDeviceIsCleared(callback)) {
87                 return;
88             }
89 
90             if (mPseudoState == DevicePseudoState.UNDEFINED) {
91                 setException(callback, "isLocked called before setting the lock state");
92 
93                 return;
94             }
95 
96             isLocked = mPseudoState == DevicePseudoState.LOCKED;
97         }
98 
99         callback.onResult(isLocked);
100     }
101 
102     @Override
getDeviceId(OutcomeReceiver<String, Exception> callback)103     public void getDeviceId(OutcomeReceiver<String, Exception> callback) {
104         setException(callback, "No registered Device ID found");
105     }
106 
107     @Override
clearDeviceRestrictions(OutcomeReceiver<Void, Exception> callback)108     public void clearDeviceRestrictions(OutcomeReceiver<Void, Exception> callback) {
109         synchronized (this) {
110             if (setExceptionIfDeviceIsCleared(callback)) {
111                 return;
112             }
113 
114             mPseudoState = DevicePseudoState.CLEARED;
115         }
116         callback.onResult(/* result= */ null);
117     }
118 
119     @Override
onUserSwitching(OutcomeReceiver<Void, Exception> callback)120     public void onUserSwitching(OutcomeReceiver<Void, Exception> callback) {
121         // Do not throw exception as we expect this to be called
122         callback.onResult(/* result= */ null);
123     }
124 
125     @Override
onUserUnlocked(OutcomeReceiver<Void, Exception> callback)126     public void onUserUnlocked(OutcomeReceiver<Void, Exception> callback) {
127         // Do not throw exception as we expect this to be called
128         callback.onResult(/* result= */ null);
129     }
130 
131     @Override
onUserSetupCompleted(OutcomeReceiver<Void, Exception> callback)132     public void onUserSetupCompleted(OutcomeReceiver<Void, Exception> callback) {
133         // Do not throw exception as we expect this to be called
134         callback.onResult(/* result= */ null);
135     }
136 
137     @Override
onAppCrashed(boolean isKiosk, OutcomeReceiver<Void, Exception> callback)138     public void onAppCrashed(boolean isKiosk, OutcomeReceiver<Void, Exception> callback) {
139         setException(callback, "Device lock controller package is disabled");
140     }
141 
setException(OutcomeReceiver<?, Exception> callback, String message)142     private static void setException(OutcomeReceiver<?, Exception> callback, String message) {
143         callback.onError(new IllegalStateException(message));
144     }
145 
146     @GuardedBy("this")
setExceptionIfDeviceIsCleared(OutcomeReceiver<?, Exception> callback)147     private boolean setExceptionIfDeviceIsCleared(OutcomeReceiver<?, Exception> callback) {
148         if (Flags.clearDeviceRestrictions()) {
149             return false;
150         }
151 
152         if (mPseudoState == DevicePseudoState.CLEARED) {
153             setException(callback, "Device has been cleared!");
154 
155             return true;
156         }
157 
158         return false;
159     }
160 }
161