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 * <service android:name=".TrustAgent" 54ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * android:label="@string/service_name" 557e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * android:permission="android.permission.BIND_TRUST_AGENT"> 56ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <intent-filter> 57ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <action android:name="android.service.trust.TrustAgentService" /> 58ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * </intent-filter> 59ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <meta-data android:name="android.service.trust.trustagent" 60ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * android:value="@xml/trust_agent" /> 61ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * </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 * <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