diff --git a/CHANGELOG.md b/CHANGELOG.md
index 418f5c319..f117029e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,6 +45,7 @@ Version 2.99.x and version 3.x will be available with a [pro license](http://www
**Next release**
+* Added restriction *registerListener* to the *Sensors* category, which will limit the rate of the gyroscope to 100 Hz to prevent eavesdropping ([issue](/../../issues/1878))
* Updated Slovenian translation
[Open issues](https://github.com/M66B/XPrivacy/issues?state=open)
diff --git a/res/values/functions.xml b/res/values/functions.xml
index c3032f157..8fc5a8cfc 100644
--- a/res/values/functions.xml
+++ b/res/values/functions.xml
@@ -297,6 +297,7 @@
Google documentation]]>
Google documentation]]>
+
Google documentation]]>
Google documentation]]>
Google documentation]]>
Google documentation]]>
diff --git a/src/biz/bokhorst/xprivacy/Meta.java b/src/biz/bokhorst/xprivacy/Meta.java
index 8e1993990..8eda592d9 100644
--- a/src/biz/bokhorst/xprivacy/Meta.java
+++ b/src/biz/bokhorst/xprivacy/Meta.java
@@ -367,6 +367,7 @@ public static List get() {
mListHook.add(new Hook("sensors", "getDefaultSensor", "", 3, null, null).unsafe().dangerous());
mListHook.add(new Hook("sensors", "getSensorList", "", 3, null, null).unsafe().dangerous());
+ mListHook.add(new Hook("sensors", "registerListener", "", 3, "2.99.27", null).unsafe());
mListHook.add(new Hook("sensors", "acceleration", "", 3, null, null).unsafe());
mListHook.add(new Hook("sensors", "gravity", "", 3, null, null).unsafe());
mListHook.add(new Hook("sensors", "humidity", "", 3, null, null).unsafe());
diff --git a/src/biz/bokhorst/xprivacy/XSensorManager.java b/src/biz/bokhorst/xprivacy/XSensorManager.java
index 130d2641a..8d6624e1e 100644
--- a/src/biz/bokhorst/xprivacy/XSensorManager.java
+++ b/src/biz/bokhorst/xprivacy/XSensorManager.java
@@ -11,6 +11,8 @@ public class XSensorManager extends XHook {
private String mClassName;
private static final String cClassName = "android.hardware.SensorManager";
+ private static final int cMaxRateUs = (int) (0.01 * 1000 * 1000); // 100 Hz
+
private XSensorManager(Methods method, String restrictionName, String className) {
super(restrictionName, method.name(), null);
mMethod = method;
@@ -25,6 +27,10 @@ public String getClassName() {
// public Sensor getDefaultSensor(int type)
// public List getSensorList(int type)
+ // boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs, int maxBatchReportLatencyUs)
+ // boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs, Handler handler)
+ // boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs, int maxBatchReportLatencyUs, Handler handler)
+ // boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs)
// frameworks/base/core/java/android/hardware/SensorManager.java
// http://developer.android.com/reference/android/hardware/SensorManager.html
// http://developer.android.com/reference/android/hardware/Sensor.html
@@ -32,7 +38,7 @@ public String getClassName() {
// @formatter:on
private enum Methods {
- getDefaultSensor, getSensorList
+ getDefaultSensor, getSensorList, registerListener
};
public static List getInstances(String className) {
@@ -43,41 +49,64 @@ public static List getInstances(String className) {
listHook.add(new XSensorManager(Methods.getDefaultSensor, PrivacyManager.cSensors, className));
listHook.add(new XSensorManager(Methods.getSensorList, PrivacyManager.cSensors, className));
+ listHook.add(new XSensorManager(Methods.registerListener, PrivacyManager.cSensors, className));
}
return listHook;
}
@Override
protected void before(XParam param) throws Throwable {
- if (mMethod == Methods.getDefaultSensor) {
+ switch (mMethod) {
+ case getDefaultSensor:
if (isRestricted(param))
param.setResult(null);
- else if (param.args.length > 0)
+ else if (param.args.length > 0 && param.args[0] instanceof Integer)
if (isRestricted(param, (Integer) param.args[0]))
param.setResult(null);
+ break;
- } else if (mMethod == Methods.getSensorList) {
+ case getSensorList:
if (isRestricted(param))
param.setResult(new ArrayList());
- else if (param.args.length > 0)
+ else if (param.args.length > 0 && param.args[0] instanceof Integer)
if (isRestricted(param, (Integer) param.args[0]))
param.setResult(new ArrayList());
+ break;
- } else
- Util.log(this, Log.WARN, "Unknown method=" + param.method.getName());
+ case registerListener:
+ if (param.args.length > 2 && param.args[1] instanceof Sensor && param.args[2] instanceof Integer) {
+ int type = ((Sensor) param.args[1]).getType();
+ if (type == Sensor.TYPE_GYROSCOPE || type == Sensor.TYPE_GYROSCOPE_UNCALIBRATED) {
+ int rateUs = (Integer) param.args[2];
+ if (rateUs < cMaxRateUs)
+ if (isRestricted(param))
+ param.args[2] = cMaxRateUs;
+ }
+ }
+ break;
+ }
}
@Override
@SuppressWarnings("unchecked")
protected void after(XParam param) throws Throwable {
- if (mMethod == Methods.getSensorList)
- if (param.getResult() != null && param.args.length > 0 && (Integer) param.args[0] == Sensor.TYPE_ALL) {
- List listSensor = new ArrayList();
- for (Sensor sensor : (List) param.getResult())
- if (!isRestricted(param, sensor.getType()))
- listSensor.add(sensor);
- param.setResult(listSensor);
- }
+ switch (mMethod) {
+ case getDefaultSensor:
+ case registerListener:
+ // Do nothing
+ break;
+
+ case getSensorList:
+ if (param.getResult() != null && param.args.length > 0 && param.args[0] instanceof Integer)
+ if ((Integer) param.args[0] == Sensor.TYPE_ALL) {
+ List listSensor = new ArrayList();
+ for (Sensor sensor : (List) param.getResult())
+ if (!isRestricted(param, sensor.getType()))
+ listSensor.add(sensor);
+ param.setResult(listSensor);
+ }
+ break;
+ }
}
@SuppressWarnings("deprecation")