aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2014-03-20 05:05:56 +0100
committerJorge Ruesga <jorge@ruesga.com>2014-03-20 05:11:17 +0100
commitf722214dff88bcc427e8a2a20790ff3543314947 (patch)
tree5af69514d83b0450aa02b0c2af08dc0dedf6e3c0
parentb6d3b71bf15e3778f8c76dab2c78be1a89683624 (diff)
downloadandroid_packages_apps_CMFileManager-f722214dff88bcc427e8a2a20790ff3543314947.tar.gz
android_packages_apps_CMFileManager-f722214dff88bcc427e8a2a20790ff3543314947.tar.bz2
android_packages_apps_CMFileManager-f722214dff88bcc427e8a2a20790ff3543314947.zip
CMFM: Allow restrict access to secondary users
Change-Id: I1bffbb32a5f02ab4ca5cdcdbc21d40c7bb299933 JIRA: CYAN-1630 Issue: https://jira.cyanogenmod.org/browse/CYAN-1630 Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--res/values/strings.xml4
-rw-r--r--res/xml/preferences_general.xml8
-rw-r--r--src/com/cyanogenmod/filemanager/FileManagerApplication.java36
-rw-r--r--src/com/cyanogenmod/filemanager/activities/NavigationActivity.java26
-rw-r--r--src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java46
-rw-r--r--src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java15
-rw-r--r--src/com/cyanogenmod/filemanager/preferences/FileManagerSettings.java7
-rw-r--r--src/com/cyanogenmod/filemanager/preferences/Preferences.java90
-rw-r--r--src/com/cyanogenmod/filemanager/util/AndroidHelper.java14
9 files changed, 242 insertions, 4 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 77fea1ef..f23d5198 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -645,6 +645,10 @@
<string name="pref_access_mode_root">Root Access mode</string>
<!-- Preferences - General - Root access mode summary -->
<string name="pref_access_mode_root_summary">Root Access mode\n\nWarning! This mode allows operations that could break your device. It\'s your responsibility to ensure that an operation is safe</string>
+ <!-- Preferences - General - Restrict secondary users access title -->
+ <string name="pref_restrict_secondary_users_access_title">Restrict users access</string>
+ <!-- Preferences - General - Restrict secondary users access summary -->
+ <string name="pref_restrict_secondary_users_access_summary">Restrict access to the whole system to secondary users</string>
<!-- Preferences - Search - Results category -->
<string name="pref_search_results_category">Results</string>
<!-- Preferences - Search - Show relevance widget -->
diff --git a/res/xml/preferences_general.xml b/res/xml/preferences_general.xml
index 2bfbf09c..07316ea5 100644
--- a/res/xml/preferences_general.xml
+++ b/res/xml/preferences_general.xml
@@ -88,6 +88,14 @@
android:defaultValue="0"
android:persistent="true" />
+ <!-- Restrict secondary users access -->
+ <CheckBoxPreference
+ android:key="cm_filemanager_restrict_secondary_users_access"
+ android:title="@string/pref_restrict_secondary_users_access_title"
+ android:summary="@string/pref_restrict_secondary_users_access_summary"
+ android:persistent="false"
+ android:defaultValue="false" />
+
<!-- Capture debug traces -->
<CheckBoxPreference
android:key="cm_filemanager_show_debug_traces"
diff --git a/src/com/cyanogenmod/filemanager/FileManagerApplication.java b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
index 2aba2941..be475dff 100644
--- a/src/com/cyanogenmod/filemanager/FileManagerApplication.java
+++ b/src/com/cyanogenmod/filemanager/FileManagerApplication.java
@@ -36,6 +36,7 @@ import com.cyanogenmod.filemanager.preferences.Preferences;
import com.cyanogenmod.filemanager.ui.ThemeManager;
import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
import com.cyanogenmod.filemanager.util.AIDHelper;
+import com.cyanogenmod.filemanager.util.AndroidHelper;
import com.cyanogenmod.filemanager.util.MimeTypeHelper;
import java.io.File;
@@ -438,6 +439,41 @@ public final class FileManagerApplication extends Application {
return mode;
}
+ public static boolean isRestrictSecondaryUsersAccess(Context context) {
+ String value = Preferences.getWorldReadableProperties(
+ context, FileManagerSettings.SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS.getId());
+ if (value == null) {
+ value = String.valueOf(FileManagerSettings.SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS.
+ getDefaultValue());
+ }
+ return Boolean.parseBoolean(value);
+ }
+
+ public static boolean checkRestrictSecondaryUsersAccess(Context context, boolean isChroot) {
+ if (!AndroidHelper.isSecondaryUser(context)) {
+ return true;
+ }
+ boolean needChroot = !isChroot && isRestrictSecondaryUsersAccess(context);
+ if (!needChroot) {
+ return true;
+ }
+
+ try {
+ Preferences.savePreference(
+ FileManagerSettings.SETTINGS_ACCESS_MODE, AccessMode.SAFE, true);
+ } catch (Throwable ex) {
+ Log.w(TAG, "can't save console preference", ex); //$NON-NLS-1$
+ }
+ ConsoleBuilder.changeToNonPrivilegedConsole(context);
+
+ // Notify the change
+ Intent intent = new Intent(FileManagerSettings.INTENT_SETTING_CHANGED);
+ intent.putExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY,
+ FileManagerSettings.SETTINGS_ACCESS_MODE.getId());
+ context.sendBroadcast(intent);
+ return false;
+ }
+
/**
* Method that reads the system properties
*/
diff --git a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
index 759d7550..8f5fcd26 100644
--- a/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
+++ b/src/com/cyanogenmod/filemanager/activities/NavigationActivity.java
@@ -242,6 +242,22 @@ public class NavigationActivity extends Activity
}
}
+ // Restricted access
+ if (key.compareTo(FileManagerSettings.
+ SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS.getId()) == 0) {
+ if (AndroidHelper.isSecondaryUser(context)) {
+ try {
+ Preferences.savePreference(
+ FileManagerSettings.SETTINGS_ACCESS_MODE,
+ AccessMode.SAFE, true);
+ } catch (Throwable ex) {
+ Log.w(TAG, "can't save console preference", ex); //$NON-NLS-1$
+ }
+ ConsoleBuilder.changeToNonPrivilegedConsole(context);
+ createChRooted();
+ }
+ }
+
// Filetime format mode
if (key.compareTo(FileManagerSettings.
SETTINGS_FILETIME_FORMAT_MODE.getId()) == 0) {
@@ -424,6 +440,16 @@ public class NavigationActivity extends Activity
}
@Override
+ protected void onResume() {
+ super.onResume();
+
+ // Check restrictions
+ if (!FileManagerApplication.checkRestrictSecondaryUsersAccess(this, mChRooted)) {
+ return;
+ }
+ }
+
+ @Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
diff --git a/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java b/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java
index f4643907..2821ce91 100644
--- a/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java
+++ b/src/com/cyanogenmod/filemanager/activities/preferences/GeneralPreferenceFragment.java
@@ -23,6 +23,7 @@ import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
+import android.preference.PreferenceCategory;
import android.preference.Preference.OnPreferenceChangeListener;
import android.util.Log;
@@ -33,6 +34,7 @@ import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier;
import com.cyanogenmod.filemanager.preferences.Preferences;
+import com.cyanogenmod.filemanager.util.AndroidHelper;
/**
* A class that manages the commons options of the application
@@ -50,6 +52,7 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment {
private CheckBoxPreference mDisplayThumbs;
private CheckBoxPreference mUseFlinger;
private ListPreference mAccessMode;
+ private CheckBoxPreference mRestrictSecondaryUsersAccess;
private CheckBoxPreference mDebugTraces;
/**
@@ -62,6 +65,7 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment {
@Override
public boolean onPreferenceChange(final Preference preference, Object newValue) {
boolean ret = true;
+ boolean notify = false;
String key = preference.getKey();
if (DEBUG) {
@@ -120,9 +124,21 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment {
preference.setSummary(summary[valueId]);
}
+ // Restricted secondary users access
+ else if (FileManagerSettings.SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS.getId().
+ compareTo(key) == 0) {
+ String value = String.valueOf(newValue);
+ if (Preferences.writeWorldReadableProperty(getActivity(), key, value)) {
+ ((CheckBoxPreference) preference).setChecked((Boolean) newValue);
+ updateAccessModeStatus();
+ notify = true;
+ }
+ ret = false;
+ }
+
// Notify the change (only if fragment is loaded. Default values are loaded
// while not in loaded mode)
- if (GeneralPreferenceFragment.this.mLoaded && ret) {
+ if (GeneralPreferenceFragment.this.mLoaded && (ret || notify)) {
Intent intent = new Intent(FileManagerSettings.INTENT_SETTING_CHANGED);
intent.putExtra(
FileManagerSettings.EXTRA_SETTING_CHANGED_KEY, preference.getKey());
@@ -206,8 +222,24 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment {
FileManagerSettings.SETTINGS_ACCESS_MODE.getId(),
defaultValue);
this.mOnChangeListener.onPreferenceChange(this.mAccessMode, value);
- // If device is not rooted, this setting cannot be changed
- this.mAccessMode.setEnabled(FileManagerApplication.isDeviceRooted());
+ updateAccessModeStatus();
+
+ // Capture Debug traces
+ this.mRestrictSecondaryUsersAccess =
+ (CheckBoxPreference)findPreference(
+ FileManagerSettings.SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS.getId());
+ if (!AndroidHelper.hasSupportForMultipleUsers(getActivity()) ||
+ AndroidHelper.isSecondaryUser(getActivity())) {
+ // Remove if device doesn't support multiple users accounts or the current user
+ // is a secondary user
+ PreferenceCategory category = (PreferenceCategory) findPreference(
+ "general_advanced_settings");
+ category.removePreference(this.mRestrictSecondaryUsersAccess);
+ } else {
+ this.mRestrictSecondaryUsersAccess.setChecked(
+ FileManagerApplication.isRestrictSecondaryUsersAccess(getActivity()));
+ this.mRestrictSecondaryUsersAccess.setOnPreferenceChangeListener(this.mOnChangeListener);
+ }
// Capture Debug traces
this.mDebugTraces =
@@ -219,6 +251,14 @@ public class GeneralPreferenceFragment extends TitlePreferenceFragment {
this.mLoaded = true;
}
+ private void updateAccessModeStatus() {
+ // If device is not rooted, or is a restricted user, this setting cannot be changed
+ final Context context = getActivity();
+ boolean restrictedAccess = AndroidHelper.isSecondaryUser(context) &&
+ FileManagerApplication.isRestrictSecondaryUsersAccess(context);
+ this.mAccessMode.setEnabled(FileManagerApplication.isDeviceRooted() && !restrictedAccess);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java
index ce066a2e..51f29818 100644
--- a/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java
+++ b/src/com/cyanogenmod/filemanager/console/ConsoleBuilder.java
@@ -29,6 +29,7 @@ import com.cyanogenmod.filemanager.console.shell.PrivilegedConsole;
import com.cyanogenmod.filemanager.preferences.AccessMode;
import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
import com.cyanogenmod.filemanager.preferences.Preferences;
+import com.cyanogenmod.filemanager.util.AndroidHelper;
import com.cyanogenmod.filemanager.util.DialogHelper;
import java.io.FileNotFoundException;
@@ -188,7 +189,19 @@ public final class ConsoleBuilder {
FileManagerApplication.getAccessMode().compareTo(AccessMode.ROOT) == 0;
boolean advancedMode =
FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) != 0;
- if (superuserMode && !advancedMode) {
+ boolean restrictedMode =
+ AndroidHelper.hasSupportForMultipleUsers(context) && !AndroidHelper.isUserOwner();
+ if (restrictedMode) {
+ // Is a secondary user. Restrict access to the whole system
+ try {
+ Preferences.savePreference(
+ FileManagerSettings.SETTINGS_ACCESS_MODE, AccessMode.SAFE, true);
+ } catch (Throwable ex) {
+ Log.w(TAG, "can't save console preference", ex); //$NON-NLS-1$
+ }
+ superuserMode = false;
+ }
+ else if (superuserMode && !advancedMode) {
try {
Preferences.savePreference(
FileManagerSettings.SETTINGS_ACCESS_MODE, AccessMode.PROMPT, true);
diff --git a/src/com/cyanogenmod/filemanager/preferences/FileManagerSettings.java b/src/com/cyanogenmod/filemanager/preferences/FileManagerSettings.java
index 4d2bb2fa..93309dae 100644
--- a/src/com/cyanogenmod/filemanager/preferences/FileManagerSettings.java
+++ b/src/com/cyanogenmod/filemanager/preferences/FileManagerSettings.java
@@ -36,6 +36,13 @@ public enum FileManagerSettings {
SETTINGS_ACCESS_MODE("cm_filemanager_access_mode", AccessMode.SAFE), //$NON-NLS-1$
/**
+ * When secondary users will have a chrooted console
+ * @hide
+ */
+ SETTINGS_RESTRICT_SECONDARY_USERS_ACCESS("cm_filemanager_restrict_secondary_users_access",
+ Boolean.TRUE), //$NON-NLS-1$
+
+ /**
* The initial directory to be used.
* @hide
*/
diff --git a/src/com/cyanogenmod/filemanager/preferences/Preferences.java b/src/com/cyanogenmod/filemanager/preferences/Preferences.java
index 171c63d4..3cdc595e 100644
--- a/src/com/cyanogenmod/filemanager/preferences/Preferences.java
+++ b/src/com/cyanogenmod/filemanager/preferences/Preferences.java
@@ -19,10 +19,16 @@ package com.cyanogenmod.filemanager.preferences;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
+import android.os.UserHandle;
import android.util.Log;
import com.cyanogenmod.filemanager.FileManagerApplication;
+import com.cyanogenmod.filemanager.util.AndroidHelper;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
import java.io.InvalidClassException;
import java.util.ArrayList;
import java.util.Collections;
@@ -30,6 +36,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
/**
@@ -49,6 +56,11 @@ public final class Preferences {
* @hide
*/
public static final String SETTINGS_FILENAME = "com.cyanogenmod.filemanager"; //$NON-NLS-1$
+ /**
+ * The name of the file manager public readable shared properties file.
+ * @hide
+ */
+ public static final String SHARED_PROPERTIES_FILENAME = "shared.properties";
/**
* The list of configuration listeners.
@@ -130,6 +142,84 @@ public final class Preferences {
SETTINGS_FILENAME, Context.MODE_PRIVATE);
}
+ private static File getWorldReadablePropertiesFile(Context context) {
+ String dataDir = context.getApplicationInfo().dataDir;
+ if (AndroidHelper.isSecondaryUser(context)) {
+ dataDir = dataDir.replace(String.valueOf(UserHandle.myUserId()),
+ String.valueOf(UserHandle.USER_OWNER));
+ }
+ return new File(dataDir, SHARED_PROPERTIES_FILENAME);
+ }
+
+ public static String getWorldReadableProperties(Context context, String key) {
+ Properties props = new Properties();
+ FileReader reader = null;
+ try {
+ reader = new FileReader(getWorldReadablePropertiesFile(context));
+ props.load(reader);
+ } catch (IOException ex) {
+ // Ignore
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ // Ignore
+ }
+ }
+ }
+ return props.getProperty(key);
+ }
+
+ public static boolean writeWorldReadableProperty(Context context, String key, String value) {
+ if (AndroidHelper.isSecondaryUser(context)) {
+ // Not allowed
+ return false;
+ }
+ Properties props = new Properties();
+ FileReader reader = null;
+ FileWriter writer = null;
+ try {
+ File dst = getWorldReadablePropertiesFile(context);
+ if (!dst.exists()) {
+ dst.createNewFile();
+ dst.setWritable(true, true);
+ dst.setReadable(true, false);
+ dst.setExecutable(false);
+ }
+ reader = new FileReader(dst);
+ props.load(reader);
+ try {
+ props.load(new FileReader(dst));
+ } catch (IOException ex) {
+ return false;
+ }
+ props.put(key, value);
+ writer = new FileWriter(dst);
+ props.store(writer, null);
+ return true;
+
+ } catch (IOException ex) {
+ // Ignore
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ // Ignore
+ }
+ }
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ // Ignore
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Method that saves a preference.
*
diff --git a/src/com/cyanogenmod/filemanager/util/AndroidHelper.java b/src/com/cyanogenmod/filemanager/util/AndroidHelper.java
index 57260ec1..f014b0d8 100644
--- a/src/com/cyanogenmod/filemanager/util/AndroidHelper.java
+++ b/src/com/cyanogenmod/filemanager/util/AndroidHelper.java
@@ -20,6 +20,8 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.DisplayMetrics;
import android.view.ViewConfiguration;
@@ -101,4 +103,16 @@ public final class AndroidHelper {
return false;
}
+ public static boolean hasSupportForMultipleUsers(Context context) {
+ return UserManager.supportsMultipleUsers();
+ }
+
+ public static boolean isUserOwner() {
+ return UserHandle.myUserId() == UserHandle.USER_OWNER;
+ }
+
+ public static boolean isSecondaryUser(Context context) {
+ return AndroidHelper.hasSupportForMultipleUsers(context)
+ && !AndroidHelper.isUserOwner();
+ }
}