| /* |
| * 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); |
| } |
| } |