* commit 'a8bbebd426b554378cedf3d4e729cabd7e0caff9': Add StrongAuthTracker
This commit is contained in:
@@ -90,6 +90,7 @@ LOCAL_SRC_FILES += \
|
|||||||
core/java/android/app/IWallpaperManager.aidl \
|
core/java/android/app/IWallpaperManager.aidl \
|
||||||
core/java/android/app/IWallpaperManagerCallback.aidl \
|
core/java/android/app/IWallpaperManagerCallback.aidl \
|
||||||
core/java/android/app/admin/IDevicePolicyManager.aidl \
|
core/java/android/app/admin/IDevicePolicyManager.aidl \
|
||||||
|
core/java/android/app/trust/IStrongAuthTracker.aidl \
|
||||||
core/java/android/app/trust/ITrustManager.aidl \
|
core/java/android/app/trust/ITrustManager.aidl \
|
||||||
core/java/android/app/trust/ITrustListener.aidl \
|
core/java/android/app/trust/ITrustListener.aidl \
|
||||||
core/java/android/app/backup/IBackupManager.aidl \
|
core/java/android/app/backup/IBackupManager.aidl \
|
||||||
|
|||||||
26
core/java/android/app/trust/IStrongAuthTracker.aidl
Normal file
26
core/java/android/app/trust/IStrongAuthTracker.aidl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2015, 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.
|
||||||
|
*/
|
||||||
|
package android.app.trust;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private API to be notified about strong auth changes
|
||||||
|
*
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
oneway interface IStrongAuthTracker {
|
||||||
|
void onStrongAuthRequiredChanged(int strongAuthRequired, int userId);
|
||||||
|
}
|
||||||
@@ -26,11 +26,9 @@ import android.app.trust.ITrustListener;
|
|||||||
interface ITrustManager {
|
interface ITrustManager {
|
||||||
void reportUnlockAttempt(boolean successful, int userId);
|
void reportUnlockAttempt(boolean successful, int userId);
|
||||||
void reportEnabledTrustAgentsChanged(int userId);
|
void reportEnabledTrustAgentsChanged(int userId);
|
||||||
void reportRequireCredentialEntry(int userId);
|
|
||||||
void registerTrustListener(in ITrustListener trustListener);
|
void registerTrustListener(in ITrustListener trustListener);
|
||||||
void unregisterTrustListener(in ITrustListener trustListener);
|
void unregisterTrustListener(in ITrustListener trustListener);
|
||||||
void reportKeyguardShowingChanged();
|
void reportKeyguardShowingChanged();
|
||||||
boolean isDeviceLocked(int userId);
|
boolean isDeviceLocked(int userId);
|
||||||
boolean isDeviceSecure(int userId);
|
boolean isDeviceSecure(int userId);
|
||||||
boolean hasUserAuthenticatedSinceBoot(int userId);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,19 @@
|
|||||||
|
|
||||||
package android.app.trust;
|
package android.app.trust;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link com.android.server.trust.TrustManagerService}
|
* See {@link com.android.server.trust.TrustManagerService}
|
||||||
@@ -72,21 +78,6 @@ public class TrustManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports that trust is disabled until credentials have been entered for user {@param userId}.
|
|
||||||
*
|
|
||||||
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
|
||||||
*
|
|
||||||
* @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
|
|
||||||
*/
|
|
||||||
public void reportRequireCredentialEntry(int userId) {
|
|
||||||
try {
|
|
||||||
mService.reportRequireCredentialEntry(userId);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
onError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports that the visibility of the keyguard has changed.
|
* Reports that the visibility of the keyguard has changed.
|
||||||
*
|
*
|
||||||
@@ -147,23 +138,6 @@ public class TrustManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the specified user has been authenticated since the last boot.
|
|
||||||
*
|
|
||||||
* @param userId the user id of the user to check for
|
|
||||||
* @return true if the user has authenticated since boot, false otherwise
|
|
||||||
*
|
|
||||||
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
|
||||||
*/
|
|
||||||
public boolean hasUserAuthenticatedSinceBoot(int userId) {
|
|
||||||
try {
|
|
||||||
return mService.hasUserAuthenticatedSinceBoot(userId);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
onError(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onError(Exception e) {
|
private void onError(Exception e) {
|
||||||
Log.e(TAG, "Error while calling TrustManagerService", e);
|
Log.e(TAG, "Error while calling TrustManagerService", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.internal.widget;
|
package com.android.internal.widget;
|
||||||
|
|
||||||
|
import android.app.trust.IStrongAuthTracker;
|
||||||
import com.android.internal.widget.VerifyCredentialResponse;
|
import com.android.internal.widget.VerifyCredentialResponse;
|
||||||
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
@@ -35,4 +36,7 @@ interface ILockSettings {
|
|||||||
boolean checkVoldPassword(int userId);
|
boolean checkVoldPassword(int userId);
|
||||||
boolean havePattern(int userId);
|
boolean havePattern(int userId);
|
||||||
boolean havePassword(int userId);
|
boolean havePassword(int userId);
|
||||||
|
void registerStrongAuthTracker(in IStrongAuthTracker tracker);
|
||||||
|
void unregisterStrongAuthTracker(in IStrongAuthTracker tracker);
|
||||||
|
void requireStrongAuth(int strongAuthReason, int userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,19 @@
|
|||||||
|
|
||||||
package com.android.internal.widget;
|
package com.android.internal.widget;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.annotation.IntDef;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityManagerNative;
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.app.trust.IStrongAuthTracker;
|
||||||
import android.app.trust.TrustManager;
|
import android.app.trust.TrustManager;
|
||||||
import android.bluetooth.BluetoothClass;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
@@ -38,9 +39,12 @@ import android.os.storage.StorageManager;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -228,7 +232,7 @@ public class LockPatternUtils {
|
|||||||
public void reportFailedPasswordAttempt(int userId) {
|
public void reportFailedPasswordAttempt(int userId) {
|
||||||
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
|
getDevicePolicyManager().reportFailedPasswordAttempt(userId);
|
||||||
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
|
getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
|
||||||
getTrustManager().reportRequireCredentialEntry(userId);
|
requireCredentialEntry(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportSuccessfulPasswordAttempt(int userId) {
|
public void reportSuccessfulPasswordAttempt(int userId) {
|
||||||
@@ -1163,10 +1167,32 @@ public class LockPatternUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see android.app.trust.TrustManager#reportRequireCredentialEntry(int)
|
* Disable trust until credentials have been entered for user {@param userId}.
|
||||||
|
*
|
||||||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||||||
|
*
|
||||||
|
* @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
|
||||||
*/
|
*/
|
||||||
public void requireCredentialEntry(int userId) {
|
public void requireCredentialEntry(int userId) {
|
||||||
getTrustManager().reportRequireCredentialEntry(userId);
|
requireStrongAuth(StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests strong authentication for user {@param userId}.
|
||||||
|
*
|
||||||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||||||
|
*
|
||||||
|
* @param strongAuthReason a combination of {@link StrongAuthTracker.StrongAuthFlags} indicating
|
||||||
|
* the reason for and the strength of the requested authentication.
|
||||||
|
* @param userId either an explicit user id or {@link android.os.UserHandle#USER_ALL}
|
||||||
|
*/
|
||||||
|
public void requireStrongAuth(@StrongAuthTracker.StrongAuthFlags int strongAuthReason,
|
||||||
|
int userId) {
|
||||||
|
try {
|
||||||
|
getLockSettings().requireStrongAuth(strongAuthReason, userId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Error while requesting strong auth: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAfterChangingPassword(int userHandle) {
|
private void onAfterChangingPassword(int userHandle) {
|
||||||
@@ -1198,4 +1224,148 @@ public class LockPatternUtils {
|
|||||||
private boolean shouldEncryptWithCredentials(boolean defaultValue) {
|
private boolean shouldEncryptWithCredentials(boolean defaultValue) {
|
||||||
return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet();
|
return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
|
||||||
|
try {
|
||||||
|
getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException("Could not register StrongAuthTracker");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
|
||||||
|
try {
|
||||||
|
getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.mStub);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Could not unregister StrongAuthTracker", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks the global strong authentication state.
|
||||||
|
*/
|
||||||
|
public static class StrongAuthTracker {
|
||||||
|
|
||||||
|
@IntDef(flag = true,
|
||||||
|
value = { STRONG_AUTH_NOT_REQUIRED,
|
||||||
|
STRONG_AUTH_REQUIRED_AFTER_BOOT,
|
||||||
|
STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
|
||||||
|
SOME_AUTH_REQUIRED_AFTER_USER_REQUEST})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface StrongAuthFlags {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strong authentication is not required.
|
||||||
|
*/
|
||||||
|
public static final int STRONG_AUTH_NOT_REQUIRED = 0x0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strong authentication is required because the user has not authenticated since boot.
|
||||||
|
*/
|
||||||
|
public static final int STRONG_AUTH_REQUIRED_AFTER_BOOT = 0x1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strong authentication is required because a device admin has requested it.
|
||||||
|
*/
|
||||||
|
public static final int STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW = 0x2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some authentication is required because the user has temporarily disabled trust.
|
||||||
|
*/
|
||||||
|
public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4;
|
||||||
|
|
||||||
|
public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||||
|
private static final int ALLOWING_FINGERPRINT = SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
|
||||||
|
|
||||||
|
final SparseIntArray mStrongAuthRequiredForUser = new SparseIntArray();
|
||||||
|
|
||||||
|
private final H mHandler;
|
||||||
|
|
||||||
|
public StrongAuthTracker() {
|
||||||
|
this(Looper.myLooper());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param looper the looper on whose thread calls to {@link #onStrongAuthRequiredChanged}
|
||||||
|
* will be scheduled.
|
||||||
|
*/
|
||||||
|
public StrongAuthTracker(Looper looper) {
|
||||||
|
mHandler = new H(looper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@link #STRONG_AUTH_NOT_REQUIRED} if strong authentication is not required,
|
||||||
|
* otherwise returns a combination of {@link StrongAuthFlags} indicating why strong
|
||||||
|
* authentication is required.
|
||||||
|
*
|
||||||
|
* @param userId the user for whom the state is queried.
|
||||||
|
*/
|
||||||
|
public @StrongAuthFlags int getStrongAuthForUser(int userId) {
|
||||||
|
return mStrongAuthRequiredForUser.get(userId, DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if unlocking with trust alone is allowed for {@param userId} by the current
|
||||||
|
* strong authentication requirements.
|
||||||
|
*/
|
||||||
|
public boolean isTrustAllowedForUser(int userId) {
|
||||||
|
return getStrongAuthForUser(userId) == STRONG_AUTH_NOT_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if unlocking with fingerprint alone is allowed for {@param userId} by the
|
||||||
|
* current strong authentication requirements.
|
||||||
|
*/
|
||||||
|
public boolean isFingerprintAllowedForUser(int userId) {
|
||||||
|
return (getStrongAuthForUser(userId) & ~ALLOWING_FINGERPRINT) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the strong authentication requirements for {@param userId} changed.
|
||||||
|
*/
|
||||||
|
public void onStrongAuthRequiredChanged(int userId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
|
||||||
|
int userId) {
|
||||||
|
|
||||||
|
int oldValue = getStrongAuthForUser(userId);
|
||||||
|
if (strongAuthFlags != oldValue) {
|
||||||
|
if (strongAuthFlags == DEFAULT) {
|
||||||
|
mStrongAuthRequiredForUser.delete(userId);
|
||||||
|
} else {
|
||||||
|
mStrongAuthRequiredForUser.put(userId, strongAuthFlags);
|
||||||
|
}
|
||||||
|
onStrongAuthRequiredChanged(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
|
||||||
|
int userId) {
|
||||||
|
mHandler.obtainMessage(H.MSG_ON_STRONG_AUTH_REQUIRED_CHANGED,
|
||||||
|
strongAuthFlags, userId).sendToTarget();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private class H extends Handler {
|
||||||
|
static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1;
|
||||||
|
|
||||||
|
public H(Looper looper) {
|
||||||
|
super(looper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_ON_STRONG_AUTH_REQUIRED_CHANGED:
|
||||||
|
handleStrongAuthRequiredChanged(msg.arg1, msg.arg2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import com.android.internal.telephony.IccCardConstants;
|
|||||||
import com.android.internal.telephony.IccCardConstants.State;
|
import com.android.internal.telephony.IccCardConstants.State;
|
||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
import com.android.internal.telephony.TelephonyIntents;
|
import com.android.internal.telephony.TelephonyIntents;
|
||||||
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -170,7 +171,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
private boolean mFingerprintAlreadyAuthenticated;
|
private boolean mFingerprintAlreadyAuthenticated;
|
||||||
private boolean mBouncer;
|
private boolean mBouncer;
|
||||||
private boolean mBootCompleted;
|
private boolean mBootCompleted;
|
||||||
private boolean mUserHasAuthenticatedSinceBoot;
|
|
||||||
|
|
||||||
// Device provisioning state
|
// Device provisioning state
|
||||||
private boolean mDeviceProvisioned;
|
private boolean mDeviceProvisioned;
|
||||||
@@ -183,6 +183,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
|
|
||||||
/** Tracks whether strong authentication hasn't been used since quite some time per user. */
|
/** Tracks whether strong authentication hasn't been used since quite some time per user. */
|
||||||
private ArraySet<Integer> mStrongAuthTimedOut = new ArraySet<>();
|
private ArraySet<Integer> mStrongAuthTimedOut = new ArraySet<>();
|
||||||
|
private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker();
|
||||||
|
|
||||||
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
|
private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
|
||||||
mCallbacks = Lists.newArrayList();
|
mCallbacks = Lists.newArrayList();
|
||||||
@@ -539,7 +540,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnlockingWithFingerprintAllowed() {
|
public boolean isUnlockingWithFingerprintAllowed() {
|
||||||
return mUserHasAuthenticatedSinceBoot && !hasFingerprintUnlockTimedOut(sCurrentUser);
|
return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
|
||||||
|
&& !hasFingerprintUnlockTimedOut(sCurrentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StrongAuthTracker getStrongAuthTracker() {
|
||||||
|
return mStrongAuthTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -827,6 +833,25 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
|
||||||
|
|
||||||
|
public boolean isUnlockingWithFingerprintAllowed() {
|
||||||
|
int userId = getCurrentUser();
|
||||||
|
return isFingerprintAllowedForUser(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasUserAuthenticatedSinceBoot() {
|
||||||
|
int userId = getCurrentUser();
|
||||||
|
return (getStrongAuthForUser(userId)
|
||||||
|
& STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStrongAuthRequiredChanged(int userId) {
|
||||||
|
// do something?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static KeyguardUpdateMonitor getInstance(Context context) {
|
public static KeyguardUpdateMonitor getInstance(Context context) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new KeyguardUpdateMonitor(context);
|
sInstance = new KeyguardUpdateMonitor(context);
|
||||||
@@ -973,6 +998,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
PERMISSION_SELF, null /* handler */);
|
PERMISSION_SELF, null /* handler */);
|
||||||
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
|
mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
|
||||||
mTrustManager.registerTrustListener(this);
|
mTrustManager.registerTrustListener(this);
|
||||||
|
new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
|
||||||
|
|
||||||
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
|
||||||
updateFingerprintListeningState();
|
updateFingerprintListeningState();
|
||||||
@@ -1001,8 +1027,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
|||||||
if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
|
if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
|
||||||
int userId = ActivityManager.getCurrentUser();
|
int userId = ActivityManager.getCurrentUser();
|
||||||
if (isUnlockWithFingerprintPossible(userId)) {
|
if (isUnlockWithFingerprintPossible(userId)) {
|
||||||
mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
|
|
||||||
ActivityManager.getCurrentUser());
|
|
||||||
if (mFingerprintCancelSignal != null) {
|
if (mFingerprintCancelSignal != null) {
|
||||||
mFingerprintCancelSignal.cancel();
|
mFingerprintCancelSignal.cancel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ public class KeyguardViewMediator extends SystemUI {
|
|||||||
int currentUser = ActivityManager.getCurrentUser();
|
int currentUser = ActivityManager.getCurrentUser();
|
||||||
if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
|
if ((mUpdateMonitor.getUserTrustIsManaged(currentUser)
|
||||||
|| mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
|
|| mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser))
|
||||||
&& !mTrustManager.hasUserAuthenticatedSinceBoot(currentUser)) {
|
&& !mUpdateMonitor.getStrongAuthTracker().hasUserAuthenticatedSinceBoot()) {
|
||||||
return KeyguardSecurityView.PROMPT_REASON_RESTART;
|
return KeyguardSecurityView.PROMPT_REASON_RESTART;
|
||||||
} else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
|
} else if (mUpdateMonitor.isUnlockWithFingerprintPossible(currentUser)
|
||||||
&& mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
|
&& mUpdateMonitor.hasFingerprintUnlockTimedOut(currentUser)) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server;
|
|||||||
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.backup.BackupManager;
|
import android.app.backup.BackupManager;
|
||||||
|
import android.app.trust.IStrongAuthTracker;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -70,6 +71,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
private final LockSettingsStorage mStorage;
|
private final LockSettingsStorage mStorage;
|
||||||
|
private final LockSettingsStrongAuth mStrongAuth = new LockSettingsStrongAuth();
|
||||||
|
|
||||||
private LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private boolean mFirstCallToVold;
|
private boolean mFirstCallToVold;
|
||||||
@@ -93,6 +95,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
filter.addAction(Intent.ACTION_USER_ADDED);
|
filter.addAction(Intent.ACTION_USER_ADDED);
|
||||||
filter.addAction(Intent.ACTION_USER_STARTING);
|
filter.addAction(Intent.ACTION_USER_STARTING);
|
||||||
filter.addAction(Intent.ACTION_USER_REMOVED);
|
filter.addAction(Intent.ACTION_USER_REMOVED);
|
||||||
|
filter.addAction(Intent.ACTION_USER_PRESENT);
|
||||||
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
|
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
|
||||||
|
|
||||||
mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
|
mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
|
||||||
@@ -122,6 +125,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
|
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
|
||||||
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
|
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
|
||||||
mStorage.prefetchUser(userHandle);
|
mStorage.prefetchUser(userHandle);
|
||||||
|
} else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {
|
||||||
|
mStrongAuth.reportUnlock(getSendingUserId());
|
||||||
} else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
|
} else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
|
||||||
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
|
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
|
||||||
if (userHandle > 0) {
|
if (userHandle > 0) {
|
||||||
@@ -713,6 +718,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
|
|
||||||
private void removeUser(int userId) {
|
private void removeUser(int userId) {
|
||||||
mStorage.removeUser(userId);
|
mStorage.removeUser(userId);
|
||||||
|
mStrongAuth.removeUser(userId);
|
||||||
|
|
||||||
final KeyStore ks = KeyStore.getInstance();
|
final KeyStore ks = KeyStore.getInstance();
|
||||||
ks.onUserRemoved(userId);
|
ks.onUserRemoved(userId);
|
||||||
@@ -727,6 +733,24 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
checkPasswordReadPermission(UserHandle.USER_ALL);
|
||||||
|
mStrongAuth.registerStrongAuthTracker(tracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
checkPasswordReadPermission(UserHandle.USER_ALL);
|
||||||
|
mStrongAuth.unregisterStrongAuthTracker(tracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requireStrongAuth(int strongAuthReason, int userId) {
|
||||||
|
checkWritePermission(userId);
|
||||||
|
mStrongAuth.requireStrongAuth(strongAuthReason, userId);
|
||||||
|
}
|
||||||
|
|
||||||
private static final String[] VALID_SETTINGS = new String[] {
|
private static final String[] VALID_SETTINGS = new String[] {
|
||||||
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
|
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
|
||||||
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
|
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
|
||||||
@@ -797,5 +821,4 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
Slog.e(TAG, "Unable to acquire GateKeeperService");
|
Slog.e(TAG, "Unable to acquire GateKeeperService");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server;
|
||||||
|
|
||||||
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
|
||||||
|
|
||||||
|
import android.app.trust.IStrongAuthTracker;
|
||||||
|
import android.os.DeadObjectException;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.util.Slog;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of requests for strong authentication.
|
||||||
|
*/
|
||||||
|
public class LockSettingsStrongAuth {
|
||||||
|
|
||||||
|
private static final String TAG = "LockSettings";
|
||||||
|
|
||||||
|
private static final int MSG_REQUIRE_STRONG_AUTH = 1;
|
||||||
|
private static final int MSG_REGISTER_TRACKER = 2;
|
||||||
|
private static final int MSG_UNREGISTER_TRACKER = 3;
|
||||||
|
private static final int MSG_REMOVE_USER = 4;
|
||||||
|
|
||||||
|
private final ArrayList<IStrongAuthTracker> mStrongAuthTrackers = new ArrayList<>();
|
||||||
|
private final SparseIntArray mStrongAuthForUser = new SparseIntArray();
|
||||||
|
|
||||||
|
private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
|
||||||
|
if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mStrongAuthTrackers.add(tracker);
|
||||||
|
|
||||||
|
for (int i = 0; i < mStrongAuthForUser.size(); i++) {
|
||||||
|
int key = mStrongAuthForUser.keyAt(i);
|
||||||
|
int value = mStrongAuthForUser.valueAt(i);
|
||||||
|
try {
|
||||||
|
tracker.onStrongAuthRequiredChanged(value, key);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Exception while adding StrongAuthTracker.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
|
||||||
|
if (mStrongAuthTrackers.get(i).asBinder() == tracker.asBinder()) {
|
||||||
|
mStrongAuthTrackers.remove(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRequireStrongAuth(int strongAuthReason, int userId) {
|
||||||
|
if (userId == UserHandle.USER_ALL) {
|
||||||
|
for (int i = 0; i < mStrongAuthForUser.size(); i++) {
|
||||||
|
int key = mStrongAuthForUser.keyAt(i);
|
||||||
|
handleRequireStrongAuthOneUser(strongAuthReason, key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleRequireStrongAuthOneUser(strongAuthReason, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) {
|
||||||
|
int oldValue = mStrongAuthForUser.get(userId, LockPatternUtils.StrongAuthTracker.DEFAULT);
|
||||||
|
int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED
|
||||||
|
? STRONG_AUTH_NOT_REQUIRED
|
||||||
|
: (oldValue | strongAuthReason);
|
||||||
|
if (oldValue != newValue) {
|
||||||
|
mStrongAuthForUser.put(userId, newValue);
|
||||||
|
notifyStrongAuthTrackers(newValue, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRemoveUser(int userId) {
|
||||||
|
int index = mStrongAuthForUser.indexOfKey(userId);
|
||||||
|
if (index >= 0) {
|
||||||
|
mStrongAuthForUser.removeAt(index);
|
||||||
|
notifyStrongAuthTrackers(StrongAuthTracker.DEFAULT, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
|
||||||
|
for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
|
||||||
|
try {
|
||||||
|
mStrongAuthTrackers.get(i).onStrongAuthRequiredChanged(strongAuthReason, userId);
|
||||||
|
} catch (DeadObjectException e) {
|
||||||
|
Slog.d(TAG, "Removing dead StrongAuthTracker.");
|
||||||
|
mStrongAuthTrackers.remove(i);
|
||||||
|
i--;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) {
|
||||||
|
mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUser(int userId) {
|
||||||
|
mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requireStrongAuth(int strongAuthReason, int userId) {
|
||||||
|
if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
|
||||||
|
mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
|
||||||
|
userId).sendToTarget();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"userId must be an explicit user id or USER_ALL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportUnlock(int userId) {
|
||||||
|
requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_REGISTER_TRACKER:
|
||||||
|
handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj);
|
||||||
|
break;
|
||||||
|
case MSG_UNREGISTER_TRACKER:
|
||||||
|
handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj);
|
||||||
|
break;
|
||||||
|
case MSG_REQUIRE_STRONG_AUTH:
|
||||||
|
handleRequireStrongAuth(msg.arg1, msg.arg2);
|
||||||
|
break;
|
||||||
|
case MSG_REMOVE_USER:
|
||||||
|
handleRemoveUser(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ package com.android.server.trust;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.content.PackageMonitor;
|
import com.android.internal.content.PackageMonitor;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
|
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
@@ -59,6 +60,7 @@ import android.util.AttributeSet;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
@@ -96,16 +98,15 @@ public class TrustManagerService extends SystemService {
|
|||||||
private static final int MSG_UNREGISTER_LISTENER = 2;
|
private static final int MSG_UNREGISTER_LISTENER = 2;
|
||||||
private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
|
private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
|
||||||
private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
|
private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
|
||||||
private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
|
|
||||||
private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
|
private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
|
||||||
private static final int MSG_START_USER = 7;
|
private static final int MSG_START_USER = 7;
|
||||||
private static final int MSG_CLEANUP_USER = 8;
|
private static final int MSG_CLEANUP_USER = 8;
|
||||||
private static final int MSG_SWITCH_USER = 9;
|
private static final int MSG_SWITCH_USER = 9;
|
||||||
|
|
||||||
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
|
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
|
||||||
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
|
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
|
||||||
private final Receiver mReceiver = new Receiver();
|
private final Receiver mReceiver = new Receiver();
|
||||||
private final SparseBooleanArray mUserHasAuthenticated = new SparseBooleanArray();
|
|
||||||
/* package */ final TrustArchive mArchive = new TrustArchive();
|
/* package */ final TrustArchive mArchive = new TrustArchive();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private final LockPatternUtils mLockPatternUtils;
|
||||||
@@ -118,9 +119,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
@GuardedBy("mDeviceLockedForUser")
|
@GuardedBy("mDeviceLockedForUser")
|
||||||
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
|
private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
|
||||||
|
|
||||||
@GuardedBy("mUserHasAuthenticatedSinceBoot")
|
|
||||||
private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
|
|
||||||
|
|
||||||
private boolean mTrustAgentsCanRun = false;
|
private boolean mTrustAgentsCanRun = false;
|
||||||
private int mCurrentUser = UserHandle.USER_OWNER;
|
private int mCurrentUser = UserHandle.USER_OWNER;
|
||||||
|
|
||||||
@@ -146,6 +144,7 @@ public class TrustManagerService extends SystemService {
|
|||||||
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
||||||
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
|
mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
|
||||||
mReceiver.register(mContext);
|
mReceiver.register(mContext);
|
||||||
|
mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
|
||||||
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
|
||||||
mTrustAgentsCanRun = true;
|
mTrustAgentsCanRun = true;
|
||||||
refreshAgentList(UserHandle.USER_ALL);
|
refreshAgentList(UserHandle.USER_ALL);
|
||||||
@@ -230,7 +229,7 @@ public class TrustManagerService extends SystemService {
|
|||||||
if (!userInfo.supportsSwitchTo()) continue;
|
if (!userInfo.supportsSwitchTo()) continue;
|
||||||
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
|
if (!mActivityManager.isUserRunning(userInfo.id)) continue;
|
||||||
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
|
if (!lockPatternUtils.isSecure(userInfo.id)) continue;
|
||||||
if (!getUserHasAuthenticated(userInfo.id)) continue;
|
if (!mStrongAuthTracker.isTrustAllowedForUser(userInfo.id)) continue;
|
||||||
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
|
DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
|
||||||
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
|
int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
|
||||||
final boolean disableTrustAgents =
|
final boolean disableTrustAgents =
|
||||||
@@ -509,7 +508,7 @@ public class TrustManagerService extends SystemService {
|
|||||||
// Agent dispatch and aggregation
|
// Agent dispatch and aggregation
|
||||||
|
|
||||||
private boolean aggregateIsTrusted(int userId) {
|
private boolean aggregateIsTrusted(int userId) {
|
||||||
if (!getUserHasAuthenticated(userId)) {
|
if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mActiveAgents.size(); i++) {
|
for (int i = 0; i < mActiveAgents.size(); i++) {
|
||||||
@@ -524,7 +523,7 @@ public class TrustManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean aggregateIsTrustManaged(int userId) {
|
private boolean aggregateIsTrustManaged(int userId) {
|
||||||
if (!getUserHasAuthenticated(userId)) {
|
if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mActiveAgents.size(); i++) {
|
for (int i = 0; i < mActiveAgents.size(); i++) {
|
||||||
@@ -545,54 +544,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
info.agent.onUnlockAttempt(successful);
|
info.agent.onUnlockAttempt(successful);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (successful) {
|
|
||||||
updateUserHasAuthenticated(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUserHasAuthenticated(int userId) {
|
|
||||||
boolean changed = setUserHasAuthenticated(userId);
|
|
||||||
if (changed) {
|
|
||||||
refreshAgentList(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean getUserHasAuthenticated(int userId) {
|
|
||||||
return mUserHasAuthenticated.get(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether the value has changed
|
|
||||||
*/
|
|
||||||
private boolean setUserHasAuthenticated(int userId) {
|
|
||||||
if (!mUserHasAuthenticated.get(userId)) {
|
|
||||||
mUserHasAuthenticated.put(userId, true);
|
|
||||||
synchronized (mUserHasAuthenticatedSinceBoot) {
|
|
||||||
mUserHasAuthenticatedSinceBoot.put(userId, true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearUserHasAuthenticated(int userId) {
|
|
||||||
if (userId == UserHandle.USER_ALL) {
|
|
||||||
mUserHasAuthenticated.clear();
|
|
||||||
} else {
|
|
||||||
mUserHasAuthenticated.put(userId, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean getUserHasAuthenticatedSinceBoot(int userId) {
|
|
||||||
synchronized (mUserHasAuthenticatedSinceBoot) {
|
|
||||||
return mUserHasAuthenticatedSinceBoot.get(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requireCredentialEntry(int userId) {
|
|
||||||
clearUserHasAuthenticated(userId);
|
|
||||||
refreshAgentList(userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
@@ -680,17 +631,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
|
mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportRequireCredentialEntry(int userId) throws RemoteException {
|
|
||||||
enforceReportPermission();
|
|
||||||
if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
|
|
||||||
mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"userId must be an explicit user id or USER_ALL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reportKeyguardShowingChanged() throws RemoteException {
|
public void reportKeyguardShowingChanged() throws RemoteException {
|
||||||
enforceReportPermission();
|
enforceReportPermission();
|
||||||
@@ -734,18 +674,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasUserAuthenticatedSinceBoot(int userId) throws RemoteException {
|
|
||||||
mContext.enforceCallingOrSelfPermission(
|
|
||||||
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null);
|
|
||||||
long token = Binder.clearCallingIdentity();
|
|
||||||
try {
|
|
||||||
return getUserHasAuthenticatedSinceBoot(userId);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enforceReportPermission() {
|
private void enforceReportPermission() {
|
||||||
mContext.enforceCallingOrSelfPermission(
|
mContext.enforceCallingOrSelfPermission(
|
||||||
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
|
Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
|
||||||
@@ -794,9 +722,8 @@ public class TrustManagerService extends SystemService {
|
|||||||
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
|
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
|
||||||
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
|
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
|
||||||
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
|
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
|
||||||
fout.print(", hasAuthenticated=" + dumpBool(getUserHasAuthenticated(user.id)));
|
fout.print(", strongAuthRequired=" + dumpHex(
|
||||||
fout.print(", hasAuthenticatedSinceBoot="
|
mStrongAuthTracker.getStrongAuthForUser(user.id)));
|
||||||
+ dumpBool(getUserHasAuthenticatedSinceBoot(user.id)));
|
|
||||||
fout.println();
|
fout.println();
|
||||||
fout.println(" Enabled agents:");
|
fout.println(" Enabled agents:");
|
||||||
boolean duplicateSimpleNames = false;
|
boolean duplicateSimpleNames = false;
|
||||||
@@ -831,6 +758,10 @@ public class TrustManagerService extends SystemService {
|
|||||||
private String dumpBool(boolean b) {
|
private String dumpBool(boolean b) {
|
||||||
return b ? "1" : "0";
|
return b ? "1" : "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String dumpHex(int i) {
|
||||||
|
return "0x" + Integer.toHexString(i);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private int resolveProfileParent(int userId) {
|
private int resolveProfileParent(int userId) {
|
||||||
@@ -864,9 +795,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
// This is also called when the security mode of a user changes.
|
// This is also called when the security mode of a user changes.
|
||||||
refreshDeviceLockedForUser(UserHandle.USER_ALL);
|
refreshDeviceLockedForUser(UserHandle.USER_ALL);
|
||||||
break;
|
break;
|
||||||
case MSG_REQUIRE_CREDENTIAL_ENTRY:
|
|
||||||
requireCredentialEntry(msg.arg1);
|
|
||||||
break;
|
|
||||||
case MSG_KEYGUARD_SHOWING_CHANGED:
|
case MSG_KEYGUARD_SHOWING_CHANGED:
|
||||||
refreshDeviceLockedForUser(mCurrentUser);
|
refreshDeviceLockedForUser(mCurrentUser);
|
||||||
break;
|
break;
|
||||||
@@ -900,6 +828,13 @@ public class TrustManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker() {
|
||||||
|
@Override
|
||||||
|
public void onStrongAuthRequiredChanged(int userId) {
|
||||||
|
refreshAgentList(userId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private class Receiver extends BroadcastReceiver {
|
private class Receiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -908,8 +843,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
|
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
|
||||||
refreshAgentList(getSendingUserId());
|
refreshAgentList(getSendingUserId());
|
||||||
updateDevicePolicyFeatures();
|
updateDevicePolicyFeatures();
|
||||||
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
|
|
||||||
updateUserHasAuthenticated(getSendingUserId());
|
|
||||||
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
|
} else if (Intent.ACTION_USER_ADDED.equals(action)) {
|
||||||
int userId = getUserId(intent);
|
int userId = getUserId(intent);
|
||||||
if (userId > 0) {
|
if (userId > 0) {
|
||||||
@@ -918,7 +851,6 @@ public class TrustManagerService extends SystemService {
|
|||||||
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
||||||
int userId = getUserId(intent);
|
int userId = getUserId(intent);
|
||||||
if (userId > 0) {
|
if (userId > 0) {
|
||||||
mUserHasAuthenticated.delete(userId);
|
|
||||||
synchronized (mUserIsTrusted) {
|
synchronized (mUserIsTrusted) {
|
||||||
mUserIsTrusted.delete(userId);
|
mUserIsTrusted.delete(userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
|
|||||||
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
|
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
|
||||||
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
|
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
|
||||||
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
|
import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
|
||||||
|
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
|
||||||
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
||||||
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
||||||
import static org.xmlpull.v1.XmlPullParser.TEXT;
|
import static org.xmlpull.v1.XmlPullParser.TEXT;
|
||||||
@@ -44,6 +45,7 @@ import android.app.admin.DevicePolicyManagerInternal;
|
|||||||
import android.app.admin.IDevicePolicyManager;
|
import android.app.admin.IDevicePolicyManager;
|
||||||
import android.app.admin.SystemUpdatePolicy;
|
import android.app.admin.SystemUpdatePolicy;
|
||||||
import android.app.backup.IBackupManager;
|
import android.app.backup.IBackupManager;
|
||||||
|
import android.app.trust.TrustManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
@@ -2957,7 +2959,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
|
boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
|
||||||
if (requireEntry) {
|
if (requireEntry) {
|
||||||
utils.requireCredentialEntry(UserHandle.USER_ALL);
|
utils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW,
|
||||||
|
UserHandle.USER_ALL);
|
||||||
}
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
int newOwner = requireEntry ? callingUid : -1;
|
int newOwner = requireEntry ? callingUid : -1;
|
||||||
@@ -3089,7 +3092,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
|
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
|
||||||
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
|
PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
|
||||||
// Ensure the device is locked
|
// Ensure the device is locked
|
||||||
new LockPatternUtils(mContext).requireCredentialEntry(UserHandle.USER_ALL);
|
new LockPatternUtils(mContext).requireStrongAuth(
|
||||||
|
STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW, UserHandle.USER_ALL);
|
||||||
getWindowManager().lockNow(null);
|
getWindowManager().lockNow(null);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user