TrustAgentService.java revision 18ea893a2319e2a192188d2288bb881149c9b06e
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 83ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private Handler mHandler = new Handler() { 84ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void handleMessage(android.os.Message msg) { 85ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos switch (msg.what) { 86ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos case MSG_UNLOCK_ATTEMPT: 87ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos onUnlockAttempt(msg.arg1 != 0); 88ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos break; 89ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 90ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos }; 91ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos }; 92ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 93cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos @Override 94cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos public void onCreate() { 95cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos super.onCreate(); 96cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos ComponentName component = new ComponentName(this, getClass()); 97cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos try { 98cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */); 99cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) { 100cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos throw new IllegalStateException(component.flattenToShortString() 101cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos + " is not declared with the permission " 102cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\""); 103cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 104cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } catch (PackageManager.NameNotFoundException e) { 105cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString()); 106cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 107cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos } 108cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73Adrian Roos 109ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 110ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Called when the user attempted to authenticate on the device. 111ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 112ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param successful true if the attempt succeeded 113ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1147e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos public void onUnlockAttempt(boolean successful) { 115ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 116ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 117ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private void onError(String msg) { 118ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos Slog.v(TAG, "Remote exception while " + msg); 119ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 120ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 121ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 1227e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos * Call to grant trust on the device. 123ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * 124ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param message describes why the device is trusted, e.g. "Trusted by location". 125ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param durationMs amount of time in milliseconds to keep the device in a trusted state. Trust 126ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * for this agent will automatically be revoked when the timeout expires. 127ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * @param initiatedByUser indicates that the user has explicitly initiated an action that proves 128ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * the user is about to use the device. 129ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1307e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos public final void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser) { 131ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos if (mCallback != null) { 132ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos try { 1337e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos mCallback.grantTrust(message.toString(), durationMs, initiatedByUser); 134ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } catch (RemoteException e) { 135ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos onError("calling enableTrust()"); 136ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 137ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 138ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 139ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 140ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos /** 141ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos * Call to revoke trust on the device. 142ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos */ 1437e03dfcb796ef1a6000a5fd5fda03c9e15ea62e1Adrian Roos public final void revokeTrust() { 144ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos if (mCallback != null) { 145ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos try { 146ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos mCallback.revokeTrust(); 147ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } catch (RemoteException e) { 148ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos onError("calling revokeTrust()"); 149ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 150ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 151ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 152ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 153ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos @Override 154ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public final IBinder onBind(Intent intent) { 155ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent); 156ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos return new TrustAgentServiceWrapper(); 157ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 158ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 159ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub { 160ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos @Override 161ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void onUnlockAttempt(boolean successful) { 162ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0) 163ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos .sendToTarget(); 164ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 165ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 166ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos public void setCallback(ITrustAgentServiceCallback callback) { 167ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos mCallback = callback; 168ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 169ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos } 170ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos 171ff2144ccb4215acf4587fc628493b3d49dca6043Adrian Roos} 172