377 lines
14 KiB
Java
377 lines
14 KiB
Java
![]() |
/*
|
||
|
* 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
|
||
|
*/
|
||
|
|
||
|
package android.app.trust;
|
||
|
|
||
|
import android.Manifest;
|
||
|
import android.annotation.RequiresPermission;
|
||
|
import android.annotation.SdkConstant;
|
||
|
import android.annotation.SystemService;
|
||
|
import android.compat.annotation.UnsupportedAppUsage;
|
||
|
import android.content.Context;
|
||
|
import android.hardware.biometrics.BiometricSourceType;
|
||
|
import android.os.Bundle;
|
||
|
import android.os.Handler;
|
||
|
import android.os.IBinder;
|
||
|
import android.os.Looper;
|
||
|
import android.os.Message;
|
||
|
import android.os.RemoteException;
|
||
|
import android.util.ArrayMap;
|
||
|
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
|
||
|
/**
|
||
|
* See {@link com.android.server.trust.TrustManagerService}
|
||
|
* @hide
|
||
|
*/
|
||
|
@SystemService(Context.TRUST_SERVICE)
|
||
|
public class TrustManager {
|
||
|
|
||
|
/**
|
||
|
* Intent action used to identify services that can serve as significant providers.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
|
||
|
public static final String ACTION_BIND_SIGNIFICANT_PLACE_PROVIDER =
|
||
|
"com.android.trust.provider.SignificantPlaceProvider.BIND";
|
||
|
|
||
|
private static final int MSG_TRUST_CHANGED = 1;
|
||
|
private static final int MSG_TRUST_MANAGED_CHANGED = 2;
|
||
|
private static final int MSG_TRUST_ERROR = 3;
|
||
|
private static final int MSG_ENABLED_TRUST_AGENTS_CHANGED = 4;
|
||
|
private static final int MSG_IS_ACTIVE_UNLOCK_RUNNING = 5;
|
||
|
|
||
|
private static final String TAG = "TrustManager";
|
||
|
private static final String DATA_FLAGS = "initiatedByUser";
|
||
|
private static final String DATA_NEWLY_UNLOCKED = "newlyUnlocked";
|
||
|
private static final String DATA_MESSAGE = "message";
|
||
|
private static final String DATA_GRANTED_MESSAGES = "grantedMessages";
|
||
|
|
||
|
private final ITrustManager mService;
|
||
|
private final ArrayMap<TrustListener, ITrustListener> mTrustListeners;
|
||
|
|
||
|
public TrustManager(IBinder b) {
|
||
|
mService = ITrustManager.Stub.asInterface(b);
|
||
|
mTrustListeners = new ArrayMap<TrustListener, ITrustListener>();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Changes the lock status for the given user. This is only applicable to Managed Profiles,
|
||
|
* other users should be handled by Keyguard.
|
||
|
*
|
||
|
* @param userId The id for the user to be locked/unlocked.
|
||
|
* @param locked The value for that user's locked state.
|
||
|
*/
|
||
|
@RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
|
||
|
public void setDeviceLockedForUser(int userId, boolean locked) {
|
||
|
try {
|
||
|
mService.setDeviceLockedForUser(userId, locked);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that user {@param userId} has tried to unlock the device.
|
||
|
*
|
||
|
* @param successful if true, the unlock attempt was successful.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*/
|
||
|
@UnsupportedAppUsage
|
||
|
public void reportUnlockAttempt(boolean successful, int userId) {
|
||
|
try {
|
||
|
mService.reportUnlockAttempt(successful, userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that the user {@code userId} is likely interested in unlocking the device.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*
|
||
|
* @param dismissKeyguard whether the user wants to dismiss keyguard
|
||
|
*/
|
||
|
public void reportUserRequestedUnlock(int userId, boolean dismissKeyguard) {
|
||
|
try {
|
||
|
mService.reportUserRequestedUnlock(userId, dismissKeyguard);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that the user {@code userId} may want to unlock the device soon.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*/
|
||
|
public void reportUserMayRequestUnlock(int userId) {
|
||
|
try {
|
||
|
mService.reportUserMayRequestUnlock(userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that user {@param userId} has entered a temporary device lockout.
|
||
|
*
|
||
|
* This generally occurs when the user has unsuccessfully tried to unlock the device too many
|
||
|
* times. The user will then be unable to unlock the device until a set amount of time has
|
||
|
* elapsed.
|
||
|
*
|
||
|
* @param timeout The amount of time that needs to elapse, in milliseconds, until the user may
|
||
|
* attempt to unlock the device again.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*/
|
||
|
public void reportUnlockLockout(int timeoutMs, int userId) {
|
||
|
try {
|
||
|
mService.reportUnlockLockout(timeoutMs, userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that the list of enabled trust agents changed for user {@param userId}.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*/
|
||
|
public void reportEnabledTrustAgentsChanged(int userId) {
|
||
|
try {
|
||
|
mService.reportEnabledTrustAgentsChanged(userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reports that the visibility of the keyguard has changed.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#ACCESS_KEYGUARD_SECURE_STORAGE} permission.
|
||
|
*/
|
||
|
public void reportKeyguardShowingChanged() {
|
||
|
try {
|
||
|
mService.reportKeyguardShowingChanged();
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns whether active unlock can be used to unlock the device for user {@code userId}.
|
||
|
*/
|
||
|
public boolean isActiveUnlockRunning(int userId) {
|
||
|
try {
|
||
|
return mService.isActiveUnlockRunning(userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Registers a listener for trust events.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
|
||
|
*/
|
||
|
public void registerTrustListener(final TrustListener trustListener) {
|
||
|
try {
|
||
|
ITrustListener.Stub iTrustListener = new ITrustListener.Stub() {
|
||
|
@Override
|
||
|
public void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId,
|
||
|
int flags, List<String> trustGrantedMessages) {
|
||
|
Message m = mHandler.obtainMessage(MSG_TRUST_CHANGED, (enabled ? 1 : 0), userId,
|
||
|
trustListener);
|
||
|
if (flags != 0) {
|
||
|
m.getData().putInt(DATA_FLAGS, flags);
|
||
|
}
|
||
|
m.getData().putInt(DATA_NEWLY_UNLOCKED, newlyUnlocked ? 1 : 0);
|
||
|
m.getData().putCharSequenceArrayList(
|
||
|
DATA_GRANTED_MESSAGES, (ArrayList) trustGrantedMessages);
|
||
|
m.sendToTarget();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onEnabledTrustAgentsChanged(int userId) {
|
||
|
final Message m = mHandler.obtainMessage(MSG_ENABLED_TRUST_AGENTS_CHANGED,
|
||
|
userId, 0, trustListener);
|
||
|
m.sendToTarget();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTrustManagedChanged(boolean managed, int userId) {
|
||
|
mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
|
||
|
trustListener).sendToTarget();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onTrustError(CharSequence message) {
|
||
|
Message m = mHandler.obtainMessage(MSG_TRUST_ERROR, trustListener);
|
||
|
m.getData().putCharSequence(DATA_MESSAGE, message);
|
||
|
m.sendToTarget();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onIsActiveUnlockRunningChanged(boolean isRunning, int userId) {
|
||
|
mHandler.obtainMessage(MSG_IS_ACTIVE_UNLOCK_RUNNING,
|
||
|
(isRunning ? 1 : 0), userId, trustListener).sendToTarget();
|
||
|
}
|
||
|
};
|
||
|
mService.registerTrustListener(iTrustListener);
|
||
|
mTrustListeners.put(trustListener, iTrustListener);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Unregisters a listener for trust events.
|
||
|
*
|
||
|
* Requires the {@link android.Manifest.permission#TRUST_LISTENER} permission.
|
||
|
*/
|
||
|
public void unregisterTrustListener(final TrustListener trustListener) {
|
||
|
ITrustListener iTrustListener = mTrustListeners.remove(trustListener);
|
||
|
if (iTrustListener != null) {
|
||
|
try {
|
||
|
mService.unregisterTrustListener(iTrustListener);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return whether {@param userId} has enabled and configured trust agents. Ignores short-term
|
||
|
* unavailability of trust due to {@link LockPatternUtils.StrongAuthTracker}.
|
||
|
*/
|
||
|
@RequiresPermission(android.Manifest.permission.TRUST_LISTENER)
|
||
|
public boolean isTrustUsuallyManaged(int userId) {
|
||
|
try {
|
||
|
return mService.isTrustUsuallyManaged(userId);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates the trust state for the user due to the user unlocking via a biometric sensor.
|
||
|
* Should only be called if user authenticated via fingerprint, face, or iris and bouncer
|
||
|
* can be skipped.
|
||
|
*
|
||
|
* @param userId
|
||
|
*/
|
||
|
@RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
|
||
|
public void unlockedByBiometricForUser(int userId, BiometricSourceType source) {
|
||
|
try {
|
||
|
mService.unlockedByBiometricForUser(userId, source);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clears authentication by the specified biometric type for all users.
|
||
|
*/
|
||
|
@RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE)
|
||
|
public void clearAllBiometricRecognized(BiometricSourceType source, int unlockedUser) {
|
||
|
try {
|
||
|
mService.clearAllBiometricRecognized(source, unlockedUser);
|
||
|
} catch (RemoteException e) {
|
||
|
throw e.rethrowFromSystemServer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||
|
@Override
|
||
|
public void handleMessage(Message msg) {
|
||
|
switch(msg.what) {
|
||
|
case MSG_TRUST_CHANGED:
|
||
|
Bundle data = msg.peekData();
|
||
|
int flags = data != null ? data.getInt(DATA_FLAGS) : 0;
|
||
|
boolean enabled = msg.arg1 != 0;
|
||
|
int newlyUnlockedInt =
|
||
|
data != null ? data.getInt(DATA_NEWLY_UNLOCKED) : 0;
|
||
|
boolean newlyUnlocked = newlyUnlockedInt != 0;
|
||
|
((TrustListener) msg.obj).onTrustChanged(enabled, newlyUnlocked, msg.arg2,
|
||
|
flags, msg.getData().getStringArrayList(DATA_GRANTED_MESSAGES));
|
||
|
break;
|
||
|
case MSG_TRUST_MANAGED_CHANGED:
|
||
|
((TrustListener)msg.obj).onTrustManagedChanged(msg.arg1 != 0, msg.arg2);
|
||
|
break;
|
||
|
case MSG_TRUST_ERROR:
|
||
|
final CharSequence message = msg.peekData().getCharSequence(DATA_MESSAGE);
|
||
|
((TrustListener) msg.obj).onTrustError(message);
|
||
|
break;
|
||
|
case MSG_ENABLED_TRUST_AGENTS_CHANGED:
|
||
|
((TrustListener) msg.obj).onEnabledTrustAgentsChanged(msg.arg1);
|
||
|
break;
|
||
|
case MSG_IS_ACTIVE_UNLOCK_RUNNING:
|
||
|
((TrustListener) msg.obj)
|
||
|
.onIsActiveUnlockRunningChanged(msg.arg1 != 0, msg.arg2);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public interface TrustListener {
|
||
|
|
||
|
/**
|
||
|
* Reports that the trust state has changed.
|
||
|
* @param enabled If true, the system believes the environment to be trusted.
|
||
|
* @param newlyUnlocked If true, the system believes the device is newly unlocked due
|
||
|
* to the trust changing.
|
||
|
* @param userId The user, for which the trust changed.
|
||
|
* @param flags Flags specified by the trust agent when granting trust. See
|
||
|
* {@link android.service.trust.TrustAgentService#grantTrust(CharSequence, long, int)
|
||
|
* TrustAgentService.grantTrust(CharSequence, long, int)}.
|
||
|
* @param trustGrantedMessages Messages to display to the user when trust has been granted
|
||
|
* by one or more trust agents.
|
||
|
*/
|
||
|
void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
|
||
|
List<String> trustGrantedMessages);
|
||
|
|
||
|
/**
|
||
|
* 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);
|
||
|
|
||
|
/**
|
||
|
* Reports that an error happened on a TrustAgentService.
|
||
|
* @param message A message that should be displayed on the UI.
|
||
|
*/
|
||
|
void onTrustError(CharSequence message);
|
||
|
|
||
|
/**
|
||
|
* Reports that the enabled trust agents for the specified user has changed.
|
||
|
*/
|
||
|
void onEnabledTrustAgentsChanged(int userId);
|
||
|
|
||
|
/**
|
||
|
* Reports changes on if the device can be unlocked with active unlock.
|
||
|
* @param isRunning If true, the device can be unlocked with active unlock.
|
||
|
* @param userId The user, for which the state changed.
|
||
|
*/
|
||
|
void onIsActiveUnlockRunningChanged(boolean isRunning, int userId);
|
||
|
}
|
||
|
}
|