diff --git a/src/biz/bokhorst/xprivacy/ActivityApp.java b/src/biz/bokhorst/xprivacy/ActivityApp.java index 3e25ce742..f88e16891 100644 --- a/src/biz/bokhorst/xprivacy/ActivityApp.java +++ b/src/biz/bokhorst/xprivacy/ActivityApp.java @@ -176,7 +176,7 @@ public RestrictionAdapter(Context context, int resource, XApplicationInfo appInf mAppInfo = appInfo; mRestrictions = restrictions; mExpert = Boolean.parseBoolean(XRestriction.getSetting(null, context, XRestriction.cSettingExpert, - Boolean.FALSE.toString())); + Boolean.FALSE.toString(), false)); } @Override diff --git a/src/biz/bokhorst/xprivacy/ActivityMain.java b/src/biz/bokhorst/xprivacy/ActivityMain.java index d6cf1201c..063da05d7 100644 --- a/src/biz/bokhorst/xprivacy/ActivityMain.java +++ b/src/biz/bokhorst/xprivacy/ActivityMain.java @@ -358,13 +358,13 @@ private void optionSettings() { // Set current values String sExpert = XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingExpert, - Boolean.FALSE.toString()); + Boolean.FALSE.toString(), false); final boolean expert = Boolean.parseBoolean(sExpert); cbSettings.setChecked(expert); - etLat.setText(XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingLatitude, "")); - etLon.setText(XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingLongitude, "")); + etLat.setText(XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingLatitude, "", false)); + etLon.setText(XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingLongitude, "", false)); etMac.setText(XRestriction.getSetting(null, ActivityMain.this, XRestriction.cSettingMac, - XRestriction.getDefacedMac())); + XRestriction.getDefacedMac(), false)); // Wait for OK btnOk.setOnClickListener(new View.OnClickListener() { diff --git a/src/biz/bokhorst/xprivacy/PackageChange.java b/src/biz/bokhorst/xprivacy/PackageChange.java index b2ec8021c..fe7ee24cd 100644 --- a/src/biz/bokhorst/xprivacy/PackageChange.java +++ b/src/biz/bokhorst/xprivacy/PackageChange.java @@ -25,7 +25,7 @@ public void onReceive(Context context, Intent intent) { int uid = intent.getIntExtra(Intent.EXTRA_UID, 0); boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); boolean expert = Boolean.parseBoolean(XRestriction.getSetting(null, context, XRestriction.cSettingExpert, - Boolean.FALSE.toString())); + Boolean.FALSE.toString(), false)); NotificationManager notificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); diff --git a/src/biz/bokhorst/xprivacy/XActivityThread.java b/src/biz/bokhorst/xprivacy/XActivityThread.java index 8857e9ded..dc9dab371 100644 --- a/src/biz/bokhorst/xprivacy/XActivityThread.java +++ b/src/biz/bokhorst/xprivacy/XActivityThread.java @@ -51,7 +51,7 @@ protected void before(MethodHookParam param) throws Throwable { if (isRestricted(param, mActionName)) if (Boolean.parseBoolean(XRestriction.getSetting(this, AndroidAppHelper.currentApplication(), XRestriction.cSettingExpert, - Boolean.FALSE.toString()))) + Boolean.FALSE.toString(), true))) param.setResult(null); } else if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { // Outgoing call diff --git a/src/biz/bokhorst/xprivacy/XApplicationInfo.java b/src/biz/bokhorst/xprivacy/XApplicationInfo.java index adcbeca39..820d12168 100644 --- a/src/biz/bokhorst/xprivacy/XApplicationInfo.java +++ b/src/biz/bokhorst/xprivacy/XApplicationInfo.java @@ -66,7 +66,7 @@ public static List getXApplicationList(Context context) { // Get references PackageManager pm = context.getPackageManager(); boolean expert = Boolean.parseBoolean(XRestriction.getSetting(null, context, XRestriction.cSettingExpert, - Boolean.FALSE.toString())); + Boolean.FALSE.toString(), false)); // Get app list SparseArray mapApp = new SparseArray(); diff --git a/src/biz/bokhorst/xprivacy/XLocationManager.java b/src/biz/bokhorst/xprivacy/XLocationManager.java index 97de1bdad..1ad3e4fac 100644 --- a/src/biz/bokhorst/xprivacy/XLocationManager.java +++ b/src/biz/bokhorst/xprivacy/XLocationManager.java @@ -129,8 +129,8 @@ private void replaceLocationListener(MethodHookParam param, int arg) throws Thro } private Location getBaseLocation(Context context) { - String sLat = XRestriction.getSetting(this, context, XRestriction.cSettingLatitude, ""); - String sLon = XRestriction.getSetting(this, context, XRestriction.cSettingLongitude, ""); + String sLat = XRestriction.getSetting(this, context, XRestriction.cSettingLatitude, "", true); + String sLon = XRestriction.getSetting(this, context, XRestriction.cSettingLongitude, "", true); if (sLat.equals("") || sLon.equals("")) return null; Location location = new Location(""); diff --git a/src/biz/bokhorst/xprivacy/XRestriction.java b/src/biz/bokhorst/xprivacy/XRestriction.java index da58312c8..afedce65e 100644 --- a/src/biz/bokhorst/xprivacy/XRestriction.java +++ b/src/biz/bokhorst/xprivacy/XRestriction.java @@ -57,7 +57,8 @@ public class XRestriction { private final static int cCacheTimeoutMs = 15 * 1000; private static Map> mPermissions = new LinkedHashMap>(); private static Map> mMethods = new LinkedHashMap>(); - private static Map mRestrictionCache = new HashMap(); + private static Map mRestrictionCache = new HashMap(); + private static Map mSettingsCache = new HashMap(); private static Map mUsageQueue = new LinkedHashMap(); static { @@ -238,7 +239,7 @@ public static void registerMethod(String methodName, String restrictionName, Str public static List getRestrictions() { List listRestriction = new ArrayList(Arrays.asList(cRestrictionNames)); if (!Boolean.parseBoolean(XRestriction.getSetting(null, null, XRestriction.cSettingExpert, - Boolean.FALSE.toString()))) + Boolean.FALSE.toString(), false))) listRestriction.remove(cBoot); return listRestriction; } @@ -322,7 +323,7 @@ public static boolean getRestricted(XHook hook, Context context, int uid, String if (useCache) synchronized (mRestrictionCache) { if (mRestrictionCache.containsKey(keyCache)) { - CacheEntry entry = mRestrictionCache.get(keyCache); + CRestriction entry = mRestrictionCache.get(keyCache); if (entry.isExpired()) mRestrictionCache.remove(keyCache); else { @@ -413,13 +414,13 @@ public static boolean getRestricted(XHook hook, Context context, int uid, String // Fallback restricted = XPrivacyProvider.getRestrictedFallback(hook, uid, restrictionName, methodName); - } else { - // Add to cache - synchronized (mRestrictionCache) { - if (mRestrictionCache.containsKey(keyCache)) - mRestrictionCache.remove(keyCache); - mRestrictionCache.put(keyCache, new CacheEntry(restricted)); - } + } + + // Add to cache + synchronized (mRestrictionCache) { + if (mRestrictionCache.containsKey(keyCache)) + mRestrictionCache.remove(keyCache); + mRestrictionCache.put(keyCache, new CRestriction(restricted)); } // Result @@ -465,8 +466,24 @@ public static void setRestricted(XHook hook, Context context, int uid, String re logRestriction(hook, context, uid, "set", restrictionName, methodName, restricted, false); } - public static String getSetting(XHook hook, Context context, String settingName, String defaultValue) { - // TODO: settings caching + public static String getSetting(XHook hook, Context context, String settingName, String defaultValue, + boolean useCache) { + // Check cache + if (useCache) + synchronized (mSettingsCache) { + if (mSettingsCache.containsKey(settingName)) { + CSetting entry = mSettingsCache.get(settingName); + if (entry.isExpired()) + mSettingsCache.remove(settingName); + else { + String value = mSettingsCache.get(settingName).getSettingsValue(); + XUtil.log(hook, Log.INFO, String.format("get setting %s=%s *", settingName, value)); + return value; + } + } + } + + // Get setting boolean fallback = true; String value = defaultValue; if (context != null) { @@ -499,9 +516,17 @@ public static String getSetting(XHook hook, Context context, String settingName, } } + // Use fallback if (fallback) value = XPrivacyProvider.getSettingFallback(settingName, defaultValue); + // Add to cache + synchronized (mSettingsCache) { + if (mSettingsCache.containsKey(settingName)) + mSettingsCache.remove(settingName); + mSettingsCache.put(settingName, new CSetting(value)); + } + XUtil.log(hook, Log.INFO, String.format("get setting %s=%s%s", settingName, value, (fallback ? " #" : ""))); return value; } @@ -536,7 +561,7 @@ public static long getDefacedHex() { } public static String getDefacedMac() { - return getSetting(null, null, cSettingMac, "de:fa:ce:de:fa:ce"); + return getSetting(null, null, cSettingMac, "de:fa:ce:de:fa:ce", true); } public static byte[] getDefacedBytes() { @@ -570,11 +595,11 @@ private static String getPackageName(Context context, int uid) { // Helper classes - private static class CacheEntry { + private static class CRestriction { private long mTimestamp; private boolean mRestricted; - public CacheEntry(boolean restricted) { + public CRestriction(boolean restricted) { mTimestamp = new Date().getTime(); mRestricted = restricted; } @@ -588,6 +613,24 @@ public boolean isRestricted() { } } + private static class CSetting { + private long mTimestamp; + private String mValue; + + public CSetting(String settingValue) { + mTimestamp = new Date().getTime(); + mValue = settingValue; + } + + public boolean isExpired() { + return (mTimestamp + cCacheTimeoutMs < new Date().getTime()); + } + + public String getSettingsValue() { + return mValue; + } + } + private static class UsageData { private Integer mUid; private String mRestriction;