/system/xbin/pwd,
/system/xbin/readlink,
/system/xbin/stat,
- /system/xbin/su,
/system/xbin/tar,
/system/xbin/xargs,
/system/xbin/md5sum,
/system/xbin/sha1sum
</string>
+ <!-- The root command -->
+ <string name="root_command" translatable="false">/system/xbin/su</string>
+
<!-- Optional shell commands in a pair=value format -->
<string name="shell_optional_commands" translatable="false">
zip=/system/xbin/zip,
<string name="msgs_settings_save_failure">The setting could not be applied or stored.</string>
<!-- The initial directory has an invalid or inaccessible reference -->
<string name="msgs_settings_invalid_initial_directory">The initial folder \'<xliff:g id="initial_dir">%1$s</xliff:g>\' is invalid. Changing to root folder.</string>
+ <!-- Root is not available message -->
+ <string name="root_not_available_msg">Root is not available in this device. Cannot perform this operation.</string>
<!-- Success -->
<string name="msgs_success">The operation was completed successfully.</string>
private static ConsoleHolder sBackgroundConsole;
private static boolean sIsDebuggable = false;
+ private static boolean sHasShellCommands = false;
private static boolean sIsDeviceRooted = false;
private final BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
// Check if the application is debuggable
sIsDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
- // Check if the device is rooted
- sIsDeviceRooted = areShellCommandsPresent();
+ // Check if the device has shell commands and if is rooted
+ sHasShellCommands = areShellCommandsPresent();
+ sIsDeviceRooted = isRootPresent();
// Check optional commands
loadOptionalCommands();
}
/**
+ * Method that returns if the device has all the required shell commands
+ *
+ * @return boolean If the device has all the required shell commands
+ */
+ public static boolean hasShellCommands() {
+ return sHasShellCommands;
+ }
+
+ /**
* Method that returns if a command is present in the system
*
* @param commandId The command key
* @return boolean If the access mode of the application
*/
public static AccessMode getAccessMode() {
- if (!sIsDeviceRooted) {
+ if (!sHasShellCommands) {
return AccessMode.SAFE;
}
String defaultValue =
return false;
}
+ /**
+ * Method that check if root command are present in the device
+ *
+ * @return boolean True if root command is present
+ */
+ private boolean isRootPresent() {
+ try {
+ String rootCommand = getString(R.string.root_command);
+ File cmd = new File(rootCommand);
+ if (!cmd.exists() || !cmd.isFile()) {
+ Log.w(TAG,
+ String.format(
+ "Command %s not found. Exists: %s; IsFile: %s.", //$NON-NLS-1$
+ rootCommand,
+ String.valueOf(cmd.exists()),
+ String.valueOf(cmd.isFile())));
+ return false;
+ }
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG,
+ "Failed to read root command.", e); //$NON-NLS-1$
+ }
+ return false;
+ }
+
@SuppressWarnings("boxing")
private void loadOptionalCommands() {
try {
((Boolean)FileManagerSettings.SETTINGS_FIRST_USE.getDefaultValue()).booleanValue());
//Display the welcome message?
- if (firstUse && FileManagerApplication.isDeviceRooted()) {
+ if (firstUse && FileManagerApplication.hasShellCommands()) {
// open navigation drawer to show user that it exists
mDrawerLayout.openDrawer(mDrawer);
import android.preference.PreferenceCategory;
import android.preference.Preference.OnPreferenceChangeListener;
import android.util.Log;
+import android.widget.Toast;
import com.cyanogenmod.filemanager.FileManagerApplication;
import com.cyanogenmod.filemanager.R;
import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.util.AndroidHelper;
+import com.cyanogenmod.filemanager.util.DialogHelper;
/**
* A class that manages the commons options of the application
String value = (String)newValue;
AccessMode oldMode = FileManagerApplication.getAccessMode();
AccessMode newMode = AccessMode.fromId(value);
+
+ // Denied change to root if su command is not present
+ if (newMode.compareTo(AccessMode.ROOT) == 0 &&
+ !FileManagerApplication.isDeviceRooted()) {
+ DialogHelper.showToast(activity, R.string.root_not_available_msg,
+ Toast.LENGTH_SHORT);
+ return false;
+ }
if (oldMode.compareTo(newMode) != 0) {
// The mode was changes. Change the console
if (newMode.compareTo(AccessMode.ROOT) == 0) {
final Context context = getActivity();
boolean restrictedAccess = AndroidHelper.isSecondaryUser(context) &&
FileManagerApplication.isRestrictSecondaryUsersAccess(context);
- this.mAccessMode.setEnabled(FileManagerApplication.isDeviceRooted() && !restrictedAccess);
- if (!FileManagerApplication.isDeviceRooted()) {
+ this.mAccessMode.setEnabled(FileManagerApplication.hasShellCommands() && !restrictedAccess);
+ if (!FileManagerApplication.hasShellCommands()) {
PreferenceCategory category = (PreferenceCategory) findPreference(
"general_advanced_settings");
category.removePreference(mAccessMode);
int bufferSize = context.getResources().getInteger(R.integer.buffer_size);
// Is rooted? Then create a shell console
- if (FileManagerApplication.isDeviceRooted()) {
+ if (FileManagerApplication.hasShellCommands()) {
NonPriviledgeConsole console = new NonPriviledgeConsole();
console.setBufferSize(bufferSize);
console.alloc();
}
return;
}
+ if (relaunchable instanceof InsufficientPermissionsException &&
+ !FileManagerApplication.isDeviceRooted()) {
+ DialogHelper.showToast(context, R.string.root_not_available_msg,
+ Toast.LENGTH_SHORT);
+
+ // Operation failed. Root is not available
+ if (listener != null) {
+ listener.onFailed(relaunchable);
+ }
+ return;
+ }
//Create a yes/no dialog and ask the user
final DialogInterface.OnClickListener clickListener =
// Refresh mount points after some time (5 minutes should be enough)
long now = System.currentTimeMillis();
if (sMountPoints == null || (now - sLastCachedTime) > MAX_CACHED_TIME ||
- FileManagerApplication.isDeviceRooted()) {
+ FileManagerApplication.hasShellCommands()) {
//Retrieve the mount points
List<MountPoint> mps =
CommandHelper.getMountPoints(null, console);