Move LockSettingsService into locksettings package.

This service now has a large number of support classes so move them into
their own package to keep things tidy and easier to refactor.

Bug: 37090873
Test: runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
Test: runtest frameworks-services -c com.android.server.locksettings.LockSettingsShellCommandTest
Test: runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
Change-Id: Ic3cd00e6565749defd74498a3491c3d9b914ad90
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
new file mode 100644
index 0000000..d1fb28a
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2016 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 com.android.server.locksettings;
+
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+import static com.android.internal.widget.LockPatternUtils.stringToPattern;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+
+class LockSettingsShellCommand extends ShellCommand {
+
+    private static final String COMMAND_SET_PATTERN = "set-pattern";
+    private static final String COMMAND_SET_PIN = "set-pin";
+    private static final String COMMAND_SET_PASSWORD = "set-password";
+    private static final String COMMAND_CLEAR = "clear";
+    private static final String COMMAND_SP = "sp";
+    private static final String COMMAND_SET_DISABLED = "set-disabled";
+
+    private int mCurrentUserId;
+    private final LockPatternUtils mLockPatternUtils;
+    private final Context mContext;
+    private String mOld = "";
+    private String mNew = "";
+
+    LockSettingsShellCommand(Context context, LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        try {
+            mCurrentUserId = ActivityManager.getService().getCurrentUser().id;
+
+            parseArgs();
+            if (!checkCredential()) {
+                return -1;
+            }
+            switch (cmd) {
+                case COMMAND_SET_PATTERN:
+                    runSetPattern();
+                    break;
+                case COMMAND_SET_PASSWORD:
+                    runSetPassword();
+                    break;
+                case COMMAND_SET_PIN:
+                    runSetPin();
+                    break;
+                case COMMAND_CLEAR:
+                    runClear();
+                    break;
+                case COMMAND_SP:
+                    runEnableSp();
+                    break;
+                case COMMAND_SET_DISABLED:
+                    runSetDisabled();
+                    break;
+                default:
+                    getErrPrintWriter().println("Unknown command: " + cmd);
+                    break;
+            }
+            return 0;
+        } catch (Exception e) {
+            getErrPrintWriter().println("Error while executing command: " + cmd);
+            e.printStackTrace(getErrPrintWriter());
+            return -1;
+        }
+    }
+
+    @Override
+    public void onHelp() {
+    }
+
+    private void parseArgs() {
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            if ("--old".equals(opt)) {
+                mOld = getNextArgRequired();
+            } else if ("--user".equals(opt)) {
+                mCurrentUserId = Integer.parseInt(getNextArgRequired());
+            } else {
+                getErrPrintWriter().println("Unknown option: " + opt);
+                throw new IllegalArgumentException();
+            }
+        }
+        mNew = getNextArg();
+    }
+
+    private void runEnableSp() {
+        if (mNew != null) {
+            mLockPatternUtils.enableSyntheticPassword();
+            getOutPrintWriter().println("Synthetic password enabled");
+        }
+        getOutPrintWriter().println(String.format("SP Enabled = %b",
+                mLockPatternUtils.isSyntheticPasswordEnabled()));
+    }
+
+    private void runSetPattern() throws RemoteException {
+        mLockPatternUtils.saveLockPattern(stringToPattern(mNew), mOld, mCurrentUserId);
+        getOutPrintWriter().println("Pattern set to '" + mNew + "'");
+    }
+
+    private void runSetPassword() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_ALPHABETIC, mCurrentUserId);
+        getOutPrintWriter().println("Password set to '" + mNew + "'");
+    }
+
+    private void runSetPin() throws RemoteException {
+        mLockPatternUtils.saveLockPassword(mNew, mOld, PASSWORD_QUALITY_NUMERIC, mCurrentUserId);
+        getOutPrintWriter().println("Pin set to '" + mNew + "'");
+    }
+
+    private void runClear() throws RemoteException {
+        mLockPatternUtils.clearLock(mOld, mCurrentUserId);
+        getOutPrintWriter().println("Lock credential cleared");
+    }
+
+    private void runSetDisabled() throws RemoteException {
+        final boolean disabled = Boolean.parseBoolean(mNew);
+        mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
+        getOutPrintWriter().println("Lock screen disabled set to " + disabled);
+    }
+
+    private boolean checkCredential() throws RemoteException, RequestThrottledException {
+        final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
+        final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
+        if (havePassword || havePattern) {
+            boolean result;
+            if (havePassword) {
+                result = mLockPatternUtils.checkPassword(mOld, mCurrentUserId);
+            } else {
+                result = mLockPatternUtils.checkPattern(stringToPattern(mOld),
+                        mCurrentUserId);
+            }
+            if (result) {
+                return true;
+            } else {
+                getOutPrintWriter().println("Old password '" + mOld + "' didn't match");
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+}