Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| avoid-sensor-manager-leak.java:20:9:20:56 | registerListener(...) | Call unregisterListener() to match this registerListener() on 'SensorManager' to avoid unnecessary battery drain. |
| avoid-sensor-manager-leak.java:26:9:26:56 | registerListener(...) | Call unregisterListener() to match this registerListener() on 'SensorManager' to avoid unnecessary battery drain. |
| avoid-sensor-manager-leak.java:32:9:32:56 | registerListener(...) | Call unregisterListener() to match this registerListener() on 'SensorManager' to avoid unnecessary battery drain. |
| avoid-sensor-manager-leak.java:33:9:33:56 | registerListener(...) | Call unregisterListener() to match this registerListener() on 'SensorManager' to avoid unnecessary battery drain. |
53 changes: 53 additions & 0 deletions codeql-custom-queries-java/android/avoid-sensor-manager-leak.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class SensorManager {
void registerListener(Object listener, Object sensor, int delay) {
}

void unregisterListener(Object listener) {
}
}

class Sensor {
static final int TYPE_ACCELEROMETER = 1;
static final int TYPE_GYROSCOPE = 4;
static final int TYPE_LIGHT = 5;
}

// 🚫 Noncompliant - registerListener without unregisterListener
class NoncompliantSensorLeak {

void startAccelerometer() {
SensorManager sManager = new SensorManager();
sManager.registerListener(null, new Sensor(), 1); // $ Alert
// missing sManager.unregisterListener()
}

void startGyroscope() {
SensorManager sManager = new SensorManager();
sManager.registerListener(null, new Sensor(), 1); // $ Alert
// missing sManager.unregisterListener()
}

void startMultipleSensors() {
SensorManager sManager = new SensorManager();
sManager.registerListener(null, new Sensor(), 1); // $ Alert
sManager.registerListener(null, new Sensor(), 1); // $ Alert
// missing sManager.unregisterListener()
}
}

// ✅ Compliant - registerListener with matching unregisterListener
class CompliantSensorUsage {

void startAccelerometer() {
SensorManager sManager = new SensorManager();
sManager.registerListener(null, new Sensor(), 1); // OK
sManager.unregisterListener(null);
}

void startMultipleSensors() {
SensorManager sManager = new SensorManager();
sManager.registerListener(null, new Sensor(), 1); // OK
sManager.registerListener(null, new Sensor(), 1); // OK
sManager.unregisterListener(null);
}
}
23 changes: 23 additions & 0 deletions codeql-custom-queries-java/android/avoid-sensor-manager-leak.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @name Avoid SensorManager listener leak
* @description Calling SensorManager.registerListener() without a matching unregisterListener() causes the sensor to keep processing data during idle states, draining battery within hours.
* @kind problem
* @problem.severity warning
* @precision medium
* @id java/android/avoid-sensor-manager-leak
* @link https://green-code-initiative.org/rules#id:GCI514
* @tags android
*/

import java

from MethodCall register
where
register.getMethod().getName() = "registerListener" and
register.getQualifier().(VarAccess).getType().(RefType).getName() = "SensorManager" and
not exists(MethodCall unregister |
unregister.getMethod().getName() = "unregisterListener" and
unregister.getEnclosingCallable() = register.getEnclosingCallable()
)
select register,
"Call unregisterListener() to match this registerListener() on 'SensorManager' to avoid unnecessary battery drain."
Loading