diff --git a/Android.mk b/Android.mk
index 21bd76b..7be48e0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -535,6 +535,7 @@
     framework-protos                                    \
     android.hardware.thermal@1.0-java-constants         \
     android.hardware.health@1.0-java-constants          \
+    android.hardware.usb@1.0-java-constants             \
 
 LOCAL_PROTOC_OPTIMIZE_TYPE := stream
 LOCAL_PROTOC_FLAGS := \
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index c9a4e9b..fea730e 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -16,11 +16,12 @@
 
 package android.hardware.usb;
 
-import com.android.internal.util.Preconditions;
-
+import android.hardware.usb.V1_0.Constants;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
 /**
  * Represents a physical USB port and describes its characteristics.
  * <p>
@@ -33,6 +34,7 @@
     private final String mId;
     private final int mSupportedModes;
 
+    public static final int MODE_NONE = Constants.PortMode.NONE;
     /**
      * Mode bit: This USB port can act as a downstream facing port (host).
      * <p>
@@ -40,7 +42,7 @@
      * combination of roles (and possibly others as well).
      * </p>
      */
-    public static final int MODE_DFP = 1 << 0;
+    public static final int MODE_DFP = Constants.PortMode.DFP;
 
     /**
      * Mode bit: This USB port can act as an upstream facing port (device).
@@ -49,7 +51,7 @@
      * combination of roles (and possibly others as well).
      * </p>
      */
-    public static final int MODE_UFP = 1 << 1;
+    public static final int MODE_UFP = Constants.PortMode.UFP;
 
     /**
      * Mode bit: This USB port can act either as an downstream facing port (host) or as
@@ -60,29 +62,43 @@
      * combination of roles (and possibly others as well).
      * </p>
      */
-    public static final int MODE_DUAL = MODE_DFP | MODE_UFP;
+    public static final int MODE_DUAL = Constants.PortMode.DRP;
+
+    /**
+     * Power role: This USB port does not have a power role.
+     */
+    public static final int POWER_ROLE_NONE = Constants.PortPowerRole.NONE;
 
     /**
      * Power role: This USB port can act as a source (provide power).
      */
-    public static final int POWER_ROLE_SOURCE = 1;
+    public static final int POWER_ROLE_SOURCE = Constants.PortPowerRole.SOURCE;
 
     /**
      * Power role: This USB port can act as a sink (receive power).
      */
-    public static final int POWER_ROLE_SINK = 2;
+    public static final int POWER_ROLE_SINK = Constants.PortPowerRole.SINK;
+
+    /**
+     * Power role: This USB port does not have a data role.
+     */
+    public static final int DATA_ROLE_NONE = Constants.PortDataRole.NONE;
 
     /**
      * Data role: This USB port can act as a host (access data services).
      */
-    public static final int DATA_ROLE_HOST = 1;
+    public static final int DATA_ROLE_HOST = Constants.PortDataRole.HOST;
 
     /**
      * Data role: This USB port can act as a device (offer data services).
      */
-    public static final int DATA_ROLE_DEVICE = 2;
+    public static final int DATA_ROLE_DEVICE = Constants.PortDataRole.DEVICE;
 
-    private static final int NUM_DATA_ROLES = 3;
+    private static final int NUM_DATA_ROLES = Constants.PortDataRole.NUM_DATA_ROLES;
+    /**
+     * Points to the first power role in the IUsb HAL.
+     */
+    private static final int POWER_ROLE_OFFSET = Constants.PortPowerRole.NONE;
 
     /** @hide */
     public UsbPort(String id, int supportedModes) {
@@ -126,14 +142,14 @@
      */
     public static int combineRolesAsBit(int powerRole, int dataRole) {
         checkRoles(powerRole, dataRole);
-        final int index = powerRole * NUM_DATA_ROLES + dataRole;
+        final int index = ((powerRole - POWER_ROLE_OFFSET) * NUM_DATA_ROLES) + dataRole;
         return 1 << index;
     }
 
     /** @hide */
     public static String modeToString(int mode) {
         switch (mode) {
-            case 0:
+            case MODE_NONE:
                 return "none";
             case MODE_DFP:
                 return "dfp";
@@ -149,7 +165,7 @@
     /** @hide */
     public static String powerRoleToString(int role) {
         switch (role) {
-            case 0:
+            case POWER_ROLE_NONE:
                 return "no-power";
             case POWER_ROLE_SOURCE:
                 return "source";
@@ -163,7 +179,7 @@
     /** @hide */
     public static String dataRoleToString(int role) {
         switch (role) {
-            case 0:
+            case DATA_ROLE_NONE:
                 return "no-data";
             case DATA_ROLE_HOST:
                 return "host";
@@ -183,7 +199,7 @@
         while (combo != 0) {
             final int index = Integer.numberOfTrailingZeros(combo);
             combo &= ~(1 << index);
-            final int powerRole = index / NUM_DATA_ROLES;
+            final int powerRole = (index / NUM_DATA_ROLES + POWER_ROLE_OFFSET);
             final int dataRole = index % NUM_DATA_ROLES;
             if (first) {
                 first = false;
@@ -200,9 +216,28 @@
     }
 
     /** @hide */
+    public static void checkMode(int powerRole) {
+        Preconditions.checkArgumentInRange(powerRole, Constants.PortMode.NONE,
+                Constants.PortMode.NUM_MODES - 1, "portMode");
+    }
+
+    /** @hide */
+    public static void checkPowerRole(int dataRole) {
+        Preconditions.checkArgumentInRange(dataRole, Constants.PortPowerRole.NONE,
+                Constants.PortPowerRole.NUM_POWER_ROLES - 1, "powerRole");
+    }
+
+    /** @hide */
+    public static void checkDataRole(int mode) {
+        Preconditions.checkArgumentInRange(mode, Constants.PortDataRole.NONE,
+                Constants.PortDataRole.NUM_DATA_ROLES - 1, "powerRole");
+    }
+
+    /** @hide */
     public static void checkRoles(int powerRole, int dataRole) {
-        Preconditions.checkArgumentInRange(powerRole, 0, POWER_ROLE_SINK, "powerRole");
-        Preconditions.checkArgumentInRange(dataRole, 0, DATA_ROLE_DEVICE, "dataRole");
+        Preconditions.checkArgumentInRange(powerRole, POWER_ROLE_NONE, POWER_ROLE_SINK,
+                "powerRole");
+        Preconditions.checkArgumentInRange(dataRole, DATA_ROLE_NONE, DATA_ROLE_DEVICE, "dataRole");
     }
 
     @Override
diff --git a/services/usb/Android.mk b/services/usb/Android.mk
index feabf0a..f560e71 100644
--- a/services/usb/Android.mk
+++ b/services/usb/Android.mk
@@ -8,5 +8,7 @@
       $(call all-java-files-under,java)
 
 LOCAL_JAVA_LIBRARIES := services.core
+LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb@1.0-java-static \
+android.hidl.manager@1.0-java-static
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 4aff3d54..4b8e4c8 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -16,36 +16,40 @@
 
 package com.android.server.usb;
 
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.FgThread;
-
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
+import android.hardware.usb.V1_0.IUsb;
+import android.hardware.usb.V1_0.IUsbCallback;
+import android.hardware.usb.V1_0.PortRole;
+import android.hardware.usb.V1_0.PortRoleType;
+import android.hardware.usb.V1_0.PortStatus;
+import android.hardware.usb.V1_0.Status;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.HwBinder;
 import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UEventObserver;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
 import android.os.UserHandle;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.FgThread;
 
-import libcore.io.IoUtils;
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
 
 /**
  * Allows trusted components to control the properties of physical USB ports
- * via the "/sys/class/dual_role_usb" kernel interface.
+ * via the IUsb.hal.
  * <p>
  * Note: This interface may not be supported on all chipsets since the USB drivers
  * must be changed to publish this information through the module.  At the moment
@@ -60,43 +64,6 @@
 
     private static final int MSG_UPDATE_PORTS = 1;
 
-    // UEvent path to watch.
-    private static final String UEVENT_FILTER = "SUBSYSTEM=dual_role_usb";
-
-    // SysFS directory that contains USB ports as subdirectories.
-    private static final String SYSFS_CLASS = "/sys/class/dual_role_usb";
-
-    // SysFS file that contains a USB port's supported modes.  (read-only)
-    // Contents: "", "ufp", "dfp", or "ufp dfp".
-    private static final String SYSFS_PORT_SUPPORTED_MODES = "supported_modes";
-
-    // SysFS file that contains a USB port's current mode.  (read-write if configurable)
-    // Contents: "", "ufp", or "dfp".
-    private static final String SYSFS_PORT_MODE = "mode";
-
-    // SysFS file that contains a USB port's current power role.  (read-write if configurable)
-    // Contents: "", "source", or "sink".
-    private static final String SYSFS_PORT_POWER_ROLE = "power_role";
-
-    // SysFS file that contains a USB port's current data role.  (read-write if configurable)
-    // Contents: "", "host", or "device".
-    private static final String SYSFS_PORT_DATA_ROLE = "data_role";
-
-    // Port modes: upstream facing port or downstream facing port.
-    private static final String PORT_MODE_DFP = "dfp";
-    private static final String PORT_MODE_UFP = "ufp";
-
-    // Port power roles: source or sink.
-    private static final String PORT_POWER_ROLE_SOURCE = "source";
-    private static final String PORT_POWER_ROLE_SINK = "sink";
-
-    // Port data roles: host or device.
-    private static final String PORT_DATA_ROLE_HOST = "host";
-    private static final String PORT_DATA_ROLE_DEVICE = "device";
-
-    private static final String USB_TYPEC_PROP_PREFIX = "sys.usb.typec.";
-    private static final String USB_TYPEC_STATE = "sys.usb.typec.state";
-
     // All non-trivial role combinations.
     private static final int COMBO_SOURCE_HOST =
             UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
@@ -110,8 +77,29 @@
     // The system context.
     private final Context mContext;
 
-    // True if we have kernel support.
-    private final boolean mHaveKernelSupport;
+    // Proxy object for the usb hal daemon.
+    // @GuardedBy("mLock")
+    private IUsb mProxy = null;
+
+    // Callback when the UsbPort status is changed by the kernel.
+    // Mostly due a command sent by the remote Usb device.
+    private HALCallback mHALCallback = new HALCallback(null, this);
+
+    // Notification object used to listen to the start of the usb daemon.
+    private final ServiceNotification mServiceNotification = new ServiceNotification();
+
+    // Cookie sent for usb hal death notification.
+    private static final int USB_HAL_DEATH_COOKIE = 1000;
+
+    // Usb hal service name.
+    private static String sSERVICENAME = "usb_hal";
+
+    // Used as the key while sending the bundle to Main thread.
+    private static final String PORT_INFO = "port_info";
+
+    // This is monitored to prevent updating the protInfo before the system
+    // is ready.
+    private boolean mSystemReady;
 
     // Mutex for all mutable shared state.
     private final Object mLock = new Object();
@@ -123,17 +111,37 @@
     private final ArrayMap<String, PortInfo> mPorts = new ArrayMap<String, PortInfo>();
 
     // List of all simulated ports, indexed by id.
-    private final ArrayMap<String, SimulatedPortInfo> mSimulatedPorts =
-            new ArrayMap<String, SimulatedPortInfo>();
+    private final ArrayMap<String, RawPortInfo> mSimulatedPorts =
+            new ArrayMap<String, RawPortInfo>();
 
     public UsbPortManager(Context context) {
         mContext = context;
-        mHaveKernelSupport = new File(SYSFS_CLASS).exists();
+        try {
+            boolean ret = IServiceManager.getService("manager")
+                    .registerForNotifications("android.hardware.usb@1.0::IUsb",
+                    "", mServiceNotification);
+            if (!ret) {
+                logAndPrint(Log.ERROR, null, "Failed to register service start notification");
+            }
+        } catch (RemoteException e) {
+            logAndPrint(Log.ERROR, null, "Failed to register service start notification");
+            Thread.dumpStack();
+            return;
+        }
+        connectToProxy(null);
     }
 
     public void systemReady() {
-        mUEventObserver.startObserving(UEVENT_FILTER);
-        scheduleUpdatePorts();
+        if (mProxy != null) {
+            try {
+                mProxy.queryPortStatus();
+            } catch (RemoteException e) {
+                logAndPrint(Log.ERROR, null,
+                        "ServiceStart: Failed to query port status");
+                Thread.dumpStack();
+            }
+        }
+        mSystemReady = true;
     }
 
     public UsbPort[] getPorts() {
@@ -223,20 +231,14 @@
                     + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)
                     + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));
 
-            SimulatedPortInfo sim = mSimulatedPorts.get(portId);
+            RawPortInfo sim = mSimulatedPorts.get(portId);
             if (sim != null) {
                 // Change simulated state.
                 sim.mCurrentMode = newMode;
                 sim.mCurrentPowerRole = newPowerRole;
                 sim.mCurrentDataRole = newDataRole;
-            } else if (mHaveKernelSupport) {
-                // Change actual state.
-                final File portDir = new File(SYSFS_CLASS, portId);
-                if (!portDir.exists()) {
-                    logAndPrint(Log.ERROR, pw, "USB port not found: portId=" + portId);
-                    return;
-                }
-
+                updatePortsLocked(pw, null);
+            } else if (mProxy != null) {
                 if (currentMode != newMode) {
                     // Changing the mode will have the side-effect of also changing
                     // the power and data roles but it might take some time to apply
@@ -244,38 +246,54 @@
                     // hardware, we have no way of knowing whether it will work apriori
                     // which is why we would prefer to set the power and data roles
                     // directly instead.
-                    if (!writeFile(portDir, SYSFS_PORT_MODE,
-                            newMode == UsbPort.MODE_DFP ? PORT_MODE_DFP : PORT_MODE_UFP)) {
-                        logAndPrint(Log.ERROR, pw, "Failed to set the USB port mode: "
+
+                    logAndPrint(Log.ERROR, pw, "Trying to set the USB port mode: "
                                 + "portId=" + portId
                                 + ", newMode=" + UsbPort.modeToString(newMode));
+                    PortRole newRole = new PortRole();
+                    newRole.type = PortRoleType.MODE;
+                    newRole.role = newMode;
+                    try {
+                        mProxy.switchRole(portId, newRole);
+                    } catch (RemoteException e) {
+                        logAndPrint(Log.ERROR, pw, "Failed to set the USB port mode: "
+                                + "portId=" + portId
+                                + ", newMode=" + UsbPort.modeToString(newRole.role));
+                        Thread.dumpStack();
                         return;
                     }
                 } else {
                     // Change power and data role independently as needed.
                     if (currentPowerRole != newPowerRole) {
-                        if (!writeFile(portDir, SYSFS_PORT_POWER_ROLE,
-                                newPowerRole == UsbPort.POWER_ROLE_SOURCE
-                                ? PORT_POWER_ROLE_SOURCE : PORT_POWER_ROLE_SINK)) {
+                        PortRole newRole = new PortRole();
+                        newRole.type = PortRoleType.POWER_ROLE;
+                        newRole.role = newPowerRole;
+                        try {
+                            mProxy.switchRole(portId, newRole);
+                        } catch (RemoteException e) {
                             logAndPrint(Log.ERROR, pw, "Failed to set the USB port power role: "
                                     + "portId=" + portId
-                                    + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole));
+                                    + ", newPowerRole=" + UsbPort.powerRoleToString(newRole.role));
+                            Thread.dumpStack();
                             return;
                         }
                     }
                     if (currentDataRole != newDataRole) {
-                        if (!writeFile(portDir, SYSFS_PORT_DATA_ROLE,
-                                newDataRole == UsbPort.DATA_ROLE_HOST
-                                ? PORT_DATA_ROLE_HOST : PORT_DATA_ROLE_DEVICE)) {
+                        PortRole newRole = new PortRole();
+                        newRole.type = PortRoleType.DATA_ROLE;
+                        newRole.role = newDataRole;
+                        try {
+                            mProxy.switchRole(portId, newRole);
+                        } catch (RemoteException e) {
                             logAndPrint(Log.ERROR, pw, "Failed to set the USB port data role: "
                                     + "portId=" + portId
-                                    + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));
+                                    + ", newDataRole=" + UsbPort.dataRoleToString(newRole.role));
+                            Thread.dumpStack();
                             return;
                         }
                     }
                 }
             }
-            updatePortsLocked(pw);
         }
     }
 
@@ -289,8 +307,8 @@
             pw.println("Adding simulated port: portId=" + portId
                     + ", supportedModes=" + UsbPort.modeToString(supportedModes));
             mSimulatedPorts.put(portId,
-                    new SimulatedPortInfo(portId, supportedModes));
-            updatePortsLocked(pw);
+                    new RawPortInfo(portId, supportedModes));
+            updatePortsLocked(pw, null);
         }
     }
 
@@ -298,7 +316,7 @@
             int powerRole, boolean canChangePowerRole,
             int dataRole, boolean canChangeDataRole, IndentingPrintWriter pw) {
         synchronized (mLock) {
-            final SimulatedPortInfo portInfo = mSimulatedPorts.get(portId);
+            final RawPortInfo portInfo = mSimulatedPorts.get(portId);
             if (portInfo == null) {
                 pw.println("Cannot connect simulated port which does not exist.");
                 return;
@@ -328,13 +346,13 @@
             portInfo.mCanChangePowerRole = canChangePowerRole;
             portInfo.mCurrentDataRole = dataRole;
             portInfo.mCanChangeDataRole = canChangeDataRole;
-            updatePortsLocked(pw);
+            updatePortsLocked(pw, null);
         }
     }
 
     public void disconnectSimulatedPort(String portId, IndentingPrintWriter pw) {
         synchronized (mLock) {
-            final SimulatedPortInfo portInfo = mSimulatedPorts.get(portId);
+            final RawPortInfo portInfo = mSimulatedPorts.get(portId);
             if (portInfo == null) {
                 pw.println("Cannot disconnect simulated port which does not exist.");
                 return;
@@ -347,7 +365,7 @@
             portInfo.mCanChangePowerRole = false;
             portInfo.mCurrentDataRole = 0;
             portInfo.mCanChangeDataRole = false;
-            updatePortsLocked(pw);
+            updatePortsLocked(pw, null);
         }
     }
 
@@ -361,7 +379,7 @@
 
             pw.println("Disconnecting simulated port: portId=" + portId);
             mSimulatedPorts.removeAt(index);
-            updatePortsLocked(pw);
+            updatePortsLocked(pw, null);
         }
     }
 
@@ -370,7 +388,7 @@
             pw.println("Removing all simulated ports and ending simulation.");
             if (!mSimulatedPorts.isEmpty()) {
                 mSimulatedPorts.clear();
-                updatePortsLocked(pw);
+                updatePortsLocked(pw, null);
             }
         }
     }
@@ -393,9 +411,108 @@
         }
     }
 
-    private void updatePortsLocked(IndentingPrintWriter pw) {
-        // Assume all ports are gone unless informed otherwise.
-        // Kind of pessimistic but simple.
+    private static class HALCallback extends IUsbCallback.Stub {
+        public IndentingPrintWriter pw;
+        public UsbPortManager portManager;
+
+        HALCallback() {
+            super();
+        }
+
+        HALCallback(IndentingPrintWriter pw, UsbPortManager portManager) {
+            this.pw = pw;
+            this.portManager = portManager;
+        }
+
+        public void notifyPortStatusChange(ArrayList<PortStatus> currentPortStatus, int retval) {
+            if (!portManager.mSystemReady) return;
+
+            if (retval != Status.SUCCESS) {
+                logAndPrint(Log.ERROR, pw, "port status enquiry failed");
+                return;
+            }
+
+            ArrayList<RawPortInfo> newPortInfo = new ArrayList<RawPortInfo>();
+
+            for (PortStatus current : currentPortStatus) {
+                RawPortInfo temp = new RawPortInfo(current.portName,
+                        current.supportedModes, current.currentMode,
+                        current.canChangeMode, current.currentPowerRole,
+                        current.canChangePowerRole,
+                        current.currentDataRole, current.canChangeDataRole);
+                newPortInfo.add(temp);
+                logAndPrint(Log.INFO, pw, "ClientCallback: " + current.portName);
+            }
+
+            Message message = portManager.mHandler.obtainMessage();
+            Bundle bundle = new Bundle();
+            bundle.putParcelableArrayList(PORT_INFO, newPortInfo);
+            message.what = MSG_UPDATE_PORTS;
+            message.setData(bundle);
+            portManager.mHandler.sendMessage(message);
+            return;
+        }
+
+        public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
+            if (retval == Status.SUCCESS) {
+                logAndPrint(Log.INFO, pw, portName + "role switch successful");
+            } else {
+                logAndPrint(Log.ERROR, pw, portName + "role switch failed");
+            }
+        }
+    };
+
+    final class DeathRecipient implements HwBinder.DeathRecipient {
+        public IndentingPrintWriter pw;
+
+        DeathRecipient(IndentingPrintWriter pw) {
+            this.pw = pw;
+        }
+
+        @Override
+        public void serviceDied(long cookie) {
+            if (cookie == USB_HAL_DEATH_COOKIE) {
+                logAndPrint(Log.ERROR, pw, "Usb hal service died cookie: " + cookie);
+                synchronized (mLock) {
+                    mProxy = null;
+                }
+            }
+        }
+    }
+
+    final class ServiceNotification extends IServiceNotification.Stub {
+        @Override
+        public void onRegistration(String fqName, String name, boolean preexisting) {
+            logAndPrint(Log.INFO, null, "Usb hal service started " + fqName + " " + name);
+            connectToProxy(null);
+        }
+    }
+
+    private void connectToProxy(IndentingPrintWriter pw) {
+        synchronized (mLock) {
+            if (mProxy != null) return;
+
+            try {
+                mProxy = IUsb.getService(sSERVICENAME);
+                mProxy.linkToDeath(new DeathRecipient(pw), USB_HAL_DEATH_COOKIE);
+                mProxy.setCallback(mHALCallback);
+                mProxy.queryPortStatus();
+            } catch (NoSuchElementException e) {
+                logAndPrint(Log.ERROR, pw, sSERVICENAME + "not found."
+                        + " Did the service failed to start ?");
+                Thread.dumpStack();
+            } catch (RemoteException e) {
+                logAndPrint(Log.ERROR, pw, sSERVICENAME + "connectToProxy: Service not responding");
+                Thread.dumpStack();
+            }
+        }
+    }
+
+    /**
+     * Simulated ports directly add the new roles to mSimulatedPorts before calling.
+     * USB hal callback populates and sends the newPortInfo.
+     */
+    private void updatePortsLocked(IndentingPrintWriter pw, ArrayList<RawPortInfo> newPortInfo) {
         for (int i = mPorts.size(); i-- > 0; ) {
             mPorts.valueAt(i).mDisposition = PortInfo.DISPOSITION_REMOVED;
         }
@@ -404,34 +521,18 @@
         if (!mSimulatedPorts.isEmpty()) {
             final int count = mSimulatedPorts.size();
             for (int i = 0; i < count; i++) {
-                final SimulatedPortInfo portInfo = mSimulatedPorts.valueAt(i);
+                final RawPortInfo portInfo = mSimulatedPorts.valueAt(i);
                 addOrUpdatePortLocked(portInfo.mPortId, portInfo.mSupportedModes,
                         portInfo.mCurrentMode, portInfo.mCanChangeMode,
                         portInfo.mCurrentPowerRole, portInfo.mCanChangePowerRole,
                         portInfo.mCurrentDataRole, portInfo.mCanChangeDataRole, pw);
             }
-        } else if (mHaveKernelSupport) {
-            final File[] portDirs = new File(SYSFS_CLASS).listFiles();
-            if (portDirs != null) {
-                for (File portDir : portDirs) {
-                    if (!portDir.isDirectory()) {
-                        continue;
-                    }
-
-                    // Parse the sysfs file contents.
-                    final String portId = portDir.getName();
-                    final int supportedModes = readSupportedModes(portDir);
-                    final int currentMode = readCurrentMode(portDir);
-                    final boolean canChangeMode = canChangeMode(portDir);
-                    final int currentPowerRole = readCurrentPowerRole(portDir);
-                    final boolean canChangePowerRole = canChangePowerRole(portDir);
-                    final int currentDataRole = readCurrentDataRole(portDir);
-                    final boolean canChangeDataRole = canChangeDataRole(portDir);
-                    addOrUpdatePortLocked(portId, supportedModes,
-                            currentMode, canChangeMode,
-                            currentPowerRole, canChangePowerRole,
-                            currentDataRole, canChangeDataRole, pw);
-                 }
+        } else {
+            for (RawPortInfo currentPortInfo : newPortInfo) {
+                addOrUpdatePortLocked(currentPortInfo.mPortId, currentPortInfo.mSupportedModes,
+                        currentPortInfo.mCurrentMode, currentPortInfo.mCanChangeMode,
+                        currentPortInfo.mCurrentPowerRole, currentPortInfo.mCanChangePowerRole,
+                        currentPortInfo.mCurrentDataRole, currentPortInfo.mCanChangeDataRole, pw);
             }
         }
 
@@ -457,20 +558,21 @@
         }
     }
 
+
     // Must only be called by updatePortsLocked.
     private void addOrUpdatePortLocked(String portId, int supportedModes,
-            int currentMode, boolean canChangeMode,
-            int currentPowerRole, boolean canChangePowerRole,
-            int currentDataRole, boolean canChangeDataRole,
-            IndentingPrintWriter pw) {
+                                       int currentMode, boolean canChangeMode,
+                                       int currentPowerRole, boolean canChangePowerRole,
+                                       int currentDataRole, boolean canChangeDataRole,
+                                       IndentingPrintWriter pw) {
         // Only allow mode switch capability for dual role ports.
         // Validate that the current mode matches the supported modes we expect.
         if (supportedModes != UsbPort.MODE_DUAL) {
             canChangeMode = false;
             if (currentMode != 0 && currentMode != supportedModes) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent current mode from USB "
-                        + "port driver: supportedModes=" + UsbPort.modeToString(supportedModes)
-                        + ", currentMode=" + UsbPort.modeToString(currentMode));
+                            + "port driver: supportedModes=" + UsbPort.modeToString(supportedModes)
+                            + ", currentMode=" + UsbPort.modeToString(currentMode));
                 currentMode = 0;
             }
         }
@@ -485,8 +587,8 @@
                 // Can change both power and data role independently.
                 // Assume all combinations are possible.
                 supportedRoleCombinations |=
-                        COMBO_SOURCE_HOST | COMBO_SOURCE_DEVICE
-                                | COMBO_SINK_HOST | COMBO_SINK_DEVICE;
+                    COMBO_SOURCE_HOST | COMBO_SOURCE_DEVICE
+                    | COMBO_SINK_HOST | COMBO_SINK_DEVICE;
             } else if (canChangePowerRole) {
                 // Can only change power role.
                 // Assume data role must remain at its current value.
@@ -514,24 +616,24 @@
         if (portInfo == null) {
             portInfo = new PortInfo(portId, supportedModes);
             portInfo.setStatus(currentMode, canChangeMode,
-                    currentPowerRole, canChangePowerRole,
-                    currentDataRole, canChangeDataRole,
-                    supportedRoleCombinations);
+                               currentPowerRole, canChangePowerRole,
+                               currentDataRole, canChangeDataRole,
+                               supportedRoleCombinations);
             mPorts.put(portId, portInfo);
         } else {
             // Sanity check that ports aren't changing definition out from under us.
             if (supportedModes != portInfo.mUsbPort.getSupportedModes()) {
                 logAndPrint(Log.WARN, pw, "Ignoring inconsistent list of supported modes from "
-                        + "USB port driver (should be immutable): "
-                        + "previous=" + UsbPort.modeToString(
-                                portInfo.mUsbPort.getSupportedModes())
-                        + ", current=" + UsbPort.modeToString(supportedModes));
+                            + "USB port driver (should be immutable): "
+                            + "previous=" + UsbPort.modeToString(
+                            portInfo.mUsbPort.getSupportedModes())
+                            + ", current=" + UsbPort.modeToString(supportedModes));
             }
 
             if (portInfo.setStatus(currentMode, canChangeMode,
-                    currentPowerRole, canChangePowerRole,
-                    currentDataRole, canChangeDataRole,
-                    supportedRoleCombinations)) {
+                                   currentPowerRole, canChangePowerRole,
+                                   currentDataRole, canChangeDataRole,
+                                   supportedRoleCombinations)) {
                 portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
             } else {
                 portInfo.mDisposition = PortInfo.DISPOSITION_READY;
@@ -572,120 +674,6 @@
         });
     }
 
-    private void scheduleUpdatePorts() {
-        if (!mHandler.hasMessages(MSG_UPDATE_PORTS)) {
-            mHandler.sendEmptyMessage(MSG_UPDATE_PORTS);
-        }
-    }
-
-    private static int readSupportedModes(File portDir) {
-        int modes = 0;
-        final String contents = readFile(portDir, SYSFS_PORT_SUPPORTED_MODES);
-        if (contents != null) {
-            if (contents.contains(PORT_MODE_DFP)) {
-                modes |= UsbPort.MODE_DFP;
-            }
-            if (contents.contains(PORT_MODE_UFP)) {
-                modes |= UsbPort.MODE_UFP;
-            }
-        }
-        return modes;
-    }
-
-    private static int readCurrentMode(File portDir) {
-        final String contents = readFile(portDir, SYSFS_PORT_MODE);
-        if (contents != null) {
-            if (contents.equals(PORT_MODE_DFP)) {
-                return UsbPort.MODE_DFP;
-            }
-            if (contents.equals(PORT_MODE_UFP)) {
-                return UsbPort.MODE_UFP;
-            }
-        }
-        return 0;
-    }
-
-    private static int readCurrentPowerRole(File portDir) {
-        final String contents = readFile(portDir, SYSFS_PORT_POWER_ROLE);
-        if (contents != null) {
-            if (contents.equals(PORT_POWER_ROLE_SOURCE)) {
-                return UsbPort.POWER_ROLE_SOURCE;
-            }
-            if (contents.equals(PORT_POWER_ROLE_SINK)) {
-                return UsbPort.POWER_ROLE_SINK;
-            }
-        }
-        return 0;
-    }
-
-    private static int readCurrentDataRole(File portDir) {
-        final String contents = readFile(portDir, SYSFS_PORT_DATA_ROLE);
-        if (contents != null) {
-            if (contents.equals(PORT_DATA_ROLE_HOST)) {
-                return UsbPort.DATA_ROLE_HOST;
-            }
-            if (contents.equals(PORT_DATA_ROLE_DEVICE)) {
-                return UsbPort.DATA_ROLE_DEVICE;
-            }
-        }
-        return 0;
-    }
-
-    private static boolean fileIsRootWritable(String path) {
-        try {
-            // If the file is user writable, then it is root writable.
-            return (Os.stat(path).st_mode & OsConstants.S_IWUSR) != 0;
-        } catch (ErrnoException e) {
-            return false;
-        }
-    }
-
-    private static boolean canChangeMode(File portDir) {
-        return fileIsRootWritable(new File(portDir, SYSFS_PORT_MODE).getPath());
-    }
-
-    private static boolean canChangePowerRole(File portDir) {
-        return fileIsRootWritable(new File(portDir, SYSFS_PORT_POWER_ROLE).getPath());
-    }
-
-    private static boolean canChangeDataRole(File portDir) {
-        return fileIsRootWritable(new File(portDir, SYSFS_PORT_DATA_ROLE).getPath());
-    }
-
-    private static String readFile(File dir, String filename) {
-        final File file = new File(dir, filename);
-        try {
-            return IoUtils.readFileAsString(file.getAbsolutePath()).trim();
-        } catch (IOException ex) {
-            return null;
-        }
-    }
-
-    private static boolean waitForState(String property, String state) {
-        // wait for the transition to complete.
-        // give up after 5 seconds.
-        // 5 seconds is probably too long, but we have seen hardware that takes
-        // over 3 seconds to change states.
-        String value = null;
-        for (int i = 0; i < 100; i++) {
-            // State transition is done when property is set to the new configuration
-            value = SystemProperties.get(property);
-            if (state.equals(value)) return true;
-            SystemClock.sleep(50);
-        }
-        Slog.e(TAG, "waitForState(" + state + ") for " + property + " FAILED: got " + value);
-        return false;
-    }
-
-    private static String propertyFromFilename(String filename) {
-        return USB_TYPEC_PROP_PREFIX + filename;
-    }
-
-    private static boolean writeFile(File dir, String filename, String contents) {
-        SystemProperties.set(propertyFromFilename(filename), contents);
-        return waitForState(USB_TYPEC_STATE, contents);
-    }
-
     private static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
         Slog.println(priority, TAG, msg);
         if (pw != null) {
@@ -698,8 +686,10 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_UPDATE_PORTS: {
+                    Bundle b = msg.getData();
+                    ArrayList<RawPortInfo> PortInfo = b.getParcelableArrayList(PORT_INFO);
                     synchronized (mLock) {
-                        updatePortsLocked(null);
+                        updatePortsLocked(null, PortInfo);
                     }
                     break;
                 }
@@ -707,13 +697,6 @@
         }
     };
 
-    private final UEventObserver mUEventObserver = new UEventObserver() {
-        @Override
-        public void onUEvent(UEvent event) {
-            scheduleUpdatePorts();
-        }
-    };
-
     /**
      * Describes a USB port.
      */
@@ -764,10 +747,10 @@
     }
 
     /**
-     * Describes a simulated USB port.
-     * Roughly mirrors the information we would ordinarily get from the kernel.
+     * Used for storing the raw data from the kernel
+     * Values of the member variables mocked directly incase of emulation.
      */
-    private static final class SimulatedPortInfo {
+    private static final class RawPortInfo implements Parcelable {
         public final String mPortId;
         public final int mSupportedModes;
         public int mCurrentMode;
@@ -777,9 +760,63 @@
         public int mCurrentDataRole;
         public boolean mCanChangeDataRole;
 
-        public SimulatedPortInfo(String portId, int supportedModes) {
+        RawPortInfo(String portId, int supportedModes) {
             mPortId = portId;
             mSupportedModes = supportedModes;
         }
+
+        RawPortInfo(String portId, int supportedModes,
+                                 int currentMode, boolean canChangeMode,
+                                 int currentPowerRole, boolean canChangePowerRole,
+                                 int currentDataRole, boolean canChangeDataRole) {
+            mPortId = portId;
+            mSupportedModes = supportedModes;
+            mCurrentMode = currentMode;
+            mCanChangeMode = canChangeMode;
+            mCurrentPowerRole = currentPowerRole;
+            mCanChangePowerRole = canChangePowerRole;
+            mCurrentDataRole = currentDataRole;
+            mCanChangeDataRole = canChangeDataRole;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(mPortId);
+            dest.writeInt(mSupportedModes);
+            dest.writeInt(mCurrentMode);
+            dest.writeByte((byte) (mCanChangeMode ? 1 : 0));
+            dest.writeInt(mCurrentPowerRole);
+            dest.writeByte((byte) (mCanChangePowerRole ? 1 : 0));
+            dest.writeInt(mCurrentDataRole);
+            dest.writeByte((byte) (mCanChangeDataRole ? 1 : 0));
+        }
+
+        public static final Parcelable.Creator<RawPortInfo> CREATOR =
+                new Parcelable.Creator<RawPortInfo>() {
+            @Override
+            public RawPortInfo createFromParcel(Parcel in) {
+                String id = in.readString();
+                int supportedModes = in.readInt();
+                int currentMode = in.readInt();
+                boolean canChangeMode = in.readByte() != 0;
+                int currentPowerRole = in.readInt();
+                boolean canChangePowerRole = in.readByte() != 0;
+                int currentDataRole = in.readInt();
+                boolean canChangeDataRole = in.readByte() != 0;
+                return new RawPortInfo(id, supportedModes, currentMode, canChangeMode,
+                                   currentPowerRole, canChangePowerRole,
+                                   currentDataRole, canChangeDataRole);
+            }
+
+            @Override
+            public RawPortInfo[] newArray(int size) {
+                return new RawPortInfo[size];
+            }
+        };
     }
 }
