TrustAgentWrapper.java revision 82142c21dd333307682d5f4bb09de3ab3ccfa06c
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 com.android.server.trust; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.Intent; 22import android.content.ServiceConnection; 23import android.os.Bundle; 24import android.os.Handler; 25import android.os.IBinder; 26import android.os.Message; 27import android.os.RemoteException; 28import android.os.UserHandle; 29import android.util.Log; 30import android.util.Slog; 31import android.service.trust.ITrustAgentService; 32import android.service.trust.ITrustAgentServiceCallback; 33 34/** 35 * A wrapper around a TrustAgentService interface. Coordinates communication between 36 * TrustManager and the actual TrustAgent. 37 */ 38public class TrustAgentWrapper { 39 private static final boolean DEBUG = false; 40 private static final String TAG = "TrustAgentWrapper"; 41 42 private static final int MSG_ENABLE_TRUST = 1; 43 private static final int MSG_REVOKE_TRUST = 2; 44 private static final int MSG_TRUST_TIMEOUT = 3; 45 46 private final TrustManagerService mTrustManagerService; 47 private final int mUserId; 48 private final Context mContext; 49 private final ComponentName mName; 50 51 private ITrustAgentService mTrustAgentService; 52 53 // Trust state 54 private boolean mTrusted; 55 private String mMessage; 56 57 private final Handler mHandler = new Handler() { 58 @Override 59 public void handleMessage(Message msg) { 60 switch (msg.what) { 61 case MSG_ENABLE_TRUST: 62 mTrusted = true; 63 mMessage = (String) msg.obj; 64 boolean initiatedByUser = msg.arg1 != 0; 65 // TODO: Handle handle user initiated trust changes. 66 mTrustManagerService.updateTrust(mUserId); 67 break; 68 case MSG_TRUST_TIMEOUT: 69 if (DEBUG) Slog.v(TAG, "Trust timed out : " + mName.flattenToShortString()); 70 // Fall through. 71 case MSG_REVOKE_TRUST: 72 mTrusted = false; 73 mMessage = null; 74 mTrustManagerService.updateTrust(mUserId); 75 break; 76 } 77 } 78 }; 79 80 private ITrustAgentServiceCallback mCallback = new ITrustAgentServiceCallback.Stub() { 81 82 public void enableTrust(String userMessage, long durationMs, boolean initiatedByUser) { 83 if (DEBUG) Slog.v(TAG, "enableTrust(" + userMessage + ", durationMs = " + durationMs 84 + ", initiatedByUser = " + initiatedByUser + ")"); 85 86 mHandler.obtainMessage(MSG_ENABLE_TRUST, initiatedByUser ? 1 : 0, 0, userMessage) 87 .sendToTarget(); 88 if (durationMs > 0) { 89 mHandler.removeMessages(MSG_TRUST_TIMEOUT); 90 mHandler.sendEmptyMessageDelayed(MSG_TRUST_TIMEOUT, durationMs); 91 } 92 } 93 94 public void revokeTrust() { 95 if (DEBUG) Slog.v(TAG, "revokeTrust()"); 96 mHandler.sendEmptyMessage(MSG_REVOKE_TRUST); 97 } 98 }; 99 100 private final ServiceConnection mConnection = new ServiceConnection() { 101 @Override 102 public void onServiceConnected(ComponentName name, IBinder service) { 103 if (DEBUG) Log.v(TAG, "TrustAgent started : " + name.flattenToString()); 104 mTrustAgentService = ITrustAgentService.Stub.asInterface(service); 105 setCallback(mCallback); 106 } 107 108 @Override 109 public void onServiceDisconnected(ComponentName name) { 110 if (DEBUG) Log.v(TAG, "TrustAgent disconnected : " + name.flattenToShortString()); 111 mTrustAgentService = null; 112 mHandler.sendEmptyMessage(MSG_REVOKE_TRUST); 113 } 114 }; 115 116 117 public TrustAgentWrapper(Context context, TrustManagerService trustManagerService, 118 Intent intent, UserHandle user) { 119 mContext = context; 120 mTrustManagerService = trustManagerService; 121 mUserId = user.getIdentifier(); 122 mName = intent.getComponent(); 123 if (!context.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, user)) { 124 if (DEBUG) Log.v(TAG, "can't bind to TrustAgent " + mName.flattenToShortString()); 125 // TODO: retry somehow? 126 } 127 } 128 129 private void onError(Exception e) { 130 Slog.w(TAG , "Remote Exception", e); 131 } 132 133 /** 134 * @see android.service.trust.TrustAgentService#onUnlockAttempt(boolean) 135 */ 136 public void onUnlockAttempt(boolean successful) { 137 try { 138 if (mTrustAgentService != null) mTrustAgentService.onUnlockAttempt(successful); 139 } catch (RemoteException e) { 140 onError(e); 141 } 142 } 143 144 private void setCallback(ITrustAgentServiceCallback callback) { 145 try { 146 if (mTrustAgentService != null) { 147 mTrustAgentService.setCallback(callback); 148 } 149 } catch (RemoteException e) { 150 onError(e); 151 } 152 } 153 154 public boolean isTrusted() { 155 return mTrusted; 156 } 157 158 public String getMessage() { 159 return mMessage; 160 } 161 162 public void unbind() { 163 if (DEBUG) Log.v(TAG, "TrustAgent unbound : " + mName.flattenToShortString()); 164 mContext.unbindService(mConnection); 165 } 166} 167