diff options
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() + "\""); } |