/** * Method that returns if the path is in a volume storage * * @param path The path * @return boolean If the path is in a volume storage */ public static boolean isPathInStorageVolume(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; if (path.startsWith(vol.getPath())) { return true; } } return false; }
/** * Method that return the chrooted path of an absolute path. xe: /storage/sdcard0 --> sdcard0. * * @param path The path * @return String The chrooted path */ public static String getChrootedPath(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; File p = new File(path); File v = new File(vol.getPath()); if (p.getAbsolutePath().startsWith(v.getAbsolutePath())) { return v.getName() + path.substring(v.getAbsolutePath().length()); } } return null; }
/** * Method that returns if the path is a storage volume * * @param path The path * @return boolean If the path is a storage volume */ public static boolean isStorageVolume(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; String p = new File(path).getAbsolutePath(); String v = new File(vol.getPath()).getAbsolutePath(); if (p.compareTo(v) == 0) { return true; } } return false; }
/** {@inheritDoc} */ @Override protected void onCreate(Bundle state) { if (DEBUG) { Log.d(TAG, "SearchActivity.onCreate"); // $NON-NLS-1$ } // Check if app is running in chrooted mode this.mChRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0; // Register the broadcast receiver IntentFilter filter = new IntentFilter(); filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED); filter.addAction(FileManagerSettings.INTENT_THEME_CHANGED); registerReceiver(this.mNotificationReceiver, filter); // Set in transition overridePendingTransition(R.anim.translate_to_right_in, R.anim.hold_out); // Set the main layout of the activity setContentView(R.layout.search); // Restore state if (state != null) { restoreState(state); } // Initialize action bars and search initTitleActionBar(); initComponents(); // Apply current theme applyTheme(); if (this.mRestoreState != null) { // Restore activity from cached data loadFromCacheData(); } else { // New query if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) { initSearch(); } else if (ACTION_RESTORE.equals(getIntent().getAction())) { restoreState(getIntent().getExtras()); loadFromCacheData(); } } // Save state super.onCreate(state); }
/** * Method that uncompress a compressed file. * * @param ctx The current context * @param fso The compressed file * @param onRequestRefreshListener The listener for request a refresh (optional) * @hide */ public static void uncompress( final Context ctx, final FileSystemObject fso, final OnRequestRefreshListener onRequestRefreshListener) { // The callable interface final BackgroundCallable callable = new BackgroundCallable() { // The current items final Context mCtx = ctx; final FileSystemObject mFso = fso; final OnRequestRefreshListener mOnRequestRefreshListener = onRequestRefreshListener; final Object mSync = new Object(); Throwable mCause; UncompressExecutable cmd; final CompressListener mListener = new CompressListener(); private String mMsg; private boolean mStarted = false; @Override public int getDialogTitle() { return R.string.waiting_dialog_extracting_title; } @Override public int getDialogIcon() { return 0; } @Override public boolean isDialogCancellable() { return true; } @Override public Spanned requestProgress() { // Initializing the dialog if (!this.mStarted) { String progress = this.mCtx.getResources().getString(R.string.waiting_dialog_analizing_msg); return Html.fromHtml(progress); } // Return the current operation String msg = (this.mMsg == null) ? "" : this.mMsg; // $NON-NLS-1$ String progress = this.mCtx.getResources().getString(R.string.waiting_dialog_extracting_msg, msg); return Html.fromHtml(progress); } @Override public void onSuccess() { try { if (this.cmd != null && this.cmd.isCancellable() && !this.cmd.isCancelled()) { this.cmd.cancel(); } } catch (Exception e) { /** NON BLOCK* */ } // Operation complete. Refresh if (this.mOnRequestRefreshListener != null) { // The reference is not the same, so refresh the complete navigation view this.mOnRequestRefreshListener.onRequestRefresh(null); } if (this.cmd != null) { showOperationSuccessMsg( ctx, R.string.msgs_extracting_success, this.cmd.getOutUncompressedFile()); } else { ActionsPolicy.showOperationSuccessMsg(ctx); } } @Override public void doInBackground(Object... params) throws Throwable { this.mCause = null; this.mStarted = true; // This method expect to receive // 1.- BackgroundAsyncTask BackgroundAsyncTask task = (BackgroundAsyncTask) params[0]; String out = null; try { this.cmd = CommandHelper.uncompress( ctx, this.mFso.getFullPath(), null, this.mListener, null); out = this.cmd.getOutUncompressedFile(); // Request paint the this.mListener.mQueue.insert(out); task.onRequestProgress(); // Don't use an active blocking because this suppose that all message // will be processed by the UI. Instead, refresh with a delay and // display the active file while (!this.mListener.mEnd) { // Sleep to don't saturate the UI thread Thread.sleep(50L); List<String> msgs = this.mListener.mQueue.peekAll(); if (msgs.size() > 0) { this.mMsg = msgs.get(msgs.size() - 1); task.onRequestProgress(); } } // Dialog is ended. Force the last redraw List<String> msgs = this.mListener.mQueue.peekAll(); if (msgs.size() > 0) { this.mMsg = msgs.get(msgs.size() - 1); task.onRequestProgress(); } } catch (Exception e) { // Need to be relaunched? if (e instanceof RelaunchableException) { OnRelaunchCommandResult rl = new OnRelaunchCommandResult() { @Override @SuppressWarnings("unqualified-field-access") public void onSuccess() { synchronized (mSync) { mSync.notify(); } } @Override @SuppressWarnings("unqualified-field-access") public void onFailed(Throwable cause) { mCause = cause; synchronized (mSync) { mSync.notify(); } } @Override @SuppressWarnings("unqualified-field-access") public void onCancelled() { synchronized (mSync) { mSync.notify(); } } }; // Translate the exception (and wait for the result) ExceptionUtil.translateException(ctx, e, false, true, rl); synchronized (this.mSync) { this.mSync.wait(); } // Persist the exception? if (this.mCause != null) { // The exception must be elevated throw this.mCause; } } else { // The exception must be elevated throw e; } } // Any exception? if (this.mListener.mCause != null) { throw this.mListener.mCause; } // Check that the operation was completed retrieving the uncompressed // file or folder boolean failed = false; try { FileSystemObject fso2 = CommandHelper.getFileInfo(ctx, out, false, null); if (fso2 == null) { // Failed. The file or folder not exists failed = true; } // Operation complete successfully } catch (Throwable e) { // Failed. The file or folder not exists failed = true; } if (failed) { throw new ExecutionException( String.format( "Failed to extract file: %s", //$NON-NLS-1$ this.mFso.getFullPath())); } } }; final BackgroundAsyncTask task = new BackgroundAsyncTask(ctx, callable); // Check if the output exists boolean askUser = false; try { UncompressExecutable ucmd = FileManagerApplication.getBackgroundConsole() .getExecutableFactory() .newCreator() .createUncompressExecutable(fso.getFullPath(), null, null); String dst = ucmd.getOutUncompressedFile(); FileSystemObject info = CommandHelper.getFileInfo(ctx, dst, null); if (info != null) { askUser = true; } } catch (Exception e) { /** NON BLOCK* */ } // Ask the user because the destination file or folder exists if (askUser) { // Show a dialog asking the user for overwrite the files AlertDialog dialog = DialogHelper.createTwoButtonsQuestionDialog( ctx, android.R.string.cancel, R.string.overwrite, R.string.confirm_overwrite, ctx.getString(R.string.msgs_overwrite_files), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface alertDialog, int which) { // NEGATIVE (overwrite) POSITIVE (cancel) if (which == DialogInterface.BUTTON_NEGATIVE) { // Check if the necessary to display a warning because // security issues checkZipSecurityWarning(ctx, task, fso); } } }); DialogHelper.delegateDialogShow(ctx, dialog); } else { // Execute background task task.execute(task); } }
/** * Method that compresses some uncompressed files or folders * * @param ctx The current context * @param mode The compression mode * @param fsos The list of files to compress * @param onSelectionListener The listener for obtain selection information (required) * @param onRequestRefreshListener The listener for request a refresh (optional) * @hide */ static void compress( final Context ctx, final CompressionMode mode, final List<FileSystemObject> fsos, final OnSelectionListener onSelectionListener, final OnRequestRefreshListener onRequestRefreshListener) { // The callable interface final BackgroundCallable callable = new BackgroundCallable() { // The current items final Context mCtx = ctx; final CompressionMode mMode = mode; final List<FileSystemObject> mFsos = fsos; final OnRequestRefreshListener mOnRequestRefreshListener = onRequestRefreshListener; final Object mSync = new Object(); Throwable mCause; CompressExecutable cmd = null; final CompressListener mListener = new CompressListener(); private String mMsg; private boolean mStarted = false; @Override public int getDialogTitle() { return R.string.waiting_dialog_compressing_title; } @Override public int getDialogIcon() { return 0; } @Override public boolean isDialogCancellable() { return true; } @Override public Spanned requestProgress() { // Initializing the dialog if (!this.mStarted) { String progress = this.mCtx.getResources().getString(R.string.waiting_dialog_analizing_msg); return Html.fromHtml(progress); } // Return the current operation String msg = (this.mMsg == null) ? "" : this.mMsg; // $NON-NLS-1$ String progress = this.mCtx.getResources().getString(R.string.waiting_dialog_compressing_msg, msg); return Html.fromHtml(progress); } @Override public void onSuccess() { try { if (this.cmd != null && this.cmd.isCancellable() && !this.cmd.isCancelled()) { this.cmd.cancel(); } } catch (Exception e) { /** NON BLOCK* */ } // Operation complete. Refresh if (this.mOnRequestRefreshListener != null) { // The reference is not the same, so refresh the complete navigation view this.mOnRequestRefreshListener.onRequestRefresh(null); } if (this.cmd != null) { showOperationSuccessMsg( ctx, R.string.msgs_compressing_success, this.cmd.getOutCompressedFile()); } else { ActionsPolicy.showOperationSuccessMsg(ctx); } } @Override public void doInBackground(Object... params) throws Throwable { this.mCause = null; this.mStarted = true; // This method expect to receive // 1.- BackgroundAsyncTask BackgroundAsyncTask task = (BackgroundAsyncTask) params[0]; String out = null; try { // Archive or Archive-Compression if (this.mMode.mArchive) { // Convert the list to an array of full paths String[] src = new String[this.mFsos.size()]; int cc = this.mFsos.size(); for (int i = 0; i < cc; i++) { src[i] = this.mFsos.get(i).getFullPath(); } // Use the current directory name for create the compressed file String curDirName = new File(onSelectionListener.onRequestCurrentDir()).getName(); if (src.length == 1) { // But only one file is passed, then used the name of unique file curDirName = FileHelper.getName(this.mFsos.get(0).getName()); } String name = String.format("%s.%s", curDirName, this.mMode.mExtension); // $NON-NLS-1$ String newName = FileHelper.createNonExistingName( ctx, onSelectionListener.onRequestCurrentItems(), name, R.string.create_new_compress_file_regexp); String newNameAbs = new File(onSelectionListener.onRequestCurrentDir(), newName).getAbsolutePath(); // Do the compression this.cmd = CommandHelper.compress(ctx, this.mMode, newNameAbs, src, this.mListener, null); // Compression } else { // Only the first item from the list is valid. If there are more in the // list, then discard them String src = this.mFsos.get(0).getFullPath(); // Do the compression this.cmd = CommandHelper.compress(ctx, this.mMode, src, this.mListener, null); } out = this.cmd.getOutCompressedFile(); // Request paint the this.mListener.mQueue.insert(out); task.onRequestProgress(); // Don't use an active blocking because this suppose that all message // will be processed by the UI. Instead, refresh with a delay and // display the active file while (!this.mListener.mEnd) { // Sleep to don't saturate the UI thread Thread.sleep(50L); List<String> msgs = this.mListener.mQueue.peekAll(); if (msgs.size() > 0) { this.mMsg = msgs.get(msgs.size() - 1); task.onRequestProgress(); } } // Dialog is ended. Force the last redraw List<String> msgs = this.mListener.mQueue.peekAll(); if (msgs.size() > 0) { this.mMsg = msgs.get(msgs.size() - 1); task.onRequestProgress(); } } catch (Exception e) { // Need to be relaunched? if (e instanceof RelaunchableException) { OnRelaunchCommandResult rl = new OnRelaunchCommandResult() { @Override @SuppressWarnings("unqualified-field-access") public void onSuccess() { synchronized (mSync) { mSync.notify(); } } @Override @SuppressWarnings("unqualified-field-access") public void onFailed(Throwable cause) { mCause = cause; synchronized (mSync) { mSync.notify(); } } @Override @SuppressWarnings("unqualified-field-access") public void onCancelled() { synchronized (mSync) { mSync.notify(); } } }; // Translate the exception (and wait for the result) ExceptionUtil.translateException(ctx, e, false, true, rl); synchronized (this.mSync) { this.mSync.wait(); } // Persist the exception? if (this.mCause != null) { // The exception must be elevated throw this.mCause; } } else { // The exception must be elevated throw e; } } // Any exception? if (this.mListener.mCause != null) { throw this.mListener.mCause; } // Check that the operation was completed retrieving the compressed file or folder boolean failed = false; try { FileSystemObject fso = CommandHelper.getFileInfo(ctx, out, false, null); if (fso == null) { // Failed. The file or folder not exists failed = true; } // Operation complete successfully } catch (Throwable e) { // Failed. The file or folder not exists failed = true; } if (failed) { throw new ExecutionException( String.format("Failed to compress file(s) to: %s", out)); // $NON-NLS-1$ } } }; final BackgroundAsyncTask task = new BackgroundAsyncTask(ctx, callable); // Check if the output exists. When the mode is archive, this method generate a new // name based in the current directory. When the mode is compressed then the name // is the name of the file to compress without extension. In this case the name should // be validate prior to compress boolean askUser = false; try { if (!mode.mArchive) { // Only the first item from the list is valid. If there are more in the // list, then discard them String src = fsos.get(0).getFullPath(); CompressExecutable ucmd = FileManagerApplication.getBackgroundConsole() .getExecutableFactory() .newCreator() .createCompressExecutable(mode, src, null); String dst = ucmd.getOutCompressedFile(); FileSystemObject info = CommandHelper.getFileInfo(ctx, dst, null); if (info != null) { askUser = true; } } } catch (Exception e) { /** NON BLOCK* */ } // Ask the user because the destination file or folder exists if (askUser) { // Show a dialog asking the user for overwrite the files AlertDialog dialog = DialogHelper.createTwoButtonsQuestionDialog( ctx, android.R.string.cancel, R.string.overwrite, R.string.confirm_overwrite, ctx.getString(R.string.msgs_overwrite_files), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface alertDialog, int which) { // NEGATIVE (overwrite) POSITIVE (cancel) if (which == DialogInterface.BUTTON_NEGATIVE) { // Execute background task task.execute(task); } } }); DialogHelper.delegateDialogShow(ctx, dialog); } else { // Execute background task task.execute(task); } }