Merge "Add isActiveUnlockRunning" into udc-dev
This commit is contained in:
@@ -29,4 +29,5 @@ oneway interface ITrustListener {
|
||||
in List<String> trustGrantedMessages);
|
||||
void onTrustManagedChanged(boolean managed, int userId);
|
||||
void onTrustError(in CharSequence message);
|
||||
void onIsActiveUnlockRunningChanged(boolean isRunning, int userId);
|
||||
}
|
||||
|
||||
@@ -40,4 +40,5 @@ interface ITrustManager {
|
||||
boolean isTrustUsuallyManaged(int userId);
|
||||
void unlockedByBiometricForUser(int userId, in BiometricSourceType source);
|
||||
void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser);
|
||||
boolean isActiveUnlockRunning(int userId);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public class TrustManager {
|
||||
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";
|
||||
@@ -165,6 +166,17 @@ public class TrustManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -206,6 +218,12 @@ public class TrustManager {
|
||||
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);
|
||||
@@ -295,6 +313,10 @@ public class TrustManager {
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -333,5 +355,12 @@ public class TrustManager {
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,6 +570,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIsActiveUnlockRunningChanged(boolean isRunning, int userId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the trust granted call with its passed flags should dismiss keyguard.
|
||||
* It's assumed that the trust was granted for the current user.
|
||||
|
||||
@@ -95,6 +95,11 @@ constructor(
|
||||
"onTrustManagedChanged"
|
||||
)
|
||||
}
|
||||
|
||||
override fun onIsActiveUnlockRunningChanged(
|
||||
isRunning: Boolean,
|
||||
userId: Int
|
||||
) = Unit
|
||||
}
|
||||
trustManager.registerTrustListener(callback)
|
||||
logger.trustListenerRegistered()
|
||||
|
||||
@@ -442,6 +442,11 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIsActiveUnlockRunningChanged(boolean isRunning, int userId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
|
||||
|
||||
@@ -667,6 +667,10 @@ public class TrustAgentWrapper {
|
||||
return mTrustable && mManagingTrust && !mTrustDisabledByDpm;
|
||||
}
|
||||
|
||||
public boolean isTrustableOrWaitingForDowngrade() {
|
||||
return mWaitingForTrustableDowngrade || isTrustable();
|
||||
}
|
||||
|
||||
/** Set the trustagent as not trustable */
|
||||
public void setUntrustable() {
|
||||
mTrustable = false;
|
||||
|
||||
@@ -149,6 +149,7 @@ public class TrustManagerService extends SystemService {
|
||||
private static final String PRIV_NAMESPACE = "http://schemas.android.com/apk/prv/res/android";
|
||||
|
||||
private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
|
||||
private final SparseBooleanArray mLastActiveUnlockRunningState = new SparseBooleanArray();
|
||||
private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
|
||||
private final Receiver mReceiver = new Receiver();
|
||||
|
||||
@@ -681,6 +682,7 @@ public class TrustManagerService extends SystemService {
|
||||
|
||||
boolean isNowTrusted = pendingTrustState == TrustState.TRUSTED;
|
||||
boolean newlyUnlocked = !alreadyUnlocked && isNowTrusted;
|
||||
maybeActiveUnlockRunningChanged(userId);
|
||||
dispatchOnTrustChanged(
|
||||
isNowTrusted, newlyUnlocked, userId, flags, getTrustGrantedMessages(userId));
|
||||
if (isNowTrusted != wasTrusted) {
|
||||
@@ -921,6 +923,18 @@ public class TrustManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeActiveUnlockRunningChanged(int userId) {
|
||||
boolean oldValue = mLastActiveUnlockRunningState.get(userId);
|
||||
boolean newValue = aggregateIsActiveUnlockRunning(userId);
|
||||
if (oldValue == newValue) {
|
||||
return;
|
||||
}
|
||||
mLastActiveUnlockRunningState.put(userId, newValue);
|
||||
for (int i = 0; i < mTrustListeners.size(); i++) {
|
||||
notifyListenerIsActiveUnlockRunning(mTrustListeners.get(i), newValue, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshDeviceLockedForUser(int userId) {
|
||||
refreshDeviceLockedForUser(userId, UserHandle.USER_NULL);
|
||||
}
|
||||
@@ -1325,6 +1339,27 @@ public class TrustManagerService extends SystemService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean aggregateIsActiveUnlockRunning(int userId) {
|
||||
if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
|
||||
return false;
|
||||
}
|
||||
synchronized (mUserTrustState) {
|
||||
TrustState currentState = mUserTrustState.get(userId);
|
||||
if (currentState != TrustState.TRUSTED && currentState != TrustState.TRUSTABLE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mActiveAgents.size(); i++) {
|
||||
AgentInfo info = mActiveAgents.valueAt(i);
|
||||
if (info.userId == userId) {
|
||||
if (info.agent.isTrustableOrWaitingForDowngrade()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* We downgrade to trustable whenever keyguard changes its showing value.
|
||||
* - becomes showing: something has caused the device to show keyguard which happens due to
|
||||
@@ -1366,7 +1401,7 @@ public class TrustManagerService extends SystemService {
|
||||
for (int i = 0; i < mActiveAgents.size(); i++) {
|
||||
AgentInfo info = mActiveAgents.valueAt(i);
|
||||
if (info.userId == userId) {
|
||||
if (info.agent.isManagingTrust()) {
|
||||
if (info.agent.isTrustableOrWaitingForDowngrade()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1424,6 +1459,26 @@ public class TrustManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenerIsActiveUnlockRunningInitialState(ITrustListener listener) {
|
||||
int numUsers = mLastActiveUnlockRunningState.size();
|
||||
for (int i = 0; i < numUsers; i++) {
|
||||
int userId = mLastActiveUnlockRunningState.keyAt(i);
|
||||
boolean isRunning = aggregateIsActiveUnlockRunning(userId);
|
||||
notifyListenerIsActiveUnlockRunning(listener, isRunning, userId);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenerIsActiveUnlockRunning(
|
||||
ITrustListener listener, boolean isRunning, int userId) {
|
||||
try {
|
||||
listener.onIsActiveUnlockRunningChanged(isRunning, userId);
|
||||
} catch (DeadObjectException e) {
|
||||
Slog.d(TAG, "TrustListener dead while trying to notify Active Unlock running state");
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Exception while notifying TrustListener.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Listeners
|
||||
|
||||
private void addListener(ITrustListener listener) {
|
||||
@@ -1433,6 +1488,7 @@ public class TrustManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
mTrustListeners.add(listener);
|
||||
notifyListenerIsActiveUnlockRunningInitialState(listener);
|
||||
updateTrustAll();
|
||||
}
|
||||
|
||||
@@ -1747,6 +1803,8 @@ public class TrustManagerService extends SystemService {
|
||||
fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
|
||||
fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
|
||||
fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
|
||||
fout.print(", isActiveUnlockRunning=" + dumpBool(
|
||||
aggregateIsActiveUnlockRunning(user.id)));
|
||||
fout.print(", strongAuthRequired=" + dumpHex(
|
||||
mStrongAuthTracker.getStrongAuthForUser(user.id)));
|
||||
fout.println();
|
||||
@@ -1865,6 +1923,16 @@ public class TrustManagerService extends SystemService {
|
||||
}
|
||||
message.sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveUnlockRunning(int userId) throws RemoteException {
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return aggregateIsActiveUnlockRunning(userId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isTrustUsuallyManagedInternal(int userId) {
|
||||
|
||||
@@ -78,6 +78,16 @@
|
||||
<action android:name="android.service.trust.TrustAgentService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name=".IsActiveUnlockRunningTrustAgent"
|
||||
android:exported="true"
|
||||
android:label="Test Agent"
|
||||
android:permission="android.permission.BIND_TRUST_AGENT">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.trust.TrustAgentService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
<!-- self-instrumenting test package. -->
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.trust.test
|
||||
|
||||
import android.app.trust.TrustManager
|
||||
import android.content.Context
|
||||
import android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE
|
||||
import android.trust.BaseTrustAgentService
|
||||
import android.trust.TrustTestActivity
|
||||
import android.trust.test.lib.LockStateTrackingRule
|
||||
import android.trust.test.lib.ScreenLockRule
|
||||
import android.trust.test.lib.TestTrustListener
|
||||
import android.trust.test.lib.TrustAgentRule
|
||||
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
|
||||
import androidx.test.uiautomator.UiDevice
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/**
|
||||
* Test for testing isActiveUnlockRunning.
|
||||
*
|
||||
* atest TrustTests:IsActiveUnlockRunningTest
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IsActiveUnlockRunningTest {
|
||||
private val uiDevice = UiDevice.getInstance(getInstrumentation())
|
||||
private val context: Context = getApplicationContext()
|
||||
private val userId = context.userId
|
||||
private val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
|
||||
private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
|
||||
private val lockStateTrackingRule = LockStateTrackingRule()
|
||||
private val trustAgentRule = TrustAgentRule<IsActiveUnlockRunningTrustAgent>()
|
||||
|
||||
private val listener = object : TestTrustListener() {
|
||||
var isRunning = false
|
||||
private set
|
||||
|
||||
override fun onIsActiveUnlockRunningChanged(isRunning: Boolean, userId: Int) {
|
||||
this.isRunning = isRunning
|
||||
}
|
||||
}
|
||||
|
||||
@get:Rule
|
||||
val rule: RuleChain = RuleChain
|
||||
.outerRule(activityScenarioRule)
|
||||
.around(ScreenLockRule())
|
||||
.around(lockStateTrackingRule)
|
||||
.around(trustAgentRule)
|
||||
|
||||
@Before
|
||||
fun manageTrust() {
|
||||
trustAgentRule.agent.setManagingTrust(true)
|
||||
trustManager.registerTrustListener(listener)
|
||||
}
|
||||
|
||||
@After
|
||||
fun unregisterListener() {
|
||||
trustManager.unregisterTrustListener(listener)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun defaultState_isActiveUnlockRunningIsFalse() {
|
||||
assertThat(trustManager.isActiveUnlockRunning(userId)).isFalse()
|
||||
assertThat(listener.isRunning).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun grantTrustLockedDevice_isActiveUnlockRunningIsFalse() {
|
||||
uiDevice.sleep()
|
||||
lockStateTrackingRule.assertLocked()
|
||||
|
||||
uiDevice.wakeUp()
|
||||
trustAgentRule.agent.grantTrust(
|
||||
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
|
||||
|
||||
assertThat(trustManager.isActiveUnlockRunning(userId)).isFalse()
|
||||
assertThat(listener.isRunning).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun grantTrustUnlockedDevice_isActiveUnlockRunningIsTrueWhileLocked() {
|
||||
trustAgentRule.agent.grantTrust(
|
||||
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
|
||||
uiDevice.sleep()
|
||||
|
||||
lockStateTrackingRule.assertLocked()
|
||||
|
||||
assertThat(trustManager.isActiveUnlockRunning(userId)).isTrue()
|
||||
assertThat(listener.isRunning).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun trustRevoked_isActiveUnlockRunningIsFalse() {
|
||||
trustAgentRule.agent.grantTrust(
|
||||
GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
|
||||
|
||||
trustAgentRule.agent.revokeTrust()
|
||||
|
||||
assertThat(trustManager.isActiveUnlockRunning(userId)).isFalse()
|
||||
assertThat(listener.isRunning).isFalse()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GRANT_MESSAGE = "granted by test"
|
||||
private fun await(millis: Long) = Thread.sleep(millis)
|
||||
}
|
||||
}
|
||||
|
||||
class IsActiveUnlockRunningTrustAgent : BaseTrustAgentService()
|
||||
@@ -17,7 +17,6 @@
|
||||
package android.trust.test.lib
|
||||
|
||||
import android.app.trust.TrustManager
|
||||
import android.app.trust.TrustManager.TrustListener
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import android.view.WindowManagerGlobal
|
||||
@@ -60,7 +59,7 @@ class LockStateTrackingRule : TestRule {
|
||||
wait("locked per TrustListener") { lockState.locked == false }
|
||||
}
|
||||
|
||||
inner class Listener : TrustListener {
|
||||
inner class Listener : TestTrustListener() {
|
||||
override fun onTrustChanged(
|
||||
enabled: Boolean,
|
||||
newlyUnlocked: Boolean,
|
||||
@@ -71,15 +70,6 @@ class LockStateTrackingRule : TestRule {
|
||||
Log.d(TAG, "Device became trusted=$enabled")
|
||||
lockState = lockState.copy(locked = !enabled)
|
||||
}
|
||||
|
||||
override fun onTrustManagedChanged(enabled: Boolean, userId: Int) {
|
||||
}
|
||||
|
||||
override fun onTrustError(message: CharSequence) {
|
||||
}
|
||||
|
||||
override fun onEnabledTrustAgentsChanged(userId: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
data class LockState(
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.trust.test.lib
|
||||
|
||||
import android.app.trust.TrustManager.TrustListener
|
||||
|
||||
/**
|
||||
* A listener that has default empty implementations for all [TrustListener] methods.
|
||||
*/
|
||||
open class TestTrustListener : TrustListener {
|
||||
override fun onTrustChanged(
|
||||
enabled: Boolean,
|
||||
newlyUnlocked: Boolean,
|
||||
userId: Int,
|
||||
flags: Int,
|
||||
trustGrantedMessages: MutableList<String>
|
||||
) {
|
||||
}
|
||||
|
||||
override fun onTrustManagedChanged(enabled: Boolean, userId: Int) {
|
||||
}
|
||||
|
||||
override fun onTrustError(message: CharSequence) {
|
||||
}
|
||||
|
||||
override fun onEnabledTrustAgentsChanged(userId: Int) {
|
||||
}
|
||||
|
||||
override fun onIsActiveUnlockRunningChanged(isRunning: Boolean, userId: Int) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user