TrustAgentService.java revision a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdb
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;
20ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.annotation.SdkConstant;
21a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roosimport android.annotation.SystemApi;
22ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.app.Service;
23604e7558ef32098644b2f9456d7743a07ae789dcJim Millerimport android.app.admin.DevicePolicyManager;
24cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.ComponentName;
25ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.content.Intent;
26cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.PackageManager;
27cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.ServiceInfo;
28ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.Handler;
29ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.IBinder;
30e303bf443532c2ad756260133f00747bcff11e69Jim Millerimport android.os.PersistableBundle;
31ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.RemoteException;
32cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.util.Log;
33ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.util.Slog;
34ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
35e303bf443532c2ad756260133f00747bcff11e69Jim Millerimport java.util.List;
36e303bf443532c2ad756260133f00747bcff11e69Jim Miller
37ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos/**
38ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * A service that notifies the system about whether it believes the environment of the device
39ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * to be trusted.
40ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
41d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * <p>Trust agents may only be provided by the platform. It is expected that there is only
42d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * one trust agent installed on the platform. In the event there is more than one,
43d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * either trust agent can enable trust.
44d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller * </p>
4518ea893a2319e2a192188d2288bb881149c9b06eAdrian Roos *
46ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>To extend this class, you must declare the service in your manifest file with
477e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission
48ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
49ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre>
50ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * &lt;service android:name=".TrustAgent"
51ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:label="&#64;string/service_name"
527e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos *          android:permission="android.permission.BIND_TRUST_AGENT">
53ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;intent-filter>
54ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *         &lt;action android:name="android.service.trust.TrustAgentService" />
55ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;/intent-filter>
56ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *     &lt;meta-data android:name="android.service.trust.trustagent"
57ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:value="&#64;xml/trust_agent" />
58ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * &lt;/service></pre>
59ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
60ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>The associated meta-data file can specify an activity that is accessible through Settings
61ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and should allow configuring the trust agent, as defined in
62ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * {@link android.R.styleable#TrustAgent}. For example:</p>
63ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *
64ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre>
657e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * &lt;trust-agent xmlns:android="http://schemas.android.com/apk/res/android"
66ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos *          android:settingsActivity=".TrustAgentSettings" /></pre>
67a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos *
68a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos * @hide
69ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */
70a06d5ca1d96af3555ad4e384994e6321a0c5bb9cAdrian Roos@SystemApi
71ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roospublic class TrustAgentService extends Service {
72ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final String TAG = TrustAgentService.class.getSimpleName() +
73ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            "[" + getClass().getSimpleName() + "]";
747861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private static final boolean DEBUG = false;
757861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
76ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
77ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The {@link Intent} that must be declared as handled by the service.
78ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
79ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
80ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String SERVICE_INTERFACE
81ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            = "android.service.trust.TrustAgentService";
82ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
83ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
84ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The name of the {@code meta-data} tag pointing to additional configuration of the trust
85ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * agent.
86ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
87ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
88ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
89e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_UNLOCK_ATTEMPT = 1;
90e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_CONFIGURE = 2;
91e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_TRUST_TIMEOUT = 3;
92481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_LOCKED = 4;
93481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_UNLOCKED = 5;
94e303bf443532c2ad756260133f00747bcff11e69Jim Miller
95604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
96e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Class containing raw data for a given configuration request.
97e303bf443532c2ad756260133f00747bcff11e69Jim Miller     */
98e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final class ConfigurationData {
99e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final IBinder token;
100e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final List<PersistableBundle> options;
101e303bf443532c2ad756260133f00747bcff11e69Jim Miller        ConfigurationData(List<PersistableBundle> opts, IBinder t) {
102e303bf443532c2ad756260133f00747bcff11e69Jim Miller            options = opts;
103e303bf443532c2ad756260133f00747bcff11e69Jim Miller            token = t;
104e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
105e303bf443532c2ad756260133f00747bcff11e69Jim Miller    }
106ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
107ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private ITrustAgentServiceCallback mCallback;
108ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
1094f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private Runnable mPendingGrantTrustTask;
1104f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
1117861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private boolean mManagingTrust;
1127861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1134f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    // Lock used to access mPendingGrantTrustTask and mCallback.
1144f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private final Object mLock = new Object();
1154f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
116ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private Handler mHandler = new Handler() {
117ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void handleMessage(android.os.Message msg) {
118ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            switch (msg.what) {
119ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                case MSG_UNLOCK_ATTEMPT:
120ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    onUnlockAttempt(msg.arg1 != 0);
121ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    break;
122e303bf443532c2ad756260133f00747bcff11e69Jim Miller                case MSG_CONFIGURE:
123e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    ConfigurationData data = (ConfigurationData) msg.obj;
1240814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller                    boolean result = onConfigure(data.options);
125a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                    if (data.token != null) {
126a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                        try {
127a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            synchronized (mLock) {
128a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                                mCallback.onConfigureCompleted(result, data.token);
129a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            }
130a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                        } catch (RemoteException e) {
131a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos                            onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
1328f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                        }
1338f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    }
1348f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    break;
135d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                case MSG_TRUST_TIMEOUT:
136d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    onTrustTimeout();
137d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    break;
138481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_LOCKED:
139481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceLocked();
140481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
141481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_UNLOCKED:
142481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceUnlocked();
143481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
144ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
1458f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos        }
146ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    };
147ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
148cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    @Override
149cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    public void onCreate() {
150cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        super.onCreate();
151cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        ComponentName component = new ComponentName(this, getClass());
152cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        try {
153cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */);
154cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) {
155cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                throw new IllegalStateException(component.flattenToShortString()
156cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + " is not declared with the permission "
157cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\"");
158cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            }
159cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        } catch (PackageManager.NameNotFoundException e) {
160cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString());
161cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        }
162cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    }
163cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos
164ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
165d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called after the user attempts to authenticate in keyguard with their device credentials,
166d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * such as pin, pattern or password.
167ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
168d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param successful true if the user successfully completed the challenge.
169ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
1707e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public void onUnlockAttempt(boolean successful) {
171ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
172ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
173d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    /**
174d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called when the timeout provided by the agent expires.  Note that this may be called earlier
175d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * than requested by the agent if the trust timeout is adjusted by the system or
176d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * {@link DevicePolicyManager}.  The agent is expected to re-evaluate the trust state and only
177d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * call {@link #grantTrust(CharSequence, long, boolean)} if the trust state should be
178d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * continued.
179d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     */
180d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    public void onTrustTimeout() {
181d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    }
182d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
183481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
184481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device enters a state where a PIN, pattern or
185481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
186481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
187481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceLocked() {
188481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
189481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
190481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
191481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device leaves a state where a PIN, pattern or
192481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
193481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
194481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceUnlocked() {
195481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
196481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
197ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private void onError(String msg) {
198ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        Slog.v(TAG, "Remote exception while " + msg);
199ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
200ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
201ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
202e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Called when device policy admin wants to enable specific options for agent in response to
203e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
204e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName,
205e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * PersistableBundle)}.
206e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * <p>Agents that support configuration options should overload this method and return 'true'.
207604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     *
208a43fd03b9b23f9ad0deae9ee69ee80aaa1433cdbAdrian Roos     * @param options The aggregated list of options or an empty list if no restrictions apply.
209e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * @return true if the {@link TrustAgentService} supports configuration options.
210604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     */
2110814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller    public boolean onConfigure(List<PersistableBundle> options) {
212604e7558ef32098644b2f9456d7743a07ae789dcJim Miller        return false;
213604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    }
214604e7558ef32098644b2f9456d7743a07ae789dcJim Miller
215604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
2167e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos     * Call to grant trust on the device.
217ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
218ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * @param message describes why the device is trusted, e.g. "Trusted by location".
219d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param durationMs amount of time in milliseconds to keep the device in a trusted state.
220d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    Trust for this agent will automatically be revoked when the timeout expires unless
221d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    extended by a subsequent call to this function. The timeout is measured from the
222d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}.
223d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    For security reasons, the value should be no larger than necessary.
224d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    The value may be adjusted by the system as necessary to comply with a policy controlled
225d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()}
226d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    for determining when trust expires.
227d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param initiatedByUser this is a hint to the system that trust is being granted as the
228d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    direct result of user action - such as solving a security challenge. The hint is used
229d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system to optimize the experience. Behavior may vary by device and release, so
230d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    one should only set this parameter if it meets the above criteria rather than relying on
231d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    the behavior of any particular device or release.
2327861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @throws IllegalStateException if the agent is not currently managing trust.
233ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
2344f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    public final void grantTrust(
2354f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            final CharSequence message, final long durationMs, final boolean initiatedByUser) {
2364f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
2377861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (!mManagingTrust) {
2387861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                throw new IllegalStateException("Cannot grant trust if agent is not managing trust."
2397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        + " Call setManagingTrust(true) first.");
2407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
2414f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
2424f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
2434f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mCallback.grantTrust(message.toString(), durationMs, initiatedByUser);
2444f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
2454f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling enableTrust()");
2464f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
2474f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            } else {
2484f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // Remember trust has been granted so we can effectively grant it once the service
2494f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // is bound.
2504f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = new Runnable() {
2514f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    @Override
2524f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    public void run() {
2534f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                        grantTrust(message, durationMs, initiatedByUser);
2544f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    }
2554f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                };
256ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
257ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
258ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
259ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
260ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
261ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * Call to revoke trust on the device.
262ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
2637e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public final void revokeTrust() {
2644f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
2654f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mPendingGrantTrustTask != null) {
2664f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = null;
2674f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
2684f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
2694f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
2704f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mCallback.revokeTrust();
2714f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
2724f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling revokeTrust()");
2734f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
274ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
275ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
276ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
277ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
2787861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    /**
2797861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Call to notify the system if the agent is ready to manage trust.
2807861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
2817861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * This property is not persistent across recreating the service and defaults to false.
2827861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Therefore this method is typically called when initializing the agent in {@link #onCreate}.
2837861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
2847861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @param managingTrust indicates if the agent would like to manage trust.
2857861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     */
2867861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public final void setManagingTrust(boolean managingTrust) {
2877861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        synchronized (mLock) {
2887861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (mManagingTrust != managingTrust) {
2897861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                mManagingTrust = managingTrust;
2907861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mCallback != null) {
2917861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
2927861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(managingTrust);
2937861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e) {
2947861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
2957861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
2967861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
2977861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
2987861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
2997861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
3007861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
301ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @Override
302ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public final IBinder onBind(Intent intent) {
303ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent);
304ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        return new TrustAgentServiceWrapper();
305ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
306ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
307ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub {
308d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
309ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void onUnlockAttempt(boolean successful) {
310d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget();
311d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        }
312d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
313d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
314d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        public void onTrustTimeout() {
315d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
316ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
317ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
318d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
319e303bf443532c2ad756260133f00747bcff11e69Jim Miller        public void onConfigure(List<PersistableBundle> args, IBinder token) {
320e303bf443532c2ad756260133f00747bcff11e69Jim Miller            mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
321e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    .sendToTarget();
322e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
323e303bf443532c2ad756260133f00747bcff11e69Jim Miller
324481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
325481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceLocked() throws RemoteException {
326481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_LOCKED).sendToTarget();
327481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
328481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
329481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
330481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceUnlocked() throws RemoteException {
331481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_UNLOCKED).sendToTarget();
332481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
333481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
334e303bf443532c2ad756260133f00747bcff11e69Jim Miller        @Override /* Binder API */
335ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void setCallback(ITrustAgentServiceCallback callback) {
3364f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            synchronized (mLock) {
3374f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mCallback = callback;
3387861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // The managingTrust property is false implicitly on the server-side, so we only
3397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // need to set it here if the agent has decided to manage trust.
3407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mManagingTrust) {
3417861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
3427861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(mManagingTrust);
3437861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e ) {
3447861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
3457861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
3467861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
3474f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                if (mPendingGrantTrustTask != null) {
3484f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask.run();
3494f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask = null;
3504f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
3514f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
352ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
353ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
354ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
355ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos}
356