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
30import com.android.internal.widget.LockPatternUtils;
31
32/**
33 * See {@link com.android.server.trust.TrustManagerService}
34 * @hide
35 */
36@SystemService(Context.TRUST_SERVICE)
37public 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
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            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     */
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)
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         */
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         */
221        void onTrustManagedChanged(boolean enabled, int userId);
222    }
223}
224