[core] Async cache (#221)
* [core] Async cache * Wait for handler * Resolve reviews * Refine imports
This commit is contained in:
parent
cf634decc1
commit
d5ee8d3842
|
|
@ -24,8 +24,11 @@ import android.content.pm.PackageInfo;
|
|||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteStatement;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
|
@ -95,6 +98,14 @@ public class ConfigManager {
|
|||
private static final File modulesLogPath = new File(logPath, "modules.log");
|
||||
private static final File verboseLogPath = new File(logPath, "all.log");
|
||||
|
||||
private final Handler cacheHandler;
|
||||
|
||||
long lastModuleCacheTime = 0;
|
||||
long requestModuleCacheTime = 0;
|
||||
|
||||
long lastScopeCacheTime = 0;
|
||||
long requestScopeCacheTime = 0;
|
||||
|
||||
static class ProcessScope {
|
||||
String processName;
|
||||
int uid;
|
||||
|
|
@ -137,9 +148,17 @@ public class ConfigManager {
|
|||
|
||||
private final ConcurrentHashMap<Integer, String> cachedModule = new ConcurrentHashMap<>();
|
||||
|
||||
private void updateCaches() {
|
||||
cacheScopes();
|
||||
cacheModules();
|
||||
private void updateCaches(boolean sync) {
|
||||
synchronized (this) {
|
||||
requestScopeCacheTime = requestModuleCacheTime = SystemClock.elapsedRealtime();
|
||||
}
|
||||
if (sync) {
|
||||
cacheModules();
|
||||
cacheScopes();
|
||||
} else {
|
||||
cacheHandler.post(this::cacheModules);
|
||||
cacheHandler.post(this::cacheScopes);
|
||||
}
|
||||
}
|
||||
|
||||
// for system server, cache is not yet ready, we need to query database for it
|
||||
|
|
@ -231,8 +250,8 @@ public class ConfigManager {
|
|||
if (PackageService.getPackageManager() != null) {
|
||||
Log.d(TAG, "pm is ready, updating cache");
|
||||
instance.packageStarted = true;
|
||||
instance.cacheScopes();
|
||||
instance.cacheModules();
|
||||
// must ensure cache is valid for later usage
|
||||
instance.updateCaches(true);
|
||||
instance.updateManager();
|
||||
}
|
||||
}
|
||||
|
|
@ -240,11 +259,15 @@ public class ConfigManager {
|
|||
}
|
||||
|
||||
private ConfigManager() {
|
||||
HandlerThread cacheThread = new HandlerThread("cache");
|
||||
cacheThread.start();
|
||||
cacheHandler = new Handler(cacheThread.getLooper());
|
||||
|
||||
createTables();
|
||||
updateConfig();
|
||||
isPermissive = readInt(selinuxPath, 1) == 0;
|
||||
cacheScopes();
|
||||
cacheModules();
|
||||
// must ensure cache is valid for later usage
|
||||
updateCaches(true);
|
||||
}
|
||||
|
||||
private void createTables() {
|
||||
|
|
@ -264,6 +287,8 @@ public class ConfigManager {
|
|||
private synchronized void cacheModules() {
|
||||
// skip caching when pm is not yet available
|
||||
if (!packageStarted) return;
|
||||
if (lastModuleCacheTime >= requestModuleCacheTime) return;
|
||||
else lastModuleCacheTime = SystemClock.elapsedRealtime();
|
||||
cachedModule.clear();
|
||||
try (Cursor cursor = db.query("modules", new String[]{"module_pkg_name"},
|
||||
"enabled = 1", null, null, null, null)) {
|
||||
|
|
@ -299,6 +324,8 @@ public class ConfigManager {
|
|||
private synchronized void cacheScopes() {
|
||||
// skip caching when pm is not yet available
|
||||
if (!packageStarted) return;
|
||||
if (lastScopeCacheTime >= requestScopeCacheTime) return;
|
||||
else lastScopeCacheTime = SystemClock.elapsedRealtime();
|
||||
cachedScope.clear();
|
||||
try (Cursor cursor = db.query("scope INNER JOIN modules ON scope.mid = modules.mid", new String[]{"app_pkg_name", "user_id", "apk_path"},
|
||||
"enabled = 1", null, null, null, null)) {
|
||||
|
|
@ -387,7 +414,8 @@ public class ConfigManager {
|
|||
if (count < 0) {
|
||||
count = db.updateWithOnConflict("modules", values, "module_pkg_name=?", new String[]{packageName}, SQLiteDatabase.CONFLICT_IGNORE);
|
||||
}
|
||||
updateCaches();
|
||||
// Called by oneway binder
|
||||
updateCaches(true);
|
||||
return count >= 0;
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +456,8 @@ public class ConfigManager {
|
|||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
updateCaches();
|
||||
// Called by manager, should be async
|
||||
updateCaches(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -449,7 +478,8 @@ public class ConfigManager {
|
|||
|
||||
public boolean removeModule(String packageName) {
|
||||
boolean res = removeModuleWithoutCache(packageName);
|
||||
updateCaches();
|
||||
// called by oneway binder
|
||||
updateCaches(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -479,7 +509,8 @@ public class ConfigManager {
|
|||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
updateCaches();
|
||||
// called by manager, should be async
|
||||
updateCaches(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -496,13 +527,15 @@ public class ConfigManager {
|
|||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
updateCaches();
|
||||
// Called by manager, should be async
|
||||
updateCaches(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean removeApp(Application app) {
|
||||
boolean res = removeAppWithoutCache(app);
|
||||
updateCaches();
|
||||
// Called by oneway binder
|
||||
updateCaches(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue