diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index d78aaa5..fe18fbf 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -27,6 +27,7 @@
 import android.os.SystemProperties;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.SystemService;
 
 import libcore.io.IoUtils;
@@ -35,6 +36,7 @@
 import java.io.DataOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * The recovery system service is responsible for coordinating recovery related
@@ -43,7 +45,7 @@
  * triggers /system/bin/uncrypt via init to de-encrypt an OTA package on the
  * /data partition so that it can be accessed under the recovery image.
  */
-public final class RecoverySystemService extends SystemService {
+public class RecoverySystemService extends IRecoverySystem.Stub {
     private static final String TAG = "RecoverySystemService";
     private static final boolean DEBUG = false;
 
@@ -51,191 +53,321 @@
     private static final String UNCRYPT_SOCKET = "uncrypt";
 
     // The init services that communicate with /system/bin/uncrypt.
-    private static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
-    private static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
-    private static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
-
-    private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
+    @VisibleForTesting
+    static final String INIT_SERVICE_UNCRYPT = "init.svc.uncrypt";
+    @VisibleForTesting
+    static final String INIT_SERVICE_SETUP_BCB = "init.svc.setup-bcb";
+    @VisibleForTesting
+    static final String INIT_SERVICE_CLEAR_BCB = "init.svc.clear-bcb";
 
     private static final Object sRequestLock = new Object();
 
-    private Context mContext;
+    private static final int SOCKET_CONNECTION_MAX_RETRY = 30;
 
-    public RecoverySystemService(Context context) {
-        super(context);
-        mContext = context;
+    private final Injector mInjector;
+    private final Context mContext;
+
+    static class Injector {
+        protected final Context mContext;
+
+        Injector(Context context) {
+            mContext = context;
+        }
+
+        public Context getContext() {
+            return mContext;
+        }
+
+        public PowerManager getPowerManager() {
+            return (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        }
+
+        public String systemPropertiesGet(String key) {
+            return SystemProperties.get(key);
+        }
+
+        public void systemPropertiesSet(String key, String value) {
+            SystemProperties.set(key, value);
+        }
+
+        public boolean uncryptPackageFileDelete() {
+            return RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+        }
+
+        public String getUncryptPackageFileName() {
+            return RecoverySystem.UNCRYPT_PACKAGE_FILE.getName();
+        }
+
+        public FileWriter getUncryptPackageFileWriter() throws IOException {
+            return new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE);
+        }
+
+        public UncryptSocket connectService() {
+            UncryptSocket socket = new UncryptSocket();
+            if (!socket.connectService()) {
+                socket.close();
+                return null;
+            }
+            return socket;
+        }
+
+        public void threadSleep(long millis) throws InterruptedException {
+            Thread.sleep(millis);
+        }
     }
 
-    @Override
-    public void onStart() {
-        publishBinderService(Context.RECOVERY_SERVICE, new BinderService());
+    /**
+     * Handles the lifecycle events for the RecoverySystemService.
+     */
+    public static final class Lifecycle extends SystemService {
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            RecoverySystemService recoverySystemService = new RecoverySystemService(getContext());
+            publishBinderService(Context.RECOVERY_SERVICE, recoverySystemService);
+        }
     }
 
-    private final class BinderService extends IRecoverySystem.Stub {
-        @Override // Binder call
-        public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
-            if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
+    private RecoverySystemService(Context context) {
+        this(new Injector(context));
+    }
 
-            synchronized (sRequestLock) {
-                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+    @VisibleForTesting
+    RecoverySystemService(Injector injector) {
+        mInjector = injector;
+        mContext = injector.getContext();
+    }
 
-                final boolean available = checkAndWaitForUncryptService();
-                if (!available) {
-                    Slog.e(TAG, "uncrypt service is unavailable.");
-                    return false;
-                }
+    @Override // Binder call
+    public boolean uncrypt(String filename, IRecoverySystemProgressListener listener) {
+        if (DEBUG) Slog.d(TAG, "uncrypt: " + filename);
 
-                // Write the filename into UNCRYPT_PACKAGE_FILE to be read by
-                // uncrypt.
-                RecoverySystem.UNCRYPT_PACKAGE_FILE.delete();
+        synchronized (sRequestLock) {
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
-                try (FileWriter uncryptFile = new FileWriter(RecoverySystem.UNCRYPT_PACKAGE_FILE)) {
-                    uncryptFile.write(filename + "\n");
-                } catch (IOException e) {
-                    Slog.e(TAG, "IOException when writing \"" +
-                            RecoverySystem.UNCRYPT_PACKAGE_FILE + "\":", e);
-                    return false;
-                }
+            if (!checkAndWaitForUncryptService()) {
+                Slog.e(TAG, "uncrypt service is unavailable.");
+                return false;
+            }
 
-                // Trigger uncrypt via init.
-                SystemProperties.set("ctl.start", "uncrypt");
+            // Write the filename into uncrypt package file to be read by
+            // uncrypt.
+            mInjector.uncryptPackageFileDelete();
 
-                // Connect to the uncrypt service socket.
-                LocalSocket socket = connectService();
-                if (socket == null) {
-                    Slog.e(TAG, "Failed to connect to uncrypt socket");
-                    return false;
-                }
+            try (FileWriter uncryptFile = mInjector.getUncryptPackageFileWriter()) {
+                uncryptFile.write(filename + "\n");
+            } catch (IOException e) {
+                Slog.e(TAG, "IOException when writing \""
+                        + mInjector.getUncryptPackageFileName() + "\":", e);
+                return false;
+            }
 
-                // Read the status from the socket.
-                DataInputStream dis = null;
-                DataOutputStream dos = null;
-                try {
-                    dis = new DataInputStream(socket.getInputStream());
-                    dos = new DataOutputStream(socket.getOutputStream());
-                    int lastStatus = Integer.MIN_VALUE;
-                    while (true) {
-                        int status = dis.readInt();
-                        // Avoid flooding the log with the same message.
-                        if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
-                            continue;
-                        }
-                        lastStatus = status;
+            // Trigger uncrypt via init.
+            mInjector.systemPropertiesSet("ctl.start", "uncrypt");
 
-                        if (status >= 0 && status <= 100) {
-                            // Update status
-                            Slog.i(TAG, "uncrypt read status: " + status);
-                            if (listener != null) {
-                                try {
-                                    listener.onProgress(status);
-                                } catch (RemoteException ignored) {
-                                    Slog.w(TAG, "RemoteException when posting progress");
-                                }
-                            }
-                            if (status == 100) {
-                                Slog.i(TAG, "uncrypt successfully finished.");
-                                // Ack receipt of the final status code. uncrypt
-                                // waits for the ack so the socket won't be
-                                // destroyed before we receive the code.
-                                dos.writeInt(0);
-                                break;
-                            }
-                        } else {
-                            // Error in /system/bin/uncrypt.
-                            Slog.e(TAG, "uncrypt failed with status: " + status);
-                            // Ack receipt of the final status code. uncrypt waits
-                            // for the ack so the socket won't be destroyed before
-                            // we receive the code.
-                            dos.writeInt(0);
-                            return false;
-                        }
+            // Connect to the uncrypt service socket.
+            UncryptSocket socket = mInjector.connectService();
+            if (socket == null) {
+                Slog.e(TAG, "Failed to connect to uncrypt socket");
+                return false;
+            }
+
+            // Read the status from the socket.
+            try {
+                int lastStatus = Integer.MIN_VALUE;
+                while (true) {
+                    int status = socket.getPercentageUncrypted();
+                    // Avoid flooding the log with the same message.
+                    if (status == lastStatus && lastStatus != Integer.MIN_VALUE) {
+                        continue;
                     }
-                } catch (IOException e) {
-                    Slog.e(TAG, "IOException when reading status: ", e);
-                    return false;
-                } finally {
-                    IoUtils.closeQuietly(dis);
-                    IoUtils.closeQuietly(dos);
-                    IoUtils.closeQuietly(socket);
-                }
+                    lastStatus = status;
 
+                    if (status >= 0 && status <= 100) {
+                        // Update status
+                        Slog.i(TAG, "uncrypt read status: " + status);
+                        if (listener != null) {
+                            try {
+                                listener.onProgress(status);
+                            } catch (RemoteException ignored) {
+                                Slog.w(TAG, "RemoteException when posting progress");
+                            }
+                        }
+                        if (status == 100) {
+                            Slog.i(TAG, "uncrypt successfully finished.");
+                            // Ack receipt of the final status code. uncrypt
+                            // waits for the ack so the socket won't be
+                            // destroyed before we receive the code.
+                            socket.sendAck();
+                            break;
+                        }
+                    } else {
+                        // Error in /system/bin/uncrypt.
+                        Slog.e(TAG, "uncrypt failed with status: " + status);
+                        // Ack receipt of the final status code. uncrypt waits
+                        // for the ack so the socket won't be destroyed before
+                        // we receive the code.
+                        socket.sendAck();
+                        return false;
+                    }
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "IOException when reading status: ", e);
+                return false;
+            } finally {
+                socket.close();
+            }
+
+            return true;
+        }
+    }
+
+    @Override // Binder call
+    public boolean clearBcb() {
+        if (DEBUG) Slog.d(TAG, "clearBcb");
+        synchronized (sRequestLock) {
+            return setupOrClearBcb(false, null);
+        }
+    }
+
+    @Override // Binder call
+    public boolean setupBcb(String command) {
+        if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
+        synchronized (sRequestLock) {
+            return setupOrClearBcb(true, command);
+        }
+    }
+
+    @Override // Binder call
+    public void rebootRecoveryWithCommand(String command) {
+        if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+        synchronized (sRequestLock) {
+            if (!setupOrClearBcb(true, command)) {
+                return;
+            }
+
+            // Having set up the BCB, go ahead and reboot.
+            PowerManager pm = mInjector.getPowerManager();
+            pm.reboot(PowerManager.REBOOT_RECOVERY);
+        }
+    }
+
+    /**
+     * Check if any of the init services is still running. If so, we cannot
+     * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
+     * it may break the socket communication since init creates / deletes
+     * the socket (/dev/socket/uncrypt) on service start / exit.
+     */
+    private boolean checkAndWaitForUncryptService() {
+        for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
+            final String uncryptService = mInjector.systemPropertiesGet(INIT_SERVICE_UNCRYPT);
+            final String setupBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_SETUP_BCB);
+            final String clearBcbService = mInjector.systemPropertiesGet(INIT_SERVICE_CLEAR_BCB);
+            final boolean busy = "running".equals(uncryptService)
+                    || "running".equals(setupBcbService) || "running".equals(clearBcbService);
+            if (DEBUG) {
+                Slog.i(TAG, "retry: " + retry + " busy: " + busy
+                        + " uncrypt: [" + uncryptService + "]"
+                        + " setupBcb: [" + setupBcbService + "]"
+                        + " clearBcb: [" + clearBcbService + "]");
+            }
+
+            if (!busy) {
                 return true;
             }
-        }
 
-        @Override // Binder call
-        public boolean clearBcb() {
-            if (DEBUG) Slog.d(TAG, "clearBcb");
-            synchronized (sRequestLock) {
-                return setupOrClearBcb(false, null);
+            try {
+                mInjector.threadSleep(1000);
+            } catch (InterruptedException e) {
+                Slog.w(TAG, "Interrupted:", e);
             }
         }
 
-        @Override // Binder call
-        public boolean setupBcb(String command) {
-            if (DEBUG) Slog.d(TAG, "setupBcb: [" + command + "]");
-            synchronized (sRequestLock) {
-                return setupOrClearBcb(true, command);
-            }
-        }
+        return false;
+    }
 
-        @Override // Binder call
-        public void rebootRecoveryWithCommand(String command) {
-            if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
-            synchronized (sRequestLock) {
-                if (!setupOrClearBcb(true, command)) {
-                    return;
-                }
+    private boolean setupOrClearBcb(boolean isSetup, String command) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
 
-                // Having set up the BCB, go ahead and reboot.
-                PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-                pm.reboot(PowerManager.REBOOT_RECOVERY);
-            }
-        }
-
-        /**
-         * Check if any of the init services is still running. If so, we cannot
-         * start a new uncrypt/setup-bcb/clear-bcb service right away; otherwise
-         * it may break the socket communication since init creates / deletes
-         * the socket (/dev/socket/uncrypt) on service start / exit.
-         */
-        private boolean checkAndWaitForUncryptService() {
-            for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
-                final String uncryptService = SystemProperties.get(INIT_SERVICE_UNCRYPT);
-                final String setupBcbService = SystemProperties.get(INIT_SERVICE_SETUP_BCB);
-                final String clearBcbService = SystemProperties.get(INIT_SERVICE_CLEAR_BCB);
-                final boolean busy = "running".equals(uncryptService) ||
-                        "running".equals(setupBcbService) || "running".equals(clearBcbService);
-                if (DEBUG) {
-                    Slog.i(TAG, "retry: " + retry + " busy: " + busy +
-                            " uncrypt: [" + uncryptService + "]" +
-                            " setupBcb: [" + setupBcbService + "]" +
-                            " clearBcb: [" + clearBcbService + "]");
-                }
-
-                if (!busy) {
-                    return true;
-                }
-
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    Slog.w(TAG, "Interrupted:", e);
-                }
-            }
-
+        final boolean available = checkAndWaitForUncryptService();
+        if (!available) {
+            Slog.e(TAG, "uncrypt service is unavailable.");
             return false;
         }
 
-        private LocalSocket connectService() {
-            LocalSocket socket = new LocalSocket();
+        if (isSetup) {
+            mInjector.systemPropertiesSet("ctl.start", "setup-bcb");
+        } else {
+            mInjector.systemPropertiesSet("ctl.start", "clear-bcb");
+        }
+
+        // Connect to the uncrypt service socket.
+        UncryptSocket socket = mInjector.connectService();
+        if (socket == null) {
+            Slog.e(TAG, "Failed to connect to uncrypt socket");
+            return false;
+        }
+
+        try {
+            // Send the BCB commands if it's to setup BCB.
+            if (isSetup) {
+                socket.sendCommand(command);
+            }
+
+            // Read the status from the socket.
+            int status = socket.getPercentageUncrypted();
+
+            // Ack receipt of the status code. uncrypt waits for the ack so
+            // the socket won't be destroyed before we receive the code.
+            socket.sendAck();
+
+            if (status == 100) {
+                Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear")
+                        + " bcb successfully finished.");
+            } else {
+                // Error in /system/bin/uncrypt.
+                Slog.e(TAG, "uncrypt failed with status: " + status);
+                return false;
+            }
+        } catch (IOException e) {
+            Slog.e(TAG, "IOException when communicating with uncrypt:", e);
+            return false;
+        } finally {
+            socket.close();
+        }
+
+        return true;
+    }
+
+    /**
+     * Provides a wrapper for the low-level details of framing packets sent to the uncrypt
+     * socket.
+     */
+    public static class UncryptSocket {
+        private LocalSocket mLocalSocket;
+        private DataInputStream mInputStream;
+        private DataOutputStream mOutputStream;
+
+        /**
+         * Attempt to connect to the uncrypt service. Connection will be retried for up to
+         * {@link #SOCKET_CONNECTION_MAX_RETRY} times. If the connection is unsuccessful, the
+         * socket will be closed. If the connection is successful, the connection must be closed
+         * by the caller.
+         *
+         * @return true if connection was successful, false if unsuccessful
+         */
+        public boolean connectService() {
+            mLocalSocket = new LocalSocket();
             boolean done = false;
             // The uncrypt socket will be created by init upon receiving the
             // service request. It may not be ready by this point. So we will
             // keep retrying until success or reaching timeout.
             for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
                 try {
-                    socket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
+                    mLocalSocket.connect(new LocalSocketAddress(UNCRYPT_SOCKET,
                             LocalSocketAddress.Namespace.RESERVED));
                     done = true;
                     break;
@@ -249,71 +381,69 @@
             }
             if (!done) {
                 Slog.e(TAG, "Timed out connecting to uncrypt socket");
-                return null;
-            }
-            return socket;
-        }
-
-        private boolean setupOrClearBcb(boolean isSetup, String command) {
-            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
-
-            final boolean available = checkAndWaitForUncryptService();
-            if (!available) {
-                Slog.e(TAG, "uncrypt service is unavailable.");
+                close();
                 return false;
             }
 
-            if (isSetup) {
-                SystemProperties.set("ctl.start", "setup-bcb");
-            } else {
-                SystemProperties.set("ctl.start", "clear-bcb");
-            }
-
-            // Connect to the uncrypt service socket.
-            LocalSocket socket = connectService();
-            if (socket == null) {
-                Slog.e(TAG, "Failed to connect to uncrypt socket");
-                return false;
-            }
-
-            DataInputStream dis = null;
-            DataOutputStream dos = null;
             try {
-                dis = new DataInputStream(socket.getInputStream());
-                dos = new DataOutputStream(socket.getOutputStream());
-
-                // Send the BCB commands if it's to setup BCB.
-                if (isSetup) {
-                    byte[] cmdUtf8 = command.getBytes("UTF-8");
-                    dos.writeInt(cmdUtf8.length);
-                    dos.write(cmdUtf8, 0, cmdUtf8.length);
-                }
-
-                // Read the status from the socket.
-                int status = dis.readInt();
-
-                // Ack receipt of the status code. uncrypt waits for the ack so
-                // the socket won't be destroyed before we receive the code.
-                dos.writeInt(0);
-
-                if (status == 100) {
-                    Slog.i(TAG, "uncrypt " + (isSetup ? "setup" : "clear") +
-                            " bcb successfully finished.");
-                } else {
-                    // Error in /system/bin/uncrypt.
-                    Slog.e(TAG, "uncrypt failed with status: " + status);
-                    return false;
-                }
+                mInputStream = new DataInputStream(mLocalSocket.getInputStream());
+                mOutputStream = new DataOutputStream(mLocalSocket.getOutputStream());
             } catch (IOException e) {
-                Slog.e(TAG, "IOException when communicating with uncrypt:", e);
+                close();
                 return false;
-            } finally {
-                IoUtils.closeQuietly(dis);
-                IoUtils.closeQuietly(dos);
-                IoUtils.closeQuietly(socket);
             }
 
             return true;
         }
+
+        /**
+         * Sends a command to the uncrypt service.
+         *
+         * @param command command to send to the uncrypt service
+         * @throws IOException if the socket is closed or there was an error writing to the socket
+         */
+        public void sendCommand(String command) throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            byte[] cmdUtf8 = command.getBytes(StandardCharsets.UTF_8);
+            mOutputStream.writeInt(cmdUtf8.length);
+            mOutputStream.write(cmdUtf8, 0, cmdUtf8.length);
+        }
+
+        /**
+         * Reads the status from the uncrypt service which is usually represented as a percentage.
+         * @return an integer representing the percentage completed
+         * @throws IOException if the socket was closed or there was an error reading the socket
+         */
+        public int getPercentageUncrypted() throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            return mInputStream.readInt();
+        }
+
+        /**
+         * Sends a confirmation to the uncrypt service.
+         * @throws IOException if the socket was closed or there was an error writing to the socket
+         */
+        public void sendAck() throws IOException {
+            if (mLocalSocket.isClosed()) {
+                throw new IOException("socket is closed");
+            }
+
+            mOutputStream.writeInt(0);
+        }
+
+        /**
+         * Closes the socket and all underlying data streams.
+         */
+        public void close() {
+            IoUtils.closeQuietly(mInputStream);
+            IoUtils.closeQuietly(mOutputStream);
+            IoUtils.closeQuietly(mLocalSocket);
+        }
     }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c1b7a50..313f884 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -699,7 +699,7 @@
 
         // Bring up recovery system in case a rescue party needs a reboot
         traceBeginAndSlog("StartRecoverySystemService");
-        mSystemServiceManager.startService(RecoverySystemService.class);
+        mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
         traceEnd();
 
         // Now that we have the bare essentials of the OS up and running, take
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
new file mode 100644
index 0000000..1f312bf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2019 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.recoverysystem;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.IRecoverySystemProgressListener;
+import android.os.Looper;
+import android.os.PowerManager;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileWriter;
+
+/**
+ * atest FrameworksServicesTests:RecoverySystemServiceTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RecoverySystemServiceTest {
+    private RecoverySystemService mRecoverySystemService;
+    private RecoverySystemServiceTestable.FakeSystemProperties mSystemProperties;
+    private RecoverySystemService.UncryptSocket mUncryptSocket;
+    private Context mContext;
+    private IPowerManager mIPowerManager;
+    private FileWriter mUncryptUpdateFileWriter;
+
+    @Before
+    public void setup() {
+        mContext = mock(Context.class);
+        mSystemProperties = new RecoverySystemServiceTestable.FakeSystemProperties();
+        mUncryptSocket = mock(RecoverySystemService.UncryptSocket.class);
+        mUncryptUpdateFileWriter = mock(FileWriter.class);
+
+        Looper looper = InstrumentationRegistry.getContext().getMainLooper();
+        mIPowerManager = mock(IPowerManager.class);
+        PowerManager powerManager = new PowerManager(mock(Context.class), mIPowerManager,
+                new Handler(looper));
+
+        mRecoverySystemService = new RecoverySystemServiceTestable(mContext, mSystemProperties,
+                powerManager, mUncryptUpdateFileWriter, mUncryptSocket);
+    }
+
+    @Test
+    public void clearBcb_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        assertThat(mRecoverySystemService.clearBcb(), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test
+    public void clearBcb_uncrypt_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        assertThat(mRecoverySystemService.clearBcb(), is(false));
+
+        assertThat(mSystemProperties.getCtlStart(), is("clear-bcb"));
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test(expected = SecurityException.class)
+    public void clearBcb_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.clearBcb();
+    }
+
+    @Test
+    public void setupBcb_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        assertThat(mRecoverySystemService.setupBcb("foo"), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test
+    public void setupBcb_uncrypt_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        assertThat(mRecoverySystemService.setupBcb("foo"), is(false));
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+
+    @Test(expected = SecurityException.class)
+    public void setupBcb_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.setupBcb("foo");
+    }
+
+    @Test
+    public void rebootRecoveryWithCommand_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(100);
+
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+        verify(mIPowerManager).reboot(anyBoolean(), eq("recovery"), anyBoolean());
+    }
+
+    @Test
+    public void rebootRecoveryWithCommand_failure() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0);
+
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+
+        assertThat(mSystemProperties.getCtlStart(), is("setup-bcb"));
+        verify(mUncryptSocket).sendCommand("foo");
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+        verifyNoMoreInteractions(mIPowerManager);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void rebootRecoveryWithCommand_noPerm() {
+        doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        mRecoverySystemService.rebootRecoveryWithCommand("foo");
+    }
+
+    @Test
+    public void uncrypt_success() throws Exception {
+        doNothing().when(mContext).enforceCallingOrSelfPermission(
+                eq(android.Manifest.permission.RECOVERY), any());
+        when(mUncryptSocket.getPercentageUncrypted()).thenReturn(0, 5, 25, 50, 90, 99, 100);
+
+        IRecoverySystemProgressListener listener = mock(IRecoverySystemProgressListener.class);
+        assertThat(mRecoverySystemService.uncrypt("foo.zip", listener), is(true));
+
+        assertThat(mSystemProperties.getCtlStart(), is("uncrypt"));
+        verify(mUncryptSocket, times(7)).getPercentageUncrypted();
+        verify(mUncryptSocket).sendAck();
+        verify(mUncryptSocket).close();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
new file mode 100644
index 0000000..a986b71
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 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.recoverysystem;
+
+import android.content.Context;
+import android.os.PowerManager;
+
+import java.io.FileWriter;
+
+public class RecoverySystemServiceTestable extends RecoverySystemService {
+    private static class MockInjector extends RecoverySystemService.Injector {
+        private final FakeSystemProperties mSystemProperties;
+        private final PowerManager mPowerManager;
+        private final FileWriter mUncryptPackageFileWriter;
+        private final UncryptSocket mUncryptSocket;
+
+        MockInjector(Context context, FakeSystemProperties systemProperties,
+                PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+                UncryptSocket uncryptSocket) {
+            super(context);
+            mSystemProperties = systemProperties;
+            mPowerManager = powerManager;
+            mUncryptPackageFileWriter = uncryptPackageFileWriter;
+            mUncryptSocket = uncryptSocket;
+        }
+
+        @Override
+        public PowerManager getPowerManager() {
+            return mPowerManager;
+        }
+
+        @Override
+        public String systemPropertiesGet(String key) {
+            return mSystemProperties.get(key);
+        }
+
+        @Override
+        public void systemPropertiesSet(String key, String value) {
+            mSystemProperties.set(key, value);
+        }
+
+        @Override
+        public boolean uncryptPackageFileDelete() {
+            return true;
+        }
+
+        @Override
+        public String getUncryptPackageFileName() {
+            return "mock-file.txt";
+        }
+
+        @Override
+        public FileWriter getUncryptPackageFileWriter() {
+            return mUncryptPackageFileWriter;
+        }
+
+        @Override
+        public UncryptSocket connectService() {
+            return mUncryptSocket;
+        }
+
+        @Override
+        public void threadSleep(long millis) {
+        }
+    }
+
+    RecoverySystemServiceTestable(Context context, FakeSystemProperties systemProperties,
+            PowerManager powerManager, FileWriter uncryptPackageFileWriter,
+            UncryptSocket uncryptSocket) {
+        super(new MockInjector(context, systemProperties, powerManager, uncryptPackageFileWriter,
+                uncryptSocket));
+    }
+
+    public static class FakeSystemProperties {
+        private String mCtlStart = null;
+
+        public String get(String key) {
+            if (RecoverySystemService.INIT_SERVICE_UNCRYPT.equals(key)
+                    || RecoverySystemService.INIT_SERVICE_SETUP_BCB.equals(key)
+                    || RecoverySystemService.INIT_SERVICE_CLEAR_BCB.equals(key)) {
+                return null;
+            } else {
+                throw new IllegalArgumentException("unexpected test key: " + key);
+            }
+        }
+
+        public void set(String key, String value) {
+            if ("ctl.start".equals(key)) {
+                mCtlStart = value;
+            } else {
+                throw new IllegalArgumentException("unexpected test key: " + key);
+            }
+        }
+
+        public String getCtlStart() {
+            return mCtlStart;
+        }
+    }
+}
