LockPatternUtilsTest: use dependency injection for ILockSettings

LockPatternUtilsTest is spying on LockPatternUtils to try to inject a
mock ILockSettings.  Using "spy" is an anti-pattern, and it doesn't seem
to work properly as the following test failure occurs:

    [8/17] com.android.internal.util.LockPatternUtilsTest#isLockScreenDisabled_isSecureAndDemoUser_false: FAILED (3ms)

    STACKTRACE:
    java.lang.AssertionError
            at org.junit.Assert.fail(Assert.java:87)
            at org.junit.Assert.assertTrue(Assert.java:42)
            at org.junit.Assert.assertFalse(Assert.java:65)
            at org.junit.Assert.assertFalse(Assert.java:75)
            at com.android.internal.util.LockPatternUtilsTest.isLockScreenDisabled_isSecureAndDemoUser_false(LockPatternUtilsTest.java:148)

This CL fixes the bug by making LockPatternUtils optionally take an
ILockSettings via constructor.

Note: LockPatternUtils#getLockSettings() cannot yet be changed to
private because it actually has a caller in non-test code.

Bug: 321737173
Ignore-AOSP-First: Conflict due to security fix ag/25939141
Flag: NA
Test: atest FrameworksUtilTests:com.android.internal.util.LockPatternUtilsTest
Change-Id: I242d3bdfe62c0be5a40df6028c6d34fad8f0abe2
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 757978b..b5b3a48 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -333,11 +333,17 @@
 
     @UnsupportedAppUsage
     public LockPatternUtils(Context context) {
+        this(context, null);
+    }
+
+    @VisibleForTesting
+    public LockPatternUtils(Context context, ILockSettings lockSettings) {
         mContext = context;
         mContentResolver = context.getContentResolver();
 
         Looper looper = Looper.myLooper();
         mHandler = looper != null ? new Handler(looper) : null;
+        mLockSettingsService = lockSettings;
     }
 
     @UnsupportedAppUsage
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index dcaf676..7b4797a 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -33,7 +33,6 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -99,10 +98,8 @@
                          : LockPatternUtils.CREDENTIAL_TYPE_NONE);
         when(mLockSettings.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED,
                 DEMO_USER_ID)).thenReturn((long) PASSWORD_QUALITY_MANAGED);
-        // TODO(b/63758238): stop spying the class under test
-        mLockPatternUtils = spy(new LockPatternUtils(context));
-        when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
-        doReturn(true).when(mLockPatternUtils).hasSecureLockScreen();
+        when(mLockSettings.hasSecureLockScreen()).thenReturn(true);
+        mLockPatternUtils = new LockPatternUtils(context, mLockSettings);
 
         final UserInfo userInfo = Mockito.mock(UserInfo.class);
         when(userInfo.isDemo()).thenReturn(isDemoUser);
@@ -313,9 +310,8 @@
 
     private ILockSettings createTestLockSettings() {
         final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
-        mLockPatternUtils = spy(new LockPatternUtils(context));
         final ILockSettings ils = Mockito.mock(ILockSettings.class);
-        when(mLockPatternUtils.getLockSettings()).thenReturn(ils);
+        mLockPatternUtils = new LockPatternUtils(context, ils);
         return ils;
     }