Android Open Source - Mountie Automounter






From Project

Back to project page Mountie.

License

The source code is released under:

GNU General Public License

If you think the Android project Mountie listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Mountie, a tool for mounting external storage on Android
 * Copyright (C) 2014 Andrew Comminos <andrew@morlunk.com>
 *//from ww w.  j  a  v  a 2s .  c o  m
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.morlunk.mountie;

import android.os.Environment;

import com.morlunk.mountie.fs.Mount;
import com.morlunk.mountie.fs.MountException;
import com.morlunk.mountie.fs.MountListener;
import com.morlunk.mountie.fs.Partition;
import com.morlunk.mountie.fs.PartitionListener;
import com.morlunk.mountie.fs.UnmountListener;
import com.morlunk.mountie.fs.Volume;
import com.stericson.RootTools.execution.Command;
import com.stericson.RootTools.execution.CommandCapture;
import com.stericson.RootTools.execution.Shell;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * Automatically mounts discovered partitions in /sdcard/mountie.
 * Created by andrew on 17/09/14.
 */
public class Automounter implements PartitionListener, UnmountListener, MountListener {
    /**
     * Android 4.2+'s mount directory for the primary user's external storage.
     * It's necessary to mount here to avoid the FUSE abstraction.
     */
    private static final String DATA_DIR = "/data/media/0/";

    private Shell mRootShell;
    /**
     * Observe that mEmulatedDirectory and mMountDirectory point to the same physical storage.
     * One is abstracted to the user as a FUSE share while the other is a mounted vfat partition.
     */
    private File mEmulatedDirectory;
    private File mMountDirectory;
    private MountListener mMountListener;
    private UnmountListener mUnmountListener;
    private Set<Mount> mMounts;

    /**
     * Creates a new automounter.
     * Must be registered to a {@link com.morlunk.mountie.fs.BlockDeviceObserver} in order to automount.
     * @param rootShell A root shell to execute mount commands in.
     * @param dirName The name of the directory to mount in on external storage.
     * @param mountListener A listener for newly automounted devices.
     * @param unmountListener A listener for unmounted automounted devices.
     */
    public Automounter(Shell rootShell, String dirName, MountListener mountListener, UnmountListener unmountListener) {
        mRootShell = rootShell;
        mEmulatedDirectory = new File(Environment.getExternalStorageDirectory(), dirName);
        mMountDirectory = new File(DATA_DIR, dirName);
        mMountListener = mountListener;
        mUnmountListener = unmountListener;
        mMounts = new HashSet<Mount>();
        cleanDirectory(); // Treat directory like a tmpfs and delete+unmount contents.
    }

    public void cleanDirectory() {
        for (final File file : mEmulatedDirectory.listFiles()) {
            Command mountCommand = new CommandCapture(0, "umount " + mMountDirectory.getAbsolutePath() + "/" + file.getName()) {
                @Override
                public void commandCompleted(int id, int exitcode) {
                    super.commandCompleted(id, exitcode);
                    file.delete();
                }
            };
            try {
                mRootShell.add(mountCommand);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onVolumeAdded(Volume volume) {
    }

    @Override
    public void onVolumeRemoved(Volume volume) {
    }

    @Override
    public void onPartitionAdded(Volume volume, Partition partition) {
        try {
            partition.mount(mRootShell, getDeviceMountDir(partition), this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onPartitionRemoved(Volume volume, final Partition partition) {
        if (partition.isMounted()) {
            try {
                partition.unmountAll(mRootShell, this);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void unmountAll() {
        for (Mount mount : mMounts) {
            try {
                mount.unmount(mRootShell, this);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        mMounts.clear();
    }

    public Collection<Mount> getMounts() {
        return mMounts;
    }

    private File getEmulatedMountDir(Partition partition) throws IOException {
        File mountDir = new File(mEmulatedDirectory, partition.getUUID());
        if (!mountDir.exists() && !mountDir.mkdirs()) {
            throw new IOException("Couldn't create mount dir!");
        }
        return mountDir;
    }

    private String getDeviceMountDir(Partition partition) throws IOException {
        return mMountDirectory + "/" + getEmulatedMountDir(partition).getName();
    }

    @Override
    public void onUnmountSuccess(Mount mount) {
        mMounts.remove(mount);
        try {
            getEmulatedMountDir(mount.getDevice()).delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mUnmountListener.onUnmountSuccess(mount);
    }

    @Override
    public void onUnmountError(Mount mount, Exception e) {
        mUnmountListener.onUnmountError(mount, e);
    }

    @Override
    public void onMountSuccess(Partition partition, Mount mount) {
        mMounts.add(mount);
        mMountListener.onMountSuccess(partition, mount);
    }

    @Override
    public void onMountError(Partition partition, MountException e) {
        mMountListener.onMountError(partition, e);
    }
}




Java Source Code List

com.morlunk.mountie.ApplicationTest.java
com.morlunk.mountie.Automounter.java
com.morlunk.mountie.Constants.java
com.morlunk.mountie.MountieActivity.java
com.morlunk.mountie.MountieBootReceiver.java
com.morlunk.mountie.MountieNotification.java
com.morlunk.mountie.MountieService.java
com.morlunk.mountie.UsbHotplugReceiver.java
com.morlunk.mountie.command.BlkidCommand.java
com.morlunk.mountie.fs.BlockDeviceObserver.java
com.morlunk.mountie.fs.BlockDevice.java
com.morlunk.mountie.fs.MountException.java
com.morlunk.mountie.fs.MountListener.java
com.morlunk.mountie.fs.Mount.java
com.morlunk.mountie.fs.PartitionListener.java
com.morlunk.mountie.fs.Partition.java
com.morlunk.mountie.fs.UnmountListener.java
com.morlunk.mountie.fs.Volume.java
com.morlunk.mountie.jni.Native.java
com.morlunk.mountie.util.Filesystems.java
com.stericson.RootTools.Constants.java
com.stericson.RootTools.RootTools.java
com.stericson.RootTools.containers.Mount.java
com.stericson.RootTools.containers.Permissions.java
com.stericson.RootTools.containers.RootClass.java
com.stericson.RootTools.containers.Symlink.java
com.stericson.RootTools.exceptions.RootDeniedException.java
com.stericson.RootTools.execution.CommandCapture.java
com.stericson.RootTools.execution.Command.java
com.stericson.RootTools.execution.JavaCommandCapture.java
com.stericson.RootTools.execution.Shell.java
com.stericson.RootTools.internal.Installer.java
com.stericson.RootTools.internal.InternalVariables.java
com.stericson.RootTools.internal.Remounter.java
com.stericson.RootTools.internal.RootToolsInternalMethods.java
com.stericson.RootTools.internal.Runner.java