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.content.Context;
23 import android.os.Handler;
24 import android.os.IBinder;
25 import android.os.Looper;
26 import android.os.Message;
27 import android.os.RemoteException;
28 import android.util.ArrayMap;
29 
30 import com.android.internal.widget.LockPatternUtils;
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 
42     private static final String TAG = "TrustManager";
43     private static final String DATA_FLAGS = "initiatedByUser";
44 
45     private final ITrustManager mService;
46     private final ArrayMap<TrustListener, ITrustListener> mTrustListeners;
47 
TrustManager(IBinder b)48     public TrustManager(IBinder b) {
49         mService = ITrustManager.Stub.asInterface(b);
50         mTrustListeners = new ArrayMap<TrustListener, ITrustListener>();
51     }
52 
53     /**
54      * Changes the lock status for the given user. This is only applicable to Managed Profiles,
55      * other users should be handled by Keyguard.
56      *
57      * @param userId The id for the user to be locked/unlocked.
58      * @param locked The value for that user's locked state.
59      */
60     @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
setDeviceLockedForUser(int userId, boolean locked)61     public void setDeviceLockedForUser(int userId, boolean locked) {
62         try {
63             mService.setDeviceLockedForUser(userId, locked);
64         } catch (RemoteException e) {
65             throw e.rethrowFromSystemServer();
66         }
67     }
68 
69     /**
70      * Reports that user {@param userId} has tried to unlock the device.
71      *
72      * @param successful if true, the unlock attempt was successful.
73      *
74      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
75      */
reportUnlockAttempt(boolean successful, int userId)76     public void reportUnlockAttempt(boolean successful, int userId) {
77         try {
78             mService.reportUnlockAttempt(successful, userId);
79         } catch (RemoteException e) {
80             throw e.rethrowFromSystemServer();
81         }
82     }
83 
84     /**
85      * Reports that user {@param userId} has entered a temporary device lockout.
86      *
87      * This generally occurs when  the user has unsuccessfully tried to unlock the device too many
88      * times. The user will then be unable to unlock the device until a set amount of time has
89      * elapsed.
90      *
91      * @param timeout The amount of time that needs to elapse, in milliseconds, until the user may
92      *    attempt to unlock the device again.
93      *
94      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
95      */
reportUnlockLockout(int timeoutMs, int userId)96     public void reportUnlockLockout(int timeoutMs, int userId) {
97         try {
98             mService.reportUnlockLockout(timeoutMs, userId);
99         } catch (RemoteException e) {
100             throw e.rethrowFromSystemServer();
101         }
102     }
103 
104     /**
105      * Reports that the list of enabled trust agents changed for user {@param userId}.
106      *
107      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
108      */
reportEnabledTrustAgentsChanged(int userId)109     public void reportEnabledTrustAgentsChanged(int userId) {
110         try {
111             mService.reportEnabledTrustAgentsChanged(userId);
112         } catch (RemoteException e) {
113             throw e.rethrowFromSystemServer();
114         }
115     }
116 
117     /**
118      * Reports that the visibility of the keyguard has changed.
119      *
120      * Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
121      */
reportKeyguardShowingChanged()122     public void reportKeyguardShowingChanged() {
123         try {
124             mService.reportKeyguardShowingChanged();
125         } catch (RemoteException e) {
126             throw e.rethrowFromSystemServer();
127         }
128     }
129 
130     /**
131      * Registers a listener for trust events.
132      *
133      * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
134      */
registerTrustListener(final TrustListener trustListener)135     public void registerTrustListener(final TrustListener trustListener) {
136         try {
137             ITrustListener.Stub iTrustListener = new ITrustListener.Stub() {
138                 @Override
139                 public void onTrustChanged(boolean enabled, int userId, int flags) {
140                     Message m = mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
141                             trustListener);
142                     if (flags != 0) {
143                         m.getData().putInt(DATA_FLAGS, flags);
144                     }
145                     m.sendToTarget();
146                 }
147 
148                 @Override
149                 public void onTrustManagedChanged(boolean managed, int userId) {
150                     mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
151                             trustListener).sendToTarget();
152                 }
153             };
154             mService.registerTrustListener(iTrustListener);
155             mTrustListeners.put(trustListener, iTrustListener);
156         } catch (RemoteException e) {
157             throw e.rethrowFromSystemServer();
158         }
159     }
160 
161     /**
162      * Unregisters a listener for trust events.
163      *
164      * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
165      */
unregisterTrustListener(final TrustListener trustListener)166     public void unregisterTrustListener(final TrustListener trustListener) {
167         ITrustListener iTrustListener = mTrustListeners.remove(trustListener);
168         if (iTrustListener != null) {
169             try {
170                 mService.unregisterTrustListener(iTrustListener);
171             } catch (RemoteException e) {
172                 throw e.rethrowFromSystemServer();
173             }
174         }
175     }
176 
177     /**
178      * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
179      * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
180      */
181     @RequiresPermission(android.Manifest.permission.TRUST_LISTENER)
isTrustUsuallyManaged(int userId)182     public boolean isTrustUsuallyManaged(int userId) {
183         try {
184             return mService.isTrustUsuallyManaged(userId);
185         } catch (RemoteException e) {
186             throw e.rethrowFromSystemServer();
187         }
188     }
189 
190     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
191         @Override
192         public void handleMessage(Message msg) {
193             switch(msg.what) {
194                 case MSG_TRUST_CHANGED:
195                     int flags = msg.peekData() != null ? msg.peekData().getInt(DATA_FLAGS) : 0;
196                     ((TrustListener)msg.obj).onTrustChanged(msg.arg1 != 0, msg.arg2, flags);
197                     break;
198                 case MSG_TRUST_MANAGED_CHANGED:
199                     ((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
200             }
201         }
202     };
203 
204     public interface TrustListener {
205 
206         /**
207          * Reports that the trust state has changed.
208          * @param enabled if true, the system believes the environment to be trusted.
209          * @param userId the user, for which the trust changed.
210          * @param flags flags specified by the trust agent when granting trust. See
211          *     {@link android.service.trust.TrustAgentService#grantTrust(CharSequence, long, int)
212          *                 TrustAgentService.grantTrust(CharSequence, long, int)}.
213          */
onTrustChanged(boolean enabled, int userId, int flags)214         void onTrustChanged(boolean enabled, int userId, int flags);
215 
216         /**
217          * Reports that whether trust is managed has changed
218          * @param enabled if true, at least one trust agent is managing trust.
219          * @param userId the user, for which the state changed.
220          */
onTrustManagedChanged(boolean enabled, int userId)221         void onTrustManagedChanged(boolean enabled, int userId);
222     }
223 }
224