Add setManagingTrust and expose it on lockscreen
Adds a facility for trust agents to indicate if they
are ready to manage trust. Also adds an indication to
the lock icon on the lockscreen to show whether trust is
being managed.
Bug: 15518469
Bug: 16123013
Change-Id: Ie17f588aebeafe66c81dea4a69c733b0d2c72fd4
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl
index 4680043..45a066d 100644
--- a/core/java/android/app/trust/ITrustListener.aidl
+++ b/core/java/android/app/trust/ITrustListener.aidl
@@ -23,4 +23,5 @@
*/
oneway interface ITrustListener {
void onTrustChanged(boolean enabled, int userId);
+ void onTrustManagedChanged(boolean managed, int userId);
}
\ No newline at end of file
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 6e90590..796e3cc 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -31,6 +31,7 @@
public class TrustManager {
private static final int MSG_TRUST_CHANGED = 1;
+ private static final int MSG_TRUST_MANAGED_CHANGED = 2;
private static final String TAG = "TrustManager";
@@ -98,6 +99,13 @@
mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
trustListener).sendToTarget();
}
+
+ @Override
+ public void onTrustManagedChanged(boolean managed, int userId)
+ throws RemoteException {
+ mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
+ trustListener).sendToTarget();
+ }
};
mService.registerTrustListener(iTrustListener);
mTrustListeners.put(trustListener, iTrustListener);
@@ -133,6 +141,8 @@
case MSG_TRUST_CHANGED:
((TrustListener)msg.obj).onTrustChanged(msg.arg1 != 0, msg.arg2);
break;
+ case MSG_TRUST_MANAGED_CHANGED:
+ ((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
}
}
};
@@ -145,5 +155,12 @@
* @param userId the user, for which the trust changed.
*/
void onTrustChanged(boolean enabled, int userId);
+
+ /**
+ * Reports that whether trust is managed has changed
+ * @param enabled if true, at least one trust agent is managing trust.
+ * @param userId the user, for which the state changed.
+ */
+ void onTrustManagedChanged(boolean enabled, int userId);
}
}
diff --git a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
index 9e4c2bf..193ac59 100644
--- a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
+++ b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
@@ -25,4 +25,5 @@
oneway interface ITrustAgentServiceCallback {
void grantTrust(CharSequence message, long durationMs, boolean initiatedByUser);
void revokeTrust();
+ void setManagingTrust(boolean managingTrust);
}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 61da85f..2609fce 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -66,6 +66,13 @@
public class TrustAgentService extends Service {
private final String TAG = TrustAgentService.class.getSimpleName() +
"[" + getClass().getSimpleName() + "]";
+ private static final boolean DEBUG = false;
+
+ // Temporary workaround to allow current trust agent implementations to continue working.
+ // This and the code guarded by this should be removed before shipping.
+ // If true, calls setManagingTrust(true) after onCreate, if it wasn't already set.
+ // TODO: Remove this once all agents are updated.
+ private static final boolean SET_MANAGED_FOR_LEGACY_AGENTS = true;
/**
* The {@link Intent} that must be declared as handled by the service.
@@ -88,12 +95,12 @@
private static final int MSG_UNLOCK_ATTEMPT = 1;
- private static final boolean DEBUG = false;
-
private ITrustAgentServiceCallback mCallback;
private Runnable mPendingGrantTrustTask;
+ private boolean mManagingTrust;
+
// Lock used to access mPendingGrantTrustTask and mCallback.
private final Object mLock = new Object();
@@ -109,6 +116,11 @@
@Override
public void onCreate() {
+ // TODO: Remove this once all agents are updated.
+ if (SET_MANAGED_FOR_LEGACY_AGENTS) {
+ setManagingTrust(true);
+ }
+
super.onCreate();
ComponentName component = new ComponentName(this, getClass());
try {
@@ -163,10 +175,15 @@
* for this agent will automatically be revoked when the timeout expires.
* @param initiatedByUser indicates that the user has explicitly initiated an action that proves
* the user is about to use the device.
+ * @throws IllegalStateException if the agent is not currently managing trust.
*/
public final void grantTrust(
final CharSequence message, final long durationMs, final boolean initiatedByUser) {
synchronized (mLock) {
+ if (!mManagingTrust) {
+ throw new IllegalStateException("Cannot grant trust if agent is not managing trust."
+ + " Call setManagingTrust(true) first.");
+ }
if (mCallback != null) {
try {
mCallback.grantTrust(message.toString(), durationMs, initiatedByUser);
@@ -204,6 +221,29 @@
}
}
+ /**
+ * Call to notify the system if the agent is ready to manage trust.
+ *
+ * This property is not persistent across recreating the service and defaults to false.
+ * Therefore this method is typically called when initializing the agent in {@link #onCreate}.
+ *
+ * @param managingTrust indicates if the agent would like to manage trust.
+ */
+ public final void setManagingTrust(boolean managingTrust) {
+ synchronized (mLock) {
+ if (mManagingTrust != managingTrust) {
+ mManagingTrust = managingTrust;
+ if (mCallback != null) {
+ try {
+ mCallback.setManagingTrust(managingTrust);
+ } catch (RemoteException e) {
+ onError("calling setManagingTrust()");
+ }
+ }
+ }
+ }
+ }
+
@Override
public final IBinder onBind(Intent intent) {
if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent);
@@ -221,6 +261,15 @@
public void setCallback(ITrustAgentServiceCallback callback) {
synchronized (mLock) {
mCallback = callback;
+ // The managingTrust property is false implicitly on the server-side, so we only
+ // need to set it here if the agent has decided to manage trust.
+ if (mManagingTrust) {
+ try {
+ mCallback.setManagingTrust(mManagingTrust);
+ } catch (RemoteException e ) {
+ onError("calling setManagingTrust()");
+ }
+ }
if (mPendingGrantTrustTask != null) {
mPendingGrantTrustTask.run();
mPendingGrantTrustTask = null;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f0f5772..e4d7850 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -216,6 +216,7 @@
};
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
+ private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray();
@Override
@@ -230,6 +231,18 @@
}
}
+ @Override
+ public void onTrustManagedChanged(boolean managed, int userId) {
+ mUserTrustIsManaged.put(userId, managed);
+
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onTrustManagedChanged(userId);
+ }
+ }
+ }
+
private void onFingerprintRecognized(int userId) {
mUserFingerprintRecognized.put(userId, true);
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -305,6 +318,10 @@
|| mUserFingerprintRecognized.get(userId);
}
+ public boolean getUserTrustIsManaged(int userId) {
+ return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
+ }
+
static class DisplayClientState {
public int clientGeneration;
public boolean clearing;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 14c1278..0aefa2d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -174,6 +174,11 @@
public void onTrustChanged(int userId) { }
/**
+ * Called when trust being managed changes for a user.
+ */
+ public void onTrustManagedChanged(int userId) { }
+
+ /**
* Called when a fingerprint is recognized.
* @param userId
*/
@@ -183,5 +188,4 @@
* Called when fingerprint is acquired but not yet recognized
*/
public void onFingerprintAcquired(int info) { }
-
}
diff --git a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
index 06a06bf..796cefb 100644
--- a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
+++ b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml
@@ -32,8 +32,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Crash" />
+ <CheckBox android:id="@+id/managing_trust"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:text="Managing trust" />
<CheckBox android:id="@+id/report_unlock_attempts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
android:text="Report unlock attempts" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
index 50a3f82..ed17494 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java
@@ -28,7 +28,8 @@
import android.util.Log;
import android.widget.Toast;
-public class SampleTrustAgent extends TrustAgentService {
+public class SampleTrustAgent extends TrustAgentService
+ implements SharedPreferences.OnSharedPreferenceChangeListener {
LocalBroadcastManager mLocalBroadcastManager;
@@ -41,6 +42,8 @@
private static final String PREFERENCE_REPORT_UNLOCK_ATTEMPTS
= "preference.report_unlock_attempts";
+ private static final String PREFERENCE_MANAGING_TRUST
+ = "preference.managing_trust";
private static final String TAG = "SampleTrustAgent";
@@ -52,6 +55,9 @@
filter.addAction(ACTION_REVOKE_TRUST);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mLocalBroadcastManager.registerReceiver(mReceiver, filter);
+ setManagingTrust(getIsManagingTrust(this));
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .registerOnSharedPreferenceChangeListener(this);
}
@Override
@@ -73,6 +79,8 @@
public void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(mReceiver);
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .unregisterOnSharedPreferenceChangeListener(this);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -80,9 +88,14 @@
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_GRANT_TRUST.equals(action)) {
- grantTrust(intent.getStringExtra(EXTRA_MESSAGE),
- intent.getLongExtra(EXTRA_DURATION, 0),
- false /* initiatedByUser */);
+ try {
+ grantTrust(intent.getStringExtra(EXTRA_MESSAGE),
+ intent.getLongExtra(EXTRA_DURATION, 0),
+ false /* initiatedByUser */);
+ } catch (IllegalStateException e) {
+ Toast.makeText(context,
+ "IllegalStateException: " + e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
} else if (ACTION_REVOKE_TRUST.equals(action)) {
revokeTrust();
}
@@ -114,4 +127,23 @@
.getDefaultSharedPreferences(context);
return sharedPreferences.getBoolean(PREFERENCE_REPORT_UNLOCK_ATTEMPTS, false);
}
+
+ public static void setIsManagingTrust(Context context, boolean enabled) {
+ SharedPreferences sharedPreferences = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ sharedPreferences.edit().putBoolean(PREFERENCE_MANAGING_TRUST, enabled).apply();
+ }
+
+ public static boolean getIsManagingTrust(Context context) {
+ SharedPreferences sharedPreferences = PreferenceManager
+ .getDefaultSharedPreferences(context);
+ return sharedPreferences.getBoolean(PREFERENCE_MANAGING_TRUST, false);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (PREFERENCE_MANAGING_TRUST.equals(key)) {
+ setManagingTrust(getIsManagingTrust(this));
+ }
+ }
}
diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
index 6b5f78b..2c85609 100644
--- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
+++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java
@@ -29,6 +29,7 @@
private static final int TRUST_DURATION_MS = 30 * 1000;
private CheckBox mReportUnlockAttempts;
+ private CheckBox mManagingTrust;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -41,12 +42,16 @@
mReportUnlockAttempts = (CheckBox) findViewById(R.id.report_unlock_attempts);
mReportUnlockAttempts.setOnCheckedChangeListener(this);
+
+ mManagingTrust = (CheckBox) findViewById(R.id.managing_trust);
+ mManagingTrust.setOnCheckedChangeListener(this);
}
@Override
protected void onResume() {
super.onResume();
mReportUnlockAttempts.setChecked(SampleTrustAgent.getReportUnlockAttempts(this));
+ mManagingTrust.setChecked(SampleTrustAgent.getIsManagingTrust(this));
}
@Override
@@ -64,8 +69,10 @@
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (buttonView.getId() == R.id.report_unlock_attempts) {
+ if (buttonView == mReportUnlockAttempts) {
SampleTrustAgent.setReportUnlockAttempts(this, isChecked);
+ } else if (buttonView == mManagingTrust) {
+ SampleTrustAgent.setIsManagingTrust(this, isChecked);
}
}
}
diff --git a/packages/SystemUI/res/drawable/trust_circle.xml b/packages/SystemUI/res/drawable/trust_circle.xml
new file mode 100644
index 0000000..89f4a0b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/trust_circle.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="ring"
+ android:innerRadius="24dp" android:thickness="1dp">
+ <solid android:color="#66ffffff" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index b5f517d..82e59c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -237,6 +237,8 @@
? R.drawable.ic_lock_open_24dp
: R.drawable.ic_lock_24dp;
mLockIcon.setImageResource(iconRes);
+ boolean trustManaged = mUnlockMethodCache.isTrustManaged();
+ mLockIcon.setBackgroundResource(trustManaged ? R.drawable.trust_circle : 0);
}
public KeyguardAffordanceView getPhoneView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index c9e0db6..58196f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -37,6 +37,7 @@
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
private boolean mMethodInsecure;
+ private boolean mTrustManaged;
private UnlockMethodCache(Context ctx) {
mLockPatternUtils = new LockPatternUtils(ctx);
@@ -71,9 +72,11 @@
int user = mLockPatternUtils.getCurrentUser();
boolean methodInsecure = !mLockPatternUtils.isSecure() ||
mKeyguardUpdateMonitor.getUserHasTrust(user);
- boolean changed = methodInsecure != mMethodInsecure;
+ boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
+ boolean changed = methodInsecure != mMethodInsecure || trustManaged != mTrustManaged;
if (changed || updateAlways) {
mMethodInsecure = methodInsecure;
+ mTrustManaged = trustManaged;
notifyListeners(mMethodInsecure);
}
}
@@ -96,15 +99,25 @@
}
@Override
+ public void onTrustManagedChanged(int userId) {
+ updateMethodSecure(false /* updateAlways */);
+ }
+
+ @Override
public void onScreenTurnedOn() {
updateMethodSecure(false /* updateAlways */);
}
+ @Override
public void onFingerprintRecognized(int userId) {
updateMethodSecure(false /* updateAlways */);
}
};
+ public boolean isTrustManaged() {
+ return mTrustManaged;
+ }
+
public static interface OnUnlockMethodChangedListener {
void onMethodSecureChanged(boolean methodSecure);
}
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 0acb82f..eee2a4d 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -52,6 +52,7 @@
private static final int MSG_TRUST_TIMEOUT = 3;
private static final int MSG_RESTART_TIMEOUT = 4;
private static final int MSG_DPM_CHANGED = 5;
+ private static final int MSG_MANAGING_TRUST = 6;
/**
* Time in uptime millis that we wait for the service connection, both when starting
@@ -77,6 +78,7 @@
private boolean mTrusted;
private CharSequence mMessage;
private boolean mTrustDisabledByDpm;
+ private boolean mManagingTrust;
private final Handler mHandler = new Handler() {
@Override
@@ -122,6 +124,15 @@
case MSG_DPM_CHANGED:
updateDevicePolicyFeatures(mName);
break;
+ case MSG_MANAGING_TRUST:
+ mManagingTrust = msg.arg1 != 0;
+ if (!mManagingTrust) {
+ mTrusted = false;
+ mMessage = null;
+ }
+ mTrustManagerService.mArchive.logManagingTrust(mUserId, mName, mManagingTrust);
+ mTrustManagerService.updateTrust(mUserId);
+ break;
}
}
};
@@ -144,6 +155,12 @@
if (DEBUG) Slog.v(TAG, "revokeTrust()");
mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
}
+
+ @Override
+ public void setManagingTrust(boolean managingTrust) {
+ if (DEBUG) Slog.v(TAG, "managingTrust()");
+ mHandler.obtainMessage(MSG_MANAGING_TRUST, managingTrust ? 1 : 0, 0).sendToTarget();
+ }
};
private final ServiceConnection mConnection = new ServiceConnection() {
@@ -162,6 +179,7 @@
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Log.v(TAG, "TrustAgent disconnected : " + name.flattenToShortString());
mTrustAgentService = null;
+ mManagingTrust = false;
mTrustManagerService.mArchive.logAgentDied(mUserId, name);
mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
if (mBound) {
@@ -278,7 +296,11 @@
}
public boolean isTrusted() {
- return mTrusted && !mTrustDisabledByDpm;
+ return mTrusted && mManagingTrust && !mTrustDisabledByDpm;
+ }
+
+ public boolean isManagingTrust() {
+ return mManagingTrust && !mTrustDisabledByDpm;
}
public CharSequence getMessage() {
diff --git a/services/core/java/com/android/server/trust/TrustArchive.java b/services/core/java/com/android/server/trust/TrustArchive.java
index 5e32d86..d4ed86d 100644
--- a/services/core/java/com/android/server/trust/TrustArchive.java
+++ b/services/core/java/com/android/server/trust/TrustArchive.java
@@ -35,6 +35,7 @@
private static final int TYPE_AGENT_DIED = 3;
private static final int TYPE_AGENT_CONNECTED = 4;
private static final int TYPE_AGENT_STOPPED = 5;
+ private static final int TYPE_MANAGING_TRUST = 6;
private static final int HISTORY_LIMIT = 200;
@@ -49,8 +50,11 @@
final long duration;
final boolean userInitiated;
+ // managingTrust
+ final boolean managingTrust;
+
private Event(int type, int userId, ComponentName agent, String message,
- long duration, boolean userInitiated) {
+ long duration, boolean userInitiated, boolean managingTrust) {
this.type = type;
this.userId = userId;
this.agent = agent;
@@ -58,6 +62,7 @@
this.message = message;
this.duration = duration;
this.userInitiated = userInitiated;
+ this.managingTrust = managingTrust;
}
}
@@ -66,27 +71,31 @@
public void logGrantTrust(int userId, ComponentName agent, String message,
long duration, boolean userInitiated) {
addEvent(new Event(TYPE_GRANT_TRUST, userId, agent, message, duration,
- userInitiated));
+ userInitiated, false));
}
public void logRevokeTrust(int userId, ComponentName agent) {
- addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, false));
+ addEvent(new Event(TYPE_REVOKE_TRUST, userId, agent, null, 0, false, false));
}
public void logTrustTimeout(int userId, ComponentName agent) {
- addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, false));
+ addEvent(new Event(TYPE_TRUST_TIMEOUT, userId, agent, null, 0, false, false));
}
public void logAgentDied(int userId, ComponentName agent) {
- addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false));
+ addEvent(new Event(TYPE_AGENT_DIED, userId, agent, null, 0, false, false));
}
public void logAgentConnected(int userId, ComponentName agent) {
- addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false));
+ addEvent(new Event(TYPE_AGENT_CONNECTED, userId, agent, null, 0, false, false));
}
public void logAgentStopped(int userId, ComponentName agent) {
- addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false));
+ addEvent(new Event(TYPE_AGENT_STOPPED, userId, agent, null, 0, false, false));
+ }
+
+ public void logManagingTrust(int userId, ComponentName agent, boolean managing) {
+ addEvent(new Event(TYPE_MANAGING_TRUST, userId, agent, null, 0, false, managing));
}
private void addEvent(Event e) {
@@ -123,6 +132,9 @@
writer.printf(", message=\"%s\", duration=%s",
ev.message, formatDuration(ev.duration));
break;
+ case TYPE_MANAGING_TRUST:
+ writer.printf(", managingTrust=" + ev.managingTrust);
+ break;
default:
}
writer.println();
@@ -166,6 +178,8 @@
return "AgentConnected";
case TYPE_AGENT_STOPPED:
return "AgentStopped";
+ case TYPE_MANAGING_TRUST:
+ return "ManagingTrust";
default:
return "Unknown(" + type + ")";
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 9c2df55..950d639 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -153,6 +153,7 @@
}
public void updateTrust(int userId) {
+ dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
dispatchOnTrustChanged(aggregateIsTrusted(userId), userId);
}
@@ -211,7 +212,7 @@
boolean trustMayHaveChanged = false;
for (int i = 0; i < obsoleteAgents.size(); i++) {
AgentInfo info = obsoleteAgents.valueAt(i);
- if (info.agent.isTrusted()) {
+ if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.unbind();
@@ -229,7 +230,7 @@
AgentInfo info = mActiveAgents.valueAt(i);
if (packageName.equals(info.component.getPackageName())) {
Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
- if (info.agent.isTrusted()) {
+ if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.unbind();
@@ -247,7 +248,7 @@
AgentInfo info = mActiveAgents.valueAt(i);
if (name.equals(info.component) && userId == info.userId) {
Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
- if (info.agent.isTrusted()) {
+ if (info.agent.isManagingTrust()) {
trustMayHaveChanged = true;
}
info.agent.unbind();
@@ -333,6 +334,21 @@
return false;
}
+ private boolean aggregateIsTrustManaged(int userId) {
+ if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
+ return false;
+ }
+ for (int i = 0; i < mActiveAgents.size(); i++) {
+ AgentInfo info = mActiveAgents.valueAt(i);
+ if (info.userId == userId) {
+ if (info.agent.isManagingTrust()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private void dispatchUnlockAttempt(boolean successful, int userId) {
for (int i = 0; i < mActiveAgents.size(); i++) {
AgentInfo info = mActiveAgents.valueAt(i);
@@ -383,7 +399,21 @@
try {
mTrustListeners.get(i).onTrustChanged(enabled, userId);
} catch (DeadObjectException e) {
- if (DEBUG) Slog.d(TAG, "Removing dead TrustListener.");
+ Slog.d(TAG, "Removing dead TrustListener.");
+ mTrustListeners.remove(i);
+ i--;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception while notifying TrustListener.", e);
+ }
+ }
+ }
+
+ private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
+ for (int i = 0; i < mTrustListeners.size(); i++) {
+ try {
+ mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
+ } catch (DeadObjectException e) {
+ Slog.d(TAG, "Removing dead TrustListener.");
mTrustListeners.remove(i);
i--;
} catch (RemoteException e) {
@@ -472,6 +502,7 @@
fout.print(" (current)");
}
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
+ fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
fout.println();
fout.println(" Enabled agents:");
boolean duplicateSimpleNames = false;
@@ -482,7 +513,9 @@
fout.print(" "); fout.println(info.component.flattenToShortString());
fout.print(" bound=" + dumpBool(info.agent.isBound()));
fout.print(", connected=" + dumpBool(info.agent.isConnected()));
- fout.println(", trusted=" + dumpBool(trusted));
+ fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
+ fout.print(", trusted=" + dumpBool(trusted));
+ fout.println();
if (trusted) {
fout.println(" message=\"" + info.agent.getMessage() + "\"");
}