diff options
12 files changed, 274 insertions, 87 deletions
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl index e4ac01195bcb..8d4478493b13 100644 --- a/core/java/android/app/trust/ITrustListener.aidl +++ b/core/java/android/app/trust/ITrustListener.aidl @@ -24,6 +24,7 @@ import java.util.List; * {@hide} */ oneway interface ITrustListener { + void onEnabledTrustAgentsChanged(int userId); void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags, in List<String> trustGrantedMessages); void onTrustManagedChanged(boolean managed, int userId); diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 62f755d0268c..3552ce0e5889 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -43,6 +43,7 @@ public class TrustManager { 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 String TAG = "TrustManager"; private static final String DATA_FLAGS = "initiatedByUser"; @@ -187,6 +188,13 @@ public class TrustManager { } @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(); @@ -283,6 +291,10 @@ public class TrustManager { 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; } } }; @@ -316,5 +328,10 @@ public class TrustManager { * @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); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index a08f540bb1b1..6507488c73f5 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -549,6 +549,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab dispatchErrorMessage(message); } + @Override + public void onEnabledTrustAgentsChanged(int userId) { + Assert.isMainThread(); + + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onEnabledTrustAgentsChanged(userId); + } + } + } + private void handleSimSubscriptionInfoChanged() { Assert.isMainThread(); mLogger.v("onSubscriptionInfoChanged()"); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index feff216310df..73940055c89f 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -322,4 +322,9 @@ public class KeyguardUpdateMonitorCallback { * Called when keyguard is going away or not going away. */ public void onKeyguardGoingAway() { } + + /** + * Called when the enabled trust agents associated with the specified user. + */ + public void onEnabledTrustAgentsChanged(int userId) { } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt index d90f328719bb..e912053a85ca 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt @@ -75,6 +75,8 @@ constructor( override fun onTrustError(message: CharSequence?) = Unit override fun onTrustManagedChanged(enabled: Boolean, userId: Int) = Unit + + override fun onEnabledTrustAgentsChanged(userId: Int) = Unit } trustManager.registerTrustListener(callback) logger.trustListenerRegistered() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java index f1269f2b012a..f4cf4eff8a7a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java @@ -452,5 +452,10 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum public void onBiometricsCleared() { update(false /* alwaysUpdate */); } + + @Override + public void onEnabledTrustAgentsChanged(int userId) { + update(false /* updateAlways */); + } } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index b1051af4ad15..417eb40eab54 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -144,6 +144,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; @@ -722,6 +723,18 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test + public void testOnEnabledTrustAgentsChangedCallback() { + final Random random = new Random(); + final int userId = random.nextInt(); + final KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class); + + mKeyguardUpdateMonitor.registerCallback(callback); + mKeyguardUpdateMonitor.onEnabledTrustAgentsChanged(userId); + + verify(callback).onEnabledTrustAgentsChanged(eq(userId)); + } + + @Test public void trustAgentHasTrust_fingerprintLockout() { // GIVEN user has trust mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java index 8f363efd9f51..d787ada90a73 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java @@ -31,18 +31,23 @@ import androidx.test.filters.SmallTest; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.logging.KeyguardUpdateMonitorLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; +import dagger.Lazy; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import dagger.Lazy; +import java.util.Random; + @SmallTest @TestableLooper.RunWithLooper @@ -169,4 +174,19 @@ public class KeyguardStateControllerTest extends SysuiTestCase { verify(callback).onKeyguardDismissAmountChanged(); } + @Test + public void testOnEnabledTrustAgentsChangedCallback() { + final Random random = new Random(); + final ArgumentCaptor<KeyguardUpdateMonitorCallback> updateCallbackCaptor = + ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); + + verify(mKeyguardUpdateMonitor).registerCallback(updateCallbackCaptor.capture()); + final KeyguardStateController.Callback stateCallback = + mock(KeyguardStateController.Callback.class); + mKeyguardStateController.addCallback(stateCallback); + + when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); + updateCallbackCaptor.getValue().onEnabledTrustAgentsChanged(random.nextInt()); + verify(stateCallback).onUnlockedChanged(); + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java index 846c2d9f3df7..a53d09678cd3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java @@ -433,6 +433,11 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage } @Override + public void onEnabledTrustAgentsChanged(int userId) { + + } + + @Override @NonNull public List<FingerprintSensorPropertiesInternal> getSensorProperties() { final List<FingerprintSensorPropertiesInternal> properties = new ArrayList<>(); diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 2ef82d74ee37..e3abf0c43397 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -53,6 +53,7 @@ import android.os.Bundle; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.RemoteException; @@ -150,6 +151,8 @@ public class TrustManagerService extends SystemService { private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>(); private final Receiver mReceiver = new Receiver(); + private final Handler mHandler; + /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; private final LockPatternUtils mLockPatternUtils; @@ -240,13 +243,40 @@ public class TrustManagerService extends SystemService { private boolean mTrustAgentsCanRun = false; private int mCurrentUser = UserHandle.USER_SYSTEM; + /** + * A class for providing dependencies to {@link TrustManagerService} in both production and test + * cases. + */ + protected static class Injector { + private final LockPatternUtils mLockPatternUtils; + private final Looper mLooper; + + public Injector(LockPatternUtils lockPatternUtils, Looper looper) { + mLockPatternUtils = lockPatternUtils; + mLooper = looper; + } + + LockPatternUtils getLockPatternUtils() { + return mLockPatternUtils; + } + + Looper getLooper() { + return mLooper; + } + } + public TrustManagerService(Context context) { + this(context, new Injector(new LockPatternUtils(context), Looper.myLooper())); + } + + protected TrustManagerService(Context context, Injector injector) { super(context); mContext = context; + mHandler = createHandler(injector.getLooper()); mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - mLockPatternUtils = new LockPatternUtils(context); - mStrongAuthTracker = new StrongAuthTracker(context); + mLockPatternUtils = injector.getLockPatternUtils(); + mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper()); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mSettingsObserver = new SettingsObserver(mHandler); } @@ -1392,6 +1422,23 @@ public class TrustManagerService extends SystemService { } } + private void dispatchOnEnabledTrustAgentsChanged(int userId) { + if (DEBUG) { + Log.i(TAG, "onEnabledTrustAgentsChanged(" + userId + ")"); + } + for (int i = 0; i < mTrustListeners.size(); i++) { + try { + mTrustListeners.get(i).onEnabledTrustAgentsChanged(userId); + } catch (DeadObjectException e) { + Slog.d(TAG, "Removing dead TrustListener."); + mTrustListeners.remove(i); + i--; + } catch (RemoteException e) { + Slog.e(TAG, "Exception while notifying TrustListener.", e); + } + } + } + private void dispatchOnTrustManagedChanged(boolean managed, int userId) { if (DEBUG) { Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")"); @@ -1495,9 +1542,7 @@ public class TrustManagerService extends SystemService { @Override public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException { enforceReportPermission(); - // coalesce refresh messages. - mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED); - mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED); + mHandler.obtainMessage(MSG_ENABLED_AGENTS_CHANGED, userId, 0).sendToTarget(); } @Override @@ -1808,88 +1853,91 @@ public class TrustManagerService extends SystemService { } } - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_REGISTER_LISTENER: - addListener((ITrustListener) msg.obj); - break; - case MSG_UNREGISTER_LISTENER: - removeListener((ITrustListener) msg.obj); - break; - case MSG_DISPATCH_UNLOCK_ATTEMPT: - dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2); - break; - case MSG_USER_REQUESTED_UNLOCK: - dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0); - break; - case MSG_USER_MAY_REQUEST_UNLOCK: - dispatchUserMayRequestUnlock(msg.arg1); - break; - case MSG_DISPATCH_UNLOCK_LOCKOUT: - dispatchUnlockLockout(msg.arg1, msg.arg2); - break; - case MSG_ENABLED_AGENTS_CHANGED: - refreshAgentList(UserHandle.USER_ALL); - // This is also called when the security mode of a user changes. - refreshDeviceLockedForUser(UserHandle.USER_ALL); - break; - case MSG_KEYGUARD_SHOWING_CHANGED: - dispatchTrustableDowngrade(); - refreshDeviceLockedForUser(mCurrentUser); - break; - case MSG_START_USER: - case MSG_CLEANUP_USER: - case MSG_UNLOCK_USER: - refreshAgentList(msg.arg1); - break; - case MSG_SWITCH_USER: - mCurrentUser = msg.arg1; - mSettingsObserver.updateContentObserver(); - refreshDeviceLockedForUser(UserHandle.USER_ALL); - break; - case MSG_STOP_USER: - setDeviceLockedForUser(msg.arg1, true); - break; - case MSG_FLUSH_TRUST_USUALLY_MANAGED: - SparseBooleanArray usuallyManaged; - synchronized (mTrustUsuallyManagedForUser) { - usuallyManaged = mTrustUsuallyManagedForUser.clone(); - } + private Handler createHandler(Looper looper) { + return new Handler(looper) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_REGISTER_LISTENER: + addListener((ITrustListener) msg.obj); + break; + case MSG_UNREGISTER_LISTENER: + removeListener((ITrustListener) msg.obj); + break; + case MSG_DISPATCH_UNLOCK_ATTEMPT: + dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2); + break; + case MSG_USER_REQUESTED_UNLOCK: + dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0); + break; + case MSG_USER_MAY_REQUEST_UNLOCK: + dispatchUserMayRequestUnlock(msg.arg1); + break; + case MSG_DISPATCH_UNLOCK_LOCKOUT: + dispatchUnlockLockout(msg.arg1, msg.arg2); + break; + case MSG_ENABLED_AGENTS_CHANGED: + refreshAgentList(UserHandle.USER_ALL); + // This is also called when the security mode of a user changes. + refreshDeviceLockedForUser(UserHandle.USER_ALL); + dispatchOnEnabledTrustAgentsChanged(msg.arg1); + break; + case MSG_KEYGUARD_SHOWING_CHANGED: + dispatchTrustableDowngrade(); + refreshDeviceLockedForUser(mCurrentUser); + break; + case MSG_START_USER: + case MSG_CLEANUP_USER: + case MSG_UNLOCK_USER: + refreshAgentList(msg.arg1); + break; + case MSG_SWITCH_USER: + mCurrentUser = msg.arg1; + mSettingsObserver.updateContentObserver(); + refreshDeviceLockedForUser(UserHandle.USER_ALL); + break; + case MSG_STOP_USER: + setDeviceLockedForUser(msg.arg1, true); + break; + case MSG_FLUSH_TRUST_USUALLY_MANAGED: + SparseBooleanArray usuallyManaged; + synchronized (mTrustUsuallyManagedForUser) { + usuallyManaged = mTrustUsuallyManagedForUser.clone(); + } - for (int i = 0; i < usuallyManaged.size(); i++) { - int userId = usuallyManaged.keyAt(i); - boolean value = usuallyManaged.valueAt(i); - if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) { - mLockPatternUtils.setTrustUsuallyManaged(value, userId); + for (int i = 0; i < usuallyManaged.size(); i++) { + int userId = usuallyManaged.keyAt(i); + boolean value = usuallyManaged.valueAt(i); + if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) { + mLockPatternUtils.setTrustUsuallyManaged(value, userId); + } } - } - break; - case MSG_REFRESH_DEVICE_LOCKED_FOR_USER: - if (msg.arg2 == 1) { - updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null); - } - final int unlockedUser = msg.getData().getInt( - REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL); - refreshDeviceLockedForUser(msg.arg1, unlockedUser); - break; - case MSG_SCHEDULE_TRUST_TIMEOUT: - boolean shouldOverride = msg.arg1 == 1 ? true : false; - TimeoutType timeoutType = - msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED; - handleScheduleTrustTimeout(shouldOverride, timeoutType); - break; - case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH: - TrustableTimeoutAlarmListener trustableAlarm = - mTrustableTimeoutAlarmListenerForUser.get(msg.arg1); - if (trustableAlarm != null && trustableAlarm.isQueued()) { - refreshTrustableTimers(msg.arg1); - } - break; + break; + case MSG_REFRESH_DEVICE_LOCKED_FOR_USER: + if (msg.arg2 == 1) { + updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null); + } + final int unlockedUser = msg.getData().getInt( + REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL); + refreshDeviceLockedForUser(msg.arg1, unlockedUser); + break; + case MSG_SCHEDULE_TRUST_TIMEOUT: + boolean shouldOverride = msg.arg1 == 1 ? true : false; + TimeoutType timeoutType = + msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED; + handleScheduleTrustTimeout(shouldOverride, timeoutType); + break; + case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH: + TrustableTimeoutAlarmListener trustableAlarm = + mTrustableTimeoutAlarmListenerForUser.get(msg.arg1); + if (trustableAlarm != null && trustableAlarm.isQueued()) { + refreshTrustableTimers(msg.arg1); + } + break; + } } - } - }; + }; + } private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override @@ -1987,8 +2035,8 @@ public class TrustManagerService extends SystemService { SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray(); - public StrongAuthTracker(Context context) { - super(context); + StrongAuthTracker(Context context, Looper looper) { + super(context, looper); } @Override diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java index 33870f1d3b86..9851bc1b4be3 100644 --- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java @@ -16,15 +16,26 @@ package com.android.server.trust; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyBoolean; + +import android.Manifest; import android.annotation.Nullable; +import android.app.trust.ITrustListener; +import android.app.trust.ITrustManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -36,11 +47,16 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.UserHandle; import android.os.test.TestLooper; import android.provider.Settings; import android.service.trust.TrustAgentService; import android.testing.TestableContext; +import android.view.IWindowManager; +import android.view.WindowManagerGlobal; import androidx.test.core.app.ApplicationProvider; @@ -55,13 +71,16 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; +import org.mockito.MockitoSession; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.ArrayList; import java.util.Collections; +import java.util.Random; public class TrustManagerServiceTest { @@ -255,6 +274,43 @@ public class TrustManagerServiceTest { systemTrustAgent1); } + @Test + public void reportEnabledTrustAgentsChangedInformsListener() throws RemoteException { + final LockPatternUtils utils = mock(LockPatternUtils.class); + final TrustManagerService service = new TrustManagerService(mMockContext, + new TrustManagerService.Injector(utils, mLooper.getLooper())); + final ITrustListener trustListener = mock(ITrustListener.class); + final IWindowManager windowManager = mock(IWindowManager.class); + final int userId = new Random().nextInt(); + + mMockContext.getTestablePermissions().setPermission(Manifest.permission.TRUST_LISTENER, + PERMISSION_GRANTED); + + when(utils.getKnownTrustAgents(anyInt())).thenReturn(new ArrayList<>()); + + MockitoSession mockSession = mockitoSession() + .initMocks(this) + .mockStatic(ServiceManager.class) + .mockStatic(WindowManagerGlobal.class) + .startMocking(); + + doReturn(windowManager).when(() -> { + WindowManagerGlobal.getWindowManagerService(); + }); + + service.onStart(); + ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class); + verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE), + binderArgumentCaptor.capture(), anyBoolean(), anyInt())); + ITrustManager manager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue()); + manager.registerTrustListener(trustListener); + mLooper.dispatchAll(); + manager.reportEnabledTrustAgentsChanged(userId); + mLooper.dispatchAll(); + verify(trustListener).onEnabledTrustAgentsChanged(eq(userId)); + mockSession.finishMocking(); + } + private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) { ApplicationInfo applicationInfo = new ApplicationInfo(); if (isSystemApp) { diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt index 583cfc781bd0..fe47fde9b268 100644 --- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt +++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt @@ -96,6 +96,9 @@ class LockStateTrackingRule : TestRule { override fun onTrustError(message: CharSequence) { } + + override fun onEnabledTrustAgentsChanged(userId: Int) { + } } data class TrustState( |