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

MountService

public class MountService extends IMountService.Stub
MountService implements an to the mount service daemon
hide

Fields Summary
private static final String
TAG
private android.content.Context
mContext
Binder context for this service
private MountListener
mListener
listener object for communicating with the mount service daemon
private android.app.Notification
mUsbStorageNotification
The notification that is shown when a USB mass storage host is connected.

This is lazily created, so use {@link #setUsbStorageNotification()}.

private android.app.Notification
mMediaStorageNotification
The notification that is shown when the following media events occur: - Media is being checked - Media is blank (or unknown filesystem) - Media is corrupt - Media is safe to unmount - Media is missing

This is lazily created, so use {@link #setMediaStorageNotification()}.

private boolean
mShowSafeUnmountNotificationWhenUnmounted
private boolean
mPlaySounds
private boolean
mMounted
private boolean
mAutoStartUms
android.content.BroadcastReceiver
mBroadcastReceiver
Constructors Summary
public MountService(android.content.Context context)
Constructs a new MountService instance

param
context Binder context for this service


                       
       
        mContext = context;

        // Register a BOOT_COMPLETED handler so that we can start
        // MountListener. We defer the startup so that we don't
        // start processing events before we ought-to
        mContext.registerReceiver(mBroadcastReceiver,
                new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);

        mListener =  new MountListener(this);       
        mShowSafeUnmountNotificationWhenUnmounted = false;

        mPlaySounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1");

        mAutoStartUms = SystemProperties.get("persist.service.mount.umsauto", "0").equals("1");
    
Methods Summary
public voidformatMedia(java.lang.String formatPath)
Attempt to format external media

        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS) 
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires MOUNT_FORMAT_FILESYSTEMS permission");
        }

        mListener.formatMedia(formatPath);
    
public booleangetAutoStartUms()
Returns true if we auto-start UMS on cable insertion.

        return mAutoStartUms;
    
public booleangetMassStorageConnected()

return
true if USB mass storage is connected.

        return mListener.getMassStorageConnected();
    
public booleangetMassStorageEnabled()

return
true if USB mass storage support is enabled.


                  
         
        return mListener.getMassStorageEnabled();
    
private synchronized booleangetMediaStorageNotificationDismissable()

        if ((mMediaStorageNotification != null) &&
            ((mMediaStorageNotification.flags & Notification.FLAG_AUTO_CANCEL) ==
                    Notification.FLAG_AUTO_CANCEL))
            return true;

        return false;
    
public booleangetPlayNotificationSounds()
Returns true if we're playing media notification sounds.

        return mPlaySounds;
    
voidhandlePossibleExplicitUnmountBroadcast(java.lang.String path)

        if (mMounted) {
            mMounted = false;
            Intent intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, 
                    Uri.parse("file://" + path));
            mContext.sendBroadcast(intent);
        }
    
public voidmountMedia(java.lang.String mountPath)
Attempt to mount external media

        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission");
        }
        mListener.mountMedia(mountPath);
    
voidnotifyMediaBadRemoval(java.lang.String path)
Broadcasts the media bad removal event to all clients.

        updateUsbMassStorageNotification(true, false);
        setMediaStorageNotification(com.android.internal.R.string.ext_media_badremoval_notification_title,
                                    com.android.internal.R.string.ext_media_badremoval_notification_message,
                                    com.android.internal.R.drawable.stat_sys_warning,
                                    true, true, null);

        handlePossibleExplicitUnmountBroadcast(path);
        Intent intent = new Intent(Intent.ACTION_MEDIA_BAD_REMOVAL, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);

        intent = new Intent(Intent.ACTION_MEDIA_REMOVED, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaChecking(java.lang.String path)
Broadcasts the media checking event to all clients.

        setMediaStorageNotification(
                com.android.internal.R.string.ext_media_checking_notification_title,
                com.android.internal.R.string.ext_media_checking_notification_message,
                com.android.internal.R.drawable.stat_notify_sim_toolkit,
                true, false, null);

        updateUsbMassStorageNotification(true, false);
        Intent intent = new Intent(Intent.ACTION_MEDIA_CHECKING, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaEject(java.lang.String path)
Broadcasts the media eject event to all clients.

        Intent intent = new Intent(Intent.ACTION_MEDIA_EJECT, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaMounted(java.lang.String path, boolean readOnly)
Broadcasts the media mounted event to all clients.

        setMediaStorageNotification(0, 0, 0, false, false, null);
        updateUsbMassStorageNotification(false, false);
        Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                Uri.parse("file://" + path));
        intent.putExtra("read-only", readOnly);
        mMounted = true;
        mContext.sendBroadcast(intent);
    
voidnotifyMediaNoFs(java.lang.String path)
Broadcasts the media nofs event to all clients.

        
        Intent intent = new Intent();
        intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
        PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);

        setMediaStorageNotification(com.android.internal.R.string.ext_media_nofs_notification_title,
                                    com.android.internal.R.string.ext_media_nofs_notification_message,
                                    com.android.internal.R.drawable.stat_sys_no_sim,
                                    true, false, pi);
        updateUsbMassStorageNotification(false, false);
        intent = new Intent(Intent.ACTION_MEDIA_NOFS, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaRemoved(java.lang.String path)
Broadcasts the media removed event to all clients.

        updateUsbMassStorageNotification(true, false);

        setMediaStorageNotification(
                com.android.internal.R.string.ext_media_nomedia_notification_title,
                com.android.internal.R.string.ext_media_nomedia_notification_message,
                com.android.internal.R.drawable.stat_sys_no_sim,
                true, false, null);
        handlePossibleExplicitUnmountBroadcast(path);

        Intent intent = new Intent(Intent.ACTION_MEDIA_REMOVED, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaShared(java.lang.String path)
Broadcasts the media shared event to all clients.

        Intent intent = new Intent();
        intent.setClass(mContext, com.android.internal.app.UsbStorageStopActivity.class);
        PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
        setUsbStorageNotification(com.android.internal.R.string.usb_storage_stop_notification_title,
                                  com.android.internal.R.string.usb_storage_stop_notification_message,
                                  com.android.internal.R.drawable.stat_sys_warning,
                                  false, true, pi);
        handlePossibleExplicitUnmountBroadcast(path);
        intent = new Intent(Intent.ACTION_MEDIA_SHARED, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaUnmountable(java.lang.String path)
Broadcasts the media unmountable event to all clients.

        Intent intent = new Intent();
        intent.setClass(mContext, com.android.internal.app.ExternalMediaFormatActivity.class);
        PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);

        setMediaStorageNotification(com.android.internal.R.string.ext_media_unmountable_notification_title,
                                    com.android.internal.R.string.ext_media_unmountable_notification_message,
                                    com.android.internal.R.drawable.stat_sys_no_sim,
                                    true, false, pi); 
        updateUsbMassStorageNotification(false, false);

        handlePossibleExplicitUnmountBroadcast(path);

        intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTABLE, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyMediaUnmounted(java.lang.String path)
Broadcasts the media unmounted event to all clients.

        if (mShowSafeUnmountNotificationWhenUnmounted) {
            setMediaStorageNotification(
                    com.android.internal.R.string.ext_media_safe_unmount_notification_title,
                    com.android.internal.R.string.ext_media_safe_unmount_notification_message,
                    com.android.internal.R.drawable.stat_notify_sim_toolkit,
                    true, true, null);
            mShowSafeUnmountNotificationWhenUnmounted = false;
        } else {
            setMediaStorageNotification(0, 0, 0, false, false, null);
        }
        updateUsbMassStorageNotification(false, false);

        Intent intent = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, 
                Uri.parse("file://" + path));
        mContext.sendBroadcast(intent);
    
voidnotifyUmsConnected()
Broadcasts the USB mass storage connected event to all clients.

        String storageState = Environment.getExternalStorageState();
        if (!storageState.equals(Environment.MEDIA_REMOVED) &&
            !storageState.equals(Environment.MEDIA_BAD_REMOVAL) &&
            !storageState.equals(Environment.MEDIA_CHECKING)) {

            if (mAutoStartUms) {
                try {
                    setMassStorageEnabled(true);
                } catch (RemoteException e) {
                }
            } else {
                updateUsbMassStorageNotification(false, true);
            }
        }

        Intent intent = new Intent(Intent.ACTION_UMS_CONNECTED);
        mContext.sendBroadcast(intent);
    
voidnotifyUmsDisconnected()
Broadcasts the USB mass storage disconnected event to all clients.

        updateUsbMassStorageNotification(false, false);
        Intent intent = new Intent(Intent.ACTION_UMS_DISCONNECTED);
        mContext.sendBroadcast(intent);
    
public voidsetAutoStartUms(boolean enabled)
Set whether or not we're playing media notification sounds.

        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_SETTINGS) 
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires WRITE_SETTINGS permission");
        }
        mAutoStartUms = enabled;
        SystemProperties.set("persist.service.mount.umsauto", (enabled ? "1" : "0"));
    
public voidsetMassStorageEnabled(boolean enable)
Enables or disables USB mass storage support.

param
enable true to enable USB mass storage support

        mListener.setMassStorageEnabled(enable);
    
private synchronized voidsetMediaStorageNotification(int titleId, int messageId, int icon, boolean visible, boolean dismissable, android.app.PendingIntent pi)
Sets the media storage notification.


        if (!visible && mMediaStorageNotification == null) {
            return;
        }

        NotificationManager notificationManager = (NotificationManager) mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);

        if (notificationManager == null) {
            return;
        }

        if (mMediaStorageNotification != null && visible) {
            /*
             * Dismiss the previous notification - we're about to
             * re-use it.
             */
            final int notificationId = mMediaStorageNotification.icon;
            notificationManager.cancel(notificationId);
        }
        
        if (visible) {
            Resources r = Resources.getSystem();
            CharSequence title = r.getText(titleId);
            CharSequence message = r.getText(messageId);

            if (mMediaStorageNotification == null) {
                mMediaStorageNotification = new Notification();
                mMediaStorageNotification.when = 0;
            }

            if (mPlaySounds) {
                mMediaStorageNotification.defaults |= Notification.DEFAULT_SOUND;
            } else {
                mMediaStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
            }

            if (dismissable) {
                mMediaStorageNotification.flags = Notification.FLAG_AUTO_CANCEL;
            } else {
                mMediaStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
            }

            mMediaStorageNotification.tickerText = title;
            if (pi == null) {
                Intent intent = new Intent();
                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
            }

            mMediaStorageNotification.icon = icon;
            mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
        }
    
        final int notificationId = mMediaStorageNotification.icon;
        if (visible) {
            notificationManager.notify(notificationId, mMediaStorageNotification);
        } else {
            notificationManager.cancel(notificationId);
        }
    
public voidsetPlayNotificationSounds(boolean enabled)
Set whether or not we're playing media notification sounds.

        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_SETTINGS) 
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires WRITE_SETTINGS permission");
        }
        mPlaySounds = enabled;
        SystemProperties.set("persist.service.mount.playsnd", (enabled ? "1" : "0"));
    
private synchronized voidsetUsbStorageNotification(int titleId, int messageId, int icon, boolean sound, boolean visible, android.app.PendingIntent pi)
Sets the USB storage notification.


        if (!visible && mUsbStorageNotification == null) {
            return;
        }

        NotificationManager notificationManager = (NotificationManager) mContext
                .getSystemService(Context.NOTIFICATION_SERVICE);

        if (notificationManager == null) {
            return;
        }
        
        if (visible) {
            Resources r = Resources.getSystem();
            CharSequence title = r.getText(titleId);
            CharSequence message = r.getText(messageId);

            if (mUsbStorageNotification == null) {
                mUsbStorageNotification = new Notification();
                mUsbStorageNotification.icon = icon;
                mUsbStorageNotification.when = 0;
            }

            if (sound && mPlaySounds) {
                mUsbStorageNotification.defaults |= Notification.DEFAULT_SOUND;
            } else {
                mUsbStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
            }
                
            mUsbStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;

            mUsbStorageNotification.tickerText = title;
            if (pi == null) {
                Intent intent = new Intent();
                pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
            }

            mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi);
        }
    
        final int notificationId = mUsbStorageNotification.icon;
        if (visible) {
            notificationManager.notify(notificationId, mUsbStorageNotification);
        } else {
            notificationManager.cancel(notificationId);
        }
    
public voidunmountMedia(java.lang.String mountPath)
Attempt to unmount external media to prepare for eject

        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS) 
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission");
        }

        // Set a flag so that when we get the unmounted event, we know
        // to display the notification
        mShowSafeUnmountNotificationWhenUnmounted = true;

        // tell mountd to unmount the media
        mListener.ejectMedia(mountPath);
    
voidupdateUsbMassStorageNotification(boolean suppressIfConnected, boolean sound)
Update the state of the USB mass storage notification


        try {

            if (getMassStorageConnected() && !suppressIfConnected) {
                Intent intent = new Intent();
                intent.setClass(mContext, com.android.internal.app.UsbStorageActivity.class);
                PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
                setUsbStorageNotification(
                        com.android.internal.R.string.usb_storage_notification_title,
                        com.android.internal.R.string.usb_storage_notification_message,
                        com.android.internal.R.drawable.stat_sys_data_usb,
                        sound, true, pi);
            } else {
                setUsbStorageNotification(0, 0, 0, false, false, null);
            }
        } catch (RemoteException e) {
            // Nothing to do
        }