Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 930898b2 authored by Steve Kondik's avatar Steve Kondik Committed by Gerrit Code Review
Browse files

Merge "Support changing USB configuration without usb_configuration switch." into gingerbread

parents 9258d794 a3676980
Loading
Loading
Loading
Loading
+117 −92
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.os.UEventObserver;
import android.provider.Settings;
import android.util.Log;
@@ -89,6 +90,7 @@ public class UsbService extends IUsbManager.Stub {
    // current connected and configuration state
    private int mConnected;
    private int mConfiguration;
    private boolean mHasUsbService = false;
    private boolean mLegacy = false;

    // last broadcasted connected and configuration state
@@ -146,23 +148,14 @@ public class UsbService extends IUsbManager.Stub {
        }
    }

    /*
     * Listens for uevent messages from the kernel to monitor the USB state (device mode)
     */
    private final UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Slog.v(TAG, "USB UEVENT: " + event.toString());
            }

            synchronized (mLock) {
                char[] buffer = new char[1024];
                if((new File(USB_LEGACY_FUNCTIONS_PATH)).exists()) {
    private void updateFunctions(File dir, boolean useEnableFiles) {
        try {
                        File[] files = new File(USB_LEGACY_FUNCTIONS_PATH).listFiles();
            char[] buffer = new char[1024];
            File[] files = dir.listFiles();
            for (int i = 0; i < files.length; i++) {
                            FileReader reader = new FileReader(files[i]);
                File file = useEnableFiles ? new File(files[i], "enable") : files[i];
                FileReader reader = new FileReader(file);
                int len = reader.read(buffer, 0, 1024);
                reader.close();
                try {
@@ -180,11 +173,39 @@ public class UsbService extends IUsbManager.Stub {
            Slog.e(TAG, "" , e);
        }
    }

    private void updateLegacyFunctionsLocked() {
        if (mLegacy) {
            File compositeDir = new File(USB_COMPOSITE_CLASS_PATH);
            if (compositeDir.exists()) {
                updateFunctions(compositeDir, true);
            } else {
                compositeDir = new File(USB_LEGACY_FUNCTIONS_PATH);
                if (compositeDir.exists()) {
                    updateFunctions(compositeDir, false);
                }
            }
        }
    }

    /*
     * Listens for uevent messages from the kernel to monitor the USB state (device mode)
     */
    private final UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Slog.v(TAG, "USB UEVENT: " + event.toString());
            }

            synchronized (mLock) {
                updateLegacyFunctionsLocked();

                String name = event.get("SWITCH_NAME");
                String state = event.get("SWITCH_STATE");
                if (name != null && state != null) {
                    try {
                        if (mLegacy) {
                        if (mLegacy && !mHasUsbService) {
                            int intState = ("online".equals(state) ? 1 : 0);
                            if ("usb_mass_storage".equals(name)) {
                                mConnected = intState;
@@ -195,7 +216,7 @@ public class UsbService extends IUsbManager.Stub {
                                    update(mConnected == 0);
                                }
                            }
                        } else {
                        } else if (!mHasUsbService) {
                            int intState = Integer.parseInt(state);
                            if ("usb_connected".equals(name)) {
                                mConnected = intState;
@@ -243,6 +264,24 @@ public class UsbService extends IUsbManager.Stub {
        }
    };

    private final BroadcastReceiver mUsbReconfiguredReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            mConnected = intent.getBooleanExtra("connected", false) ? 1 : 0;
            if (intent.hasExtra("configuration")) {
                mConfiguration = intent.getIntExtra("configuration", 0);
            }

            Log.d(TAG, "Got USB reconfiguration event, connected " + mConnected);

            synchronized (mLock) {
                updateLegacyFunctionsLocked();
                if (mSystemReady) {
                    update(mConnected == 0);
                }
            }
        }
    };

    public UsbService(Context context) {
        mContext = context;
        mDeviceManager = new UsbDeviceSettingsManager(context);
@@ -253,7 +292,7 @@ public class UsbService extends IUsbManager.Stub {
            init();  // set initial status

            // Watch for USB configuration changes
            if (mConfiguration >= 0) {
            if (mConfiguration >= 0 && !mHasUsbService) {
                if (mLegacy) {
                    mUEventObserver.startObserving(USB_LEGACY_MATCH);
                } else {
@@ -269,6 +308,8 @@ public class UsbService extends IUsbManager.Stub {
        char[] buffer = new char[1024];
        boolean inAccessoryMode = false;

        mHasUsbService = SystemProperties.getInt("ro.usb.use_custom_service", 0) != 0;

        // Read initial USB state (device mode)
        mConfiguration = -1;
        try {
@@ -305,46 +346,45 @@ public class UsbService extends IUsbManager.Stub {
            return;
        }

        if((new File(USB_COMPOSITE_CLASS_PATH)).exists()){
            // Read initial list of enabled and disabled functions (device mode)
            try {
                File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
                for (int i = 0; i < files.length; i++) {
                    File file = new File(files[i], "enable");
                    FileReader reader = new FileReader(file);
                    int len = reader.read(buffer, 0, 1024);
                    reader.close();
                    int value = Integer.valueOf((new String(buffer, 0, len)).trim());
                    String functionName = files[i].getName();
                    if (value == 1) {
                        mEnabledFunctions.add(functionName);
                        if (UsbManager.USB_FUNCTION_ACCESSORY.equals(functionName)) {
                            // The USB accessory driver is on by default, but it might have been
                            // enabled before the USB service has initialized.
                            inAccessoryMode = true;
                        } else if (!UsbManager.USB_FUNCTION_ADB.equals(functionName)) {
                            // adb is enabled/disabled automatically by the adbd daemon,
                            // so don't treat it as a default function.
                            mDefaultFunctions.add(functionName);
                        }
        File compositeDir = new File(USB_COMPOSITE_CLASS_PATH);
        if (compositeDir.exists()) {
            inAccessoryMode |= initFunctions(compositeDir, true, buffer);
        } else {
                        mDisabledFunctions.add(functionName);
            Slog.w(TAG, "This kernel does not have USB composite class support");
            compositeDir = new File(USB_LEGACY_FUNCTIONS_PATH);
            if (compositeDir.exists()) {
                inAccessoryMode |= initFunctions(compositeDir, false, buffer);
            } else if (mLegacy) {
                mDisabledFunctions.add(UsbManager.USB_FUNCTION_MASS_STORAGE);
            }
        }
            } catch (FileNotFoundException e) {
                Slog.w(TAG, "This kernel does not have USB composite class support");
            } catch (Exception e) {
                Slog.e(TAG, "" , e);

        // handle the case where an accessory switched the driver to accessory mode
        // before the framework finished booting
        if (inAccessoryMode && !mLegacy) {
            readCurrentAccessoryLocked();

            // FIXME - if we booted in accessory mode, then we have no way to figure out
            // which functions are enabled by default.
            // For now, assume that MTP or mass storage are the only possibilities
            if (mDisabledFunctions.contains(UsbManager.USB_FUNCTION_MTP)) {
                mDefaultFunctions.add(UsbManager.USB_FUNCTION_MTP);
            } else if (mDisabledFunctions.contains(UsbManager.USB_FUNCTION_MASS_STORAGE)) {
                mDefaultFunctions.add(UsbManager.USB_FUNCTION_MASS_STORAGE);
            }
        }
        else if((new File(USB_LEGACY_FUNCTIONS_PATH)).exists()) {
    }

    /* returns true if USB is in accessory mode */
    private boolean initFunctions(File dir, boolean useEnableFiles, char[] buffer) {
        boolean inAccessoryMode = false;
        try {
                File[] files = new File(USB_LEGACY_FUNCTIONS_PATH).listFiles();
            File[] files = dir.listFiles();
            for (int i = 0; i < files.length; i++) {
                    FileReader reader = new FileReader(files[i]);
                File file = useEnableFiles ? new File(files[i], "enable") : files[i];
                FileReader reader = new FileReader(file);
                int len = reader.read(buffer, 0, 1024);
                reader.close();
                    try{
                int value = Integer.valueOf((new String(buffer, 0, len)).trim());
                String functionName = files[i].getName();
                if (value == 1) {
@@ -362,31 +402,10 @@ public class UsbService extends IUsbManager.Stub {
                    mDisabledFunctions.add(functionName);
                }
            }
                    catch(NumberFormatException nfe){
                        Slog.d(TAG, files[i].getName()+" contains non-numeric data");
                    }
                }
        } catch (Exception e) {
            Slog.e(TAG, "" , e);
        }
        }
        else if (mLegacy)
            mDisabledFunctions.add(UsbManager.USB_FUNCTION_MASS_STORAGE);

        // handle the case where an accessory switched the driver to accessory mode
        // before the framework finished booting
        if (inAccessoryMode && !mLegacy) {
            readCurrentAccessoryLocked();

            // FIXME - if we booted in accessory mode, then we have no way to figure out
            // which functions are enabled by default.
            // For now, assume that MTP or mass storage are the only possibilities
            if (mDisabledFunctions.contains(UsbManager.USB_FUNCTION_MTP)) {
                mDefaultFunctions.add(UsbManager.USB_FUNCTION_MTP);
            } else if (mDisabledFunctions.contains(UsbManager.USB_FUNCTION_MASS_STORAGE)) {
                mDefaultFunctions.add(UsbManager.USB_FUNCTION_MASS_STORAGE);
            }
        }
        return inAccessoryMode;
    }

    public void systemReady() {
@@ -399,6 +418,12 @@ public class UsbService extends IUsbManager.Stub {
                mContext.registerReceiver(mBootCompletedReceiver,
                        new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
            }

            if (mHasUsbService) {
                mContext.registerReceiver(mUsbReconfiguredReceiver,
                        new IntentFilter("com.android.internal.usb.reconfigured"));
            }

            mSystemReady = true;
        }
    }