diff options
Diffstat (limited to 'src/com/cyanogenmod/filemanager/console')
5 files changed, 109 insertions, 164 deletions
diff --git a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java index 1552abd9..17914693 100644 --- a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java +++ b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java @@ -30,7 +30,6 @@ import com.cyanogenmod.filemanager.preferences.AccessMode; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.Preferences; import com.cyanogenmod.filemanager.util.DialogHelper; -import com.cyanogenmod.filemanager.util.FileHelper; import java.io.FileNotFoundException; import java.io.IOException; @@ -125,7 +124,7 @@ public final class ConsoleBuilder { try { //Create the console, destroy the current console, and marks as current holder = new ConsoleHolder( - createNonPrivilegedConsole(context, FileHelper.ROOT_DIRECTORY)); + createNonPrivilegedConsole(context)); destroyConsole(); sHolder = holder; return true; @@ -157,7 +156,7 @@ public final class ConsoleBuilder { try { //Create the console, destroy the current console, and marks as current holder = new ConsoleHolder( - createAndCheckPrivilegedConsole(context, FileHelper.ROOT_DIRECTORY)); + createAndCheckPrivilegedConsole(context)); destroyConsole(); sHolder = holder; @@ -243,11 +242,8 @@ public final class ConsoleBuilder { //Is there a console allocated if (sHolder == null) { sHolder = (superuserMode) - ? new ConsoleHolder( - createAndCheckPrivilegedConsole( - context, FileHelper.ROOT_DIRECTORY)) - : new ConsoleHolder( - createNonPrivilegedConsole(context, FileHelper.ROOT_DIRECTORY)); + ? new ConsoleHolder(createAndCheckPrivilegedConsole(context)) + : new ConsoleHolder(createNonPrivilegedConsole(context)); if (superuserMode) { // Change also the background console to privileged FileManagerApplication.changeBackgroundConsoleToPriviligedConsole(); @@ -275,7 +271,6 @@ public final class ConsoleBuilder { * Method that creates a new non privileged console. * * @param context The current context - * @param initialDirectory The initial directory of the console * @return Console The non privileged console * @throws FileNotFoundException If the initial directory not exists * @throws IOException If initial directory couldn't be checked @@ -283,7 +278,7 @@ public final class ConsoleBuilder { * @throws ConsoleAllocException If the console can't be allocated * @see NonPriviledgeConsole */ - public static Console createNonPrivilegedConsole(Context context, String initialDirectory) + public static Console createNonPrivilegedConsole(Context context) throws FileNotFoundException, IOException, InvalidCommandDefinitionException, ConsoleAllocException { @@ -291,14 +286,14 @@ public final class ConsoleBuilder { // Is rooted? Then create a shell console if (FileManagerApplication.isDeviceRooted()) { - NonPriviledgeConsole console = new NonPriviledgeConsole(initialDirectory); + NonPriviledgeConsole console = new NonPriviledgeConsole(); console.setBufferSize(bufferSize); console.alloc(); return console; } // No rooted. Then create a java console - JavaConsole console = new JavaConsole(context, initialDirectory, bufferSize); + JavaConsole console = new JavaConsole(context, bufferSize); console.alloc(); return console; } @@ -308,7 +303,6 @@ public final class ConsoleBuilder { * privileged console fails, the a non privileged console * * @param context The current context - * @param initialDirectory The initial directory of the console * @return Console The privileged console * @throws FileNotFoundException If the initial directory not exists * @throws IOException If initial directory couldn't be checked @@ -317,10 +311,10 @@ public final class ConsoleBuilder { * @throws InsufficientPermissionsException If the console created is not a privileged console * @see PrivilegedConsole */ - public static Console createPrivilegedConsole(Context context, String initialDirectory) + public static Console createPrivilegedConsole(Context context) throws FileNotFoundException, IOException, InvalidCommandDefinitionException, ConsoleAllocException, InsufficientPermissionsException { - PrivilegedConsole console = new PrivilegedConsole(initialDirectory); + PrivilegedConsole console = new PrivilegedConsole(); console.setBufferSize(context.getResources().getInteger(R.integer.buffer_size)); console.alloc(); if (console.getIdentity().getUser().getId() != ROOT_UID) { @@ -340,7 +334,6 @@ public final class ConsoleBuilder { * privileged console fails, the a non privileged console * * @param context The current context - * @param initialDirectory The initial directory of the console * @return Console The privileged console * @throws FileNotFoundException If the initial directory not exists * @throws IOException If initial directory couldn't be checked @@ -349,10 +342,10 @@ public final class ConsoleBuilder { * @throws InsufficientPermissionsException If the console created is not a privileged console * @see PrivilegedConsole */ - public static Console createAndCheckPrivilegedConsole(Context context, String initialDirectory) + public static Console createAndCheckPrivilegedConsole(Context context) throws FileNotFoundException, IOException, InvalidCommandDefinitionException, ConsoleAllocException, InsufficientPermissionsException { - return createAndCheckPrivilegedConsole(context, initialDirectory, true); + return createAndCheckPrivilegedConsole(context, true); } /** @@ -360,7 +353,6 @@ public final class ConsoleBuilder { * privileged console fails, the a non privileged console * * @param context The current context - * @param initialDirectory The initial directory of the console * @param silent Indicates that no message have to be displayed * @return Console The privileged console * @throws FileNotFoundException If the initial directory not exists @@ -371,12 +363,12 @@ public final class ConsoleBuilder { * @see PrivilegedConsole */ public static Console createAndCheckPrivilegedConsole( - Context context, String initialDirectory, boolean silent) + Context context, boolean silent) throws FileNotFoundException, IOException, InvalidCommandDefinitionException, ConsoleAllocException, InsufficientPermissionsException { try { // Create the privileged console - return createPrivilegedConsole(context, initialDirectory); + return createPrivilegedConsole(context); } catch (ConsoleAllocException caEx) { //Show a message with the problem? @@ -404,7 +396,7 @@ public final class ConsoleBuilder { } //Create the non-privileged console - return createNonPrivilegedConsole(context, initialDirectory); + return createNonPrivilegedConsole(context); } // Rethrow the exception diff --git a/src/com/cyanogenmod/filemanager/console/java/JavaConsole.java b/src/com/cyanogenmod/filemanager/console/java/JavaConsole.java index df04d4a5..2edb42a9 100644 --- a/src/com/cyanogenmod/filemanager/console/java/JavaConsole.java +++ b/src/com/cyanogenmod/filemanager/console/java/JavaConsole.java @@ -17,10 +17,8 @@ package com.cyanogenmod.filemanager.console.java; import android.content.Context; -import android.os.storage.StorageVolume; import android.util.Log; -import com.cyanogenmod.filemanager.commands.ChangeCurrentDirExecutable; import com.cyanogenmod.filemanager.commands.Executable; import com.cyanogenmod.filemanager.commands.ExecutableFactory; import com.cyanogenmod.filemanager.commands.SIGNAL; @@ -35,7 +33,6 @@ import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; import com.cyanogenmod.filemanager.console.OperationTimeoutException; import com.cyanogenmod.filemanager.console.ReadOnlyFilesystemException; import com.cyanogenmod.filemanager.model.Identity; -import com.cyanogenmod.filemanager.util.StorageHelper; /** * An implementation of a {@link Console} based on a java implementation.<br/> @@ -48,7 +45,6 @@ public final class JavaConsole extends Console { private static final String TAG = "JavaConsole"; //$NON-NLS-1$ private boolean mActive; - private String mCurrentDir; private final Context mCtx; private final int mBufferSize; @@ -57,14 +53,12 @@ public final class JavaConsole extends Console { * Constructor of <code>JavaConsole</code> * * @param ctx The current context - * @param initialDir The initial directory * @param bufferSize The buffer size */ - public JavaConsole(Context ctx, String initialDir, int bufferSize) { + public JavaConsole(Context ctx, int bufferSize) { super(); this.mCtx = ctx; this.mBufferSize = bufferSize; - this.mCurrentDir = initialDir; } /** @@ -76,21 +70,6 @@ public final class JavaConsole extends Console { if (isTrace()) { Log.v(TAG, "Allocating Java console"); //$NON-NLS-1$ } - - //Retrieve the current directory from the first storage volume - StorageVolume[] vols = StorageHelper.getStorageVolumes(this.mCtx); - if (vols == null || vols.length == 0) { - throw new ConsoleAllocException("Can't stat any directory"); //$NON-NLS-1$ - } - - // Test to change to current directory - ChangeCurrentDirExecutable currentDirCmd = - getExecutableFactory(). - newCreator().createChangeCurrentDirExecutable(this.mCurrentDir); - execute(currentDirCmd); - - // Tested. Is not active - this.mCurrentDir = vols[0].getPath(); this.mActive = true; } catch (Exception e) { Log.e(TAG, "Failed to allocate Java console", e); //$NON-NLS-1$ @@ -151,24 +130,6 @@ public final class JavaConsole extends Console { } /** - * Method that returns the current directory of the console - * - * @return String The current directory - */ - public String getCurrentDir() { - return this.mCurrentDir; - } - - /** - * Method that sets the current directory of the console - * - * @param currentDir The current directory - */ - public void setCurrentDir(String currentDir) { - this.mCurrentDir = currentDir; - } - - /** * Method that returns the current context * * @return Context The current context diff --git a/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java b/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java index aec764f8..7673bbf0 100644 --- a/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java +++ b/src/com/cyanogenmod/filemanager/console/shell/NonPriviledgeConsole.java @@ -33,19 +33,6 @@ public class NonPriviledgeConsole extends ShellConsole { /** * Constructor of <code>NonPriviledgeConsole</code>. * - * @param initialDirectory The initial directory of the shell - * @throws FileNotFoundException If the initial directory not exists - * @throws IOException If initial directory couldn't be checked - * @throws InvalidCommandDefinitionException If the command has an invalid definition - */ - public NonPriviledgeConsole(String initialDirectory) - throws FileNotFoundException, IOException, InvalidCommandDefinitionException { - super(new BashShell(), initialDirectory); - } - - /** - * Constructor of <code>NonPriviledgeConsole</code>. - * * @throws FileNotFoundException If the default initial directory not exists * @throws IOException If initial directory couldn't be checked * @throws InvalidCommandDefinitionException If the command has an invalid definition diff --git a/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java b/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java index 4e5d3088..cc441314 100644 --- a/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java +++ b/src/com/cyanogenmod/filemanager/console/shell/PrivilegedConsole.java @@ -34,19 +34,6 @@ public class PrivilegedConsole extends ShellConsole { /** * Constructor of <code>PrivilegedConsole</code>. * - * @param initialDirectory The initial directory of the shell - * @throws FileNotFoundException If the initial directory not exists - * @throws IOException If initial directory couldn't be checked - * @throws InvalidCommandDefinitionException If the command has an invalid definition - */ - public PrivilegedConsole(String initialDirectory) - throws FileNotFoundException, IOException, InvalidCommandDefinitionException { - super(new SuperuserShell(), initialDirectory); - } - - /** - * Constructor of <code>PrivilegedConsole</code>. - * * @throws FileNotFoundException If the default initial directory not exists * @throws IOException If initial directory couldn't be checked * @throws InvalidCommandDefinitionException If the command has an invalid definition diff --git a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java index fb3b5075..12b7fe26 100644 --- a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java +++ b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java @@ -42,8 +42,6 @@ import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; import com.cyanogenmod.filemanager.console.OperationTimeoutException; import com.cyanogenmod.filemanager.console.ReadOnlyFilesystemException; import com.cyanogenmod.filemanager.model.Identity; -import com.cyanogenmod.filemanager.preferences.FileManagerSettings; -import com.cyanogenmod.filemanager.preferences.Preferences; import com.cyanogenmod.filemanager.util.CommandHelper; import com.cyanogenmod.filemanager.util.FileHelper; @@ -72,13 +70,12 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis // A timeout of 5 seconds should be enough for no-debugging environments private static final long DEFAULT_TIMEOUT = - FileManagerApplication.isDebuggable() ? 20000L : 5000L; + FileManagerApplication.isDebuggable() ? 20000L : 3000L; private static final int DEFAULT_BUFFER = 512; //Shell References private final Shell mShell; - private final String mInitialDirectory; private Identity mIdentity; //Process References @@ -134,24 +131,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis * Constructor of <code>ShellConsole</code>. * * @param shell The shell used to execute commands - * @throws FileNotFoundException If the default initial directory not exists - * @throws IOException If initial directory couldn't be resolved - */ - public ShellConsole(Shell shell) throws FileNotFoundException, IOException { - this(shell, Preferences.getSharedPreferences().getString( - FileManagerSettings.SETTINGS_INITIAL_DIR.getId(), - (String)FileManagerSettings.SETTINGS_INITIAL_DIR.getDefaultValue())); - } - - /** - * Constructor of <code>ShellConsole</code>. - * - * @param shell The shell used to execute commands - * @param initialDirectory The initial directory of the shell * @throws FileNotFoundException If the initial directory not exists * @throws IOException If initial directory couldn't be resolved */ - public ShellConsole(Shell shell, String initialDirectory) + public ShellConsole(Shell shell) throws FileNotFoundException, IOException { super(); this.mShell = shell; @@ -159,16 +142,6 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis this.mBufferSize = DEFAULT_BUFFER; - //Resolve and checks the initial directory - File f = new File(initialDirectory); - while (FileHelper.isSymlink(f)) { - f = FileHelper.resolveSymlink(f); - } - if (!f.exists() || !f.isDirectory()) { - throw new FileNotFoundException(f.toString()); - } - this.mInitialDirectory = initialDirectory; - //Restart the buffers this.mSbIn = new StringBuffer(); this.mSbErr = new StringBuffer(); @@ -242,7 +215,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis rt.exec( cmd.toArray(new String[cmd.size()]), null, - new File(this.mInitialDirectory)); + new File(FileHelper.ROOT_DIRECTORY).getCanonicalFile()); synchronized (this.mSync) { this.mActive = true; } @@ -312,7 +285,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis this.mIdentity.setGroups(groupsCmd.getResult()); } } catch (Exception ex) { - Log.w(TAG, "Groups command failed. Ignored.", ex); + Log.w(TAG, "Groups command failed. Ignored.", ex); //$NON-NLS-1$ } } catch (Exception ex) { @@ -504,7 +477,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis (program instanceof AsyncResultProgram && ((AsyncResultProgram)program).isExpectEnd())); - this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2 + "\\n"; //$NON-NLS-1$ //$NON-NLS-2$ + this.mStartControlPattern = startId1 + "\\d{1,3}" + startId2; //$NON-NLS-1$ this.mEndControlPattern = endId1 + "\\d{1,3}" + endId2; //$NON-NLS-1$ String startCmd = Command.getStartCodeCommandInfo( @@ -529,7 +502,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis .append(endCmd); } sb.append(FileHelper.NEWLINE); - this.mOut.write(sb.toString().getBytes()); + synchronized (this.mSync) { + this.mFinished = false; + this.mOut.write(sb.toString().getBytes()); + } } catch (InvalidCommandDefinitionException icdEx) { throw new CommandNotFoundException( "ExitCodeCommandInfo not found", icdEx); //$NON-NLS-1$ @@ -537,12 +513,14 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis //Now, wait for buffers to be filled synchronized (this.mSync) { - if (program instanceof AsyncResultProgram) { - this.mSync.wait(); - } else { - this.mSync.wait(DEFAULT_TIMEOUT); - if (!this.mFinished) { - throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd); + if (!this.mFinished) { + if (program instanceof AsyncResultProgram) { + this.mSync.wait(); + } else { + this.mSync.wait(DEFAULT_TIMEOUT); + if (!this.mFinished) { + throw new OperationTimeoutException(DEFAULT_TIMEOUT, cmd); + } } } } @@ -629,10 +607,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis */ private Thread createStdInThread(final InputStream in) { Thread t = new Thread(new Runnable() { + @SuppressWarnings("synthetic-access") @Override public void run() { int read = 0; - + StringBuffer sb = null; try { while (ShellConsole.this.mActive) { //Read only one byte with active wait @@ -645,14 +624,17 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis boolean async = ShellConsole.this.mActiveCommand != null && ShellConsole.this.mActiveCommand instanceof AsyncResultProgram; + if (!async || sb == null) { + sb = new StringBuffer(); + } - StringBuffer sb = new StringBuffer(); if (!ShellConsole.this.mCancelled) { ShellConsole.this.mSbIn.append((char)r); if (!ShellConsole.this.mStarted) { ShellConsole.this.mStarted = isCommandStarted(ShellConsole.this.mSbIn); if (ShellConsole.this.mStarted) { + sb = new StringBuffer(ShellConsole.this.mSbIn.toString()); if (async) { synchronized (ShellConsole.this.mPartialSync) { @@ -668,21 +650,44 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis sb.append((char)r); } + //Check if the command has finished (and extract the control) + boolean finished = isCommandFinished(ShellConsole.this.mSbIn, sb); + //Notify asynchronous partial data if (ShellConsole.this.mStarted && async) { AsyncResultProgram program = ((AsyncResultProgram)ShellConsole.this.mActiveCommand); String partial = sb.toString(); - program.onRequestParsePartialResult(partial); - ShellConsole.this.toStdIn(partial); + int cc = ShellConsole.this.mEndControlPattern.length(); + if (partial.length() >= cc) { + program.onRequestParsePartialResult(partial); + ShellConsole.this.toStdIn(partial); - // Reset the temp buffer - sb = new StringBuffer(); + // Reset the temp buffer + sb = new StringBuffer(); + } } - } - if (!async) { - ShellConsole.this.toStdIn(sb.toString()); + if (finished) { + if (!async) { + ShellConsole.this.toStdIn(String.valueOf((char)r)); + } else { + AsyncResultProgram program = + ((AsyncResultProgram)ShellConsole.this.mActiveCommand); + String partial = sb.toString(); + if (program != null) { + program.onRequestParsePartialResult(partial); + } + ShellConsole.this.toStdIn(partial); + } + + //Notify the end + notifyProcessFinished(); + break; + } + if (!async && !finished) { + ShellConsole.this.toStdIn(String.valueOf((char)r)); + } } //Has more data? Read with available as more as exists @@ -690,8 +695,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis int count = 0; while (in.available() > 0 && count < 10) { count++; - int available = Math.min(in.available(), - ShellConsole.this.mBufferSize); + int available = + Math.min(in.available(), ShellConsole.this.mBufferSize); byte[] data = new byte[available]; read = in.read(data); @@ -735,18 +740,29 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis AsyncResultProgram program = ((AsyncResultProgram)ShellConsole.this.mActiveCommand); String partial = sb.toString(); - if (program != null) { - program.onRequestParsePartialResult(partial); - } - ShellConsole.this.toStdIn(partial); + int cc = ShellConsole.this.mEndControlPattern.length(); + if (partial.length() >= cc) { + if (program != null) { + program.onRequestParsePartialResult(partial); + } + ShellConsole.this.toStdIn(partial); - // Reset the temp buffer - sb = new StringBuffer(); + // Reset the temp buffer + sb = new StringBuffer(); + } } if (finished) { if (!async) { ShellConsole.this.toStdIn(s); + } else { + AsyncResultProgram program = + ((AsyncResultProgram)ShellConsole.this.mActiveCommand); + String partial = sb.toString(); + if (program != null) { + program.onRequestParsePartialResult(partial); + } + ShellConsole.this.toStdIn(partial); } //Notify the end @@ -759,10 +775,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis //Wait for buffer to be filled try { - Thread.sleep(50L); - } catch (Throwable ex) { - /**NON BLOCK**/ - } + Thread.sleep(1L); + } catch (Throwable ex) {/**NON BLOCK**/} } //Asynchronous programs can cause a lot of output, control buffers @@ -1094,28 +1108,32 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis if (program.getCommand() != null) { try { if (program.isCancellable()) { - //Get the PID in background - Integer pid = - CommandHelper.getProcessId( + try { + //Get the PID in background + Integer pid = + CommandHelper.getProcessId( + null, + this.mShell.getPid(), + program.getCommand(), + FileManagerApplication.getBackgroundConsole()); + if (pid != null) { + CommandHelper.sendSignal( null, - this.mShell.getPid(), - program.getCommand(), + pid.intValue(), FileManagerApplication.getBackgroundConsole()); - if (pid != null) { - CommandHelper.sendSignal( - null, - pid.intValue(), - FileManagerApplication.getBackgroundConsole()); - try { - //Wait for process kill - Thread.sleep(100L); - } catch (Throwable ex) { - /**NON BLOCK**/ + try { + //Wait for process kill + Thread.sleep(100L); + } catch (Throwable ex) { + /**NON BLOCK**/ + } + return true; } + } finally { + // It's finished this.mCancelled = true; notifyProcessFinished(); this.mSync.notify(); - return this.mCancelled; } } } catch (Throwable ex) { |