/*
* This file is part of the RootTools Project: http://code.google.com/p/roottools/
*
* Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks
*
* This code is dual-licensed under the terms of the Apache License Version 2.0 and
* the terms of the General Public License (GPL) Version 2.
* You may use this code according to either of these licenses as is most appropriate
* for your project on a case-by-case basis.
*
* The terms of each license can be found in the root directory of this project's repository as well as at:
*
* * http://www.apache.org/licenses/LICENSE-2.0
* * http://www.gnu.org/licenses/gpl-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under these Licenses is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See each License for the specific language governing permissions and
* limitations under that License.
*/
package com.stericson.RootTools.internal;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import com.stericson.RootTools.Constants;
import com.stericson.RootTools.RootTools;
import com.stericson.RootTools.containers.Mount;
import com.stericson.RootTools.execution.Command;
import com.stericson.RootTools.execution.CommandCapture;
import com.stericson.RootTools.execution.Shell;
public class Remounter {
//-------------
//# Remounter #
//-------------
/**
* This will take a path, which can contain the file name as well,
* and attempt to remount the underlying partition.
* <p/>
* For example, passing in the following string:
* "/system/bin/some/directory/that/really/would/never/exist"
* will result in /system ultimately being remounted.
* However, keep in mind that the longer the path you supply, the more work this has to do,
* and the slower it will run.
*
* @param file file path
* @param mountType mount type: pass in RO (Read only) or RW (Read Write)
* @return a <code>boolean</code> which indicates whether or not the partition
* has been remounted as specified.
*/
public boolean remount(String file, String mountType) {
//if the path has a trailing slash get rid of it.
if (file.endsWith("/") && !file.equals("/")) {
file = file.substring(0, file.lastIndexOf("/"));
}
//Make sure that what we are trying to remount is in the mount list.
boolean foundMount = false;
while (!foundMount) {
try {
for (Mount mount : RootTools.getMounts()) {
RootTools.log(mount.getMountPoint().toString());
if (file.equals(mount.getMountPoint().toString())) {
foundMount = true;
break;
}
}
} catch (Exception e) {
if (RootTools.debugMode) {
e.printStackTrace();
}
return false;
}
if (!foundMount) {
try {
file = (new File(file).getParent());
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Mount mountPoint = findMountPointRecursive(file);
if (mountPoint != null) {
RootTools.log(Constants.TAG, "Remounting " + mountPoint.getMountPoint().getAbsolutePath() + " as " + mountType.toLowerCase());
final boolean isMountMode = mountPoint.getFlags().contains(mountType.toLowerCase());
if (!isMountMode) {
//grab an instance of the internal class
try {
CommandCapture command = new CommandCapture(0,
true,
"busybox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(),
"toolbox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(),
"mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(),
"/system/bin/toolbox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath()
);
Shell.startRootShell().add(command);
commandWait(command);
} catch (Exception e) {}
mountPoint = findMountPointRecursive(file);
}
if (mountPoint != null) {
RootTools.log(Constants.TAG, mountPoint.getFlags() + " AND " + mountType.toLowerCase());
if (mountPoint.getFlags().contains(mountType.toLowerCase())) {
RootTools.log(mountPoint.getFlags().toString());
return true;
} else {
RootTools.log(mountPoint.getFlags().toString());
return false;
}
}
else {
RootTools.log("mount is null, file was: " + file + " mountType was: " + mountType);
}
}
else {
RootTools.log("mount is null, file was: " + file + " mountType was: " + mountType);
}
return false;
}
private Mount findMountPointRecursive(String file) {
try {
ArrayList<Mount> mounts = RootTools.getMounts();
for (File path = new File(file); path != null; ) {
for (Mount mount : mounts) {
if (mount.getMountPoint().equals(path)) {
return mount;
}
}
}
return null;
} catch (IOException e) {
if (RootTools.debugMode) {
e.printStackTrace();
}
} catch (Exception e) {
if (RootTools.debugMode) {
e.printStackTrace();
}
}
return null;
}
private void commandWait(Command cmd) {
synchronized (cmd) {
try {
if (!cmd.isFinished()) {
cmd.wait(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}