OSDN Git Service

Move the logs and settings into a separate database, to prevent database locks by...
authorKoushik Dutta <koushd@gmail.com>
Tue, 5 Mar 2013 21:46:25 +0000 (13:46 -0800)
committerKoushik Dutta <koushd@gmail.com>
Tue, 5 Mar 2013 21:46:25 +0000 (13:46 -0800)
The policy database, for the most part, should just be read only.

Change-Id: I90de7496bbe68eb37f0ecf8c8bdf3ed08a3bc8c1

Superuser/src/com/koushikdutta/superuser/LogFragmentInternal.java
Superuser/src/com/koushikdutta/superuser/SuReceiver.java
Superuser/src/com/koushikdutta/superuser/db/SuDatabaseHelper.java
Superuser/src/com/koushikdutta/superuser/db/SuperuserDatabaseHelper.java [new file with mode: 0644]
Superuser/src/com/koushikdutta/superuser/db/UidCommand.java
Superuser/src/com/koushikdutta/superuser/util/Settings.java

index 340cc47..12afd13 100644 (file)
@@ -32,6 +32,7 @@ import android.widget.TextView;
 
 import com.koushikdutta.superuser.db.LogEntry;
 import com.koushikdutta.superuser.db.SuDatabaseHelper;
+import com.koushikdutta.superuser.db.SuperuserDatabaseHelper;
 import com.koushikdutta.superuser.db.UidPolicy;
 import com.koushikdutta.superuser.util.Settings;
 import com.koushikdutta.widgets.BetterListFragmentInternal;
@@ -72,7 +73,7 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
                 if (up != null)
                     SuDatabaseHelper.delete(getActivity(), up);
                 else
-                    SuDatabaseHelper.deleteLogs(getActivity());
+                    SuperuserDatabaseHelper.deleteLogs(getActivity());
                 onDelete();
                 return true;
             }
@@ -126,11 +127,11 @@ public class LogFragmentInternal extends BetterListFragmentInternal {
 
             getListView().setSelector(android.R.color.transparent);
 
-            logs = SuDatabaseHelper.getLogs(getActivity(), up, -1);
+            logs = SuperuserDatabaseHelper.getLogs(getActivity(), up, -1);
         }
         else {
             view.findViewById(R.id.title_container).setVisibility(View.GONE);
-            logs = SuDatabaseHelper.getLogs(getActivity());
+            logs = SuperuserDatabaseHelper.getLogs(getActivity());
         }
         
         setEmpty(R.string.no_logs);
index 81a1e7d..f4ab638 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.koushikdutta.superuser;
 
-import java.util.Random;
-
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -27,7 +25,7 @@ import android.support.v4.app.NotificationCompat;
 import android.widget.Toast;
 
 import com.koushikdutta.superuser.db.LogEntry;
-import com.koushikdutta.superuser.db.SuDatabaseHelper;
+import com.koushikdutta.superuser.db.SuperuserDatabaseHelper;
 import com.koushikdutta.superuser.db.UidPolicy;
 import com.koushikdutta.superuser.util.Settings;
 
@@ -60,13 +58,13 @@ public class SuReceiver extends BroadcastReceiver {
         le.desiredName = desiredName;
         le.username = fromName;
         le.date = (int)(System.currentTimeMillis() / 1000);
-        SuDatabaseHelper.getPackageInfoForUid(context, le);
+        le.getPackageInfo(context);
         // wait a bit before logging... lots of concurrent su requests at the same time
         // cause a db lock
         new Handler().postDelayed(new Runnable() {
             public void run() {
                 try {
-                    SuDatabaseHelper.addLog(context, le);
+                    SuperuserDatabaseHelper.addLog(context, le);
                 }
                 catch (Exception e) {
                 }
index 10caf06..f3bcee6 100644 (file)
@@ -29,9 +29,11 @@ import android.database.sqlite.SQLiteOpenHelper;
 import com.koushikdutta.superuser.util.Settings;
 
 public class SuDatabaseHelper extends SQLiteOpenHelper {
-    private static final int CURRENT_VERSION = 3;
+    private static final int CURRENT_VERSION = 4;
+    Context mContext;
     public SuDatabaseHelper(Context context) {
         super(context, "su.sqlite", null, CURRENT_VERSION);
+        mContext = context;
     }
 
     @Override
@@ -43,35 +45,55 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         if (oldVersion == 0) {
             db.execSQL("create table if not exists uid_policy (logging integer, desired_name text, username text, policy text, until integer, command text, uid integer, desired_uid integer, package_name text, name text, primary key(uid, command, desired_uid))");
-            db.execSQL("create table if not exists log (id integer primary key autoincrement, desired_name text, username text, uid integer, desired_uid integer, command text, date integer, action text, package_name text, name text)");
-            db.execSQL("create index if not exists log_uid_index on log(uid)");
-            db.execSQL("create index if not exists log_desired_uid_index on log(desired_uid)");
-            db.execSQL("create index if not exists log_command_index on log(command)");
-            db.execSQL("create index if not exists log_date_index on log(date)");
-            oldVersion = 1;
+            oldVersion = 4;
         }
-        
+
         if (oldVersion == 1 || oldVersion == 2) {
             db.execSQL("create table if not exists settings (key TEXT PRIMARY KEY, value TEXT)");
             oldVersion = 3;
         }
-    }
-    
-    public static void getPackageInfoForUid(Context context, UidCommand cpi) {
-        try {
-            PackageManager pm = context.getPackageManager();
-            PackageInfo pi = context.getPackageManager().getPackageInfo(pm.getPackagesForUid(cpi.uid)[0], 0);
-            cpi.name = pi.applicationInfo.loadLabel(pm).toString();
-            cpi.packageName = pi.packageName;
-        }
-        catch (Exception ex) {
+        
+        if (oldVersion == 3) {
+            // grab all old logs and migrate
+            SQLiteDatabase superuser = new SuperuserDatabaseHelper(mContext).getWritableDatabase();
+            
+            ArrayList<LogEntry> logs = SuperuserDatabaseHelper.getLogs(mContext, db);
+            superuser.beginTransaction();
+            try {
+                for (LogEntry log: logs) {
+                    SuperuserDatabaseHelper.addLog(superuser, log);
+                }
+                
+                Cursor c = db.query("settings", null, null,null, null, null, null);
+                while (c.moveToNext()) {
+                    String key = c.getString(c.getColumnIndex("key"));
+                    String value = c.getString(c.getColumnIndex("value"));
+                    ContentValues cv = new ContentValues();
+                    cv.put("key", key);
+                    cv.put("value", value);
+
+                    superuser.replace("settings", null, cv);
+                }
+            }
+            catch (Exception e) {
+                e.printStackTrace();
+            }
+            finally {
+                superuser.setTransactionSuccessful();
+                superuser.endTransaction();
+                superuser.close();
+            }
+            
+            db.execSQL("drop table if exists log");
+            db.execSQL("drop table if exists settings");
+            oldVersion = 4;
         }
     }
 
     public static void setPolicy(Context context, UidPolicy policy) {
         SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
         
-        getPackageInfoForUid(context, policy);
+        policy.getPackageInfo(context);
 
         ContentValues values = new ContentValues();
         values.put("logging", policy.logging);
@@ -87,25 +109,15 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         db.replace("uid_policy", null, values);
         db.close();
     }
-    
-    private static void getUidCommand(Cursor c, UidCommand u) {
-        u.uid = c.getInt(c.getColumnIndex("uid"));
-        u.command = c.getString(c.getColumnIndex("command"));
-        u.name = c.getString(c.getColumnIndex("name"));
-        u.packageName = c.getString(c.getColumnIndex("package_name"));
-        u.desiredUid = c.getInt(c.getColumnIndex("desired_uid"));
-        u.desiredName = c.getString(c.getColumnIndex("desired_name"));
-        u.username = c.getString(c.getColumnIndex("username"));
-    }
-    
-    private static UidPolicy getPolicy(Context context, Cursor c) {
+
+    static UidPolicy getPolicy(Context context, Cursor c) {
         UidPolicy u = new UidPolicy();
-        getUidCommand(c, u);
+        u.getUidCommand(c);
         u.policy = c.getString(c.getColumnIndex("policy"));
         u.until = c.getInt(c.getColumnIndex("until"));
         u.logging = c.getInt(c.getColumnIndex("logging")) != 0;
         
-        ArrayList<LogEntry> logs = getLogs(context, u, 1);
+        ArrayList<LogEntry> logs = SuperuserDatabaseHelper.getLogs(context, u, 1);
         if (logs.size() > 0)
             u.last = logs.get(0).date;
         return u;
@@ -133,56 +145,6 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         }
         return ret;
     }
-    
-    public static ArrayList<LogEntry> getLogs(Context context, UidPolicy policy, int limit) {
-        ArrayList<LogEntry> ret = new ArrayList<LogEntry>();
-        SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
-        Cursor c;
-        if (policy.command != null)
-            c = db.query("log", null, "uid = ? and desired_uid = ? and command = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid), policy.command }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
-        else
-            c = db.query("log", null, "uid = ? and desired_uid = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid) }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
-        try {
-            while (c.moveToNext()) {
-                LogEntry l = new LogEntry();
-                ret.add(l);
-                getUidCommand(c, l);
-                l.id = c.getLong(c.getColumnIndex("id"));
-                l.date = c.getInt(c.getColumnIndex("date"));
-                l.action = c.getString(c.getColumnIndex("action"));
-            }
-        }
-        catch (Exception ex) {
-        }
-        finally {
-            c.close();
-            db.close();
-        }
-        return ret;
-    }
-    
-    public static ArrayList<LogEntry> getLogs(Context context) {
-        ArrayList<LogEntry> ret = new ArrayList<LogEntry>();
-        SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
-        Cursor c = db.query("log", null, null, null, null, null, "date DESC");
-        try {
-            while (c.moveToNext()) {
-                LogEntry l = new LogEntry();
-                ret.add(l);
-                getUidCommand(c, l);
-                l.id = c.getLong(c.getColumnIndex("id"));
-                l.date = c.getInt(c.getColumnIndex("date"));
-                l.action = c.getString(c.getColumnIndex("action"));
-            }
-        }
-        catch (Exception ex) {
-        }
-        finally {
-            c.close();
-            db.close();
-        }
-        return ret;
-    }
 
     public static void delete(Context context, UidPolicy policy) {
         SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
@@ -211,44 +173,5 @@ public class SuDatabaseHelper extends SQLiteOpenHelper {
         }
         return null;
     }
-
-    public static void deleteLogs(Context context) {
-        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
-        db.delete("log", null, null);
-        db.close();
-    }
-    
-    public static void addLog(Context context, LogEntry log) {
-        if (!Settings.getLogging(context))
-            return;
-        
-        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
-        Cursor c = db.query("uid_policy", null, "uid = ? and command = ? and desired_uid = ?", new String[] { String.valueOf(log.uid), log.command, String.valueOf(log.desiredUid) }, null, null, null, null);
-        try {
-            if (c.moveToNext()) {
-                UidPolicy u = getPolicy(context, c);
-                if (!u.logging) {
-                    db.close();
-                    return;
-                }
-            }
-        }
-        finally {
-            c.close();
-        }
-
-        ContentValues values = new ContentValues();
-        values.put("uid", log.uid);
-        values.put("command", log.command);
-        values.put("action", log.action);
-        values.put("date", log.date);
-        values.put("name", log.name);
-        values.put("desired_uid", log.desiredUid);
-        values.put("package_name", log.packageName);
-        values.put("desired_name", log.desiredName);
-        values.put("username", log.username);
-        db.insert("log", null, values);
-        db.close();
-    }
     private static final String LOGTAG = "SuReceiver";
 }
diff --git a/Superuser/src/com/koushikdutta/superuser/db/SuperuserDatabaseHelper.java b/Superuser/src/com/koushikdutta/superuser/db/SuperuserDatabaseHelper.java
new file mode 100644 (file)
index 0000000..f072e35
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2013 Koushik Dutta (@koush)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.koushikdutta.superuser.db;
+
+import java.util.ArrayList;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import com.koushikdutta.superuser.util.Settings;
+
+public class SuperuserDatabaseHelper extends SQLiteOpenHelper {
+    private static final int CURRENT_VERSION = 1;
+    public SuperuserDatabaseHelper(Context context) {
+        super(context, "superuser.sqlite", null, CURRENT_VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        onUpgrade(db, 0, CURRENT_VERSION);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        if (oldVersion == 0) {
+            db.execSQL("create table if not exists log (id integer primary key autoincrement, desired_name text, username text, uid integer, desired_uid integer, command text, date integer, action text, package_name text, name text)");
+            db.execSQL("create index if not exists log_uid_index on log(uid)");
+            db.execSQL("create index if not exists log_desired_uid_index on log(desired_uid)");
+            db.execSQL("create index if not exists log_command_index on log(command)");
+            db.execSQL("create index if not exists log_date_index on log(date)");
+            db.execSQL("create table if not exists settings (key TEXT PRIMARY KEY, value TEXT)");
+            oldVersion = 1;
+        }
+    }
+    
+    public static ArrayList<LogEntry> getLogs(Context context, UidPolicy policy, int limit) {
+        ArrayList<LogEntry> ret = new ArrayList<LogEntry>();
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getReadableDatabase();
+        Cursor c;
+        if (policy.command != null)
+            c = db.query("log", null, "uid = ? and desired_uid = ? and command = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid), policy.command }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
+        else
+            c = db.query("log", null, "uid = ? and desired_uid = ?", new String[] { String.valueOf(policy.uid), String.valueOf(policy.desiredUid) }, null, null, "date DESC", limit == -1 ? null : String.valueOf(limit));
+        try {
+            while (c.moveToNext()) {
+                LogEntry l = new LogEntry();
+                ret.add(l);
+                l.getUidCommand(c);
+                l.id = c.getLong(c.getColumnIndex("id"));
+                l.date = c.getInt(c.getColumnIndex("date"));
+                l.action = c.getString(c.getColumnIndex("action"));
+            }
+        }
+        catch (Exception ex) {
+        }
+        finally {
+            c.close();
+            db.close();
+        }
+        return ret;
+    }
+    
+    public static ArrayList<LogEntry> getLogs(Context context) {
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getReadableDatabase();
+        try {
+            return getLogs(context, db);
+        }
+        finally {
+            db.close();
+        }
+    }    
+    public static ArrayList<LogEntry> getLogs(Context context, SQLiteDatabase db) {
+        ArrayList<LogEntry> ret = new ArrayList<LogEntry>();
+        Cursor c = db.query("log", null, null, null, null, null, "date DESC");
+        try {
+            while (c.moveToNext()) {
+                LogEntry l = new LogEntry();
+                ret.add(l);
+                l.getUidCommand(c);
+                l.id = c.getLong(c.getColumnIndex("id"));
+                l.date = c.getInt(c.getColumnIndex("date"));
+                l.action = c.getString(c.getColumnIndex("action"));
+            }
+        }
+        catch (Exception ex) {
+        }
+        finally {
+            c.close();
+        }
+        return ret;
+    }
+
+    public static void deleteLogs(Context context) {
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getWritableDatabase();
+        db.delete("log", null, null);
+        db.close();
+    }
+    
+    static void addLog(SQLiteDatabase db, LogEntry log) {
+        ContentValues values = new ContentValues();
+        values.put("uid", log.uid);
+        values.put("command", log.command);
+        values.put("action", log.action);
+        values.put("date", log.date);
+        values.put("name", log.name);
+        values.put("desired_uid", log.desiredUid);
+        values.put("package_name", log.packageName);
+        values.put("desired_name", log.desiredName);
+        values.put("username", log.username);
+        db.insert("log", null, values);
+    }
+    
+    public static void addLog(Context context, LogEntry log) {
+        if (!Settings.getLogging(context))
+            return;
+        
+        SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
+        Cursor c = db.query("uid_policy", null, "uid = ? and command = ? and desired_uid = ?", new String[] { String.valueOf(log.uid), log.command, String.valueOf(log.desiredUid) }, null, null, null, null);
+        try {
+            if (c.moveToNext()) {
+                UidPolicy u = SuDatabaseHelper.getPolicy(context, c);
+                if (!u.logging) {
+                    db.close();
+                    return;
+                }
+            }
+        }
+        finally {
+            c.close();
+            db.close();
+        }
+
+        try {
+            addLog(db, log);
+        }
+        finally {
+            db.close();
+        }
+    }
+}
index e89c675..88ed65f 100644 (file)
 
 package com.koushikdutta.superuser.db;
 
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+
 
 public class UidCommand {
     public String username;
@@ -35,4 +40,26 @@ public class UidCommand {
             return username;
         return String.valueOf(uid);
     }
+    
+    
+    public void getPackageInfo(Context context) {
+        try {
+            PackageManager pm = context.getPackageManager();
+            PackageInfo pi = context.getPackageManager().getPackageInfo(pm.getPackagesForUid(uid)[0], 0);
+            name = pi.applicationInfo.loadLabel(pm).toString();
+            packageName = pi.packageName;
+        }
+        catch (Exception ex) {
+        }
+    }
+
+    public void getUidCommand(Cursor c) {
+        uid = c.getInt(c.getColumnIndex("uid"));
+        command = c.getString(c.getColumnIndex("command"));
+        name = c.getString(c.getColumnIndex("name"));
+        packageName = c.getString(c.getColumnIndex("package_name"));
+        desiredUid = c.getInt(c.getColumnIndex("desired_uid"));
+        desiredName = c.getString(c.getColumnIndex("desired_name"));
+        username = c.getString(c.getColumnIndex("username"));
+    }
 }
index fb4d14b..b9ecc6c 100755 (executable)
@@ -20,7 +20,7 @@ import android.text.TextUtils;
 import android.util.Base64;
 
 import com.koushikdutta.superuser.Helper;
-import com.koushikdutta.superuser.db.SuDatabaseHelper;
+import com.koushikdutta.superuser.db.SuperuserDatabaseHelper;
 
 public class Settings {
     SQLiteDatabase mDatabase;
@@ -30,7 +30,7 @@ public class Settings {
         ContentValues cv = new ContentValues();
         cv.put("key", name);
         cv.put("value", value);
-        SQLiteDatabase db = new SuDatabaseHelper(context).getWritableDatabase();
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getWritableDatabase();
         try {
             db.replace("settings", null, cv);
         }
@@ -44,7 +44,7 @@ public class Settings {
     }
 
     public static String getString(Context context, String name, String defaultValue) {
-        SQLiteDatabase db = new SuDatabaseHelper(context).getReadableDatabase();
+        SQLiteDatabase db = new SuperuserDatabaseHelper(context).getReadableDatabase();
         Cursor cursor = db.query("settings", new String[] { "value" }, "key='" + name + "'", null, null, null, null);
         try {
             if (cursor.moveToNext())