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