Unreleased Android WakeLock

ID

java.android_wakelock

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

CWE:400, android, efficiency, reliability

Description

Reports WakeLock variables acquired via PowerManager.newWakeLock(…​) that are never released within the same method body. An unreleased WakeLock prevents the device from entering a low-power state, causing significant battery drain that the user may not notice until the battery is depleted.

Rationale

A WakeLock keeps the CPU (or screen) running even when the user is not interacting with the device. If the lock is never released, the device remains awake indefinitely:

public void doWork(PowerManager pm) {
  WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myapp:work");
  wl.acquire();
  performTask();
  // Bug: wl is never released -- the CPU stays awake forever
}

The rule applies an escape heuristic to avoid false positives: if the WakeLock variable is returned, passed as an argument, or assigned to a field, the release may happen elsewhere, so the rule conservatively stays silent.

Remediation

Always release the WakeLock when it is no longer needed. Use a try-finally block to ensure release even when exceptions occur:

public void doWork(PowerManager pm) {
  WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myapp:work");
  wl.acquire();
  try {
    performTask();
  } finally {
    wl.release();
  }
}

Alternatively, use wl.acquire(timeout) with a timeout to ensure automatic release.