1ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos/**
2ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Copyright (C) 2014 The Android Open Source Project
3ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
4ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License");
5ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * you may not use this file except in compliance with the License.
6ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * You may obtain a copy of the License at
7ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
8ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *      http://www.apache.org/licenses/LICENSE-2.0
9ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
10ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Unless required by applicable law or agreed to in writing, software
11ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS,
12ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * See the License for the specific language governing permissions and
14ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * limitations under the License.
15ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */
16ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
17ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roospackage android.service.trust;
18ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
19cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.Manifest;
2094e15a59b757678949cccb5d783bee1638e84697Adrian Roosimport android.annotation.IntDef;
21ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.annotation.SdkConstant;
22a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roosimport android.annotation.SystemApi;
23ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.app.Service;
24604e7558ef32098644b2f9456d7743a07ae789dcJim Millerimport android.app.admin.DevicePolicyManager;
25cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.ComponentName;
26ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.content.Intent;
27cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.PackageManager;
28cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.ServiceInfo;
29ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.Handler;
30ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.IBinder;
31e303bf443532c2ad756260133f00747bcff11e69Jim Millerimport android.os.PersistableBundle;
32ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.RemoteException;
33cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.util.Log;
34ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.util.Slog;
35ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
3694e15a59b757678949cccb5d783bee1638e84697Adrian Roosimport java.lang.annotation.Retention;
3794e15a59b757678949cccb5d783bee1638e84697Adrian Roosimport java.lang.annotation.RetentionPolicy;
38e303bf443532c2ad756260133f00747bcff11e69Jim Millerimport java.util.List;
39e303bf443532c2ad756260133f00747bcff11e69Jim Miller
40ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos/**
41ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * A service that notifies the system about whether it believes the environment of the device
42ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * to be trusted.
43ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
44d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * <p>Trust agents may only be provided by the platform. It is expected that there is only
45d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * one trust agent installed on the platform. In the event there is more than one,
46d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * either trust agent can enable trust.
47d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * </p>
4818ea893a2319e2a192188d2288bb881149c9b06eAdrian Roos *
49ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>To extend this class, you must declare the service in your manifest file with
507e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission
51ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
52ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre>
53ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * &lt;service android:name=".TrustAgent"
54ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:label="&#64;string/service_name"
557e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos *          android:permission="android.permission.BIND_TRUST_AGENT">
56ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;intent-filter>
57ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *         &lt;action android:name="android.service.trust.TrustAgentService" />
58ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;/intent-filter>
59ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;meta-data android:name="android.service.trust.trustagent"
60ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:value="&#64;xml/trust_agent" />
61ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * &lt;/service></pre>
62ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
63ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>The associated meta-data file can specify an activity that is accessible through Settings
64ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and should allow configuring the trust agent, as defined in
65ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * {@link android.R.styleable#TrustAgent}. For example:</p>
66ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
67ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre>
687e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * &lt;trust-agent xmlns:android="http://schemas.android.com/apk/res/android"
69ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:settingsActivity=".TrustAgentSettings" /></pre>
70a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos *
71a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos * @hide
72ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */
73a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos@SystemApi
74ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roospublic class TrustAgentService extends Service {
7594e15a59b757678949cccb5d783bee1638e84697Adrian Roos
76ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final String TAG = TrustAgentService.class.getSimpleName() +
77ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            "[" + getClass().getSimpleName() + "]";
787861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private static final boolean DEBUG = false;
797861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
80ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
81ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The {@link Intent} that must be declared as handled by the service.
82ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
83ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
84ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String SERVICE_INTERFACE
85ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            = "android.service.trust.TrustAgentService";
86ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
87ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
88ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The name of the {@code meta-data} tag pointing to additional configuration of the trust
89ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * agent.
90ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
91ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
92ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
9394e15a59b757678949cccb5d783bee1638e84697Adrian Roos
9494e15a59b757678949cccb5d783bee1638e84697Adrian Roos    /**
9594e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * Flag for {@link #grantTrust(CharSequence, long, int)} indicating that trust is being granted
9694e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * as the direct result of user action - such as solving a security challenge. The hint is used
9794e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * by the system to optimize the experience. Behavior may vary by device and release, so
9894e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * one should only set this parameter if it meets the above criteria rather than relying on
9994e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * the behavior of any particular device or release.
10094e15a59b757678949cccb5d783bee1638e84697Adrian Roos     */
10194e15a59b757678949cccb5d783bee1638e84697Adrian Roos    public static final int FLAG_GRANT_TRUST_INITIATED_BY_USER = 1 << 0;
10294e15a59b757678949cccb5d783bee1638e84697Adrian Roos
10394e15a59b757678949cccb5d783bee1638e84697Adrian Roos    /**
10494e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * Flag for {@link #grantTrust(CharSequence, long, int)} indicating that the agent would like
10594e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * to dismiss the keyguard. When using this flag, the {@code TrustAgentService} must ensure
10694e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * it is only set in response to a direct user action with the expectation of dismissing the
10794e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * keyguard.
10894e15a59b757678949cccb5d783bee1638e84697Adrian Roos     */
10994e15a59b757678949cccb5d783bee1638e84697Adrian Roos    public static final int FLAG_GRANT_TRUST_DISMISS_KEYGUARD = 1 << 1;
11094e15a59b757678949cccb5d783bee1638e84697Adrian Roos
11194e15a59b757678949cccb5d783bee1638e84697Adrian Roos    /** @hide */
11294e15a59b757678949cccb5d783bee1638e84697Adrian Roos    @Retention(RetentionPolicy.SOURCE)
11394e15a59b757678949cccb5d783bee1638e84697Adrian Roos    @IntDef(flag = true,
11494e15a59b757678949cccb5d783bee1638e84697Adrian Roos            value = {
11594e15a59b757678949cccb5d783bee1638e84697Adrian Roos                    FLAG_GRANT_TRUST_INITIATED_BY_USER,
11694e15a59b757678949cccb5d783bee1638e84697Adrian Roos                    FLAG_GRANT_TRUST_DISMISS_KEYGUARD,
11794e15a59b757678949cccb5d783bee1638e84697Adrian Roos            })
11894e15a59b757678949cccb5d783bee1638e84697Adrian Roos    public @interface GrantTrustFlags {}
11994e15a59b757678949cccb5d783bee1638e84697Adrian Roos
12094e15a59b757678949cccb5d783bee1638e84697Adrian Roos
121e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_UNLOCK_ATTEMPT = 1;
122e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_CONFIGURE = 2;
123e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_TRUST_TIMEOUT = 3;
124481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_LOCKED = 4;
125481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_UNLOCKED = 5;
126e303bf443532c2ad756260133f00747bcff11e69Jim Miller
127604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
128e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Class containing raw data for a given configuration request.
129e303bf443532c2ad756260133f00747bcff11e69Jim Miller     */
130e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final class ConfigurationData {
131e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final IBinder token;
132e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final List<PersistableBundle> options;
133e303bf443532c2ad756260133f00747bcff11e69Jim Miller        ConfigurationData(List<PersistableBundle> opts, IBinder t) {
134e303bf443532c2ad756260133f00747bcff11e69Jim Miller            options = opts;
135e303bf443532c2ad756260133f00747bcff11e69Jim Miller            token = t;
136e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
137e303bf443532c2ad756260133f00747bcff11e69Jim Miller    }
138ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
139ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private ITrustAgentServiceCallback mCallback;
140ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
1414f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private Runnable mPendingGrantTrustTask;
1424f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
1437861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private boolean mManagingTrust;
1447861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1454f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    // Lock used to access mPendingGrantTrustTask and mCallback.
1464f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private final Object mLock = new Object();
1474f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
148ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private Handler mHandler = new Handler() {
149ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void handleMessage(android.os.Message msg) {
150ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            switch (msg.what) {
151ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                case MSG_UNLOCK_ATTEMPT:
152ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    onUnlockAttempt(msg.arg1 != 0);
153ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    break;
154e303bf443532c2ad756260133f00747bcff11e69Jim Miller                case MSG_CONFIGURE:
155e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    ConfigurationData data = (ConfigurationData) msg.obj;
1560814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller                    boolean result = onConfigure(data.options);
157a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                    if (data.token != null) {
158a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                        try {
159a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            synchronized (mLock) {
160a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                                mCallback.onConfigureCompleted(result, data.token);
161a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            }
162a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                        } catch (RemoteException e) {
163a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
1648f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                        }
1658f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    }
1668f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    break;
167d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                case MSG_TRUST_TIMEOUT:
168d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    onTrustTimeout();
169d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    break;
170481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_LOCKED:
171481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceLocked();
172481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
173481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_UNLOCKED:
174481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceUnlocked();
175481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
176ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
1778f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos        }
178ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    };
179ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
180cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    @Override
181cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    public void onCreate() {
182cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        super.onCreate();
183cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        ComponentName component = new ComponentName(this, getClass());
184cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        try {
185cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */);
186cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) {
187cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                throw new IllegalStateException(component.flattenToShortString()
188cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + " is not declared with the permission "
189cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\"");
190cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            }
191cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        } catch (PackageManager.NameNotFoundException e) {
192cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString());
193cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        }
194cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    }
195cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos
196ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
197d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called after the user attempts to authenticate in keyguard with their device credentials,
198d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * such as pin, pattern or password.
199ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
200d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param successful true if the user successfully completed the challenge.
201ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
2027e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public void onUnlockAttempt(boolean successful) {
203ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
204ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
205d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    /**
206d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called when the timeout provided by the agent expires.  Note that this may be called earlier
207d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * than requested by the agent if the trust timeout is adjusted by the system or
208d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * {@link DevicePolicyManager}.  The agent is expected to re-evaluate the trust state and only
209d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * call {@link #grantTrust(CharSequence, long, boolean)} if the trust state should be
210d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * continued.
211d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     */
212d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    public void onTrustTimeout() {
213d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    }
214d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
215481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
216481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device enters a state where a PIN, pattern or
217481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
218481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
219481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceLocked() {
220481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
221481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
222481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
223481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device leaves a state where a PIN, pattern or
224481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
225481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
226481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceUnlocked() {
227481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
228481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
229ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private void onError(String msg) {
230ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        Slog.v(TAG, "Remote exception while " + msg);
231ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
232ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
233ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
234e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Called when device policy admin wants to enable specific options for agent in response to
235e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
236e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName,
237e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * PersistableBundle)}.
238e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * <p>Agents that support configuration options should overload this method and return 'true'.
239604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     *
240a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos     * @param options The aggregated list of options or an empty list if no restrictions apply.
241e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * @return true if the {@link TrustAgentService} supports configuration options.
242604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     */
2430814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller    public boolean onConfigure(List<PersistableBundle> options) {
244604e7558ef32098644b2f9456d7743a07ae789dcJim Miller        return false;
245604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    }
246604e7558ef32098644b2f9456d7743a07ae789dcJim Miller
247604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
2487e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos     * Call to grant trust on the device.
249ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
250ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * @param message describes why the device is trusted, e.g. "Trusted by location".
251d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param durationMs amount of time in milliseconds to keep the device in a trusted state.
252d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    Trust for this agent will automatically be revoked when the timeout expires unless
253d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    extended by a subsequent call to this function. The timeout is measured from the
254d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}.
255d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    For security reasons, the value should be no larger than necessary.
256d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    The value may be adjusted by the system as necessary to comply with a policy controlled
257d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()}
258d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    for determining when trust expires.
259d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param initiatedByUser this is a hint to the system that trust is being granted as the
260d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    direct result of user action - such as solving a security challenge. The hint is used
261d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system to optimize the experience. Behavior may vary by device and release, so
262d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    one should only set this parameter if it meets the above criteria rather than relying on
26394e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    the behavior of any particular device or release. Corresponds to
26494e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    {@link #FLAG_GRANT_TRUST_INITIATED_BY_USER}.
2657861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @throws IllegalStateException if the agent is not currently managing trust.
26694e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *
26794e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * @deprecated use {@link #grantTrust(CharSequence, long, int)} instead.
268ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
26994e15a59b757678949cccb5d783bee1638e84697Adrian Roos    @Deprecated
2704f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    public final void grantTrust(
2714f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            final CharSequence message, final long durationMs, final boolean initiatedByUser) {
27294e15a59b757678949cccb5d783bee1638e84697Adrian Roos        grantTrust(message, durationMs, initiatedByUser ? FLAG_GRANT_TRUST_INITIATED_BY_USER : 0);
27394e15a59b757678949cccb5d783bee1638e84697Adrian Roos    }
27494e15a59b757678949cccb5d783bee1638e84697Adrian Roos
27594e15a59b757678949cccb5d783bee1638e84697Adrian Roos    /**
27694e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * Call to grant trust on the device.
27794e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *
27894e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * @param message describes why the device is trusted, e.g. "Trusted by location".
27994e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * @param durationMs amount of time in milliseconds to keep the device in a trusted state.
28094e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    Trust for this agent will automatically be revoked when the timeout expires unless
28194e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    extended by a subsequent call to this function. The timeout is measured from the
28294e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}.
28394e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    For security reasons, the value should be no larger than necessary.
28494e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    The value may be adjusted by the system as necessary to comply with a policy controlled
28594e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()}
28694e15a59b757678949cccb5d783bee1638e84697Adrian Roos     *    for determining when trust expires.
28794e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * @param flags TBDocumented
28894e15a59b757678949cccb5d783bee1638e84697Adrian Roos     * @throws IllegalStateException if the agent is not currently managing trust.
28994e15a59b757678949cccb5d783bee1638e84697Adrian Roos     */
29094e15a59b757678949cccb5d783bee1638e84697Adrian Roos    public final void grantTrust(
29194e15a59b757678949cccb5d783bee1638e84697Adrian Roos            final CharSequence message, final long durationMs, @GrantTrustFlags final int flags) {
2924f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
2937861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (!mManagingTrust) {
2947861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                throw new IllegalStateException("Cannot grant trust if agent is not managing trust."
2957861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        + " Call setManagingTrust(true) first.");
2967861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
2974f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
2984f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
29994e15a59b757678949cccb5d783bee1638e84697Adrian Roos                    mCallback.grantTrust(message.toString(), durationMs, flags);
3004f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
3014f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling enableTrust()");
3024f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
3034f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            } else {
3044f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // Remember trust has been granted so we can effectively grant it once the service
3054f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // is bound.
3064f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = new Runnable() {
3074f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    @Override
3084f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    public void run() {
30994e15a59b757678949cccb5d783bee1638e84697Adrian Roos                        grantTrust(message, durationMs, flags);
3104f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    }
3114f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                };
312ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
313ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
314ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
315ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
316ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
317ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * Call to revoke trust on the device.
318ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
3197e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public final void revokeTrust() {
3204f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
3214f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mPendingGrantTrustTask != null) {
3224f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = null;
3234f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
3244f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
3254f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
3264f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mCallback.revokeTrust();
3274f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
3284f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling revokeTrust()");
3294f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
330ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
331ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
332ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
333ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
3347861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    /**
3357861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Call to notify the system if the agent is ready to manage trust.
3367861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
3377861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * This property is not persistent across recreating the service and defaults to false.
3387861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Therefore this method is typically called when initializing the agent in {@link #onCreate}.
3397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
3407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @param managingTrust indicates if the agent would like to manage trust.
3417861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     */
3427861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public final void setManagingTrust(boolean managingTrust) {
3437861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        synchronized (mLock) {
3447861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (mManagingTrust != managingTrust) {
3457861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                mManagingTrust = managingTrust;
3467861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mCallback != null) {
3477861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
3487861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(managingTrust);
3497861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e) {
3507861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
3517861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
3527861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
3537861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
3547861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
3557861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
3567861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
357ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @Override
358ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public final IBinder onBind(Intent intent) {
359ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent);
360ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        return new TrustAgentServiceWrapper();
361ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
362ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
363ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub {
364d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
365ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void onUnlockAttempt(boolean successful) {
366d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget();
367d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        }
368d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
369d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
370d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        public void onTrustTimeout() {
371d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
372ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
373ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
374d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
375e303bf443532c2ad756260133f00747bcff11e69Jim Miller        public void onConfigure(List<PersistableBundle> args, IBinder token) {
376e303bf443532c2ad756260133f00747bcff11e69Jim Miller            mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
377e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    .sendToTarget();
378e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
379e303bf443532c2ad756260133f00747bcff11e69Jim Miller
380481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
381481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceLocked() throws RemoteException {
382481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_LOCKED).sendToTarget();
383481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
384481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
385481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
386481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceUnlocked() throws RemoteException {
387481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_UNLOCKED).sendToTarget();
388481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
389481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
390e303bf443532c2ad756260133f00747bcff11e69Jim Miller        @Override /* Binder API */
391ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void setCallback(ITrustAgentServiceCallback callback) {
3924f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            synchronized (mLock) {
3934f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mCallback = callback;
3947861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // The managingTrust property is false implicitly on the server-side, so we only
3957861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // need to set it here if the agent has decided to manage trust.
3967861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mManagingTrust) {
3977861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
3987861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(mManagingTrust);
3997861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e ) {
4007861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
4017861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
4027861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
4034f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                if (mPendingGrantTrustTask != null) {
4044f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask.run();
4054f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask = null;
4064f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
4074f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
408ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
409ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
410ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
411ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos}
412