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;
28604e7558ef32098644b2f9456d7743a07ae789dcJim Millerimport android.os.Bundle;
29ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.Handler;
30ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.IBinder;
318f21158fe64eb93ff005dc1b831b282b95531023Adrian Roosimport android.os.Message;
32e303bf443532c2ad756260133f00747bcff11e69Jim Millerimport android.os.PersistableBundle;
33ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.RemoteException;
34d4efaac5d54cdb3735b032bb76a5639949f33216Jim Millerimport android.os.SystemClock;
35cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.util.Log;
36ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.util.Slog;
37ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
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 {
75ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final String TAG = TrustAgentService.class.getSimpleName() +
76ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            "[" + getClass().getSimpleName() + "]";
777861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private static final boolean DEBUG = false;
787861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
79ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
80ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The {@link Intent} that must be declared as handled by the service.
81ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
82ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
83ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String SERVICE_INTERFACE
84ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            = "android.service.trust.TrustAgentService";
85ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
86ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
87ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * The name of the {@code meta-data} tag pointing to additional configuration of the trust
88ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * agent.
89ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
90ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
91ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
92e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_UNLOCK_ATTEMPT = 1;
93e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_CONFIGURE = 2;
94e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final int MSG_TRUST_TIMEOUT = 3;
95481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_LOCKED = 4;
96481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    private static final int MSG_DEVICE_UNLOCKED = 5;
97e303bf443532c2ad756260133f00747bcff11e69Jim Miller
98604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
99e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Class containing raw data for a given configuration request.
100e303bf443532c2ad756260133f00747bcff11e69Jim Miller     */
101e303bf443532c2ad756260133f00747bcff11e69Jim Miller    private static final class ConfigurationData {
102e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final IBinder token;
103e303bf443532c2ad756260133f00747bcff11e69Jim Miller        final List<PersistableBundle> options;
104e303bf443532c2ad756260133f00747bcff11e69Jim Miller        ConfigurationData(List<PersistableBundle> opts, IBinder t) {
105e303bf443532c2ad756260133f00747bcff11e69Jim Miller            options = opts;
106e303bf443532c2ad756260133f00747bcff11e69Jim Miller            token = t;
107e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
108e303bf443532c2ad756260133f00747bcff11e69Jim Miller    }
109ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
110ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private ITrustAgentServiceCallback mCallback;
111ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
1124f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private Runnable mPendingGrantTrustTask;
1134f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
1147861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private boolean mManagingTrust;
1157861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1164f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    // Lock used to access mPendingGrantTrustTask and mCallback.
1174f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    private final Object mLock = new Object();
1184f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli
119ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private Handler mHandler = new Handler() {
120ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void handleMessage(android.os.Message msg) {
121ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            switch (msg.what) {
122ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                case MSG_UNLOCK_ATTEMPT:
123ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    onUnlockAttempt(msg.arg1 != 0);
124ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos                    break;
125e303bf443532c2ad756260133f00747bcff11e69Jim Miller                case MSG_CONFIGURE:
126e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    ConfigurationData data = (ConfigurationData) msg.obj;
1270814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller                    boolean result = onConfigure(data.options);
1288f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    try {
1298f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                        synchronized (mLock) {
130e303bf443532c2ad756260133f00747bcff11e69Jim Miller                            mCallback.onConfigureCompleted(result, data.token);
1318f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                        }
1328f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    } catch (RemoteException e) {
1338f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                        onError("calling onSetTrustAgentFeaturesEnabledCompleted()");
1348f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    }
1358f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos                    break;
136d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                case MSG_TRUST_TIMEOUT:
137d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    onTrustTimeout();
138d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller                    break;
139481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_LOCKED:
140481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceLocked();
141481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
142481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                case MSG_DEVICE_UNLOCKED:
143481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    onDeviceUnlocked();
144481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos                    break;
145ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
1468f21158fe64eb93ff005dc1b831b282b95531023Adrian Roos        }
147ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    };
148ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
149cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    @Override
150cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    public void onCreate() {
151cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        super.onCreate();
152cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        ComponentName component = new ComponentName(this, getClass());
153cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        try {
154cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */);
155cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) {
156cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                throw new IllegalStateException(component.flattenToShortString()
157cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + " is not declared with the permission "
158cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos                        + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\"");
159cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            }
160cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        } catch (PackageManager.NameNotFoundException e) {
161cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos            Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString());
162cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos        }
163cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos    }
164cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos
165ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
166d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called after the user attempts to authenticate in keyguard with their device credentials,
167d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * such as pin, pattern or password.
168ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
169d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param successful true if the user successfully completed the challenge.
170ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
1717e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public void onUnlockAttempt(boolean successful) {
172ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
173ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
174d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    /**
175d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * Called when the timeout provided by the agent expires.  Note that this may be called earlier
176d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * than requested by the agent if the trust timeout is adjusted by the system or
177d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * {@link DevicePolicyManager}.  The agent is expected to re-evaluate the trust state and only
178d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * call {@link #grantTrust(CharSequence, long, boolean)} if the trust state should be
179d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * continued.
180d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     */
181d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    public void onTrustTimeout() {
182d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller    }
183d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
184481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
185481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device enters a state where a PIN, pattern or
186481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
187481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
188481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceLocked() {
189481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
190481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
191481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    /**
192481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * Called when the device leaves a state where a PIN, pattern or
193481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     * password must be entered to unlock it.
194481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos     */
195481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    public void onDeviceUnlocked() {
196481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos    }
197481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
198ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private void onError(String msg) {
199ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        Slog.v(TAG, "Remote exception while " + msg);
200ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
201ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
202ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
203e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * Called when device policy admin wants to enable specific options for agent in response to
204e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and
205e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName,
206e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * PersistableBundle)}.
207e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * <p>Agents that support configuration options should overload this method and return 'true'.
208604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     *
209e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * @param options bundle containing all options or null if none.
210e303bf443532c2ad756260133f00747bcff11e69Jim Miller     * @return true if the {@link TrustAgentService} supports configuration options.
211604e7558ef32098644b2f9456d7743a07ae789dcJim Miller     */
2120814d41c73fe3ebc2d1269f1a4fc73d0cf4cb230Jim Miller    public boolean onConfigure(List<PersistableBundle> options) {
213604e7558ef32098644b2f9456d7743a07ae789dcJim Miller        return false;
214604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    }
215604e7558ef32098644b2f9456d7743a07ae789dcJim Miller
216604e7558ef32098644b2f9456d7743a07ae789dcJim Miller    /**
2177e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos     * Call to grant trust on the device.
218ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     *
219ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * @param message describes why the device is trusted, e.g. "Trusted by location".
220d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param durationMs amount of time in milliseconds to keep the device in a trusted state.
221d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    Trust for this agent will automatically be revoked when the timeout expires unless
222d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    extended by a subsequent call to this function. The timeout is measured from the
223d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}.
224d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    For security reasons, the value should be no larger than necessary.
225d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    The value may be adjusted by the system as necessary to comply with a policy controlled
226d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()}
227d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    for determining when trust expires.
228d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     * @param initiatedByUser this is a hint to the system that trust is being granted as the
229d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    direct result of user action - such as solving a security challenge. The hint is used
230d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    by the system to optimize the experience. Behavior may vary by device and release, so
231d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    one should only set this parameter if it meets the above criteria rather than relying on
232d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller     *    the behavior of any particular device or release.
2337861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @throws IllegalStateException if the agent is not currently managing trust.
234ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
2354f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli    public final void grantTrust(
2364f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            final CharSequence message, final long durationMs, final boolean initiatedByUser) {
2374f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
2387861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (!mManagingTrust) {
2397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                throw new IllegalStateException("Cannot grant trust if agent is not managing trust."
2407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        + " Call setManagingTrust(true) first.");
2417861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
2424f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
2434f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
2444f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mCallback.grantTrust(message.toString(), durationMs, initiatedByUser);
2454f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
2464f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling enableTrust()");
2474f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
2484f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            } else {
2494f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // Remember trust has been granted so we can effectively grant it once the service
2504f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                // is bound.
2514f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = new Runnable() {
2524f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    @Override
2534f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    public void run() {
2544f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                        grantTrust(message, durationMs, initiatedByUser);
2554f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    }
2564f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                };
257ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
258ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
259ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
260ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
261ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    /**
262ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     * Call to revoke trust on the device.
263ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos     */
2647e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos    public final void revokeTrust() {
2654f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli        synchronized (mLock) {
2664f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mPendingGrantTrustTask != null) {
2674f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mPendingGrantTrustTask = null;
2684f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
2694f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            if (mCallback != null) {
2704f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                try {
2714f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mCallback.revokeTrust();
2724f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                } catch (RemoteException e) {
2734f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    onError("calling revokeTrust()");
2744f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
275ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos            }
276ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
277ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
278ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
2797861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    /**
2807861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Call to notify the system if the agent is ready to manage trust.
2817861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
2827861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * This property is not persistent across recreating the service and defaults to false.
2837861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * Therefore this method is typically called when initializing the agent in {@link #onCreate}.
2847861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     *
2857861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     * @param managingTrust indicates if the agent would like to manage trust.
2867861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos     */
2877861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public final void setManagingTrust(boolean managingTrust) {
2887861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        synchronized (mLock) {
2897861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            if (mManagingTrust != managingTrust) {
2907861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                mManagingTrust = managingTrust;
2917861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mCallback != null) {
2927861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
2937861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(managingTrust);
2947861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e) {
2957861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
2967861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
2977861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
2987861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            }
2997861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
3007861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
3017861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
302ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    @Override
303ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    public final IBinder onBind(Intent intent) {
304ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent);
305ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        return new TrustAgentServiceWrapper();
306ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
307ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
308ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub {
309d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
310ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void onUnlockAttempt(boolean successful) {
311d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget();
312d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        }
313d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller
314d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
315d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        public void onTrustTimeout() {
316d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller            mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
317ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
318ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
319d4efaac5d54cdb3735b032bb76a5639949f33216Jim Miller        @Override /* Binder API */
320e303bf443532c2ad756260133f00747bcff11e69Jim Miller        public void onConfigure(List<PersistableBundle> args, IBinder token) {
321e303bf443532c2ad756260133f00747bcff11e69Jim Miller            mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token))
322e303bf443532c2ad756260133f00747bcff11e69Jim Miller                    .sendToTarget();
323e303bf443532c2ad756260133f00747bcff11e69Jim Miller        }
324e303bf443532c2ad756260133f00747bcff11e69Jim Miller
325481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
326481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceLocked() throws RemoteException {
327481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_LOCKED).sendToTarget();
328481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
329481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
330481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        @Override
331481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        public void onDeviceUnlocked() throws RemoteException {
332481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos            mHandler.obtainMessage(MSG_DEVICE_UNLOCKED).sendToTarget();
333481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos        }
334481a6df99fea124bc4354da34ff668750cdc9041Adrian Roos
335e303bf443532c2ad756260133f00747bcff11e69Jim Miller        @Override /* Binder API */
336ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        public void setCallback(ITrustAgentServiceCallback callback) {
3374f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            synchronized (mLock) {
3384f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                mCallback = callback;
3397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // The managingTrust property is false implicitly on the server-side, so we only
3407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                // need to set it here if the agent has decided to manage trust.
3417861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                if (mManagingTrust) {
3427861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    try {
3437861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        mCallback.setManagingTrust(mManagingTrust);
3447861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    } catch (RemoteException e ) {
3457861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                        onError("calling setManagingTrust()");
3467861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                    }
3477861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos                }
3484f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                if (mPendingGrantTrustTask != null) {
3494f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask.run();
3504f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                    mPendingGrantTrustTask = null;
3514f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli                }
3524f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli            }
353ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos        }
354ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos    }
355ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos
356ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos}
357