AOSP Framework & Internals
3 min read

Wakelocks

Understand the aggressive power management system that allows Android to force the CPU into a deep sleep state to save battery.

If you leave a laptop screen turned on without touching the mouse, a standard Linux operating system will happily sit there, keeping the CPU awake and burning power indefinitely.

Smartphones cannot afford this behavior. To preserve the battery, the Android kernel is incredibly aggressive. If the screen is off and no active tasks are running, the kernel will forcefully shut down the main CPU cores, power off the RAM controllers, and drop the device into a "Deep Suspend" state within seconds.

However, if you are downloading a 2GB file or listening to music with the screen off, the device cannot be allowed to go to sleep. To solve this, Android uses Wakelocks.

The Wakelock Concept

A Wakelock is essentially a veto against the kernel's suspend mechanism.

As long as at least one Wakelock is active anywhere in the system, the Linux kernel is strictly forbidden from entering deep sleep. The moment the number of active Wakelocks drops to zero, the kernel immediately suspends the system.

Kernel vs Userspace Wakelocks

Wakelocks exist at two different layers of the Android stack.

1. Kernel Wakelocks

These are used by low-level hardware drivers. For example, if the Wi-Fi chip receives an incoming WhatsApp packet while the phone is asleep, the Wi-Fi kernel driver will instantly grab a kernel-level wakelock, wake up the main CPU, and process the packet.

2. Userspace Wakelocks (PowerManager)

Android applications cannot grab kernel wakelocks directly. Instead, they must ask the Android framework.

If an app wants to keep the phone awake to finish a download, it uses the Java PowerManager API to acquire a WAKE_LOCK. Under the hood, the PowerManagerService (running in the System Server) aggregates all the requests from all the user apps, and holds a single master kernel wakelock on their behalf.

// How an Android app requests a Partial Wakelock in Java
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
        PowerManager.PARTIAL_WAKE_LOCK, "MyApp::DownloadWakelock");

// Acquire the lock (prevents deep sleep)
wakeLock.acquire();

// ... perform long background download ...

// ALWAYS release the lock when finished!
wakeLock.release(); 

Types of Wakelocks

When an app developer requests a wakelock via PowerManager, they must specify the severity:

  • PARTIAL_WAKE_LOCK: The most common type. It guarantees the CPU will continue running, but it allows the screen and the keyboard backlight to turn off. This is what Spotify uses to play music in your pocket.
  • SCREEN_DIM_WAKE_LOCK / SCREEN_BRIGHT_WAKE_LOCK: Keeps the CPU running and forces the screen to stay turned on. Used by video players (like YouTube) or reading apps where the user is staring at the screen without physically touching it.

Debugging Wakelock Abusers

Wakelocks are the number one cause of severe battery drain in Android. If a poorly written app grabs a PARTIAL_WAKE_LOCK to sync data but crashes or forgets to release it, the CPU will stay pinned at 100% awake for hours, completely draining the battery in the background.

Platform engineers heavily rely on tools like Battery Historian and ADB to analyze the system logs, track exactly which process held a wakelock, and identify the rogue applications killing the device's battery life.

You can inspect active wakelocks right now from your terminal:

adb shell dumpsys power | grep -i wake_lock