From a52acddd161f04f950b5285af333883967cb7671 Mon Sep 17 00:00:00 2001 From: Jorge Ruesga Date: Fri, 21 Nov 2014 02:03:36 +0100 Subject: [PATCH] cmfm: allow prompt console without su command Separete shell console commands from su command. This allow to create a shell console when su command is not present. A warning will be displayed is root mode is trying to be selected or a elevated operation is required. Change-Id: I27a2e850aec87026c8dd4b3baacf7ebd0f897a1a Signed-off-by: Jorge Ruesga --- res/values/overlay.xml | 4 +- res/values/strings.xml | 2 + .../filemanager/FileManagerApplication.java | 43 ++++++++++++++++++++-- .../filemanager/activities/NavigationActivity.java | 2 +- .../preferences/GeneralPreferenceFragment.java | 14 ++++++- .../filemanager/console/ConsoleBuilder.java | 2 +- .../filemanager/util/ExceptionUtil.java | 11 ++++++ .../filemanager/util/MountPointHelper.java | 2 +- 8 files changed, 71 insertions(+), 9 deletions(-) diff --git a/res/values/overlay.xml b/res/values/overlay.xml index 88c5d68..6b624ad 100644 --- a/res/values/overlay.xml +++ b/res/values/overlay.xml @@ -65,13 +65,15 @@ /system/xbin/pwd, /system/xbin/readlink, /system/xbin/stat, - /system/xbin/su, /system/xbin/tar, /system/xbin/xargs, /system/xbin/md5sum, /system/xbin/sha1sum + + /system/xbin/su + zip=/system/xbin/zip, diff --git a/res/values/strings.xml b/res/values/strings.xml index dc79bc0..766f4fd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -93,6 +93,8 @@ The setting could not be applied or stored. The initial folder \'%1$s\' is invalid. Changing to root folder. + + Root is not available in this device. Cannot perform this operation. The operation was completed successfully. diff --git a/src/com/cyanogenmod/filemanager/FileManagerApplication.java b/src/com/cyanogenmod/filemanager/FileManagerApplication.java index 8230c1f..ebf369a 100644 --- a/src/com/cyanogenmod/filemanager/FileManagerApplication.java +++ b/src/com/cyanogenmod/filemanager/FileManagerApplication.java @@ -71,6 +71,7 @@ public final class FileManagerApplication extends Application { 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() { @@ -237,8 +238,9 @@ public final class FileManagerApplication extends Application { // 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(); @@ -312,6 +314,15 @@ public final class FileManagerApplication extends Application { } /** + * 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 @@ -430,7 +441,7 @@ public final class FileManagerApplication extends Application { * @return boolean If the access mode of the application */ public static AccessMode getAccessMode() { - if (!sIsDeviceRooted) { + if (!sHasShellCommands) { return AccessMode.SAFE; } String defaultValue = @@ -531,6 +542,32 @@ public final class FileManagerApplication extends Application { 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 { diff --git a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java index d23acc6..4728d5d 100644 --- a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java +++ b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java @@ -658,7 +658,7 @@ public class NavigationActivity extends Activity ((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); diff --git a/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java b/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java index 8c5c991..e578dc6 100644 --- a/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java +++ b/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java @@ -26,6 +26,7 @@ import android.preference.Preference; 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; @@ -35,6 +36,7 @@ import com.cyanogenmod.filemanager.preferences.FileManagerSettings; 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 @@ -101,6 +103,14 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment { 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) { @@ -256,8 +266,8 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment { 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); diff --git a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java index 51f2981..f5f7cdd 100644 --- a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java +++ b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java @@ -291,7 +291,7 @@ public final class ConsoleBuilder { 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(); diff --git a/src/com/cyanogenmod/filemanager/util/ExceptionUtil.java b/src/com/cyanogenmod/filemanager/util/ExceptionUtil.java index 7b7ce74..edd876a 100644 --- a/src/com/cyanogenmod/filemanager/util/ExceptionUtil.java +++ b/src/com/cyanogenmod/filemanager/util/ExceptionUtil.java @@ -285,6 +285,17 @@ public final class ExceptionUtil { } 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 = diff --git a/src/com/cyanogenmod/filemanager/util/MountPointHelper.java b/src/com/cyanogenmod/filemanager/util/MountPointHelper.java index e2e7b4c..d63c1b5 100644 --- a/src/com/cyanogenmod/filemanager/util/MountPointHelper.java +++ b/src/com/cyanogenmod/filemanager/util/MountPointHelper.java @@ -97,7 +97,7 @@ public final class MountPointHelper { // 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 mps = CommandHelper.getMountPoints(null, console); -- 2.11.0