diff options
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | core/java/android/app/KeyguardManager.java | 35 | ||||
-rw-r--r-- | core/java/android/app/trust/ITrustManager.aidl | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/trust/TrustManagerService.java | 36 |
4 files changed, 71 insertions, 2 deletions
diff --git a/api/current.txt b/api/current.txt index 7f57f3c..bfe8d7a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4405,6 +4405,7 @@ package android.app { method public boolean inKeyguardRestrictedInputMode(); method public boolean isKeyguardLocked(); method public boolean isKeyguardSecure(); + method public boolean isKeyguardInTrustedState(); method public deprecated android.app.KeyguardManager.KeyguardLock newKeyguardLock(java.lang.String); } diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index cc9aed8..5038df9 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -16,10 +16,14 @@ package android.app; +import android.app.trust.ITrustManager; +import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.RemoteException; import android.os.IBinder; +import android.os.ServiceManager; +import android.os.UserHandle; import android.view.IWindowManager; import android.view.IOnKeyguardExitResult; import android.view.WindowManagerGlobal; @@ -33,6 +37,7 @@ import android.view.WindowManagerGlobal; */ public class KeyguardManager { private IWindowManager mWM; + private ITrustManager mTrustManager; /** * Intent used to prompt user for device credentials. @@ -151,6 +156,8 @@ public class KeyguardManager { KeyguardManager() { mWM = WindowManagerGlobal.getWindowManagerService(); + mTrustManager = ITrustManager.Stub.asInterface( + ServiceManager.getService(Context.TRUST_SERVICE)); } /** @@ -218,6 +225,34 @@ public class KeyguardManager { } /** + * Return whether unlocking the device is currently not requiring a password + * because of a trust agent. + * + * @return true if the keyguard can currently be unlocked without entering credentials + * because the device is in a trusted environment. + */ + public boolean isKeyguardInTrustedState() { + return isKeyguardInTrustedState(UserHandle.getCallingUserId()); + } + + /** + * Return whether unlocking the device is currently not requiring a password + * because of a trust agent. + * + * @param userId the user for which the trusted state should be reported. + * @return true if the keyguard can currently be unlocked without entering credentials + * because the device is in a trusted environment. + * @hide + */ + public boolean isKeyguardInTrustedState(int userId) { + try { + return mTrustManager.isTrusted(userId); + } catch (RemoteException e) { + return false; + } + } + + /** * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} * instead; this allows you to seamlessly hide the keyguard as your application diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl index 6fbf87d..0193711 100644 --- a/core/java/android/app/trust/ITrustManager.aidl +++ b/core/java/android/app/trust/ITrustManager.aidl @@ -29,4 +29,5 @@ interface ITrustManager { void reportRequireCredentialEntry(int userId); void registerTrustListener(in ITrustListener trustListener); void unregisterTrustListener(in ITrustListener trustListener); + boolean isTrusted(int userId); } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index f9b1704..1649535 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -16,6 +16,7 @@ package com.android.server.trust; +import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemService; @@ -24,6 +25,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.Manifest; +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.admin.DevicePolicyManager; import android.app.trust.ITrustListener; @@ -41,6 +43,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; @@ -100,8 +103,10 @@ public class TrustManagerService extends SystemService { /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; private final LockPatternUtils mLockPatternUtils; + private final UserManager mUserManager; - private UserManager mUserManager; + @GuardedBy("mUserIsTrusted") + private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); public TrustManagerService(Context context) { super(context); @@ -160,7 +165,11 @@ public class TrustManagerService extends SystemService { public void updateTrust(int userId, boolean initiatedByUser) { dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId); - dispatchOnTrustChanged(aggregateIsTrusted(userId), userId, initiatedByUser); + boolean trusted = aggregateIsTrusted(userId); + synchronized (mUserIsTrusted) { + mUserIsTrusted.put(userId, trusted); + } + dispatchOnTrustChanged(trusted, userId, initiatedByUser); } void refreshAgentList(int userId) { @@ -547,6 +556,16 @@ public class TrustManagerService extends SystemService { mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget(); } + @Override + public boolean isTrusted(int userId) throws RemoteException { + userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, + false /* allowAll */, true /* requireFull */, "isTrusted", null); + userId = resolveProfileParent(userId); + synchronized (mUserIsTrusted) { + return mUserIsTrusted.get(userId); + } + } + private void enforceReportPermission() { mContext.enforceCallingOrSelfPermission( Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events"); @@ -623,6 +642,19 @@ public class TrustManagerService extends SystemService { } }; + private int resolveProfileParent(int userId) { + long identity = Binder.clearCallingIdentity(); + try { + UserInfo parent = mUserManager.getProfileParent(userId); + if (parent != null) { + return parent.getUserHandle().getIdentifier(); + } + return userId; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { |