FileDocCategorySizeDatePackage
MountListener.javaAPI DocAndroid 1.5 API11449Wed May 06 22:42:00 BST 2009com.android.server

MountListener

public final class MountListener extends Object implements Runnable
Thread for communicating with the vol service daemon via a local socket. Events received from the daemon are passed to the MountService instance, and the MountService instance calls MountListener to send commands to the daemon.

Fields Summary
private static final String
TAG
private static final String
VOLD_SOCKET
private static final String
VOLD_CMD_ENABLE_UMS
private static final String
VOLD_CMD_DISABLE_UMS
private static final String
VOLD_CMD_SEND_UMS_STATUS
private static final String
VOLD_CMD_MOUNT_VOLUME
private static final String
VOLD_CMD_EJECT_MEDIA
private static final String
VOLD_CMD_FORMAT_MEDIA
private static final String
VOLD_EVT_UMS_ENABLED
private static final String
VOLD_EVT_UMS_DISABLED
private static final String
VOLD_EVT_UMS_CONNECTED
private static final String
VOLD_EVT_UMS_DISCONNECTED
private static final String
VOLD_EVT_NOMEDIA
private static final String
VOLD_EVT_UNMOUNTED
private static final String
VOLD_EVT_MOUNTED
private static final String
VOLD_EVT_MOUNTED_RO
private static final String
VOLD_EVT_UMS
private static final String
VOLD_EVT_BAD_REMOVAL
private static final String
VOLD_EVT_DAMAGED
private static final String
VOLD_EVT_CHECKING
private static final String
VOLD_EVT_NOFS
private static final String
VOLD_EVT_EJECTING
private MountService
mService
MountService that handles events received from the vol service daemon
private OutputStream
mOutputStream
Stream for sending commands to the vol service daemon.
private boolean
mUmsEnabled
Cached value indicating whether or not USB mass storage is enabled.
private boolean
mUmsConnected
Cached value indicating whether or not USB mass storage is connected.
Constructors Summary
MountListener(MountService service)
Constructor for MountListener

param
service The MountListener we are handling communication with USB daemon for.


                                         
       
        mService = service;   
    
Methods Summary
public voidejectMedia(java.lang.String mountPoint)
Unmount media at given mount point.

        writeCommand2(VOLD_CMD_EJECT_MEDIA, mountPoint);
    
public voidformatMedia(java.lang.String mountPoint)
Format media at given mount point.

        writeCommand2(VOLD_CMD_FORMAT_MEDIA, mountPoint);
    
booleangetMassStorageConnected()

return
true if USB mass storage is connected

        return mUmsConnected;
    
booleangetMassStorageEnabled()

return
true if USB mass storage is enabled

        return mUmsEnabled;
    
private voidhandleEvent(java.lang.String event)
Process and dispatches events received from the vol service daemon

param
event An event received from the vol service daemon

        if (Config.LOGD) Log.d(TAG, "handleEvent " + event);
    
        int colonIndex = event.indexOf(':");
        String path = (colonIndex > 0 ? event.substring(colonIndex + 1) : null);
        
        if (event.equals(VOLD_EVT_UMS_ENABLED)) {
            mUmsEnabled = true;
        } else if (event.equals(VOLD_EVT_UMS_DISABLED)) {
            mUmsEnabled = false;
        } else if (event.equals(VOLD_EVT_UMS_CONNECTED)) {
            mUmsConnected = true;
            mService.notifyUmsConnected();
        } else if (event.equals(VOLD_EVT_UMS_DISCONNECTED)) {
            mUmsConnected = false;        
            mService.notifyUmsDisconnected();
        } else if (event.startsWith(VOLD_EVT_NOMEDIA)) {
            mService.notifyMediaRemoved(path);
        } else if (event.startsWith(VOLD_EVT_UNMOUNTED)) {
            mService.notifyMediaUnmounted(path);
        } else if (event.startsWith(VOLD_EVT_CHECKING)) {
            mService.notifyMediaChecking(path);
        } else if (event.startsWith(VOLD_EVT_NOFS)) {
            mService.notifyMediaNoFs(path);
        } else if (event.startsWith(VOLD_EVT_MOUNTED)) {
            mService.notifyMediaMounted(path, false);
        } else if (event.startsWith(VOLD_EVT_MOUNTED_RO)) {
            mService.notifyMediaMounted(path, true);
        } else if (event.startsWith(VOLD_EVT_UMS)) {
            mService.notifyMediaShared(path);
        } else if (event.startsWith(VOLD_EVT_BAD_REMOVAL)) {
            mService.notifyMediaBadRemoval(path);
            // also send media eject intent, to notify apps to close any open
            // files on the media.
            mService.notifyMediaEject(path);
        } else if (event.startsWith(VOLD_EVT_DAMAGED)) {
            mService.notifyMediaUnmountable(path);
        } else if (event.startsWith(VOLD_EVT_EJECTING)) {
            mService.notifyMediaEject(path);
        }    
    
private voidlistenToSocket()
Opens a socket to communicate with the mount service daemon and listens for events from the daemon.

       LocalSocket socket = null;

        try {
            socket = new LocalSocket();
            LocalSocketAddress address = new LocalSocketAddress(VOLD_SOCKET, 
                    LocalSocketAddress.Namespace.RESERVED);

            socket.connect(address);

            InputStream inputStream = socket.getInputStream();
            mOutputStream = socket.getOutputStream();

            byte[] buffer = new byte[100];

            writeCommand(VOLD_CMD_SEND_UMS_STATUS);
            
            while (true) {
                int count = inputStream.read(buffer);
                if (count < 0) break;

                int start = 0;
                for (int i = 0; i < count; i++) {
                    if (buffer[i] == 0) {
                        String event = new String(buffer, start, i - start);
                        handleEvent(event);
                        start = i + 1;
                    }                   
                }
            }                
        } catch (IOException ex) {
            // This exception is normal when running in desktop simulator 
            // where there is no mount daemon to talk to

            // log("IOException in listenToSocket");
        }
        
        synchronized (this) {
            if (mOutputStream != null) {
                try {
                    mOutputStream.close();
                } catch (IOException e) {
                    Log.w(TAG, "IOException closing output stream");
                }
                
                mOutputStream = null;
            }
        }
        
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (IOException ex) {
            Log.w(TAG, "IOException closing socket");
        }
       
        /*
         * Sleep before trying again.
         * This should not happen except while debugging.
         * Without this sleep, the emulator will spin and
         * create tons of throwaway LocalSockets, making
         * system_server GC constantly.
         */
        Log.e(TAG, "Failed to connect to vold", new IllegalStateException());
        SystemClock.sleep(2000);
    
public voidmountMedia(java.lang.String mountPoint)
Mount media at given mount point.

        writeCommand2(VOLD_CMD_MOUNT_VOLUME, mountPoint);
    
public voidrun()
Main loop for MountListener thread.

        // ugly hack for the simulator.
        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
            SystemProperties.set("EXTERNAL_STORAGE_STATE", Environment.MEDIA_MOUNTED);
            // usbd does not run in the simulator, so send a fake device mounted event to trigger the Media Scanner
            mService.notifyMediaMounted(Environment.getExternalStorageDirectory().getPath(), false);
            
            // no usbd in the simulator, so no point in hanging around.
            return;
        }
    
        try {  
            while (true) {
                listenToSocket();
            }
        } catch (Throwable t) {
            // catch all Throwables so we don't bring down the system process
            Log.e(TAG, "Fatal error " + t + " in MountListener thread!");
        }
    
voidsetMassStorageEnabled(boolean enable)
Enables or disables USB mass storage support.

param
enable true to enable USB mass storage support

        writeCommand(enable ? VOLD_CMD_ENABLE_UMS : VOLD_CMD_DISABLE_UMS);
    
private voidwriteCommand(java.lang.String command)
Sends a command to the mount service daemon via a local socket

param
command The command to send to the mount service daemon

        writeCommand2(command, null);
    
private voidwriteCommand2(java.lang.String command, java.lang.String argument)
Sends a command to the mount service daemon via a local socket with a single argument

param
command The command to send to the mount service daemon
param
argument The argument to send with the command (or null)

        synchronized (this) {
            if (mOutputStream == null) {
                Log.e(TAG, "No connection to vold", new IllegalStateException());
            } else {
                StringBuilder builder = new StringBuilder(command);
                if (argument != null) {
                    builder.append(argument);
                }
                builder.append('\0");

                try {
                    mOutputStream.write(builder.toString().getBytes());
                } catch (IOException ex) {
                    Log.e(TAG, "IOException in writeCommand", ex);
                }
            }
        }