Skip to content

Commit

Permalink
Improved queries performance
Browse files Browse the repository at this point in the history
  • Loading branch information
jacopotediosi committed Dec 7, 2022
1 parent 809de72 commit 840a607
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 122 deletions.
231 changes: 145 additions & 86 deletions app/src/main/java/com/jacopomii/googledialermod/DBFlagsSingleton.java
@@ -1,12 +1,14 @@
package com.jacopomii.googledialermod;

import static com.jacopomii.googledialermod.Constants.DIALER_PACKAGE_NAME;
import static com.jacopomii.googledialermod.Constants.DIALER_PHENOTYPE_CACHE;
import static com.jacopomii.googledialermod.Constants.PHENOTYPE_DB;
import static com.jacopomii.googledialermod.Utils.byteArrayToHexString;
import static com.jacopomii.googledialermod.Utils.execPhenotypeQuery;
import static com.jacopomii.googledialermod.Utils.killDialerAndDeletePhenotypeCache;

import android.content.Context;

import com.topjohnwu.superuser.Shell;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -74,48 +76,52 @@ private void reloadDBUsers() {
}
}

public void reloadDBBooleanFlags() {
private void reloadDBBooleanFlags() {
mDBBooleanFlags.clear();
String[] tables = {"Flags", "FlagOverrides"};
for (String table : tables) {
JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT DISTINCT name, boolVal FROM %s WHERE packageName = '%s' AND user = '' AND boolVal != 'NULL'",
table,
DIALER_PACKAGE_NAME
)
);
for (int i=0; i < queryResult.length(); i++) {
try {
JSONObject flag = queryResult.getJSONObject(i);
mDBBooleanFlags.put(flag.getString("name"), flag.getInt("boolVal")!=0);
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT DISTINCT name, boolVal " +
"FROM Flags " +
"WHERE packageName = '%s' AND user = '' AND boolVal != 'NULL' AND name NOT IN (SELECT name FROM FlagOverrides) " +
"UNION ALL " +
"SELECT DISTINCT name, boolVal FROM FlagOverrides " +
"WHERE packageName = '%s' AND user = '' AND boolVal != 'NULL'",
DIALER_PACKAGE_NAME,
DIALER_PACKAGE_NAME
)
);
for (int i=0; i < queryResult.length(); i++) {
try {
JSONObject flag = queryResult.getJSONObject(i);
mDBBooleanFlags.put(flag.getString("name"), flag.getInt("boolVal")!=0);
} catch (JSONException e) {
e.printStackTrace();
}
}
}

public void reloadDBStringFlags() {
private void reloadDBStringFlags() {
mDBStringFlags.clear();
String[] tables = {"Flags", "FlagOverrides"};
for (String table : tables) {
JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT DISTINCT name, stringVal FROM %s WHERE packageName = '%s' AND user = '' AND stringVal != 'NULL'",
table,
DIALER_PACKAGE_NAME
)
);
for (int i=0; i < queryResult.length(); i++) {
try {
JSONObject flag = queryResult.getJSONObject(i);
mDBStringFlags.put(flag.getString("name"), flag.getString("stringVal"));
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT DISTINCT name, stringVal " +
"FROM Flags " +
"WHERE packageName = '%s' AND user = '' AND stringVal != 'NULL' AND name NOT IN (SELECT name FROM FlagOverrides) " +
"UNION ALL " +
"SELECT DISTINCT name, stringVal FROM FlagOverrides " +
"WHERE packageName = '%s' AND user = '' AND stringVal != 'NULL'",
DIALER_PACKAGE_NAME,
DIALER_PACKAGE_NAME
)
);
for (int i=0; i < queryResult.length(); i++) {
try {
JSONObject flag = queryResult.getJSONObject(i);
mDBStringFlags.put(flag.getString("name"), flag.getString("stringVal"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Expand All @@ -131,17 +137,22 @@ public void updateDBFlag(String flag, boolean value) {
flag.replace("'", "\\'")
)
);

ArrayList<String> queryValues = new ArrayList<>();
for (String user : mDBUsers)
execPhenotypeQuery(
mContext,
queryValues.add(
String.format(
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, boolVal, committed) VALUES ('%s', 0, '%s', '%s', '%s', 0)",
"('%s', 0, '%s', '%s', '%s', 0)",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'"),
user.replace("'", "\\'"),
(value ? '1' : '0')
)
);
execPhenotypeQuery(
mContext,
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, boolVal, committed) VALUES " + String.join(",", queryValues)
);
}

public void updateDBFlag(String flag, String value) {
Expand All @@ -151,20 +162,26 @@ public void updateDBFlag(String flag, String value) {
mContext,
String.format(
"DELETE FROM FlagOverrides WHERE packageName = '%s' AND name = '%s'",
DIALER_PACKAGE_NAME,flag.replace("'", "\\'")
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'")
)
);

ArrayList<String> queryValues = new ArrayList<>();
for (String user : mDBUsers)
execPhenotypeQuery(
mContext,
queryValues.add(
String.format(
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, stringVal, committed) VALUES ('%s', 0, '%s', '%s', '%s', 0)",
"('%s', 0, '%s', '%s', '%s', 0)",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'"),
user.replace("'", "\\'"),
value.replace("'", "\\'")
)
);
execPhenotypeQuery(
mContext,
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, stringVal, committed) VALUES " + String.join(",", queryValues)
);
}

public void updateDBFlag(String flag, byte[] value) {
Expand All @@ -178,49 +195,58 @@ public void updateDBFlag(String flag, byte[] value) {
flag.replace("'", "\\'")
)
);

ArrayList<String> queryValues = new ArrayList<>();
for (String user : mDBUsers)
execPhenotypeQuery(
mContext,
queryValues.add(
String.format(
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, extensionVal, committed) VALUES ('%s', 0, '%s', '%s', X'%s', 0)",
"('%s', 0, '%s', '%s', '%s', 0)",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'"),
user.replace("'", "\\'"),
byteArrayToHexString(value)
)
);
execPhenotypeQuery(
mContext,
"INSERT OR REPLACE INTO FlagOverrides (packageName, flagType, name, user, extensionVal, committed) VALUES " + String.join(",", queryValues)
);
}

public void deleteFlagOverrides(String... flags) {
for (String flag : flags) {
execPhenotypeQuery(
mContext,
String.format(
"DELETE FROM FlagOverrides WHERE packageName = '%s' AND name = '%s'",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'")
)
);
// Updating internal singleton cached flags
try {
JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT boolVal, stringVal FROM Flags WHERE packageName = '%s' AND user = '' AND name = '%s'",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'")
)
);
if (queryResult.length() > 0) {
JSONObject flagValues = queryResult.getJSONObject(0);
if (!flagValues.isNull("boolVal"))
mDBBooleanFlags.put(flag, flagValues.getBoolean(flag));
else if (!flagValues.isNull("stringVal"))
mDBStringFlags.put(flag, flagValues.getString(flag));
}
} catch (JSONException e) {
e.printStackTrace();
killDialerAndDeletePhenotypeCache();

ArrayList<String> queryValues = new ArrayList<>();
for (String flag : flags)
queryValues.add("'" + flag.replace("'", "\\'") + "'");

execPhenotypeQuery(
mContext,
String.format(
"DELETE FROM FlagOverrides WHERE packageName = '%s' AND name IN (%s)",
DIALER_PACKAGE_NAME,
String.join(",", queryValues)
)
);

JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT name, boolVal, stringVal FROM Flags WHERE packageName = '%s' AND user = '' AND name IN (%s)",
DIALER_PACKAGE_NAME,
String.join(",", queryValues)
)
);
try {
for (int i=0; i<queryResult.length(); i++) {
JSONObject flagValues = queryResult.getJSONObject(i);
if (!flagValues.isNull("boolVal"))
mDBBooleanFlags.put(flagValues.getString("name"), flagValues.getInt("boolVal")==1);
else if (!flagValues.isNull("stringVal"))
mDBStringFlags.put(flagValues.getString("name"), flagValues.getString("stringVal"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}

Expand Down Expand Up @@ -255,18 +281,51 @@ public void deleteAllFlagOverrides() {
}

public boolean areAllFlagsOverridden(String... flags) {
for (String flag : flags) {
JSONArray queryResult = execPhenotypeQuery(
mContext,
ArrayList<String> queryValues = new ArrayList<>();
for (String flag : flags)
queryValues.add("'" + flag.replace("'", "\\'") + "'");

JSONArray queryResult = execPhenotypeQuery(
mContext,
String.format(
"SELECT DISTINCT name FROM Flags WHERE packageName = '%s' AND name IN (%s)",
DIALER_PACKAGE_NAME,
String.join(",", queryValues)
)
);

return queryResult.length() == flags.length;
}

private JSONArray execPhenotypeQuery(Context context, String query) {
JSONArray result = null;
try {
String query_result = String.join("", Shell.cmd(
String.format(
"SELECT name FROM FlagOverrides WHERE packageName = '%s' AND name = '%s'",
DIALER_PACKAGE_NAME,
flag.replace("'", "\\'")
"%s/sqlite3 -batch -json %s \"%s;\"",
context.getApplicationInfo().dataDir,
PHENOTYPE_DB,
query
)
);
if (queryResult.length() < 1)
return false;
).exec().getOut());
if (query_result.equals("")) {
result = new JSONArray("[]");
} else {
result = new JSONArray(query_result);
}
} catch (JSONException e) {
e.printStackTrace();
}
return true;
return result;
}

private void killDialerAndDeletePhenotypeCache() {
Shell.cmd(
String.format(
"am kill all %s; rm -rf %s",
DIALER_PACKAGE_NAME,
DIALER_PHENOTYPE_CACHE
)
).exec();
}
}
39 changes: 3 additions & 36 deletions app/src/main/java/com/jacopomii/googledialermod/Utils.java
Expand Up @@ -3,7 +3,6 @@
import static com.jacopomii.googledialermod.Constants.DIALER_CALLRECORDINGPROMPT;
import static com.jacopomii.googledialermod.Constants.DIALER_DATA_DATA;
import static com.jacopomii.googledialermod.Constants.DIALER_PACKAGE_NAME;
import static com.jacopomii.googledialermod.Constants.DIALER_PHENOTYPE_CACHE;
import static com.jacopomii.googledialermod.Constants.PHENOTYPE_DB;

import android.content.Context;
Expand All @@ -20,7 +19,6 @@
import com.android.volley.toolbox.Volley;
import com.topjohnwu.superuser.Shell;

import org.json.JSONArray;
import org.json.JSONException;

import java.io.IOException;
Expand Down Expand Up @@ -62,35 +60,9 @@ public static String byteArrayToHexString(byte[] byteArray) {
return formatter.toString();
}

public static JSONArray execPhenotypeQuery(Context context, String query) {
JSONArray result = null;
try {
String query_result = String.join("", Shell.cmd(
String.format(
"%s/sqlite3 -batch -json %s \"%s;\"",
context.getApplicationInfo().dataDir,
PHENOTYPE_DB,
query
)
).exec().getOut());
if (query_result.equals("")) {
result = new JSONArray("[]");
} else {
result = new JSONArray(query_result);
}
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}

public static void killDialerAndDeletePhenotypeCache() {
Shell.cmd(
String.format(
"am kill all com.google.android.dialer; rm -rf %s",
DIALER_PHENOTYPE_CACHE
)
).exec();
public static void revertAllMods(Context context) {
DBFlagsSingleton.getInstance(context).deleteAllFlagOverrides();
deleteCallrecordingpromptFolder();
}

public static void deleteCallrecordingpromptFolder() {
Expand All @@ -102,11 +74,6 @@ public static void deleteCallrecordingpromptFolder() {
).exec();
}

public static void revertAllMods(Context context) {
DBFlagsSingleton.getInstance(context).deleteAllFlagOverrides();
deleteCallrecordingpromptFolder();
}

public static void checkIsLatestGithubVersion(Context context) {
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(
Expand Down

0 comments on commit 840a607

Please sign in to comment.