use of android.os.StrictMode.ThreadPolicy in project XPrivacy by M66B.
the class PrivacyService method getSetting.
@Override
public PSetting getSetting(PSetting setting) throws RemoteException {
long start = System.currentTimeMillis();
// Translate isolated uid
setting.uid = getIsolatedUid(setting.uid);
int userId = Util.getUserId(setting.uid);
// Special case
if (Meta.cTypeAccountHash.equals(setting.type))
try {
setting.type = Meta.cTypeAccount;
setting.name = Util.sha1(setting.name);
} catch (Throwable ex) {
Util.bug(null, ex);
}
// Default result
PSetting result = new PSetting(setting.uid, setting.type, setting.name, setting.value);
// Disable strict mode
ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
ThreadPolicy newPolicy = new ThreadPolicy.Builder(oldPolicy).permitDiskReads().permitDiskWrites().build();
StrictMode.setThreadPolicy(newPolicy);
try {
// No permissions enforced
// Check cache
CSetting key = new CSetting(setting.uid, setting.type, setting.name);
synchronized (mSettingCache) {
if (mSettingCache.containsKey(key)) {
result.value = mSettingCache.get(key).getValue();
if (result.value == null)
// default value
result.value = setting.value;
return result;
}
}
// No persmissions required
SQLiteDatabase db = getDb();
if (db == null)
return result;
// Fallback
if (!PrivacyManager.cSettingMigrated.equals(setting.name) && !getSettingBool(userId, PrivacyManager.cSettingMigrated, false)) {
if (setting.uid == 0)
result.value = PrivacyProvider.getSettingFallback(setting.name, null, false);
if (result.value == null) {
result.value = PrivacyProvider.getSettingFallback(String.format("%s.%d", setting.name, setting.uid), setting.value, false);
return result;
}
}
// Precompile statement when needed
if (stmtGetSetting == null) {
String sql = "SELECT value FROM " + cTableSetting + " WHERE uid=? AND type=? AND name=?";
stmtGetSetting = db.compileStatement(sql);
}
// Execute statement
boolean found = false;
mLock.readLock().lock();
try {
db.beginTransaction();
try {
try {
synchronized (stmtGetSetting) {
stmtGetSetting.clearBindings();
stmtGetSetting.bindLong(1, setting.uid);
stmtGetSetting.bindString(2, setting.type);
stmtGetSetting.bindString(3, setting.name);
result.value = stmtGetSetting.simpleQueryForString();
found = true;
}
} catch (SQLiteDoneException ignored) {
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
} finally {
mLock.readLock().unlock();
}
// Add to cache
key.setValue(found ? result.value : null);
synchronized (mSettingCache) {
if (mSettingCache.containsKey(key))
mSettingCache.remove(key);
mSettingCache.put(key, key);
}
// Default value
if (result.value == null)
result.value = setting.value;
} catch (SQLiteException ex) {
notifyException(ex);
} catch (Throwable ex) {
Util.bug(null, ex);
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
long ms = System.currentTimeMillis() - start;
Util.log(null, ms < PrivacyManager.cWarnServiceDelayMs ? Log.INFO : Log.WARN, String.format("Get service %s %d ms", setting, ms));
return result;
}
use of android.os.StrictMode.ThreadPolicy in project XPrivacy by M66B.
the class PrivacyService method getRestriction.
@Override
public PRestriction getRestriction(final PRestriction restriction, boolean usage, String secret) throws RemoteException {
long start = System.currentTimeMillis();
// Translate isolated uid
restriction.uid = getIsolatedUid(restriction.uid);
boolean ccached = false;
boolean mcached = false;
int userId = Util.getUserId(restriction.uid);
final PRestriction mresult = new PRestriction(restriction);
// Disable strict mode
ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
ThreadPolicy newPolicy = new ThreadPolicy.Builder(oldPolicy).permitDiskReads().permitDiskWrites().build();
StrictMode.setThreadPolicy(newPolicy);
try {
// Sanity checks
if (restriction.restrictionName == null) {
Util.log(null, Log.ERROR, "Get invalid restriction " + restriction);
return mresult;
}
if (usage && restriction.methodName == null) {
Util.log(null, Log.ERROR, "Get invalid restriction " + restriction);
return mresult;
}
// Get meta data
Hook hook = null;
if (restriction.methodName != null) {
hook = PrivacyManager.getHook(restriction.restrictionName, restriction.methodName);
if (hook == null)
// Can happen after updating
Util.log(null, Log.WARN, "Hook not found in service: " + restriction);
else if (hook.getFrom() != null) {
String version = getSetting(new PSetting(userId, "", PrivacyManager.cSettingVersion, null)).value;
if (version != null && new Version(version).compareTo(hook.getFrom()) < 0)
if (hook.getReplacedRestriction() == null) {
Util.log(null, Log.WARN, "Disabled version=" + version + " from=" + hook.getFrom() + " hook=" + hook);
return mresult;
} else {
restriction.restrictionName = hook.getReplacedRestriction();
restriction.methodName = hook.getReplacedMethod();
Util.log(null, Log.WARN, "Checking " + restriction + " instead of " + hook);
}
}
}
// Process IP address
if (restriction.extra != null && Meta.cTypeIPAddress.equals(hook.whitelist())) {
int colon = restriction.extra.lastIndexOf(':');
String address = (colon >= 0 ? restriction.extra.substring(0, colon) : restriction.extra);
String port = (colon >= 0 ? restriction.extra.substring(colon) : "");
int slash = address.indexOf('/');
if (// IP address
slash == 0)
restriction.extra = address.substring(slash + 1) + port;
else if (// Domain name
slash > 0)
restriction.extra = address.substring(0, slash) + port;
}
// Check for system component
if (!PrivacyManager.isApplication(restriction.uid))
if (!getSettingBool(userId, PrivacyManager.cSettingSystem, false))
return mresult;
// Check if restrictions enabled
if (usage && !getSettingBool(restriction.uid, PrivacyManager.cSettingRestricted, true))
return mresult;
// Check if can be restricted
if (!PrivacyManager.canRestrict(restriction.uid, getXUid(), restriction.restrictionName, restriction.methodName, false))
mresult.asked = true;
else {
// Check cache for method
CRestriction key = new CRestriction(restriction, restriction.extra);
synchronized (mRestrictionCache) {
if (mRestrictionCache.containsKey(key)) {
mcached = true;
CRestriction cache = mRestrictionCache.get(key);
mresult.restricted = cache.restricted;
mresult.asked = cache.asked;
}
}
if (!mcached) {
boolean methodFound = false;
PRestriction cresult = new PRestriction(restriction.uid, restriction.restrictionName, null);
// Check cache for category
CRestriction ckey = new CRestriction(cresult, null);
synchronized (mRestrictionCache) {
if (mRestrictionCache.containsKey(ckey)) {
ccached = true;
CRestriction crestriction = mRestrictionCache.get(ckey);
cresult.restricted = crestriction.restricted;
cresult.asked = crestriction.asked;
mresult.restricted = cresult.restricted;
mresult.asked = cresult.asked;
}
}
// Get database reference
SQLiteDatabase db = getDb();
if (db == null)
return mresult;
// Precompile statement when needed
if (stmtGetRestriction == null) {
String sql = "SELECT restricted FROM " + cTableRestriction + " WHERE uid=? AND restriction=? AND method=?";
stmtGetRestriction = db.compileStatement(sql);
}
// Execute statement
mLock.readLock().lock();
try {
db.beginTransaction();
try {
if (!ccached)
try {
synchronized (stmtGetRestriction) {
stmtGetRestriction.clearBindings();
stmtGetRestriction.bindLong(1, restriction.uid);
stmtGetRestriction.bindString(2, restriction.restrictionName);
stmtGetRestriction.bindString(3, "");
long state = stmtGetRestriction.simpleQueryForLong();
cresult.restricted = ((state & 1) != 0);
cresult.asked = ((state & 2) != 0);
mresult.restricted = cresult.restricted;
mresult.asked = cresult.asked;
}
} catch (SQLiteDoneException ignored) {
}
if (restriction.methodName != null)
try {
synchronized (stmtGetRestriction) {
stmtGetRestriction.clearBindings();
stmtGetRestriction.bindLong(1, restriction.uid);
stmtGetRestriction.bindString(2, restriction.restrictionName);
stmtGetRestriction.bindString(3, restriction.methodName);
long state = stmtGetRestriction.simpleQueryForLong();
// Method can be excepted
if (mresult.restricted)
mresult.restricted = ((state & 1) == 0);
// Category asked=true takes precedence
if (!mresult.asked)
mresult.asked = ((state & 2) != 0);
methodFound = true;
}
} catch (SQLiteDoneException ignored) {
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
} finally {
mLock.readLock().unlock();
}
// Default dangerous
if (!methodFound && hook != null && hook.isDangerous())
if (!getSettingBool(userId, PrivacyManager.cSettingDangerous, false)) {
if (mresult.restricted)
mresult.restricted = false;
if (!mresult.asked)
mresult.asked = (hook.whitelist() == null);
}
// Check whitelist
if (usage && hook != null && hook.whitelist() != null && restriction.extra != null) {
String value = getSetting(new PSetting(restriction.uid, hook.whitelist(), restriction.extra, null)).value;
if (value == null) {
for (String xextra : getXExtra(restriction, hook)) {
value = getSetting(new PSetting(restriction.uid, hook.whitelist(), xextra, null)).value;
if (value != null)
break;
}
}
if (value != null) {
// true means allow, false means block
mresult.restricted = !Boolean.parseBoolean(value);
mresult.asked = true;
}
}
// Fallback
if (!mresult.restricted && usage && PrivacyManager.isApplication(restriction.uid) && !getSettingBool(userId, PrivacyManager.cSettingMigrated, false)) {
if (hook != null && !hook.isDangerous()) {
mresult.restricted = PrivacyProvider.getRestrictedFallback(null, restriction.uid, restriction.restrictionName, restriction.methodName);
Util.log(null, Log.WARN, "Fallback " + mresult);
}
}
// Update cache
CRestriction cukey = new CRestriction(cresult, null);
synchronized (mRestrictionCache) {
if (mRestrictionCache.containsKey(cukey))
mRestrictionCache.remove(cukey);
mRestrictionCache.put(cukey, cukey);
}
CRestriction ukey = new CRestriction(mresult, restriction.extra);
synchronized (mRestrictionCache) {
if (mRestrictionCache.containsKey(ukey))
mRestrictionCache.remove(ukey);
mRestrictionCache.put(ukey, ukey);
}
}
// Ask to restrict
OnDemandResult oResult = new OnDemandResult();
if (!mresult.asked && usage) {
oResult = onDemandDialog(hook, restriction, mresult);
// Update cache
if (oResult.ondemand && !oResult.once) {
CRestriction okey = new CRestriction(mresult, oResult.whitelist ? restriction.extra : null);
synchronized (mRestrictionCache) {
if (mRestrictionCache.containsKey(okey))
mRestrictionCache.remove(okey);
mRestrictionCache.put(okey, okey);
}
}
}
// Notify user
if (!oResult.ondemand && mresult.restricted && usage && hook != null && hook.shouldNotify()) {
notifyRestricted(restriction);
mresult.time = new Date().getTime();
}
}
// Store usage data
if (usage && hook != null)
storeUsageData(restriction, secret, mresult);
} catch (SQLiteException ex) {
notifyException(ex);
} catch (Throwable ex) {
Util.bug(null, ex);
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
long ms = System.currentTimeMillis() - start;
Util.log(null, ms < PrivacyManager.cWarnServiceDelayMs ? Log.INFO : Log.WARN, String.format("Get service %s%s %d ms", restriction, (ccached ? " (ccached)" : "") + (mcached ? " (mcached)" : ""), ms));
if (mresult.debug)
Util.logStack(null, Log.WARN);
if (usage) {
mCount.incrementAndGet();
if (mresult.restricted)
mRestricted.incrementAndGet();
}
return mresult;
}
Aggregations