diff --git a/services/java/com/android/server/MountListener.java b/services/java/com/android/server/MountListener.java
deleted file mode 100644
index 9443ff8..0000000
--- a/services/java/com/android/server/MountListener.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.lang.IllegalStateException;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Vold Connection class
- */
-final class MountListener implements Runnable {
-    private static final String TAG = "MountListener";
-    private static final String VOLD_SOCKET = "vold";
-    private static final int    RESPONSE_QUEUE_SIZE = 10;
-
-    private MountService          mService;
-    private BlockingQueue<String> mResponseQueue;
-    private OutputStream          mOutputStream;
-
-    class ResponseCode {
-        public static final int ActionInitiated                = 100;
-        public static final int VolumeListResult               = 110;
-        public static final int AsecListResult                 = 111;
-
-        public static final int CommandOkay                    = 200;
-        public static final int ShareAvailabilityResult        = 210;
-        public static final int AsecPathResult                 = 211;
-
-        public static final int UnsolicitedInformational       = 600;
-        public static final int VolumeStateChange              = 605;
-        public static final int VolumeMountFailedBlank         = 610;
-        public static final int VolumeMountFailedDamaged       = 611;
-        public static final int VolumeMountFailedNoMedia       = 612;
-        public static final int ShareAvailabilityChange        = 620;
-        public static final int VolumeDiskInserted             = 630;
-        public static final int VolumeDiskRemoved              = 631;
-        public static final int VolumeBadRemoval               = 632;
-    }
-
-    MountListener(MountService service) {
-        mService = service;
-        mResponseQueue = new LinkedBlockingQueue<String>(RESPONSE_QUEUE_SIZE);
-    }
-
-    public void run() {
-        // Vold does not run in the simulator, so fake out a mounted event to trigger the Media Scanner
-        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
-            mService.notifyMediaMounted(Environment.getExternalStorageDirectory().getPath(), false);
-            return;
-        }
-
-        try {
-            while (true) {
-                listenToSocket();
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "Fatal error " + t + " in MountListener thread!");
-        }
-    }
-
-    private void listenToSocket() {
-       LocalSocket socket = null;
-
-        try {
-            socket = new LocalSocket();
-            LocalSocketAddress address = new LocalSocketAddress(VOLD_SOCKET, 
-                    LocalSocketAddress.Namespace.RESERVED);
-
-            socket.connect(address);
-            mService.onVoldConnected();
-
-            InputStream inputStream = socket.getInputStream();
-            mOutputStream = socket.getOutputStream();
-
-            byte[] buffer = new byte[4096];
-
-            while (true) {
-                int count = inputStream.read(buffer);
-                if (count < 0) break;
-
-                int start = 0;
-                for (int i = 0; i < count; i++) {
-                    if (buffer[i] == 0) {
-                        String event = new String(buffer, start, i - start);
-//                        Log.d(TAG, "Got packet {" + event + "}");
-
-                        String[] tokens = event.split(" ");
-                        try {
-                            int code = Integer.parseInt(tokens[0]);
-
-                            if (code >= ResponseCode.UnsolicitedInformational) {
-                                try {
-                                    handleUnsolicitedEvent(code, event, tokens);
-                                } catch (Exception ex) {
-                                    Log.e(TAG, String.format(
-                                            "Error handling '%s'", event), ex);
-                                }
-                            } else {
-                                try {
-                                    mResponseQueue.put(event);
-                                } catch (InterruptedException ex) {
-                                    Log.e(TAG, "InterruptedException");
-                                }
-                            }
-                        } catch (NumberFormatException nfe) {
-                            Log.w(TAG,
-                                  "Unknown msg from Vold '" + event + "'");
-                        }
-                        start = i + 1;
-                    }                   
-                }
-            }                
-        } catch (IOException ex) {
-            Log.e(TAG, "IOException in listenToSocket");
-        }
-        
-        synchronized (this) {
-            if (mOutputStream != null) {
-                try {
-                    mOutputStream.close();
-                } catch (IOException e) {
-                    Log.w(TAG, "IOException closing output stream");
-                }
-                
-                mOutputStream = null;
-            }
-        }
-        
-        try {
-            if (socket != null) {
-                socket.close();
-            }
-        } catch (IOException ex) {
-            Log.w(TAG, "IOException closing socket");
-        }
-       
-        Log.e(TAG, "Failed to connect to Vold", new IllegalStateException());
-        SystemClock.sleep(5000);
-    }
-
-    private void handleUnsolicitedEvent(int code, String raw,
-                                        String[] cooked) throws IllegalStateException {
-//        Log.d(TAG, "unsolicited {" + raw + "}");
-        if (code == ResponseCode.VolumeStateChange) {
-            // FMT: NNN Volume <label> <mountpoint> state changed from <old_#> (<old_str>) to <new_#> (<new_str>)
-            mService.notifyVolumeStateChange(cooked[2], cooked[3],
-                                             Integer.parseInt(cooked[7]),
-                                             Integer.parseInt(cooked[10]));
-        } else if (code == ResponseCode.VolumeMountFailedBlank) {
-            // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems
-            mService.notifyMediaNoFs(cooked[3]);
-            // FMT: NNN Volume <label> <mountpoint> mount failed - no media
-        } else if (code == ResponseCode.VolumeMountFailedNoMedia) {
-            mService.notifyMediaRemoved(cooked[3]);
-        } else if (code == ResponseCode.VolumeMountFailedDamaged) {
-            // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed
-            mService.notifyMediaUnmountable(cooked[3]);
-        } else if (code == ResponseCode.ShareAvailabilityChange) {
-            // FMT: NNN Share method <method> now <available|unavailable>
-            boolean avail = false;
-            if (cooked[5].equals("available")) {
-                avail = true;
-            }
-            mService.notifyShareAvailabilityChange(cooked[3], avail);
-        } else if (code == ResponseCode.VolumeDiskInserted) {
-            // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>)
-            mService.notifyMediaInserted(cooked[3]);
-        } else if (code == ResponseCode.VolumeDiskRemoved) {
-            // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>)
-            mService.notifyMediaRemoved(cooked[3]);
-        } else if (code == ResponseCode.VolumeBadRemoval) {
-            // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>)
-            mService.notifyMediaBadRemoval(cooked[3]);
-        } else {
-            Log.w(TAG, "Unhandled event {" + raw + "}");
-        }
-    }
-    
-
-    private void sendCommand(String command) {
-        sendCommand(command, null);
-    }
-
-    /**
-     * Sends a command to Vold with a single argument
-     *
-     * @param command  The command to send to the mount service daemon
-     * @param argument The argument to send with the command (or null)
-     */
-    private void sendCommand(String command, String argument) {
-        synchronized (this) {
-            // Log.d(TAG, "sendCommand {" + command + "} {" + argument + "}");
-            if (mOutputStream == null) {
-                Log.e(TAG, "No connection to Vold", new IllegalStateException());
-            } else {
-                StringBuilder builder = new StringBuilder(command);
-                if (argument != null) {
-                    builder.append(argument);
-                }
-                builder.append('\0');
-
-                try {
-                    mOutputStream.write(builder.toString().getBytes());
-                } catch (IOException ex) {
-                    Log.e(TAG, "IOException in sendCommand", ex);
-                }
-            }
-        }
-    }
-
-    private synchronized ArrayList<String> doCommand(String cmd) throws IllegalStateException {
-        sendCommand(cmd);
-
-        ArrayList<String> response = new ArrayList<String>();
-        boolean complete = false;
-        int code = -1;
-
-        while (!complete) {
-            try {
-                String line = mResponseQueue.take();
-//                Log.d(TAG, "Removed off queue -> " + line);
-                String[] tokens = line.split(" ");
-                code = Integer.parseInt(tokens[0]);
-
-                if ((code >= 200) && (code < 600))
-                    complete = true;
-                response.add(line);
-            } catch (InterruptedException ex) {
-                Log.e(TAG, "InterruptedException");
-            }
-        }
-
-        if (code >= 400 && code < 600) {
-            throw new IllegalStateException(String.format(
-                                               "Command %s failed with code %d",
-                                                cmd, code));
-        }
-        return response;
-    }
-
-    boolean getShareAvailable(String method) throws IllegalStateException  {
-        ArrayList<String> rsp = doCommand("share_available " + method);
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == ResponseCode.ShareAvailabilityResult) {
-                if (tok[2].equals("available"))
-                    return true;
-                return false;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
-    }
-
-    /**
-     * Enables or disables USB mass storage support.
-     * 
-     * @param enable  true to enable USB mass storage support
-     */
-    void setShareMethodEnabled(String mountPoint, String method,
-                               boolean enable) throws IllegalStateException {
-        doCommand((enable ? "" : "un") + "share " + mountPoint + " " + method);
-    }
-
-    /**
-     * Mount media at given mount point.
-     */
-    public void mountVolume(String label) throws IllegalStateException {
-        doCommand("mount " + label);
-    }
-
-    /**
-     * Unmount media at given mount point.
-     */
-    public void unmountVolume(String label) throws IllegalStateException {
-        doCommand("unmount " + label);
-    }
-
-    /**
-     * Format media at given mount point.
-     */
-    public void formatVolume(String label) throws IllegalStateException {
-        doCommand("format " + label);
-    }
-
-    public String createAsec(String id, int sizeMb, String fstype, String key,
-                           int ownerUid) throws IllegalStateException {
-        String cmd = String.format("create_asec %s %d %s %s %d",
-                                   id, sizeMb, fstype, key, ownerUid);
-        doCommand(cmd);
-        return getAsecPath(id);
-    }
-
-    public void finalizeAsec(String id) throws IllegalStateException {
-        doCommand("finalize_asec " + id);
-    }
-
-    public void destroyAsec(String id) throws IllegalStateException {
-        doCommand("destroy_asec " + id);
-    }
-
-    public String mountAsec(String id, String key, int ownerUid) throws IllegalStateException {
-        String cmd = String.format("mount_asec %s %s %d",
-                                   id, key, ownerUid);
-        doCommand(cmd);
-        return getAsecPath(id);
-    }
-
-    public String getAsecPath(String id) throws IllegalStateException {
-        ArrayList<String> rsp = doCommand("asec_path " + id);
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == ResponseCode.AsecPathResult) {
-                return tok[1];
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
-    }
-
-    public String[] listAsec() throws IllegalStateException {
-        ArrayList<String> rsp = doCommand("list_asec");
-
-        String[] rdata = new String[rsp.size()];
-        int idx = 0;
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code == ResponseCode.AsecListResult) {
-                rdata[idx++] = tok[1];
-            } else if (code == ResponseCode.CommandOkay) {
-                return rdata;
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
-    }
-}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 81ebe03..c8a6915 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -33,6 +33,7 @@
 import android.os.Handler;
 import android.text.TextUtils;
 import android.util.Log;
+import java.util.ArrayList;
 
 import android.provider.Settings;
 import android.content.ContentResolver;
@@ -46,7 +47,8 @@
  * MountService implements an to the mount service daemon
  * @hide
  */
-class MountService extends IMountService.Stub {
+class MountService extends IMountService.Stub
+        implements INativeDaemonConnectorCallbacks {
     
     private static final String TAG = "MountService";
 
@@ -63,15 +65,33 @@
         public static final int SharedMnt  = 8;
     }
 
+    class VoldResponseCode {
+        public static final int VolumeListResult               = 110;
+        public static final int AsecListResult                 = 111;
+
+        public static final int ShareAvailabilityResult        = 210;
+        public static final int AsecPathResult                 = 211;
+
+        public static final int VolumeStateChange              = 605;
+        public static final int VolumeMountFailedBlank         = 610;
+        public static final int VolumeMountFailedDamaged       = 611;
+        public static final int VolumeMountFailedNoMedia       = 612;
+        public static final int ShareAvailabilityChange        = 620;
+        public static final int VolumeDiskInserted             = 630;
+        public static final int VolumeDiskRemoved              = 631;
+        public static final int VolumeBadRemoval               = 632;
+    }
+
+
     /**
      * Binder context for this service
      */
     private Context mContext;
     
     /**
-     * listener object for communicating with the mount service daemon
+     * connectorr object for communicating with vold
      */
-    private MountListener mListener;
+    private NativeDaemonConnector mConnector;
 
     /**
      * The notification that is shown when a USB mass storage host
@@ -119,12 +139,12 @@
         mContext = context;
 
         // Register a BOOT_COMPLETED handler so that we can start
-        // MountListener. We defer the startup so that we don't
+        // our NativeDaemonConnector. We defer the startup so that we don't
         // start processing events before we ought-to
         mContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
 
-        mListener =  new MountListener(this);       
+        mConnector = new NativeDaemonConnector(this, "vold", 10, "VoldConnector");
         mShowSafeUnmountNotificationWhenUnmounted = false;
 
         mPlaySounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1");
@@ -202,7 +222,18 @@
             String action = intent.getAction();
 
             if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
-                Thread thread = new Thread(mListener, MountListener.class.getName());
+                /*
+                 * Vold does not run in the simulator, so fake out a mounted
+                 * event to trigger MediaScanner
+                 */
+                if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
+                    notifyMediaMounted(
+                            Environment.getExternalStorageDirectory().getPath(), false);
+                    return;
+                }
+
+                Thread thread = new Thread(
+                        mConnector, NativeDaemonConnector.class.getName());
                 thread.start();
             }
         }
@@ -258,7 +289,7 @@
              */
             try {
                 String m = Environment.getExternalStorageDirectory().toString();
-                unmountMedia(m);
+                unmountVolume(m);
 
                 int retries = 12;
                 while (!state.equals(Environment.MEDIA_UNMOUNTED) && (retries-- >=0)) {
@@ -302,17 +333,14 @@
             String vs = getVolumeState(vp);
 
             if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
-                mListener.unmountVolume(vp);
+                unmountVolume(vp);
                 updateUsbMassStorageNotification(true, false);
             }
 
-            mListener.setShareMethodEnabled(Environment
-                                            .getExternalStorageDirectory()
-                                            .getPath(),
-                                            "ums", enable);
+            setShareMethodEnabled(vp, "ums", enable);
             mUmsEnabled = enable;
             if (!enable) {
-                mountMedia(vp);
+                mountVolume(vp);
                 if (mPromptUms) {
                     updateUsbMassStorageNotification(false, false);
                 } else {
@@ -352,19 +380,19 @@
     /**
      * Attempt to mount external media
      */
-    public void mountMedia(String mountPath) throws IllegalStateException {
+    public void mountVolume(String mountPath) throws IllegalStateException {
         if (mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission");
         }
-        mListener.mountVolume(mountPath);
+        mConnector.doCommand(String.format("mount %s", mountPath));
     }
 
     /**
      * Attempt to unmount external media to prepare for eject
      */
-    public void unmountMedia(String mountPath) throws IllegalStateException {
+    public void unmountVolume(String mountPath) throws IllegalStateException {
         if (mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 
                 != PackageManager.PERMISSION_GRANTED) {
@@ -375,23 +403,51 @@
         // to display the notification
         mShowSafeUnmountNotificationWhenUnmounted = true;
 
-        // tell mountd to unmount the media
-        mListener.unmountVolume(mountPath);
+        mConnector.doCommand(String.format("unmount %s", mountPath));
     }
 
     /**
      * Attempt to format external media
      */
-    public void formatMedia(String formatPath) throws IllegalStateException {
+    public void formatVolume(String formatPath) throws IllegalStateException {
         if (mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS) 
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires MOUNT_FORMAT_FILESYSTEMS permission");
         }
 
-        mListener.formatVolume(formatPath);
+        mConnector.doCommand(String.format("format %s", formatPath));
     }
 
+    boolean getShareAvailable(String method) throws IllegalStateException  {
+        ArrayList<String> rsp = mConnector.doCommand("share_available " + method);
+
+        for (String line : rsp) {
+            String []tok = line.split(" ");
+            int code = Integer.parseInt(tok[0]);
+            if (code == VoldResponseCode.ShareAvailabilityResult) {
+                if (tok[2].equals("available"))
+                    return true;
+                return false;
+            } else {
+                throw new IllegalStateException(String.format("Unexpected response code %d", code));
+            }
+        }
+        throw new IllegalStateException("Got an empty response");
+    }
+
+    /**
+     * Enables or disables USB mass storage support.
+     * 
+     * @param enable  true to enable USB mass storage support
+     */
+    void setShareMethodEnabled(String mountPoint, String method,
+                               boolean enable) throws IllegalStateException {
+        mConnector.doCommand(String.format(
+                "%sshare %s %s", (enable ? "" : "un"), mountPoint, method));
+    }
+
+
     /**
      * Returns true if we're playing media notification sounds.
      */
@@ -417,7 +473,7 @@
             Log.w(TAG, "Multiple volumes not currently supported");
             return;
         }
-        Log.w(TAG, "State for {" + mountPoint + "} = {" + state + "}");
+        Log.i(TAG, "State for {" + mountPoint + "} = {" + state + "}");
         mLegacyState = state;
     }
 
@@ -455,14 +511,18 @@
         }
     }
 
-    void onVoldConnected() {
+    /**
+     *
+     * Callback from NativeDaemonConnector
+     */
+    public void onDaemonConnected() {
         new Thread() {
             public void run() {
                 try {
                     if (!getVolumeState(Environment.getExternalStorageDirectory().getPath())
                                  .equals(Environment.MEDIA_MOUNTED)) {
                         try {
-                            mountMedia(Environment.getExternalStorageDirectory().getPath());
+                            mountVolume(Environment.getExternalStorageDirectory().getPath());
                         } catch (Exception ex) {
                             Log.w(TAG, "Connection-mount failed");
                         }
@@ -474,7 +534,7 @@
                 }
 
                 try {
-                    boolean avail = mListener.getShareAvailable("ums");
+                    boolean avail = getShareAvailable("ums");
                     notifyShareAvailabilityChange("ums", avail);
                 } catch (Exception ex) {
                     Log.w(TAG, "Failed to get share availability");
@@ -483,6 +543,49 @@
         }.start();
     }
 
+    /**
+     *
+     * Callback from NativeDaemonConnector
+     */
+    public boolean onEvent(int code, String raw, String[] cooked) {
+        // Log.d(TAG, "event {" + raw + "}");
+        if (code == VoldResponseCode.VolumeStateChange) {
+            // FMT: NNN Volume <label> <mountpoint> state changed
+            // from <old_#> (<old_str>) to <new_#> (<new_str>)
+            notifyVolumeStateChange(
+                    cooked[2], cooked[3], Integer.parseInt(cooked[7]),
+                            Integer.parseInt(cooked[10]));
+        } else if (code == VoldResponseCode.VolumeMountFailedBlank) {
+            // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems
+            notifyMediaNoFs(cooked[3]);
+            // FMT: NNN Volume <label> <mountpoint> mount failed - no media
+        } else if (code == VoldResponseCode.VolumeMountFailedNoMedia) {
+            notifyMediaRemoved(cooked[3]);
+        } else if (code == VoldResponseCode.VolumeMountFailedDamaged) {
+            // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed
+            notifyMediaUnmountable(cooked[3]);
+        } else if (code == VoldResponseCode.ShareAvailabilityChange) {
+            // FMT: NNN Share method <method> now <available|unavailable>
+            boolean avail = false;
+            if (cooked[5].equals("available")) {
+                avail = true;
+            }
+            notifyShareAvailabilityChange(cooked[3], avail);
+        } else if (code == VoldResponseCode.VolumeDiskInserted) {
+            // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>)
+            notifyMediaInserted(cooked[3]);
+        } else if (code == VoldResponseCode.VolumeDiskRemoved) {
+            // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>)
+            notifyMediaRemoved(cooked[3]);
+        } else if (code == VoldResponseCode.VolumeBadRemoval) {
+            // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>)
+            notifyMediaBadRemoval(cooked[3]);
+        } else {
+            return false;
+        }
+       return true;
+    }
+
     void notifyVolumeStateChange(String label, String mountPoint, int oldState,
                                  int newState) throws IllegalStateException {
         String vs = getVolumeState(mountPoint);
@@ -587,7 +690,7 @@
         new Thread() {
             public void run() {
                 try {
-                    mountMedia(path);
+                    mountVolume(path);
                 } catch (Exception ex) {
                     Log.w(TAG, "Failed to mount media on insertion", ex);
                 }
@@ -903,29 +1006,62 @@
     }
 
     public String[] getSecureContainerList() throws IllegalStateException {
-        return mListener.listAsec();
+        ArrayList<String> rsp = mConnector.doCommand("list_asec");
+
+        String[] rdata = new String[rsp.size()];
+        int idx = 0;
+
+        for (String line : rsp) {
+            String []tok = line.split(" ");
+            int code = Integer.parseInt(tok[0]);
+            if (code == VoldResponseCode.AsecListResult) {
+                rdata[idx++] = tok[1];
+            } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
+                return rdata;
+            } else {
+                throw new IllegalStateException(String.format("Unexpected response code %d", code));
+            }
+        }
+        throw new IllegalStateException("Got an empty response");
     }
 
     public String createSecureContainer(String id, int sizeMb, String fstype,
                                     String key, int ownerUid) throws IllegalStateException {
-        return mListener.createAsec(id, sizeMb, fstype, key, ownerUid);
+        String cmd = String.format("create_asec %s %d %s %s %d",
+                                   id, sizeMb, fstype, key, ownerUid);
+        mConnector.doCommand(cmd);
+        return getSecureContainerPath(id);
     }
 
     public void finalizeSecureContainer(String id) throws IllegalStateException {
-        mListener.finalizeAsec(id);
+        mConnector.doCommand(String.format("finalize_asec %s", id));
     }
 
     public void destroySecureContainer(String id) throws IllegalStateException {
-        mListener.destroyAsec(id);
+        mConnector.doCommand(String.format("destroy_asec %s", id));
     }
    
-    public String mountSecureContainer(String id, String key, int ownerUid) throws IllegalStateException {
-        return mListener.mountAsec(id, key, ownerUid);
+    public String mountSecureContainer(String id, String key,
+                                       int ownerUid) throws IllegalStateException {
+        String cmd = String.format("mount_asec %s %s %d",
+                                   id, key, ownerUid);
+        mConnector.doCommand(cmd);
+        return getSecureContainerPath(id);
     }
 
     public String getSecureContainerPath(String id) throws IllegalStateException {
-        return mListener.getAsecPath(id);
-    }
+        ArrayList<String> rsp = mConnector.doCommand("asec_path " + id);
 
+        for (String line : rsp) {
+            String []tok = line.split(" ");
+            int code = Integer.parseInt(tok[0]);
+            if (code == VoldResponseCode.AsecPathResult) {
+                return tok[1];
+            } else {
+                throw new IllegalStateException(String.format("Unexpected response code %d", code));
+            }
+        }
+        throw new IllegalStateException("Got an empty response");
+    }
 }
 
