OSDN Git Service

Superuser: Don't set root access as a default fallback option.
[android-x86/external-koush-Superuser.git] / Superuser / src / com / koushikdutta / superuser / util / Settings.java
index 70b312e..4255f8c 100755 (executable)
@@ -8,129 +8,115 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Method;
 import java.security.MessageDigest;
 
+import android.app.Activity;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
 import android.os.Build;
+import android.text.TextUtils;
 import android.util.Base64;
+import android.util.Log;
 
 import com.koushikdutta.superuser.Helper;
+import com.koushikdutta.superuser.db.SuperuserDatabaseHelper;
 
 public class Settings {
+    static final String TAG = "Superuser";
     SQLiteDatabase mDatabase;
     Context mContext;
 
-    private Settings(Context context) {
-        mContext = context;
-        SQLiteOpenHelper helper = new SQLiteOpenHelper(mContext, "settings.db", null, 1) {
-            private final static String mDDL = "CREATE TABLE settings (key TEXT PRIMARY KEY, value TEXT);";
-
-            @Override
-            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-                onCreate(db);
-            }
-
-            @Override
-            public void onCreate(SQLiteDatabase db) {
-                db.execSQL(mDDL);
-            }
-        };
-        mDatabase = helper.getWritableDatabase();
-    }
-
-    private static Settings mInstance;
-
-    public static Settings getInstance(Context context) {
-        if (mInstance == null) {
-            mInstance = new Settings(context.getApplicationContext());
-        }
-        return mInstance;
-    }
-
-    public void setString(String name, String value) {
+    public static void setString(Context context, String name, String value) {
         ContentValues cv = new ContentValues();
         cv.put("key", name);
         cv.put("value", value);
-        mDatabase.replace("settings", null, cv);
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getWritableDatabase();
+        try {
+            db.replace("settings", null, cv);
+        }
+        finally {
+            db.close();
+        }
     }
 
-    public String getString(String name) {
-        return getString(name, null);
+    public static String getString(Context context, String name) {
+        return getString(context, name, null);
     }
 
-    public String getString(String name, String defaultValue) {
-        Cursor cursor = mDatabase.query("settings", new String[] { "value" }, "key='" + name + "'", null, null, null, null);
+    public static String getString(Context context, String name, String defaultValue) {
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getReadableDatabase();
+        Cursor cursor = db.query("settings", new String[] { "value" }, "key='" + name + "'", null, null, null, null);
         try {
             if (cursor.moveToNext())
                 return cursor.getString(0);
         }
         finally {
             cursor.close();
+            db.close();
         }
         return defaultValue;
     }
 
-    public void setInt(String name, int value) {
-        setString(name, ((Integer) value).toString());
+    public static void setInt(Context context, String name, int value) {
+        setString(context, name, ((Integer) value).toString());
     }
 
-    public int getInt(String name, int defaultValue) {
+    public static int getInt(Context context, String name, int defaultValue) {
         try {
-            return Integer.parseInt(getString(name, null));
+            return Integer.parseInt(getString(context, name, null));
         }
         catch (Exception ex) {
             return defaultValue;
         }
     }
 
-    public void setLong(String name, long value) {
-        setString(name, ((Long) value).toString());
+    public static void setLong(Context context, String name, long value) {
+        setString(context, name, ((Long) value).toString());
     }
 
-    public long getLong(String name, long defaultValue) {
+    public static long getLong(Context context, String name, long defaultValue) {
         try {
-            return Long.parseLong(getString(name, null));
+            return Long.parseLong(getString(context, name, null));
         }
         catch (Exception ex) {
             return defaultValue;
         }
     }
 
-    public void setBoolean(String name, boolean value) {
-        setString(name, ((Boolean) value).toString());
+    public static void setBoolean(Context context, String name, boolean value) {
+        setString(context, name, ((Boolean) value).toString());
     }
 
-    public boolean getBoolean(String name, boolean defaultValue) {
+    public static boolean getBoolean(Context context, String name, boolean defaultValue) {
         try {
-            return Boolean.parseBoolean(getString(name, ((Boolean) defaultValue).toString()));
+            return Boolean.parseBoolean(getString(context, name, ((Boolean) defaultValue).toString()));
         }
         catch (Exception ex) {
             ex.printStackTrace();
             return defaultValue;
         }
     }
-    
+
     private static final String KEY_LOGGING = "logging";
     public static boolean getLogging(Context context) {
-        return getInstance(context).getBoolean(KEY_LOGGING, true);
+        return getBoolean(context, KEY_LOGGING, true);
     }
-    
+
     public static void setLogging(Context context, boolean logging) {
-        getInstance(context).setBoolean(KEY_LOGGING, logging);
+        setBoolean(context, KEY_LOGGING, logging);
     }
-    
+
     private static final String KEY_TIMEOUT = "timeout";
     public static final int REQUEST_TIMEOUT_DEFAULT = 30;
     public static int getRequestTimeout(Context context) {
-        return getInstance(context).getInt(KEY_TIMEOUT, REQUEST_TIMEOUT_DEFAULT);
+        return getInt(context, KEY_TIMEOUT, REQUEST_TIMEOUT_DEFAULT);
     }
-    
+
     public static void setTimeout(Context context, int timeout) {
-        getInstance(context).setInt(KEY_TIMEOUT, timeout);
+        setInt(context, KEY_TIMEOUT, timeout);
     }
 
     private static final String KEY_NOTIFICATION = "notification";
@@ -139,7 +125,7 @@ public class Settings {
     public static final int NOTIFICATION_TYPE_NOTIFICATION = 2;
     public static final int NOTIFICATION_TYPE_DEFAULT = NOTIFICATION_TYPE_TOAST;
     public static int getNotificationType(Context context) {
-        switch (getInstance(context).getInt(KEY_NOTIFICATION, NOTIFICATION_TYPE_DEFAULT)) {
+        switch (getInt(context, KEY_NOTIFICATION, NOTIFICATION_TYPE_DEFAULT)) {
         case NOTIFICATION_TYPE_NONE:
             return NOTIFICATION_TYPE_NONE;
         case NOTIFICATION_TYPE_NOTIFICATION:
@@ -150,23 +136,23 @@ public class Settings {
             return NOTIFICATION_TYPE_DEFAULT;
         }
     }
-    
+
     public static void setNotificationType(Context context, int notification) {
-        getInstance(context).setInt(KEY_NOTIFICATION, notification);
+        setInt(context, KEY_NOTIFICATION, notification);
     }
-    
+
     public static final String KEY_PIN = "pin";
     public static final boolean isPinProtected(Context context) {
-        return Settings.getInstance(context).getString(KEY_PIN) != null;
+        return Settings.getString(context, KEY_PIN) != null;
     }
-    
+
     private static String digest(String value) {
         // ok, there's honestly no point in digesting the pin.
         // if someone gets a hold of the hash, there's really only like
         // 10^n possible values to brute force, where N is generally
         // 4. Ie, 10000. Yay, security theater. This really ought
         // to be a password.
-        if (value == null || value.length() == 0)
+        if (TextUtils.isEmpty(value))
             return null;
         try {
             MessageDigest digester = MessageDigest.getInstance("MD5");
@@ -176,35 +162,35 @@ public class Settings {
             return value;
         }
     }
-    
+
     public static void setPin(Context context, String pin) {
-        Settings.getInstance(context).setString(KEY_PIN, digest(pin));
+        Settings.setString(context, KEY_PIN, digest(pin));
     }
-    
+
     public static boolean checkPin(Context context, String pin) {
         pin = digest(pin);
-        String hashed = Settings.getInstance(context).getString(KEY_PIN);
-        if (pin == null)
-            return hashed == null || hashed.length() == 0;
+        String hashed = Settings.getString(context, KEY_PIN);
+        if (TextUtils.isEmpty(pin))
+            return TextUtils.isEmpty(hashed);
         return pin.equals(hashed);
     }
 
     private static final String KEY_REQUIRE_PREMISSION = "require_permission";
     public static boolean getRequirePermission(Context context) {
-        return getInstance(context).getBoolean(KEY_REQUIRE_PREMISSION, false);
+        return getBoolean(context, KEY_REQUIRE_PREMISSION, false);
     }
-    
+
     public static void setRequirePermission(Context context, boolean require) {
-        getInstance(context).setBoolean(KEY_REQUIRE_PREMISSION, require);
+        setBoolean(context, KEY_REQUIRE_PREMISSION, require);
     }
-    
+
     private static final String KEY_AUTOMATIC_RESPONSE = "automatic_response";
     public static final int AUTOMATIC_RESPONSE_PROMPT = 0;
     public static final int AUTOMATIC_RESPONSE_ALLOW = 1;
     public static final int AUTOMATIC_RESPONSE_DENY = 2;
     public static final int AUTOMATIC_RESPONSE_DEFAULT = AUTOMATIC_RESPONSE_PROMPT;
     public static int getAutomaticResponse(Context context) {
-        switch (getInstance(context).getInt(KEY_AUTOMATIC_RESPONSE, AUTOMATIC_RESPONSE_DEFAULT)) {
+        switch (getInt(context, KEY_AUTOMATIC_RESPONSE, AUTOMATIC_RESPONSE_DEFAULT)) {
         case AUTOMATIC_RESPONSE_ALLOW:
             return AUTOMATIC_RESPONSE_ALLOW;
         case AUTOMATIC_RESPONSE_PROMPT:
@@ -217,25 +203,26 @@ public class Settings {
     }
 
     public static void setAutomaticResponse(Context context, int response) {
-        getInstance(context).setInt(KEY_AUTOMATIC_RESPONSE, response);
+        setInt(context, KEY_AUTOMATIC_RESPONSE, response);
     }
-    
-    
+
+
     static public String readFile(String filename) throws IOException {
         return readFile(new File(filename));
     }
-    
+
     static public String readFile(File file) throws IOException {
         byte[] buffer = new byte[(int) file.length()];
         DataInputStream input = new DataInputStream(new FileInputStream(file));
         input.readFully(buffer);
+        input.close();
         return new String(buffer);
     }
-    
+
     public static void writeFile(File file, String string) throws IOException {
         writeFile(file.getAbsolutePath(), string);
     }
-    
+
     public static void writeFile(String file, String string) throws IOException {
         File f = new File(file);
         f.getParentFile().mkdirs();
@@ -243,7 +230,7 @@ public class Settings {
         dout.write(string.getBytes());
         dout.close();
     }
-    
+
     public static byte[] readToEndAsArray(InputStream input) throws IOException {
         DataInputStream dis = new DataInputStream(input);
         byte[] stuff = new byte[1024];
@@ -265,7 +252,7 @@ public class Settings {
     public static final int MULTIUSER_MODE_OWNER_MANAGED = 1;
     public static final int MULTIUSER_MODE_USER = 2;
     public static final int MULTIUSER_MODE_NONE = 3;
-    
+
     private static final String MULTIUSER_VALUE_OWNER_ONLY  = "owner";
     private static final String MULTIUSER_VALUE_OWNER_MANAGED = "managed";
     private static final String MULTIUSER_VALUE_USER = "user";
@@ -276,7 +263,7 @@ public class Settings {
 
         if (!Helper.supportsMultipleUsers(context))
             return MULTIUSER_MODE_NONE;
-        
+
         try {
             String mode;
             if (Helper.isAdminUser(context)) {
@@ -287,7 +274,7 @@ public class Settings {
                 Process p = Runtime.getRuntime().exec("su -u");
                 mode = readToEnd(p.getInputStream()).trim();
             }
-            
+
             if (MULTIUSER_VALUE_OWNER_MANAGED.equals(mode))
                 return MULTIUSER_MODE_OWNER_MANAGED;
             if (MULTIUSER_VALUE_USER.equals(mode))
@@ -299,7 +286,7 @@ public class Settings {
         }
         return MULTIUSER_MODE_OWNER_ONLY;
     }
-    
+
     public static void setMultiuserMode(Context context, int mode) {
         if (!Helper.isAdminUser(context))
             return;
@@ -323,4 +310,81 @@ public class Settings {
         catch (Exception ex) {
         }
     }
+
+
+    public static final int SUPERUSER_ACCESS_DISABLED = 0;
+    public static final int SUPERUSER_ACCESS_APPS_ONLY = 1;
+    public static final int SUPERUSER_ACCESS_ADB_ONLY = 2;
+    public static final int SUPERUSER_ACCESS_APPS_AND_ADB = 3;
+    public static int getSuperuserAccess() {
+        try {
+            Class<?> c = Class.forName("android.os.SystemProperties");
+            Method m = c.getMethod("get", String.class);
+            String value = (String)m.invoke(null, "persist.sys.root_access");
+            int val = Integer.valueOf(value);
+            switch (val) {
+            case SUPERUSER_ACCESS_DISABLED:
+            case SUPERUSER_ACCESS_APPS_ONLY:
+            case SUPERUSER_ACCESS_ADB_ONLY:
+            case SUPERUSER_ACCESS_APPS_AND_ADB:
+                return val;
+            default:
+                return SUPERUSER_ACCESS_DISABLED;
+            }
+        }
+        catch (Exception e) {
+            return SUPERUSER_ACCESS_DISABLED;
+        }
+    }
+
+    public static void setSuperuserAccess(int mode) {
+        try {
+            if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
+                Class<?> c = Class.forName("android.os.SystemProperties");
+                Method m = c.getMethod("set", String.class, String.class);
+                m.invoke(null, "persist.sys.root_access", String.valueOf(mode));
+                if (mode == getSuperuserAccess()) return;
+            }
+            String command = "setprop persist.sys.root_access " + mode;
+            Process p = Runtime.getRuntime().exec("su");
+            p.getOutputStream().write(command.getBytes());
+            p.getOutputStream().close();
+            int ret = p.waitFor();
+            if (ret != 0) Log.w(TAG, "su failed: " + ret);
+        }
+        catch (Exception ex) {
+            Log.w(TAG, "got exception: ", ex);
+        }
+    }
+
+    private static final String CHECK_SU_QUIET = "check_su_quiet";
+    public static final int getCheckSuQuietCounter(Context context) {
+        return getInt(context, CHECK_SU_QUIET, 0);
+    }
+
+    public static final void setCheckSuQuietCounter(Context context, int counter) {
+        setInt(context, CHECK_SU_QUIET, counter);
+    }
+
+    private static final String KEY_THEME = "theme";
+    public static final int THEME_LIGHT = 0;
+    public static final int THEME_DARK = 1;
+    public static void applyDarkThemeSetting(Activity activity, int dark) {
+        if (!"com.koushikdutta.superuser".equals(activity.getPackageName()))
+            return;
+        try {
+            if (getTheme(activity) == THEME_DARK)
+                activity.setTheme(dark);
+        }
+        catch (Exception e) {
+        }
+    }
+
+    public static final int getTheme(Context context) {
+        return getInt(context, KEY_THEME, THEME_LIGHT);
+    }
+
+    public static final void setTheme(Context context, int theme) {
+        setInt(context, KEY_THEME, theme);
+    }
 }