TrustAgentService.java revision cb9fbc3a30b562a61e316af54fb0aa1d26ce0a73
1/** 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.service.trust; 18 19import android.Manifest; 20import android.annotation.SdkConstant; 21import android.app.Service; 22import android.content.ComponentName; 23import android.content.Intent; 24import android.content.pm.PackageManager; 25import android.content.pm.ServiceInfo; 26import android.os.Handler; 27import android.os.IBinder; 28import android.os.RemoteException; 29import android.util.Log; 30import android.util.Slog; 31 32/** 33 * A service that notifies the system about whether it believes the environment of the device 34 * to be trusted. 35 * 36 * <p>To extend this class, you must declare the service in your manifest file with 37 * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission 38 * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> 39 * <pre> 40 * <service android:name=".TrustAgent" 41 * android:label="@string/service_name" 42 * android:permission="android.permission.BIND_TRUST_AGENT"> 43 * <intent-filter> 44 * <action android:name="android.service.trust.TrustAgentService" /> 45 * </intent-filter> 46 * <meta-data android:name="android.service.trust.trustagent" 47 * android:value="@xml/trust_agent" /> 48 * </service></pre> 49 * 50 * <p>The associated meta-data file can specify an activity that is accessible through Settings 51 * and should allow configuring the trust agent, as defined in 52 * {@link android.R.styleable#TrustAgent}. For example:</p> 53 * 54 * <pre> 55 * <trust-agent xmlns:android="http://schemas.android.com/apk/res/android" 56 * android:settingsActivity=".TrustAgentSettings" /></pre> 57 */ 58public class TrustAgentService extends Service { 59 private final String TAG = TrustAgentService.class.getSimpleName() + 60 "[" + getClass().getSimpleName() + "]"; 61 62 /** 63 * The {@link Intent} that must be declared as handled by the service. 64 */ 65 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 66 public static final String SERVICE_INTERFACE 67 = "android.service.trust.TrustAgentService"; 68 69 /** 70 * The name of the {@code meta-data} tag pointing to additional configuration of the trust 71 * agent. 72 */ 73 public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent"; 74 75 private static final int MSG_UNLOCK_ATTEMPT = 1; 76 77 private static final boolean DEBUG = false; 78 79 private ITrustAgentServiceCallback mCallback; 80 81 private Handler mHandler = new Handler() { 82 public void handleMessage(android.os.Message msg) { 83 switch (msg.what) { 84 case MSG_UNLOCK_ATTEMPT: 85 onUnlockAttempt(msg.arg1 != 0); 86 break; 87 } 88 }; 89 }; 90 91 @Override 92 public void onCreate() { 93 super.onCreate(); 94 ComponentName component = new ComponentName(this, getClass()); 95 try { 96 ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */); 97 if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) { 98 throw new IllegalStateException(component.flattenToShortString() 99 + " is not declared with the permission " 100 + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\""); 101 } 102 } catch (PackageManager.NameNotFoundException e) { 103 Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString()); 104 } 105 } 106 107 /** 108 * Called when the user attempted to authenticate on the device. 109 * 110 * @param successful true if the attempt succeeded 111 */ 112 public void onUnlockAttempt(boolean successful) { 113 } 114 115 private void onError(String msg) { 116 Slog.v(TAG, "Remote exception while " + msg); 117 } 118 119 /** 120 * Call to grant trust on the device. 121 * 122 * @param message describes why the device is trusted, e.g. "Trusted by location". 123 * @param durationMs amount of time in milliseconds to keep the device in a trusted state. Trust 124 * for this agent will automatically be revoked when the timeout expires. 125 * @param initiatedByUser indicates that the user has explicitly initiated an action that proves 126 * the user is about to use the device. 127 */ 128 public final void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser) { 129 if (mCallback != null) { 130 try { 131 mCallback.grantTrust(message.toString(), durationMs, initiatedByUser); 132 } catch (RemoteException e) { 133 onError("calling enableTrust()"); 134 } 135 } 136 } 137 138 /** 139 * Call to revoke trust on the device. 140 */ 141 public final void revokeTrust() { 142 if (mCallback != null) { 143 try { 144 mCallback.revokeTrust(); 145 } catch (RemoteException e) { 146 onError("calling revokeTrust()"); 147 } 148 } 149 } 150 151 @Override 152 public final IBinder onBind(Intent intent) { 153 if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent); 154 return new TrustAgentServiceWrapper(); 155 } 156 157 private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub { 158 @Override 159 public void onUnlockAttempt(boolean successful) { 160 mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0) 161 .sendToTarget(); 162 } 163 164 public void setCallback(ITrustAgentServiceCallback callback) { 165 mCallback = callback; 166 } 167 } 168 169} 170