summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Roos <roosa@google.com>2014-07-25 15:37:28 +0200
committerAdrian Roos <roosa@google.com>2014-07-30 12:33:33 +0000
commit7861c663fd64af33ec2a4c5ad653c806dc8bd994 (patch)
tree84404afe7c7438fddbd9c659202a34e1d8e24515
parent8c146ae9be387da55b5cbf57314543a4fa16052b (diff)
downloadframeworks_base-7861c663fd64af33ec2a4c5ad653c806dc8bd994.zip
frameworks_base-7861c663fd64af33ec2a4c5ad653c806dc8bd994.tar.gz
frameworks_base-7861c663fd64af33ec2a4c5ad653c806dc8bd994.tar.bz2
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
-rw-r--r--core/java/android/app/trust/ITrustListener.aidl1
-rw-r--r--core/java/android/app/trust/TrustManager.java17
-rw-r--r--core/java/android/service/trust/ITrustAgentServiceCallback.aidl1
-rw-r--r--core/java/android/service/trust/TrustAgentService.java53
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java17
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java6
-rw-r--r--packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml8
-rw-r--r--packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java40
-rw-r--r--packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java9
-rw-r--r--packages/SystemUI/res/drawable/trust_circle.xml22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java15
-rw-r--r--services/core/java/com/android/server/trust/TrustAgentWrapper.java24
-rw-r--r--services/core/java/com/android/server/trust/TrustArchive.java28
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java43
15 files changed, 264 insertions, 22 deletions
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 @@ package android.app.trust;
*/
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 @@ import android.util.Log;
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 @@ public class TrustManager {
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 @@ public class TrustManager {
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 @@ public class TrustManager {
* @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 @@ import android.os.UserHandle;
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 @@ import android.util.Slog;
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 @@ public class TrustAgentService extends Service {
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 @@ public class TrustAgentService extends Service {
@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 @@ public class TrustAgentService extends Service {
* 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 @@ public class TrustAgentService extends Service {
}
}
+ /**
+ * 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 class TrustAgentService extends Service {
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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
};
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
+ private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray();
@Override
@@ -230,6 +231,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
}
+ @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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|| 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 class KeyguardUpdateMonitorCallback {
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 @@ public class KeyguardUpdateMonitorCallback {
* 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.support.v4.content.LocalBroadcastManager;
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 @@ public class SampleTrustAgent extends TrustAgentService {
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 @@ public class SampleTrustAgent extends TrustAgentService {
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 class SampleTrustAgent extends TrustAgentService {
public void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(mReceiver);
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .unregisterOnSharedPreferenceChangeListener(this);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -80,9 +88,14 @@ public class SampleTrustAgent extends TrustAgentService {
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 @@ public class SampleTrustAgent extends TrustAgentService {
.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 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi
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 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi
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 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi
@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 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
? 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 @@ public class UnlockMethodCache {
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 @@ public class UnlockMethodCache {
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 @@ public class UnlockMethodCache {
}
@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 @@ public class TrustAgentWrapper {
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 @@ public class TrustAgentWrapper {
private boolean mTrusted;
private CharSequence mMessage;
private boolean mTrustDisabledByDpm;
+ private boolean mManagingTrust;
private final Handler mHandler = new Handler() {
@Override
@@ -122,6 +124,15 @@ public class TrustAgentWrapper {
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 @@ public class TrustAgentWrapper {
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 class TrustAgentWrapper {
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 class TrustAgentWrapper {
}
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 @@ public class TrustArchive {
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 @@ public class TrustArchive {
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 @@ public class TrustArchive {
this.message = message;
this.duration = duration;
this.userInitiated = userInitiated;
+ this.managingTrust = managingTrust;
}
}
@@ -66,27 +71,31 @@ public class TrustArchive {
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 @@ public class TrustArchive {
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 @@ public class TrustArchive {
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 class TrustManagerService extends SystemService {
}
public void updateTrust(int userId) {
+ dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
dispatchOnTrustChanged(aggregateIsTrusted(userId), userId);
}
@@ -211,7 +212,7 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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 @@ public class TrustManagerService extends SystemService {
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() + "\"");
}