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
17package android.app.trust;
18
19import android.Manifest;
20import android.annotation.RequiresPermission;
21import android.annotation.SystemService;
22import android.content.Context;
23import android.os.Handler;
24import android.os.IBinder;
25import android.os.Looper;
26import android.os.Message;
27import android.os.RemoteException;
28import android.util.ArrayMap;
29
30/**
31 * See {@link com.android.server.trust.TrustManagerService}
32 * @hide
33 */
34@SystemService(Context.TRUST_SERVICE)
35public class TrustManager {
36
37    private static final int MSG_TRUST_CHANGED = 1;
38    private static final int MSG_TRUST_MANAGED_CHANGED = 2;
39    private static final int MSG_TRUST_ERROR = 3;
40
41    private static final String TAG = "TrustManager";
42    private static final String DATA_FLAGS = "initiatedByUser";
43    private static final String DATA_MESSAGE = "message";
44
45    private final ITrustManager mService;
46    private final ArrayMap<TrustListener, ITrustListener> mTrustListeners;
47
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)
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     */
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     */
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     */
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     */
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     */
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                @Override
155                public void onTrustError(CharSequence message) {
156                    Message m = mHandler.obtainMessage(MSG_TRUST_ERROR);
157                    m.getData().putCharSequence(DATA_MESSAGE, message);
158                    m.sendToTarget();
159                }
160            };
161            mService.registerTrustListener(iTrustListener);
162            mTrustListeners.put(trustListener, iTrustListener);
163        } catch (RemoteException e) {
164            throw e.rethrowFromSystemServer();
165        }
166    }
167
168    /**
169     * Unregisters a listener for trust events.
170     *
171     * Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
172     */
173    public void unregisterTrustListener(final TrustListener trustListener) {
174        ITrustListener iTrustListener = mTrustListeners.remove(trustListener);
175        if (iTrustListener != null) {
176            try {
177                mService.unregisterTrustListener(iTrustListener);
178            } catch (RemoteException e) {
179                throw e.rethrowFromSystemServer();
180            }
181        }
182    }
183
184    /**
185     * @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
186     * unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
187     */
188    @RequiresPermission(android.Manifest.permission.TRUST_LISTENER)
189    public boolean isTrustUsuallyManaged(int userId) {
190        try {
191            return mService.isTrustUsuallyManaged(userId);
192        } catch (RemoteException e) {
193            throw e.rethrowFromSystemServer();
194        }
195    }
196
197    /**
198     * Updates the trust state for the user due to the user unlocking via fingerprint.
199     * Should only be called if user authenticated via fingerprint and bouncer can be skipped.
200     * @param userId
201     */
202    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
203    public void unlockedByFingerprintForUser(int userId) {
204        try {
205            mService.unlockedByFingerprintForUser(userId);
206        } catch (RemoteException e) {
207            throw e.rethrowFromSystemServer();
208        }
209    }
210
211    /**
212     * Clears authenticated fingerprints for all users.
213     */
214    @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
215    public void clearAllFingerprints() {
216        try {
217            mService.clearAllFingerprints();
218        } catch (RemoteException e) {
219            throw e.rethrowFromSystemServer();
220        }
221    }
222
223    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
224        @Override
225        public void handleMessage(Message msg) {
226            switch(msg.what) {
227                case MSG_TRUST_CHANGED:
228                    int flags = msg.peekData() != null ? msg.peekData().getInt(DATA_FLAGS) : 0;
229                    ((TrustListener)msg.obj).onTrustChanged(msg.arg1 != 0, msg.arg2, flags);
230                    break;
231                case MSG_TRUST_MANAGED_CHANGED:
232                    ((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
233                    break;
234                case MSG_TRUST_ERROR:
235                    final CharSequence message = msg.peekData().getCharSequence(DATA_MESSAGE);
236                    ((TrustListener)msg.obj).onTrustError(message);
237            }
238        }
239    };
240
241    public interface TrustListener {
242
243        /**
244         * Reports that the trust state has changed.
245         * @param enabled If true, the system believes the environment to be trusted.
246         * @param userId The user, for which the trust changed.
247         * @param flags Flags specified by the trust agent when granting trust. See
248         *     {@link android.service.trust.TrustAgentService#grantTrust(CharSequence, long, int)
249         *                 TrustAgentService.grantTrust(CharSequence, long, int)}.
250         */
251        void onTrustChanged(boolean enabled, int userId, int flags);
252
253        /**
254         * Reports that whether trust is managed has changed
255         * @param enabled If true, at least one trust agent is managing trust.
256         * @param userId The user, for which the state changed.
257         */
258        void onTrustManagedChanged(boolean enabled, int userId);
259
260        /**
261         * Reports that an error happened on a TrustAgentService.
262         * @param message A message that should be displayed on the UI.
263         */
264        void onTrustError(CharSequence message);
265    }
266}
267