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 
17 package com.android.server.trust;
18 
19 import android.annotation.TargetApi;
20 import android.app.AlarmManager;
21 import android.app.PendingIntent;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.BroadcastReceiver;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.ServiceConnection;
29 import android.net.Uri;
30 import android.os.Binder;
31 import android.os.Build;
32 import android.os.Handler;
33 import android.os.IBinder;
34 import android.os.Message;
35 import android.os.PatternMatcher;
36 import android.os.PersistableBundle;
37 import android.os.RemoteException;
38 import android.os.SystemClock;
39 import android.os.UserHandle;
40 import android.service.trust.ITrustAgentService;
41 import android.service.trust.ITrustAgentServiceCallback;
42 import android.service.trust.TrustAgentService;
43 import android.util.Log;
44 import android.util.Slog;
45 
46 import java.util.Collections;
47 import java.util.List;
48 
49 /**
50  * A wrapper around a TrustAgentService interface. Coordinates communication between
51  * TrustManager and the actual TrustAgent.
52  */
53 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
54 public class TrustAgentWrapper {
55     private static final String EXTRA_COMPONENT_NAME = "componentName";
56     private static final String TRUST_EXPIRED_ACTION = "android.server.trust.TRUST_EXPIRED_ACTION";
57     private static final String PERMISSION = android.Manifest.permission.PROVIDE_TRUST_AGENT;
58     private static final boolean DEBUG = TrustManagerService.DEBUG;
59     private static final String TAG = "TrustAgentWrapper";
60 
61     private static final int MSG_GRANT_TRUST = 1;
62     private static final int MSG_REVOKE_TRUST = 2;
63     private static final int MSG_TRUST_TIMEOUT = 3;
64     private static final int MSG_RESTART_TIMEOUT = 4;
65     private static final int MSG_SET_TRUST_AGENT_FEATURES_COMPLETED = 5;
66     private static final int MSG_MANAGING_TRUST = 6;
67     private static final int MSG_ADD_ESCROW_TOKEN = 7;
68     private static final int MSG_REMOVE_ESCROW_TOKEN = 8;
69     private static final int MSG_ESCROW_TOKEN_STATE = 9;
70     private static final int MSG_UNLOCK_USER = 10;
71     private static final int MSG_SHOW_KEYGUARD_ERROR_MESSAGE = 11;
72 
73     /**
74      * Time in uptime millis that we wait for the service connection, both when starting
75      * and when the service disconnects.
76      */
77     private static final long RESTART_TIMEOUT_MILLIS = 5 * 60000;
78 
79     /**
80      * Long extra for {@link #MSG_GRANT_TRUST}
81      */
82     private static final String DATA_DURATION = "duration";
83     private static final String DATA_ESCROW_TOKEN = "escrow_token";
84     private static final String DATA_HANDLE = "handle";
85     private static final String DATA_USER_ID = "user_id";
86     private static final String DATA_MESSAGE = "message";
87 
88     private final TrustManagerService mTrustManagerService;
89     private final int mUserId;
90     private final Context mContext;
91     private final ComponentName mName;
92 
93     private ITrustAgentService mTrustAgentService;
94     private boolean mBound;
95     private long mScheduledRestartUptimeMillis;
96     private long mMaximumTimeToLock; // from DevicePolicyManager
97     private boolean mPendingSuccessfulUnlock = false;
98 
99     // Trust state
100     private boolean mTrusted;
101     private CharSequence mMessage;
102     private boolean mTrustDisabledByDpm;
103     private boolean mManagingTrust;
104     private IBinder mSetTrustAgentFeaturesToken;
105     private AlarmManager mAlarmManager;
106     private final Intent mAlarmIntent;
107     private PendingIntent mAlarmPendingIntent;
108 
109     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
110         @Override
111         public void onReceive(Context context, Intent intent) {
112             ComponentName component = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);
113             if (TRUST_EXPIRED_ACTION.equals(intent.getAction())
114                     && mName.equals(component)) {
115                 mHandler.removeMessages(MSG_TRUST_TIMEOUT);
116                 mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
117             }
118         }
119     };
120 
121     private final Handler mHandler = new Handler() {
122         @Override
123         public void handleMessage(Message msg) {
124             switch (msg.what) {
125                 case MSG_GRANT_TRUST:
126                     if (!isConnected()) {
127                         Log.w(TAG, "Agent is not connected, cannot grant trust: "
128                                 + mName.flattenToShortString());
129                         return;
130                     }
131                     mTrusted = true;
132                     mMessage = (CharSequence) msg.obj;
133                     int flags = msg.arg1;
134                     long durationMs = msg.getData().getLong(DATA_DURATION);
135                     if (durationMs > 0) {
136                         final long duration;
137                         if (mMaximumTimeToLock != 0) {
138                             // Enforce DevicePolicyManager timeout.  This is here as a safeguard to
139                             // ensure trust agents are evaluating trust state at least as often as
140                             // the policy dictates. Admins that want more guarantees should be using
141                             // DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS.
142                             duration = Math.min(durationMs, mMaximumTimeToLock);
143                             if (DEBUG) {
144                                 Slog.d(TAG, "DPM lock timeout in effect. Timeout adjusted from "
145                                     + durationMs + " to " + duration);
146                             }
147                         } else {
148                             duration = durationMs;
149                         }
150                         long expiration = SystemClock.elapsedRealtime() + duration;
151                         mAlarmPendingIntent = PendingIntent.getBroadcast(mContext, 0, mAlarmIntent,
152                                 PendingIntent.FLAG_CANCEL_CURRENT);
153                         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, expiration,
154                                 mAlarmPendingIntent);
155                     }
156                     mTrustManagerService.mArchive.logGrantTrust(mUserId, mName,
157                             (mMessage != null ? mMessage.toString() : null),
158                             durationMs, flags);
159                     mTrustManagerService.updateTrust(mUserId, flags);
160                     break;
161                 case MSG_TRUST_TIMEOUT:
162                     if (DEBUG) Slog.d(TAG, "Trust timed out : " + mName.flattenToShortString());
163                     mTrustManagerService.mArchive.logTrustTimeout(mUserId, mName);
164                     onTrustTimeout();
165                     // Fall through.
166                 case MSG_REVOKE_TRUST:
167                     mTrusted = false;
168                     mMessage = null;
169                     mHandler.removeMessages(MSG_TRUST_TIMEOUT);
170                     if (msg.what == MSG_REVOKE_TRUST) {
171                         mTrustManagerService.mArchive.logRevokeTrust(mUserId, mName);
172                     }
173                     mTrustManagerService.updateTrust(mUserId, 0);
174                     break;
175                 case MSG_RESTART_TIMEOUT:
176                     Slog.w(TAG, "Connection attempt to agent " + mName.flattenToShortString()
177                             + " timed out, rebinding");
178                     destroy();
179                     mTrustManagerService.resetAgent(mName, mUserId);
180                     break;
181                 case MSG_SET_TRUST_AGENT_FEATURES_COMPLETED:
182                     IBinder token = (IBinder) msg.obj;
183                     boolean result = msg.arg1 != 0;
184                     if (mSetTrustAgentFeaturesToken == token) {
185                         mSetTrustAgentFeaturesToken = null;
186                         if (mTrustDisabledByDpm && result) {
187                             if (DEBUG) Slog.d(TAG, "Re-enabling agent because it acknowledged "
188                                     + "enabled features: " + mName.flattenToShortString());
189                             mTrustDisabledByDpm = false;
190                             mTrustManagerService.updateTrust(mUserId, 0);
191                         }
192                     } else {
193                         if (DEBUG) Slog.w(TAG, "Ignoring MSG_SET_TRUST_AGENT_FEATURES_COMPLETED "
194                                 + "with obsolete token: " + mName.flattenToShortString());
195                     }
196                     break;
197                 case MSG_MANAGING_TRUST:
198                     mManagingTrust = msg.arg1 != 0;
199                     if (!mManagingTrust) {
200                         mTrusted = false;
201                         mMessage = null;
202                     }
203                     mTrustManagerService.mArchive.logManagingTrust(mUserId, mName, mManagingTrust);
204                     mTrustManagerService.updateTrust(mUserId, 0);
205                     break;
206                 case MSG_ADD_ESCROW_TOKEN: {
207                     byte[] eToken = msg.getData().getByteArray(DATA_ESCROW_TOKEN);
208                     int userId = msg.getData().getInt(DATA_USER_ID);
209                     long handle = mTrustManagerService.addEscrowToken(eToken, userId);
210                     boolean resultDeliverred = false;
211                     try {
212                         if (mTrustAgentService != null) {
213                             mTrustAgentService.onEscrowTokenAdded(
214                                     eToken, handle, UserHandle.of(userId));
215                             resultDeliverred = true;
216                         }
217                     } catch (RemoteException e) {
218                         onError(e);
219                     }
220 
221                     if (!resultDeliverred) {
222                         mTrustManagerService.removeEscrowToken(handle, userId);
223                     }
224                     break;
225                 }
226                 case MSG_ESCROW_TOKEN_STATE: {
227                     long handle = msg.getData().getLong(DATA_HANDLE);
228                     int userId = msg.getData().getInt(DATA_USER_ID);
229                     boolean active = mTrustManagerService.isEscrowTokenActive(handle, userId);
230                     try {
231                         if (mTrustAgentService != null) {
232                             mTrustAgentService.onTokenStateReceived(handle,
233                                     active ? TrustAgentService.TOKEN_STATE_ACTIVE
234                                             : TrustAgentService.TOKEN_STATE_INACTIVE);
235                         }
236                     } catch (RemoteException e) {
237                         onError(e);
238                     }
239                     break;
240                 }
241                 case MSG_REMOVE_ESCROW_TOKEN: {
242                     long handle = msg.getData().getLong(DATA_HANDLE);
243                     int userId = msg.getData().getInt(DATA_USER_ID);
244                     boolean success = mTrustManagerService.removeEscrowToken(handle, userId);
245                     try {
246                         if (mTrustAgentService != null) {
247                             mTrustAgentService.onEscrowTokenRemoved(handle, success);
248                         }
249                     } catch (RemoteException e) {
250                         onError(e);
251                     }
252                     break;
253                 }
254                 case MSG_UNLOCK_USER: {
255                     long handle = msg.getData().getLong(DATA_HANDLE);
256                     int userId = msg.getData().getInt(DATA_USER_ID);
257                     byte[] eToken = msg.getData().getByteArray(DATA_ESCROW_TOKEN);
258                     mTrustManagerService.unlockUserWithToken(handle, eToken, userId);
259                     break;
260                 }
261                 case MSG_SHOW_KEYGUARD_ERROR_MESSAGE: {
262                     CharSequence message = msg.getData().getCharSequence(DATA_MESSAGE);
263                     mTrustManagerService.showKeyguardErrorMessage(message);
264                     break;
265                 }
266             }
267         }
268     };
269 
270     private ITrustAgentServiceCallback mCallback = new ITrustAgentServiceCallback.Stub() {
271 
272         @Override
273         public void grantTrust(CharSequence userMessage, long durationMs, int flags) {
274             if (DEBUG) Slog.d(TAG, "enableTrust(" + userMessage + ", durationMs = " + durationMs
275                         + ", flags = " + flags + ")");
276 
277             Message msg = mHandler.obtainMessage(
278                     MSG_GRANT_TRUST, flags, 0, userMessage);
279             msg.getData().putLong(DATA_DURATION, durationMs);
280             msg.sendToTarget();
281         }
282 
283         @Override
284         public void revokeTrust() {
285             if (DEBUG) Slog.d(TAG, "revokeTrust()");
286             mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
287         }
288 
289         @Override
290         public void setManagingTrust(boolean managingTrust) {
291             if (DEBUG) Slog.d(TAG, "managingTrust()");
292             mHandler.obtainMessage(MSG_MANAGING_TRUST, managingTrust ? 1 : 0, 0).sendToTarget();
293         }
294 
295         @Override
296         public void onConfigureCompleted(boolean result, IBinder token) {
297             if (DEBUG) Slog.d(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
298             mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
299                     result ? 1 : 0, 0, token).sendToTarget();
300         }
301 
302         @Override
303         public void addEscrowToken(byte[] token, int userId) {
304             if (mContext.getResources()
305                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
306                 throw  new SecurityException("Escrow token API is not allowed.");
307             }
308 
309             if (DEBUG) Slog.d(TAG, "adding escrow token for user " + userId);
310             Message msg = mHandler.obtainMessage(MSG_ADD_ESCROW_TOKEN);
311             msg.getData().putByteArray(DATA_ESCROW_TOKEN, token);
312             msg.getData().putInt(DATA_USER_ID, userId);
313             msg.sendToTarget();
314         }
315 
316         @Override
317         public void isEscrowTokenActive(long handle, int userId) {
318             if (mContext.getResources()
319                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
320                 throw new SecurityException("Escrow token API is not allowed.");
321             }
322 
323             if (DEBUG) Slog.d(TAG, "checking the state of escrow token on user " + userId);
324             Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_STATE);
325             msg.getData().putLong(DATA_HANDLE, handle);
326             msg.getData().putInt(DATA_USER_ID, userId);
327             msg.sendToTarget();
328         }
329 
330         @Override
331         public void removeEscrowToken(long handle, int userId) {
332             if (mContext.getResources()
333                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
334                 throw new SecurityException("Escrow token API is not allowed.");
335             }
336 
337             if (DEBUG) Slog.d(TAG, "removing escrow token on user " + userId);
338             Message msg = mHandler.obtainMessage(MSG_REMOVE_ESCROW_TOKEN);
339             msg.getData().putLong(DATA_HANDLE, handle);
340             msg.getData().putInt(DATA_USER_ID, userId);
341             msg.sendToTarget();
342         }
343 
344         @Override
345         public void unlockUserWithToken(long handle, byte[] token, int userId) {
346             if (mContext.getResources()
347                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
348                 throw new SecurityException("Escrow token API is not allowed.");
349             }
350 
351             if (DEBUG) Slog.d(TAG, "unlocking user " + userId);
352             Message msg = mHandler.obtainMessage(MSG_UNLOCK_USER);
353             msg.getData().putInt(DATA_USER_ID, userId);
354             msg.getData().putLong(DATA_HANDLE, handle);
355             msg.getData().putByteArray(DATA_ESCROW_TOKEN, token);
356             msg.sendToTarget();
357         }
358 
359         @Override
360         public void showKeyguardErrorMessage(CharSequence message) {
361             if (DEBUG) Slog.d(TAG, "Showing keyguard error message: " + message);
362             Message msg = mHandler.obtainMessage(MSG_SHOW_KEYGUARD_ERROR_MESSAGE);
363             msg.getData().putCharSequence(DATA_MESSAGE, message);
364             msg.sendToTarget();
365         }
366     };
367 
368     private final ServiceConnection mConnection = new ServiceConnection() {
369         @Override
370         public void onServiceConnected(ComponentName name, IBinder service) {
371             if (DEBUG) Slog.d(TAG, "TrustAgent started : " + name.flattenToString());
372             mHandler.removeMessages(MSG_RESTART_TIMEOUT);
373             mTrustAgentService = ITrustAgentService.Stub.asInterface(service);
374             mTrustManagerService.mArchive.logAgentConnected(mUserId, name);
375             setCallback(mCallback);
376             updateDevicePolicyFeatures();
377 
378             if (mPendingSuccessfulUnlock) {
379                 onUnlockAttempt(true);
380                 mPendingSuccessfulUnlock = false;
381             }
382 
383             if (mTrustManagerService.isDeviceLockedInner(mUserId)) {
384                 onDeviceLocked();
385             } else {
386                 onDeviceUnlocked();
387             }
388         }
389 
390         @Override
391         public void onServiceDisconnected(ComponentName name) {
392             if (DEBUG) Slog.d(TAG, "TrustAgent disconnected : " + name.flattenToShortString());
393             mTrustAgentService = null;
394             mManagingTrust = false;
395             mSetTrustAgentFeaturesToken = null;
396             mTrustManagerService.mArchive.logAgentDied(mUserId, name);
397             mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
398             if (mBound) {
399                 scheduleRestart();
400             }
401             // mTrustDisabledByDpm maintains state
402         }
403     };
404 
TrustAgentWrapper(Context context, TrustManagerService trustManagerService, Intent intent, UserHandle user)405     public TrustAgentWrapper(Context context, TrustManagerService trustManagerService,
406             Intent intent, UserHandle user) {
407         mContext = context;
408         mTrustManagerService = trustManagerService;
409         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
410         mUserId = user.getIdentifier();
411         mName = intent.getComponent();
412 
413         mAlarmIntent = new Intent(TRUST_EXPIRED_ACTION).putExtra(EXTRA_COMPONENT_NAME, mName);
414         mAlarmIntent.setData(Uri.parse(mAlarmIntent.toUri(Intent.URI_INTENT_SCHEME)));
415         mAlarmIntent.setPackage(context.getPackageName());
416 
417         final IntentFilter alarmFilter = new IntentFilter(TRUST_EXPIRED_ACTION);
418         alarmFilter.addDataScheme(mAlarmIntent.getScheme());
419         final String pathUri = mAlarmIntent.toUri(Intent.URI_INTENT_SCHEME);
420         alarmFilter.addDataPath(pathUri, PatternMatcher.PATTERN_LITERAL);
421 
422         // Schedules a restart for when connecting times out. If the connection succeeds,
423         // the restart is canceled in mCallback's onConnected.
424         scheduleRestart();
425         mBound = context.bindServiceAsUser(intent, mConnection,
426                 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, user);
427         if (mBound) {
428             mContext.registerReceiver(mBroadcastReceiver, alarmFilter, PERMISSION, null);
429         } else {
430             Log.e(TAG, "Can't bind to TrustAgent " + mName.flattenToShortString());
431         }
432     }
433 
onError(Exception e)434     private void onError(Exception e) {
435         Slog.w(TAG , "Exception ", e);
436     }
437 
onTrustTimeout()438     private void onTrustTimeout() {
439         try {
440             if (mTrustAgentService != null) mTrustAgentService.onTrustTimeout();
441         } catch (RemoteException e) {
442             onError(e);
443         }
444     }
445 
446     /**
447      * @see android.service.trust.TrustAgentService#onUnlockAttempt(boolean)
448      */
onUnlockAttempt(boolean successful)449     public void onUnlockAttempt(boolean successful) {
450         try {
451             if (mTrustAgentService != null) {
452                 mTrustAgentService.onUnlockAttempt(successful);
453             } else {
454                 mPendingSuccessfulUnlock = successful;
455             }
456         } catch (RemoteException e) {
457             onError(e);
458         }
459     }
460 
461     /**
462      * @see android.service.trust.TrustAgentService#onUnlockLockout(int)
463      */
onUnlockLockout(int timeoutMs)464     public void onUnlockLockout(int timeoutMs) {
465         try {
466             if (mTrustAgentService != null) {
467                 mTrustAgentService.onUnlockLockout(timeoutMs);
468             }
469         } catch (RemoteException e) {
470             onError(e);
471         }
472     }
473 
474     /**
475      * @see android.service.trust.TrustAgentService#onDeviceLocked()
476      */
onDeviceLocked()477     public void onDeviceLocked() {
478         try {
479             if (mTrustAgentService != null) mTrustAgentService.onDeviceLocked();
480         } catch (RemoteException e) {
481             onError(e);
482         }
483     }
484 
485     /**
486      * @see android.service.trust.TrustAgentService#onDeviceUnlocked()
487      */
onDeviceUnlocked()488     public void onDeviceUnlocked() {
489         try {
490             if (mTrustAgentService != null) mTrustAgentService.onDeviceUnlocked();
491         } catch (RemoteException e) {
492             onError(e);
493         }
494     }
495 
496     /**
497      * @see android.service.trust.TrustAgentService#onTokenStateReceived()
498      *
499      */
onEscrowTokenActivated(long handle, int userId)500     public void onEscrowTokenActivated(long handle, int userId) {
501         if (DEBUG) Slog.d(TAG, "onEscrowTokenActivated: " + handle + " user: " + userId);
502         if (mTrustAgentService != null) {
503             try {
504                 mTrustAgentService.onTokenStateReceived(handle,
505                         TrustAgentService.TOKEN_STATE_ACTIVE);
506             } catch (RemoteException e) {
507                 onError(e);
508             }
509         }
510     }
setCallback(ITrustAgentServiceCallback callback)511     private void setCallback(ITrustAgentServiceCallback callback) {
512         try {
513             if (mTrustAgentService != null) {
514                 mTrustAgentService.setCallback(callback);
515             }
516         } catch (RemoteException e) {
517             onError(e);
518         }
519     }
520 
updateDevicePolicyFeatures()521     boolean updateDevicePolicyFeatures() {
522         boolean trustDisabled = false;
523         if (DEBUG) Slog.d(TAG, "updateDevicePolicyFeatures(" + mName + ")");
524         try {
525             if (mTrustAgentService != null) {
526                 DevicePolicyManager dpm =
527                     (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
528 
529                 if ((dpm.getKeyguardDisabledFeatures(null, mUserId)
530                         & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0) {
531                     List<PersistableBundle> config = dpm.getTrustAgentConfiguration(
532                             null, mName, mUserId);
533                     trustDisabled = true;
534                     if (DEBUG) Slog.d(TAG, "Detected trust agents disabled. Config = " + config);
535                     if (config != null && config.size() > 0) {
536                         if (DEBUG) {
537                             Slog.d(TAG, "TrustAgent " + mName.flattenToShortString()
538                                     + " disabled until it acknowledges "+ config);
539                         }
540                         mSetTrustAgentFeaturesToken = new Binder();
541                         mTrustAgentService.onConfigure(config, mSetTrustAgentFeaturesToken);
542                     }
543                 } else {
544                     mTrustAgentService.onConfigure(Collections.EMPTY_LIST, null);
545                 }
546                 final long maxTimeToLock = dpm.getMaximumTimeToLock(null, mUserId);
547                 if (maxTimeToLock != mMaximumTimeToLock) {
548                     // If the timeout changes, cancel the alarm and send a timeout event to have
549                     // the agent re-evaluate trust.
550                     mMaximumTimeToLock = maxTimeToLock;
551                     if (mAlarmPendingIntent != null) {
552                         mAlarmManager.cancel(mAlarmPendingIntent);
553                         mAlarmPendingIntent = null;
554                         mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT);
555                     }
556                 }
557             }
558         } catch (RemoteException e) {
559             onError(e);
560         }
561         if (mTrustDisabledByDpm != trustDisabled) {
562             mTrustDisabledByDpm = trustDisabled;
563             mTrustManagerService.updateTrust(mUserId, 0);
564         }
565         return trustDisabled;
566     }
567 
isTrusted()568     public boolean isTrusted() {
569         return mTrusted && mManagingTrust && !mTrustDisabledByDpm;
570     }
571 
isManagingTrust()572     public boolean isManagingTrust() {
573         return mManagingTrust && !mTrustDisabledByDpm;
574     }
575 
getMessage()576     public CharSequence getMessage() {
577         return mMessage;
578     }
579 
destroy()580     public void destroy() {
581         mHandler.removeMessages(MSG_RESTART_TIMEOUT);
582 
583         if (!mBound) {
584             return;
585         }
586         if (DEBUG) Slog.d(TAG, "TrustAgent unbound : " + mName.flattenToShortString());
587         mTrustManagerService.mArchive.logAgentStopped(mUserId, mName);
588         mContext.unbindService(mConnection);
589         mBound = false;
590         mContext.unregisterReceiver(mBroadcastReceiver);
591         mTrustAgentService = null;
592         mSetTrustAgentFeaturesToken = null;
593         mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
594     }
595 
isConnected()596     public boolean isConnected() {
597         return mTrustAgentService != null;
598     }
599 
isBound()600     public boolean isBound() {
601         return mBound;
602     }
603 
604     /**
605      * If not connected, returns the time at which the agent is restarted.
606      *
607      * @return restart time in uptime millis.
608      */
getScheduledRestartUptimeMillis()609     public long getScheduledRestartUptimeMillis() {
610         return mScheduledRestartUptimeMillis;
611     }
612 
scheduleRestart()613     private void scheduleRestart() {
614         mHandler.removeMessages(MSG_RESTART_TIMEOUT);
615         mScheduledRestartUptimeMillis = SystemClock.uptimeMillis() + RESTART_TIMEOUT_MILLIS;
616         mHandler.sendEmptyMessageAtTime(MSG_RESTART_TIMEOUT, mScheduledRestartUptimeMillis);
617     }
618 }
619