/*
 * Copyright (C) 2015 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.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.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UEventObserver;
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 libcore.io.IoUtils;

/**
 * Allows trusted components to control the properties of physical USB ports
 * via the "/sys/class/dual_role_usb" kernel interface.
 * <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
 * we only need this for devices with USB Type C ports to allow the System UI to
 * control USB charging and data direction.  On devices that do not support this
 * interface the list of ports may incorrectly appear to be empty
 * (but we don't care today).
 * </p>
 */
public class UsbPortManager {
    private static final String TAG = "UsbPortManager";

    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);
    private static final int COMBO_SOURCE_DEVICE =
            UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE);
    private static final int COMBO_SINK_HOST =
            UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST);
    private static final int COMBO_SINK_DEVICE =
            UsbPort.combineRolesAsBit(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);

    // The system context.
    private final Context mContext;

    // True if we have kernel support.
    private final boolean mHaveKernelSupport;

    // Mutex for all mutable shared state.
    private final Object mLock = new Object();

    // List of all ports, indexed by id.
    // Ports may temporarily have different dispositions as they are added or removed
    // but the class invariant is that this list will only contain ports with DISPOSITION_READY
    // except while updatePortsLocked() is in progress.
    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>();

    public UsbPortManager(Context context) {
        mContext = context;
        mHaveKernelSupport = new File(SYSFS_CLASS).exists();
    }

    public void systemReady() {
        mUEventObserver.startObserving(UEVENT_FILTER);
        scheduleUpdatePorts();
    }

    public UsbPort[] getPorts() {
        synchronized (mLock) {
            final int count = mPorts.size();
            final UsbPort[] result = new UsbPort[count];
            for (int i = 0; i < count; i++) {
                result[i] = mPorts.valueAt(i).mUsbPort;
            }
            return result;
        }
    }

    public UsbPortStatus getPortStatus(String portId) {
        synchronized (mLock) {
            final PortInfo portInfo = mPorts.get(portId);
            return portInfo != null ? portInfo.mUsbPortStatus : null;
        }
    }

    public void setPortRoles(String portId, int newPowerRole, int newDataRole,
            IndentingPrintWriter pw) {
        synchronized (mLock) {
            final PortInfo portInfo = mPorts.get(portId);
            if (portInfo == null) {
                if (pw != null) {
                    pw.println("No such USB port: " + portId);
                }
                return;
            }

            // Check whether the new role is actually supported.
            if (!portInfo.mUsbPortStatus.isRoleCombinationSupported(newPowerRole, newDataRole)) {
                logAndPrint(Log.ERROR, pw, "Attempted to set USB port into unsupported "
                        + "role combination: portId=" + portId
                        + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)
                        + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));
                return;
            }

            // Check whether anything actually changed.
            final int currentDataRole = portInfo.mUsbPortStatus.getCurrentDataRole();
            final int currentPowerRole = portInfo.mUsbPortStatus.getCurrentPowerRole();
            if (currentDataRole == newDataRole && currentPowerRole == newPowerRole) {
                if (pw != null) {
                    pw.println("No change.");
                }
                return;
            }

            // Determine whether we need to change the mode in order to accomplish this goal.
            // We prefer not to do this since it's more likely to fail.
            //
            // Note: Arguably it might be worth allowing the client to influence this policy
            // decision so that we could show more powerful developer facing UI but let's
            // see how far we can get without having to do that.
            final boolean canChangeMode = portInfo.mCanChangeMode;
            final boolean canChangePowerRole = portInfo.mCanChangePowerRole;
            final boolean canChangeDataRole = portInfo.mCanChangeDataRole;
            final int currentMode = portInfo.mUsbPortStatus.getCurrentMode();
            final int newMode;
            if ((!canChangePowerRole && currentPowerRole != newPowerRole)
                    || (!canChangeDataRole && currentDataRole != newDataRole)) {
                if (canChangeMode && newPowerRole == UsbPort.POWER_ROLE_SOURCE
                        && newDataRole == UsbPort.DATA_ROLE_HOST) {
                    newMode = UsbPort.MODE_DFP;
                } else if (canChangeMode && newPowerRole == UsbPort.POWER_ROLE_SINK
                        && newDataRole == UsbPort.DATA_ROLE_DEVICE) {
                    newMode = UsbPort.MODE_UFP;
                } else {
                    logAndPrint(Log.ERROR, pw, "Found mismatch in supported USB role combinations "
                            + "while attempting to change role: " + portInfo
                            + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)
                            + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));
                    return;
                }
            } else {
                newMode = currentMode;
            }

            // Make it happen.
            logAndPrint(Log.INFO, pw, "Setting USB port mode and role: portId=" + portId
                    + ", currentMode=" + UsbPort.modeToString(currentMode)
                    + ", currentPowerRole=" + UsbPort.powerRoleToString(currentPowerRole)
                    + ", currentDataRole=" + UsbPort.dataRoleToString(currentDataRole)
                    + ", newMode=" + UsbPort.modeToString(newMode)
                    + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole)
                    + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));

            SimulatedPortInfo 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;
                }

                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
                    // and the renegotiation might fail.  Due to limitations of the USB
                    // 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: "
                                + "portId=" + portId
                                + ", newMode=" + UsbPort.modeToString(newMode));
                        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)) {
                            logAndPrint(Log.ERROR, pw, "Failed to set the USB port power role: "
                                    + "portId=" + portId
                                    + ", newPowerRole=" + UsbPort.powerRoleToString(newPowerRole));
                            return;
                        }
                    }
                    if (currentDataRole != newDataRole) {
                        if (!writeFile(portDir, SYSFS_PORT_DATA_ROLE,
                                newDataRole == UsbPort.DATA_ROLE_HOST
                                ? PORT_DATA_ROLE_HOST : PORT_DATA_ROLE_DEVICE)) {
                            logAndPrint(Log.ERROR, pw, "Failed to set the USB port data role: "
                                    + "portId=" + portId
                                    + ", newDataRole=" + UsbPort.dataRoleToString(newDataRole));
                            return;
                        }
                    }
                }
            }
            updatePortsLocked(pw);
        }
    }

    public void addSimulatedPort(String portId, int supportedModes, IndentingPrintWriter pw) {
        synchronized (mLock) {
            if (mSimulatedPorts.containsKey(portId)) {
                pw.println("Port with same name already exists.  Please remove it first.");
                return;
            }

            pw.println("Adding simulated port: portId=" + portId
                    + ", supportedModes=" + UsbPort.modeToString(supportedModes));
            mSimulatedPorts.put(portId,
                    new SimulatedPortInfo(portId, supportedModes));
            updatePortsLocked(pw);
        }
    }

    public void connectSimulatedPort(String portId, int mode, boolean canChangeMode,
            int powerRole, boolean canChangePowerRole,
            int dataRole, boolean canChangeDataRole, IndentingPrintWriter pw) {
        synchronized (mLock) {
            final SimulatedPortInfo portInfo = mSimulatedPorts.get(portId);
            if (portInfo == null) {
                pw.println("Cannot connect simulated port which does not exist.");
                return;
            }

            if (mode == 0 || powerRole == 0 || dataRole == 0) {
                pw.println("Cannot connect simulated port in null mode, "
                        + "power role, or data role.");
                return;
            }

            if ((portInfo.mSupportedModes & mode) == 0) {
                pw.println("Simulated port does not support mode: " + UsbPort.modeToString(mode));
                return;
            }

            pw.println("Connecting simulated port: portId=" + portId
                    + ", mode=" + UsbPort.modeToString(mode)
                    + ", canChangeMode=" + canChangeMode
                    + ", powerRole=" + UsbPort.powerRoleToString(powerRole)
                    + ", canChangePowerRole=" + canChangePowerRole
                    + ", dataRole=" + UsbPort.dataRoleToString(dataRole)
                    + ", canChangeDataRole=" + canChangeDataRole);
            portInfo.mCurrentMode = mode;
            portInfo.mCanChangeMode = canChangeMode;
            portInfo.mCurrentPowerRole = powerRole;
            portInfo.mCanChangePowerRole = canChangePowerRole;
            portInfo.mCurrentDataRole = dataRole;
            portInfo.mCanChangeDataRole = canChangeDataRole;
            updatePortsLocked(pw);
        }
    }

    public void disconnectSimulatedPort(String portId, IndentingPrintWriter pw) {
        synchronized (mLock) {
            final SimulatedPortInfo portInfo = mSimulatedPorts.get(portId);
            if (portInfo == null) {
                pw.println("Cannot disconnect simulated port which does not exist.");
                return;
            }

            pw.println("Disconnecting simulated port: portId=" + portId);
            portInfo.mCurrentMode = 0;
            portInfo.mCanChangeMode = false;
            portInfo.mCurrentPowerRole = 0;
            portInfo.mCanChangePowerRole = false;
            portInfo.mCurrentDataRole = 0;
            portInfo.mCanChangeDataRole = false;
            updatePortsLocked(pw);
        }
    }

    public void removeSimulatedPort(String portId, IndentingPrintWriter pw) {
        synchronized (mLock) {
            final int index = mSimulatedPorts.indexOfKey(portId);
            if (index < 0) {
                pw.println("Cannot remove simulated port which does not exist.");
                return;
            }

            pw.println("Disconnecting simulated port: portId=" + portId);
            mSimulatedPorts.removeAt(index);
            updatePortsLocked(pw);
        }
    }

    public void resetSimulation(IndentingPrintWriter pw) {
        synchronized (mLock) {
            pw.println("Removing all simulated ports and ending simulation.");
            if (!mSimulatedPorts.isEmpty()) {
                mSimulatedPorts.clear();
                updatePortsLocked(pw);
            }
        }
    }

    public void dump(IndentingPrintWriter pw) {
        synchronized (mLock) {
            pw.print("USB Port State:");
            if (!mSimulatedPorts.isEmpty()) {
                pw.print(" (simulation active; end with 'dumpsys usb reset')");
            }
            pw.println();

            if (mPorts.isEmpty()) {
                pw.println("  <no ports>");
            } else {
                for (PortInfo portInfo : mPorts.values()) {
                    pw.println("  " + portInfo.mUsbPort.getId() + ": " + portInfo);
                }
            }
        }
    }

    private void updatePortsLocked(IndentingPrintWriter pw) {
        // Assume all ports are gone unless informed otherwise.
        // Kind of pessimistic but simple.
        for (int i = mPorts.size(); i-- > 0; ) {
            mPorts.valueAt(i).mDisposition = PortInfo.DISPOSITION_REMOVED;
        }

        // Enumerate all extant ports.
        if (!mSimulatedPorts.isEmpty()) {
            final int count = mSimulatedPorts.size();
            for (int i = 0; i < count; i++) {
                final SimulatedPortInfo 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);
                 }
            }
        }

        // Process the updates.
        // Once finished, the list of ports will only contain ports in DISPOSITION_READY.
        for (int i = mPorts.size(); i-- > 0; ) {
            final PortInfo portInfo = mPorts.valueAt(i);
            switch (portInfo.mDisposition) {
                case PortInfo.DISPOSITION_ADDED:
                    handlePortAddedLocked(portInfo, pw);
                    portInfo.mDisposition = PortInfo.DISPOSITION_READY;
                    break;
                case PortInfo.DISPOSITION_CHANGED:
                    handlePortChangedLocked(portInfo, pw);
                    portInfo.mDisposition = PortInfo.DISPOSITION_READY;
                    break;
                case PortInfo.DISPOSITION_REMOVED:
                    mPorts.removeAt(i);
                    portInfo.mUsbPortStatus = null; // must do this early
                    handlePortRemovedLocked(portInfo, pw);
                    break;
            }
        }
    }

    // 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) {
        // 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));
                currentMode = 0;
            }
        }

        // Determine the supported role combinations.
        // Note that the policy is designed to prefer setting the power and data
        // role independently rather than changing the mode.
        int supportedRoleCombinations = UsbPort.combineRolesAsBit(
                currentPowerRole, currentDataRole);
        if (currentMode != 0 && currentPowerRole != 0 && currentDataRole != 0) {
            if (canChangePowerRole && canChangeDataRole) {
                // 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;
            } else if (canChangePowerRole) {
                // Can only change power role.
                // Assume data role must remain at its current value.
                supportedRoleCombinations |= UsbPort.combineRolesAsBit(
                        UsbPort.POWER_ROLE_SOURCE, currentDataRole);
                supportedRoleCombinations |= UsbPort.combineRolesAsBit(
                        UsbPort.POWER_ROLE_SINK, currentDataRole);
            } else if (canChangeDataRole) {
                // Can only change data role.
                // Assume power role must remain at its current value.
                supportedRoleCombinations |= UsbPort.combineRolesAsBit(
                        currentPowerRole, UsbPort.DATA_ROLE_HOST);
                supportedRoleCombinations |= UsbPort.combineRolesAsBit(
                        currentPowerRole, UsbPort.DATA_ROLE_DEVICE);
            } else if (canChangeMode) {
                // Can only change the mode.
                // Assume both standard UFP and DFP configurations will become available
                // when this happens.
                supportedRoleCombinations |= COMBO_SOURCE_HOST | COMBO_SINK_DEVICE;
            }
        }

        // Update the port data structures.
        PortInfo portInfo = mPorts.get(portId);
        if (portInfo == null) {
            portInfo = new PortInfo(portId, supportedModes);
            portInfo.setStatus(currentMode, canChangeMode,
                    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));
            }

            if (portInfo.setStatus(currentMode, canChangeMode,
                    currentPowerRole, canChangePowerRole,
                    currentDataRole, canChangeDataRole,
                    supportedRoleCombinations)) {
                portInfo.mDisposition = PortInfo.DISPOSITION_CHANGED;
            } else {
                portInfo.mDisposition = PortInfo.DISPOSITION_READY;
            }
        }
    }

    private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
        logAndPrint(Log.INFO, pw, "USB port added: " + portInfo);
        sendPortChangedBroadcastLocked(portInfo);
    }

    private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
        logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo);
        sendPortChangedBroadcastLocked(portInfo);
    }

    private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
        logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo);
        sendPortChangedBroadcastLocked(portInfo);
    }

    private void sendPortChangedBroadcastLocked(PortInfo portInfo) {
        final Intent intent = new Intent(UsbManager.ACTION_USB_PORT_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        intent.putExtra(UsbManager.EXTRA_PORT, portInfo.mUsbPort);
        intent.putExtra(UsbManager.EXTRA_PORT_STATUS, portInfo.mUsbPortStatus);

        // Guard against possible reentrance by posting the broadcast from the handler
        // instead of from within the critical section.
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
            }
        });
    }

    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) {
            pw.println(msg);
        }
    }

    private final Handler mHandler = new Handler(FgThread.get().getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_UPDATE_PORTS: {
                    synchronized (mLock) {
                        updatePortsLocked(null);
                    }
                    break;
                }
            }
        }
    };

    private final UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEvent event) {
            scheduleUpdatePorts();
        }
    };

    /**
     * Describes a USB port.
     */
    private static final class PortInfo {
        public static final int DISPOSITION_ADDED = 0;
        public static final int DISPOSITION_CHANGED = 1;
        public static final int DISPOSITION_READY = 2;
        public static final int DISPOSITION_REMOVED = 3;

        public final UsbPort mUsbPort;
        public UsbPortStatus mUsbPortStatus;
        public boolean mCanChangeMode;
        public boolean mCanChangePowerRole;
        public boolean mCanChangeDataRole;
        public int mDisposition; // default initialized to 0 which means added

        public PortInfo(String portId, int supportedModes) {
            mUsbPort = new UsbPort(portId, supportedModes);
        }

        public boolean setStatus(int currentMode, boolean canChangeMode,
                int currentPowerRole, boolean canChangePowerRole,
                int currentDataRole, boolean canChangeDataRole,
                int supportedRoleCombinations) {
            mCanChangeMode = canChangeMode;
            mCanChangePowerRole = canChangePowerRole;
            mCanChangeDataRole = canChangeDataRole;
            if (mUsbPortStatus == null
                    || mUsbPortStatus.getCurrentMode() != currentMode
                    || mUsbPortStatus.getCurrentPowerRole() != currentPowerRole
                    || mUsbPortStatus.getCurrentDataRole() != currentDataRole
                    || mUsbPortStatus.getSupportedRoleCombinations()
                            != supportedRoleCombinations) {
                mUsbPortStatus = new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
                        supportedRoleCombinations);
                return true;
            }
            return false;
        }

        @Override
        public String toString() {
            return "port=" + mUsbPort + ", status=" + mUsbPortStatus
                    + ", canChangeMode=" + mCanChangeMode
                    + ", canChangePowerRole=" + mCanChangePowerRole
                    + ", canChangeDataRole=" + mCanChangeDataRole;
        }
    }

    /**
     * Describes a simulated USB port.
     * Roughly mirrors the information we would ordinarily get from the kernel.
     */
    private static final class SimulatedPortInfo {
        public final String mPortId;
        public final int mSupportedModes;
        public int mCurrentMode;
        public boolean mCanChangeMode;
        public int mCurrentPowerRole;
        public boolean mCanChangePowerRole;
        public int mCurrentDataRole;
        public boolean mCanChangeDataRole;

        public SimulatedPortInfo(String portId, int supportedModes) {
            mPortId = portId;
            mSupportedModes = supportedModes;
        }
    }
}
