TrustAgentService.java revision 4f22777efb6dc99b61c664b39b4087fe89f0c050
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; 21ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.app.Service; 22cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.ComponentName; 23ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.content.Intent; 24cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.PackageManager; 25cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.content.pm.ServiceInfo; 26ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.Handler; 27ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.IBinder; 28ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.os.RemoteException; 29cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roosimport android.util.Log; 30ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roosimport android.util.Slog; 31ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 32ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos/** 33ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * A service that notifies the system about whether it believes the environment of the device 34ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * to be trusted. 35ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 3618ea893a2319e2a192188d2288bb881149c9b06eAdrian Roos * <p>Trust agents may only be provided by the platform.</p> 3718ea893a2319e2a192188d2288bb881149c9b06eAdrian Roos * 38ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>To extend this class, you must declare the service in your manifest file with 397e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission 40ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> 41ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre> 42ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <service android:name=".TrustAgent" 43ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * android:label="@string/service_name" 447e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * android:permission="android.permission.BIND_TRUST_AGENT"> 45ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <intent-filter> 46ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <action android:name="android.service.trust.TrustAgentService" /> 47ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * </intent-filter> 48ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <meta-data android:name="android.service.trust.trustagent" 49ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * android:value="@xml/trust_agent" /> 50ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * </service></pre> 51ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 52ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <p>The associated meta-data file can specify an activity that is accessible through Settings 53ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * and should allow configuring the trust agent, as defined in 54ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * {@link android.R.styleable#TrustAgent}. For example:</p> 55ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 56ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * <pre> 577e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * <trust-agent xmlns:android="http://schemas.android.com/apk/res/android" 58ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * android:settingsActivity=".TrustAgentSettings" /></pre> 59ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 60ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roospublic class TrustAgentService extends Service { 61ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private final String TAG = TrustAgentService.class.getSimpleName() + 62ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos "[" + getClass().getSimpleName() + "]"; 63ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 64ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 65ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * The {@link Intent} that must be declared as handled by the service. 66ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 67ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 68ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public static final String SERVICE_INTERFACE 69ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos = "android.service.trust.TrustAgentService"; 70ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 71ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 72ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * The name of the {@code meta-data} tag pointing to additional configuration of the trust 73ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * agent. 74ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 75ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent"; 76ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 77ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private static final int MSG_UNLOCK_ATTEMPT = 1; 78ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 79ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private static final boolean DEBUG = false; 80ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 81ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private ITrustAgentServiceCallback mCallback; 82ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 834f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli private Runnable mPendingGrantTrustTask; 844f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli 854f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli // Lock used to access mPendingGrantTrustTask and mCallback. 864f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli private final Object mLock = new Object(); 874f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli 88ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private Handler mHandler = new Handler() { 89ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void handleMessage(android.os.Message msg) { 90ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos switch (msg.what) { 91ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos case MSG_UNLOCK_ATTEMPT: 92ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos onUnlockAttempt(msg.arg1 != 0); 93ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos break; 94ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 95ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos }; 96ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos }; 97ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 98cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos @Override 99cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos public void onCreate() { 100cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos super.onCreate(); 101cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos ComponentName component = new ComponentName(this, getClass()); 102cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos try { 103cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */); 104cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) { 105cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos throw new IllegalStateException(component.flattenToShortString() 106cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos + " is not declared with the permission " 107cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\""); 108cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 109cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } catch (PackageManager.NameNotFoundException e) { 110cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString()); 111cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 112cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 113cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos 114ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 115ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Called when the user attempted to authenticate on the device. 116ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 117ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param successful true if the attempt succeeded 118ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1197e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos public void onUnlockAttempt(boolean successful) { 120ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 121ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 122ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private void onError(String msg) { 123ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos Slog.v(TAG, "Remote exception while " + msg); 124ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 125ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 126ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 1277e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * Call to grant trust on the device. 128ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 129ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param message describes why the device is trusted, e.g. "Trusted by location". 130ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param durationMs amount of time in milliseconds to keep the device in a trusted state. Trust 131ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * for this agent will automatically be revoked when the timeout expires. 132ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param initiatedByUser indicates that the user has explicitly initiated an action that proves 133ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * the user is about to use the device. 134ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1354f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli public final void grantTrust( 1364f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli final CharSequence message, final long durationMs, final boolean initiatedByUser) { 1374f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli synchronized (mLock) { 1384f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli if (mCallback != null) { 1394f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli try { 1404f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mCallback.grantTrust(message.toString(), durationMs, initiatedByUser); 1414f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } catch (RemoteException e) { 1424f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli onError("calling enableTrust()"); 1434f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 1444f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } else { 1454f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli // Remember trust has been granted so we can effectively grant it once the service 1464f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli // is bound. 1474f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mPendingGrantTrustTask = new Runnable() { 1484f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli @Override 1494f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli public void run() { 1504f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli grantTrust(message, durationMs, initiatedByUser); 1514f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 1524f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli }; 153ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 154ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 155ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 156ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 157ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 158ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Call to revoke trust on the device. 159ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1607e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos public final void revokeTrust() { 1614f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli synchronized (mLock) { 1624f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli if (mPendingGrantTrustTask != null) { 1634f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mPendingGrantTrustTask = null; 1644f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 1654f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli if (mCallback != null) { 1664f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli try { 1674f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mCallback.revokeTrust(); 1684f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } catch (RemoteException e) { 1694f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli onError("calling revokeTrust()"); 1704f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 171ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 172ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 173ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 174ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 175ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos @Override 176ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public final IBinder onBind(Intent intent) { 177ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent); 178ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos return new TrustAgentServiceWrapper(); 179ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 180ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 181ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub { 182ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos @Override 183ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void onUnlockAttempt(boolean successful) { 184ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0) 185ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos .sendToTarget(); 186ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 187ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 188ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void setCallback(ITrustAgentServiceCallback callback) { 1894f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli synchronized (mLock) { 1904f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mCallback = callback; 1914f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli if (mPendingGrantTrustTask != null) { 1924f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mPendingGrantTrustTask.run(); 1934f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli mPendingGrantTrustTask = null; 1944f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 1954f22777efb6dc99b61c664b39b4087fe89f0c050Jay Civelli } 196ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 197ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 198ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 199ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos} 200