1 /*
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 
17 package android.app.trust;
18 
19 import android.Manifest;
20 import android.annotation.RequiresPermission;
21 import android.annotation.SystemService;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.content.Context;
24 import android.hardware.biometrics.BiometricSourceType;
25 import android.os.Handler;
26 import android.os.IBinder;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.RemoteException;
30 import android.util.ArrayMap;
31 
32 /**
33  * See {@link com.android.server.trust.TrustManagerService}
34  * @hide
35  */
36 @SystemService(Context.TRUST_SERVICE)
37 public class TrustManager {
38 
39     private static final int MSG_TRUST_CHANGED = 1;
40     private static final int MSG_TRUST_MANAGED_CHANGED = 2;
41     private static final int MSG_TRUST_ERROR = 3;
42 
43     private static final String TAG = "TrustManager";
44     private static final String DATA_FLAGS = "initiatedByUser";
45     private static final String DATA_MESSAGE = "message";
46 
47     private final ITrustManager mService;
48     private final ArrayMap<TrustListener, ITrustListener> mTrustListeners;
49 
TrustManager(IBinder b)50     public TrustManager(IBinder b) {
51         mService = ITrustManager.Stub.asInterface(b);
52         mTrustListeners = new ArrayMap<TrustListener, ITrustListener>();
53     }
54 
55     /**
56      * Changes the lock status for the given user. This is only applicable to Managed Profiles,
57      * other users should be handled by Keyguard.
58      *
59      * @param userId The id for the user to be locked/unlocked.
60      * @param locked The value for that user's locked state.
61      */
62     @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
setDeviceLockedForUser(int userId, boolean locked)63     public void setDeviceLockedForUser(int userId, boolean locked) {
64         try {
65             mService.setDeviceLockedForUser(userId, locked);
66         } catch (RemoteException e) {
67             throw e.rethrowFromSystemServer();
68         }
69     }
70 
71     /**
72      * Reports that user {@param userId} has tried to unlock the device.
73      *
74      * @param successful if true, the unlock attempt was successful.
75      *
76      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
77      */
78     @UnsupportedAppUsage
reportUnlockAttempt(boolean successful, int userId)79     public void reportUnlockAttempt(boolean successful, int userId) {
80         try {
81             mService.reportUnlockAttempt(successful, userId);
82         } catch (RemoteException e) {
83             throw e.rethrowFromSystemServer();
84         }
85     }
86 
87     /**
88      * Reports that user {@param userId} has entered a temporary device lockout.
89      *
90      * This generally occurs when  the user has unsuccessfully tried to unlock the device too many
91      * times. The user will then be unable to unlock the device until a set amount of time has
92      * elapsed.
93      *
94      * @param timeout The amount of time that needs to elapse, in milliseconds, until the user may
95      *    attempt to unlock the device again.
96      *
97      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
98      */
reportUnlockLockout(int timeoutMs, int userId)99     public void reportUnlockLockout(int timeoutMs, int userId) {
100         try {
101             mService.reportUnlockLockout(timeoutMs, userId);
102         } catch (RemoteException e) {
103             throw e.rethrowFromSystemServer();
104         }
105     }
106 
107     /**
108      * Reports that the list of enabled trust agents changed for user {@param userId}.
109      *
110      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
111      */
reportEnabledTrustAgentsChanged(int userId)112     public void reportEnabledTrustAgentsChanged(int userId) {
113         try {
114             mService.reportEnabledTrustAgentsChanged(userId);
115         } catch (RemoteException e) {
116             throw e.rethrowFromSystemServer();
117         }
118     }
119 
120     /**
121      * Reports that the visibility of the keyguard has changed.
122      *
123      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
124      */
reportKeyguardShowingChanged()125     public void reportKeyguardShowingChanged() {
126         try {
127             mService.reportKeyguardShowingChanged();
128         } catch (RemoteException e) {
129             throw e.rethrowFromSystemServer();
130         }
131     }
132 
133     /**
134      * Registers a listener for trust events.
135      *
136      * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
137      */
registerTrustListener(final TrustListener trustListener)138     public void registerTrustListener(final TrustListener trustListener) {
139         try {
140             ITrustListener.Stub iTrustListener = new ITrustListener.Stub() {
141                 @Override
142                 public void onTrustChanged(boolean enabled, int userId, int flags) {
143                     Message m = mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
144                             trustListener);
145                     if (flags != 0) {
146                         m.getData().putInt(DATA_FLAGS, flags);
147                     }
148                     m.sendToTarget();
149                 }
150 
151                 @Override
152                 public void onTrustManagedChanged(boolean managed, int userId) {
153                     mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
154                             trustListener).sendToTarget();
155                 }
156 
157                 @Override
158                 public void onTrustError(CharSequence message) {
159                     Message m = mHandler.obtainMessage(MSG_TRUST_ERROR);
160                     m.getData().putCharSequence(DATA_MESSAGE, message);
161                     m.sendToTarget();
162                 }
163             };
164             mService.registerTrustListener(iTrustListener);
165             mTrustListeners.put(trustListener, iTrustListener);
166         } catch (RemoteException e) {
167             throw e.rethrowFromSystemServer();
168         }
169     }
170 
171     /**
172      * Unregisters a listener for trust events.
173      *
174      * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
175      */
unregisterTrustListener(final TrustListener trustListener)176     public void unregisterTrustListener(final TrustListener trustListener) {
177         ITrustListener iTrustListener = mTrustListeners.remove(trustListener);
178         if (iTrustListener != null) {
179             try {
180                 mService.unregisterTrustListener(iTrustListener);
181             } catch (RemoteException e) {
182                 throw e.rethrowFromSystemServer();
183             }
184         }
185     }
186 
187     /**
188      * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
189      * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
190      */
191     @RequiresPermission(android.Manifest.permission.TRUST_LISTENER)
isTrustUsuallyManaged(int userId)192     public boolean isTrustUsuallyManaged(int userId) {
193         try {
194             return mService.isTrustUsuallyManaged(userId);
195         } catch (RemoteException e) {
196             throw e.rethrowFromSystemServer();
197         }
198     }
199 
200     /**
201      * Updates the trust state for the user due to the user unlocking via a biometric sensor.
202      * Should only be called if user authenticated via fingerprint, face, or iris and bouncer
203      * can be skipped.
204      *
205      * @param userId
206      */
207     @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
unlockedByBiometricForUser(int userId, BiometricSourceType source)208     public void unlockedByBiometricForUser(int userId, BiometricSourceType source) {
209         try {
210             mService.unlockedByBiometricForUser(userId, source);
211         } catch (RemoteException e) {
212             throw e.rethrowFromSystemServer();
213         }
214     }
215 
216     /**
217      * Clears authentication by the specified biometric type for all users.
218      */
219     @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
clearAllBiometricRecognized(BiometricSourceType source)220     public void clearAllBiometricRecognized(BiometricSourceType source) {
221         try {
222             mService.clearAllBiometricRecognized(source);
223         } catch (RemoteException e) {
224             throw e.rethrowFromSystemServer();
225         }
226     }
227 
228     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
229         @Override
230         public void handleMessage(Message msg) {
231             switch(msg.what) {
232                 case MSG_TRUST_CHANGED:
233                     int flags = msg.peekData() != null ? msg.peekData().getInt(DATA_FLAGS) : 0;
234                     ((TrustListener)msg.obj).onTrustChanged(msg.arg1 != 0, msg.arg2, flags);
235                     break;
236                 case MSG_TRUST_MANAGED_CHANGED:
237                     ((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
238                     break;
239                 case MSG_TRUST_ERROR:
240                     final CharSequence message = msg.peekData().getCharSequence(DATA_MESSAGE);
241                     ((TrustListener)msg.obj).onTrustError(message);
242             }
243         }
244     };
245 
246     public interface TrustListener {
247 
248         /**
249          * Reports that the trust state has changed.
250          * @param enabled If true, the system believes the environment to be trusted.
251          * @param userId The user, for which the trust changed.
252          * @param flags Flags specified by the trust agent when granting trust. See
253          *     {@link android.service.trust.TrustAgentService#grantTrust(CharSequence, long, int)
254          *                 TrustAgentService.grantTrust(CharSequence, long, int)}.
255          */
onTrustChanged(boolean enabled, int userId, int flags)256         void onTrustChanged(boolean enabled, int userId, int flags);
257 
258         /**
259          * Reports that whether trust is managed has changed
260          * @param enabled If true, at least one trust agent is managing trust.
261          * @param userId The user, for which the state changed.
262          */
onTrustManagedChanged(boolean enabled, int userId)263         void onTrustManagedChanged(boolean enabled, int userId);
264 
265         /**
266          * Reports that an error happened on a TrustAgentService.
267          * @param message A message that should be displayed on the UI.
268          */
onTrustError(CharSequence message)269         void onTrustError(CharSequence message);
270     }
271 }
272