diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fa461a9..a6f07ba1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Changelog * Added restriction *getInstalledProvidersForProfile* ([issue](/../../issues/1757)) * Allow white listing / show parameter of *getExternalStorageState* ([issue](/../../issues/1757)) * Added quirk *nousage* to disable usage data for specific applications ([issue](/../../issues/2085)) +* Added restrictions for [UsageStatsManager](https://developer.android.com/reference/android/app/usage/UsageStatsManager.html) ([issue](/../../issues/1757)) [Open issues](https://github.com/M66B/XPrivacy/issues?state=open) diff --git a/res/values/functions.xml b/res/values/functions.xml index 61299eee5..221a71d12 100644 --- a/res/values/functions.xml +++ b/res/values/functions.xml @@ -395,6 +395,13 @@ Google documentation]]> Google documentation]]> Documentation]]> + Documentation]]> + Documentation]]> + Documentation]]> + Documentation]]> + Documentation]]> + Documentation]]> + Documentation]]> Google documentation]]> diff --git a/src/biz/bokhorst/xprivacy/Meta.java b/src/biz/bokhorst/xprivacy/Meta.java index 9f1ce845d..17b2b33b2 100644 --- a/src/biz/bokhorst/xprivacy/Meta.java +++ b/src/biz/bokhorst/xprivacy/Meta.java @@ -467,6 +467,14 @@ public static List get() { mListHook.add(new Hook("system", "IntentFirewall", "", 19, "2.2.2", null).AOSP(19).dangerous().whitelist(cTypeAction)); + mListHook.add(new Hook("system", "queryAndAggregateUsageStats", null, 21, "3.5.6", null).notAOSP(21)); + mListHook.add(new Hook("system", "queryConfigurations", null, 21, "3.5.6", null).notAOSP(21)); + mListHook.add(new Hook("system", "queryEvents", null, 21, "3.5.6", null).notAOSP(21)); + mListHook.add(new Hook("system", "queryUsageStats", null, 21, "3.5.6", null).notAOSP(21)); + mListHook.add(new Hook("system", "Srv_queryConfigurationStats", null, 21, "3.5.6", null).AOSP(21)); + mListHook.add(new Hook("system", "Srv_queryEvents", null, 21, "3.5.6", null).AOSP(21)); + mListHook.add(new Hook("system", "Srv_queryUsageStats", null, 21, "3.5.6", null).AOSP(21)); + mListHook.add(new Hook("view", "loadUrl", "", 1, null, null).unsafe().whitelist(cTypeUrl)); mListHook.add(new Hook("view", "WebView", "", 1, null, null).unsafe()); mListHook.add(new Hook("view", "getDefaultUserAgent", "", 17, null, null).unsafe()); diff --git a/src/biz/bokhorst/xprivacy/XPrivacy.java b/src/biz/bokhorst/xprivacy/XPrivacy.java index a9bab554f..77426fe51 100644 --- a/src/biz/bokhorst/xprivacy/XPrivacy.java +++ b/src/biz/bokhorst/xprivacy/XPrivacy.java @@ -328,6 +328,9 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable { // Telephone service hookAll(XTelephonyManager.getInstances(null), null, mSecret); + // Usage statistics manager + hookAll(XUsageStatsManager.getInstances(), null, mSecret); + // USB device hookAll(XUsbDevice.getInstances(), null, mSecret); diff --git a/src/biz/bokhorst/xprivacy/XUsageStatsManager.java b/src/biz/bokhorst/xprivacy/XUsageStatsManager.java new file mode 100644 index 000000000..0a0fbbbe5 --- /dev/null +++ b/src/biz/bokhorst/xprivacy/XUsageStatsManager.java @@ -0,0 +1,111 @@ +package biz.bokhorst.xprivacy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import android.app.usage.ConfigurationStats; +import android.app.usage.UsageStats; + +import biz.bokhorst.xprivacy.XHook; + +public class XUsageStatsManager extends XHook { + private Methods mMethod; + + private XUsageStatsManager(Methods method, String restrictionName) { + super(restrictionName, method.name(), null); + mMethod = method; + } + + public String getClassName() { + if (mMethod.name().startsWith("Srv_")) + return "com.android.server.usage.UserUsageStatsService"; + else + return "android.app.usage.UsageStatsManager"; + } + + // @formatter:off + + // public Map queryAndAggregateUsageStats(long beginTime, long endTime) + // public List queryConfigurations(int intervalType, long beginTime, long endTime) + // public UsageEvents queryEvents(long beginTime, long endTime) + // public List queryUsageStats(int intervalType, long beginTime, long endTime) + // https://developer.android.com/reference/android/app/usage/UsageStatsManager.html + + // List queryConfigurationStats(int userId, int bucketType, long beginTime, long endTime) + // UsageEvents queryEvents(int userId, long beginTime, long endTime) + // List queryUsageStats(int userId, int bucketType, long beginTime, long endTime) + // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/com/android/server/usage/UsageStatsService.java + + private enum Methods { + queryAndAggregateUsageStats, queryConfigurations, queryEvents, queryUsageStats, + Srv_queryConfigurationStats, Srv_queryEvents, Srv_queryUsageStats + }; + + // @formatter:on + + public static List getInstances() { + List listHook = new ArrayList(); + listHook.add(new XUsageStatsManager(Methods.queryAndAggregateUsageStats, PrivacyManager.cSystem)); + listHook.add(new XUsageStatsManager(Methods.queryConfigurations, PrivacyManager.cSystem)); + listHook.add(new XUsageStatsManager(Methods.queryEvents, PrivacyManager.cSystem)); + listHook.add(new XUsageStatsManager(Methods.queryUsageStats, PrivacyManager.cSystem)); + + listHook.add(new XUsageStatsManager(Methods.Srv_queryConfigurationStats, PrivacyManager.cSystem)); + listHook.add(new XUsageStatsManager(Methods.Srv_queryEvents, PrivacyManager.cSystem)); + listHook.add(new XUsageStatsManager(Methods.Srv_queryUsageStats, PrivacyManager.cSystem)); + return listHook; + } + + @Override + protected void before(XParam param) throws Throwable { + switch (mMethod) { + case queryAndAggregateUsageStats: + case queryConfigurations: + case queryUsageStats: + case Srv_queryConfigurationStats: + case Srv_queryUsageStats: + // Do nothing + break; + case queryEvents: + if (isRestricted(param)) + if (param.args.length > 1) { + param.args[0] = 0; + param.args[1] = 0; + } + break; + + case Srv_queryEvents: + if (isRestricted(param)) + if (param.args.length > 2) { + param.args[1] = 0; + param.args[2] = 0; + } + break; + } + } + + @Override + protected void after(XParam param) throws Throwable { + switch (mMethod) { + case queryAndAggregateUsageStats: + if (isRestricted(param)) + param.setResult(new HashMap()); + break; + case queryConfigurations: + case Srv_queryConfigurationStats: + if (isRestricted(param)) + param.setResult(new ArrayList()); + break; + case queryEvents: + case Srv_queryEvents: + // Do nothing + break; + case queryUsageStats: + case Srv_queryUsageStats: + if (isRestricted(param)) + param.setResult(new ArrayList()); + break; + } + } +}