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

Commit 1f13a693 authored by jianzhou's avatar jianzhou Committed by Steve Kondik
Browse files

UsbSettings: Add UMS mode support.

Add Usb Mass storage mode support for Android device;
Fix SD card can not be mounted to device when usb cable
is plugged in or unplugged fast and frequently.

Change-Id: Iff6de6b1b3e066f4a4ab610ae3fe10b22f5b0822
parent 4f77a414
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.HandlerThread;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


@@ -272,6 +273,15 @@ public class StorageNotification extends SystemUI {
     */
     */
    private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon,
    private synchronized void setUsbStorageNotification(int titleId, int messageId, int icon,
            boolean sound, boolean visible, PendingIntent pi) {
            boolean sound, boolean visible, PendingIntent pi) {
        // force to show UsbSettings screen to select usb mode if property is true
        if (SystemProperties.getBoolean("persist.sys.ums", true)) {
            titleId = 0;
            messageId = 0;
            icon = 0;
            sound = false;
            visible = false;
            pi = null;
        }


        if (!visible && mUsbStorageNotification == null) {
        if (!visible && mUsbStorageNotification == null) {
            return;
            return;
+84 −47
Original line number Original line Diff line number Diff line
@@ -751,6 +751,7 @@ class MountService extends IMountService.Stub
                MountServiceBinderListener bl = mListeners.get(i);
                MountServiceBinderListener bl = mListeners.get(i);
                try {
                try {
                    bl.mListener.onStorageStateChanged(path, oldState, state);
                    bl.mListener.onStorageStateChanged(path, oldState, state);
                    disbaleEnableUMSAfterStorageChanged(state);
                } catch (RemoteException rex) {
                } catch (RemoteException rex) {
                    Slog.e(TAG, "Listener dead");
                    Slog.e(TAG, "Listener dead");
                    mListeners.remove(i);
                    mListeners.remove(i);
@@ -761,6 +762,20 @@ class MountService extends IMountService.Stub
        }
        }
    }
    }


    private void disbaleEnableUMSAfterStorageChanged(String state){
        if (state.equals(Environment.MEDIA_SHARED)) {
            if (!mUmsAvailable) {
                setUsbMassStorageEnabled(false);
            }
        } else if (state.equals(Environment.MEDIA_MOUNTED)) {
            String usbMode = new UsbManager(null, null).getDefaultFunction();
            final boolean isUmsMode = UsbManager.USB_FUNCTION_MASS_STORAGE.equals(usbMode);
            if (mUmsAvailable && isUmsMode) {
                setUsbMassStorageEnabled(true);
            }
        }
    }

    /**
    /**
     * Callback from NativeDaemonConnector
     * Callback from NativeDaemonConnector
     */
     */
@@ -1236,10 +1251,14 @@ class MountService extends IMountService.Stub
            mSendUmsConnectedOnBoot = avail;
            mSendUmsConnectedOnBoot = avail;
        }
        }


        final StorageVolume primary = getPrimaryPhysicalVolume();
        final ArrayList<String> volumes = getShareableVolumes();
        if (avail == false && primary != null
        boolean mediaShared = false;
                && Environment.MEDIA_SHARED.equals(getVolumeState(primary.getPath()))) {
        for (String path : volumes) {
            final String path = primary.getPath();
            if (getVolumeState(path).equals(Environment.MEDIA_SHARED))
                mediaShared = true;
        }

        if (!avail && mediaShared) {
            /*
            /*
             * USB mass storage disconnected while enabled
             * USB mass storage disconnected while enabled
             */
             */
@@ -1249,17 +1268,24 @@ class MountService extends IMountService.Stub
                    try {
                    try {
                        int rc;
                        int rc;
                        Slog.w(TAG, "Disabling UMS after cable disconnect");
                        Slog.w(TAG, "Disabling UMS after cable disconnect");
                        for (String path : volumes) {
                            if (getVolumeState(path).equals(Environment.MEDIA_SHARED)) {
                                doShareUnshareVolume(path, "ums", false);
                                doShareUnshareVolume(path, "ums", false);
                        if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
                                rc = doMountVolume(path);
                                if (rc != StorageResultCode.OperationSucceeded) {
                                    Slog.e(TAG, String.format(
                                    Slog.e(TAG, String.format(
                                        "Failed to remount {%s} on UMS enabled-disconnect (%d)",
                                        "Failed to remount {%s} on UMS enabled-disconnect (%d)",
                                                path, rc));
                                                path, rc));
                                }
                                }
                            }
                        }
                    } catch (Exception ex) {
                    } catch (Exception ex) {
                        Slog.w(TAG, "Failed to mount media on UMS enabled-disconnect", ex);
                        Slog.w(TAG, "Failed to mount media on UMS enabled-disconnect", ex);
                    }
                    }
                }
                }
            }.start();
            }.start();
        } else if (avail && !mediaShared) {
            setUsbMassStorageEnabled(true);
        }
        }
    }
    }


@@ -1473,7 +1499,9 @@ class MountService extends IMountService.Stub


        // Watch for USB changes on primary volume
        // Watch for USB changes on primary volume
        final StorageVolume primary = getPrimaryPhysicalVolume();
        final StorageVolume primary = getPrimaryPhysicalVolume();
        if (primary != null && primary.allowMassStorage()) {
        if ((primary != null && primary.allowMassStorage()) ||
            //ignore primary config, force to register if property is true
            SystemProperties.getBoolean("persist.sys.ums", true)) {
            mContext.registerReceiver(
            mContext.registerReceiver(
                    mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE), null, mHandler);
                    mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE), null, mHandler);
        }
        }
@@ -1602,6 +1630,19 @@ class MountService extends IMountService.Stub
        }
        }
    }
    }


    private ArrayList<String> getShareableVolumes() {
        // Sharable volumes have android:allowMassStorage="true" in storage_list.xml
        ArrayList<String> volumesToMount = new ArrayList<String>();
        synchronized (mVolumes) {
            for (StorageVolume v : mVolumes) {
                if (v.allowMassStorage()) {
                    volumesToMount.add(v.getPath());
                }
            }
        }
        return volumesToMount;
    }

    public boolean isUsbMassStorageConnected() {
    public boolean isUsbMassStorageConnected() {
        waitForReady();
        waitForReady();


@@ -1618,15 +1659,11 @@ class MountService extends IMountService.Stub
        validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
        validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
        validateUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
        validateUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);


        final StorageVolume primary = getPrimaryPhysicalVolume();
        if (primary == null) return;

        // TODO: Add support for multiple share methods
        // TODO: Add support for multiple share methods

        for (String path : getShareableVolumes()) {
            /*
            /*
             * If the volume is mounted and we're enabling then unmount it
             * If the volume is mounted and we're enabling then unmount it
             */
             */
        String path = primary.getPath();
            String vs = getVolumeState(path);
            String vs = getVolumeState(path);
            String method = "ums";
            String method = "ums";
            if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
            if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
@@ -1653,16 +1690,16 @@ class MountService extends IMountService.Stub
                }
                }
            }
            }
        }
        }
    }


    public boolean isUsbMassStorageEnabled() {
    public boolean isUsbMassStorageEnabled() {
        waitForReady();
        waitForReady();

        for (String path : getShareableVolumes()) {
        final StorageVolume primary = getPrimaryPhysicalVolume();
            if (doGetVolumeShared(path, "ums"))
        if (primary != null) {
                return true;
            return doGetVolumeShared(primary.getPath(), "ums");
        } else {
            return false;
        }
        }
        // no volume is shared
        return false;
    }
    }


    /**
    /**