agentsclimarketplace

Battery profiling

Skill almasumdev/awesome-mobile-performance-agent-skills/.github/skills/battery/battery-profiling

Agent skills for profiling and optimizing mobile app performance (startup, memory, frame-rate, network).

Install
npx -y skills add almasumdev/awesome-mobile-performance-agent-skills --skill battery-profiling

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Attribute battery drain to CPU, radio, GPS, display, and background work using Android Battery Historian and Xcode Energy Log / Instruments Energy gauge.

SKILL.md

5.9 KB, as published. Nobody here has run it

Battery Profiling

Instructions

Battery drain is always attributable — CPU, radio wakeups, GPS, screen brightness, or unreleased wakelocks. This skill shows how to capture a reliable energy trace and how to read it.

1. What to Measure

  • mAh per hour in a representative workload (idle, active feed, video).
  • CPU time (user + kernel).
  • Radio time (Wi-Fi on, cellular on, data transfer).
  • Wakelocks / assertions count and duration.
  • GPS / sensor active time.
  • Screen on-time at which brightness.

Budgets (rule of thumb):

StateForeground (%/h)Background (%/h)
Idle< 3< 0.5
Browsing< 8
Video< 15

2. Android — Battery Historian

  1. adb shell dumpsys batterystats --reset

  2. Unplug the device. Use the app for 10–20 minutes.

  3. adb bugreport bugreport.zip

  4. Open Battery Historian or run locally via Docker:

    docker run -p 9999:9999 bhaavan/battery-historian
    
  5. Upload bugreport.zip. Inspect:

    • Wakelocks — per-app held wakelocks. Any partial wakelock > 30 s is suspect.
    • Kernel wakeups — modem, Wi-Fi, alarm. Reduce with JobScheduler / WorkManager constraints.
    • Process CPU — top processes while screen-off.
    • Doze transitions — confirm the app respects Doze (no network during idle maintenance windows).

3. Android — On-Device Energy Profiler

Android Studio Profiler → Energy row on API 26+. Shows a unit-less high/medium/low indicator with a breakdown:

  • CPU
  • Network (radio-on cost + transfer cost)
  • Location (GPS on)

Click a bar to see wakelock, alarm, and job events with stack traces — correlates code to energy cost.

4. iOS — Instruments Energy Log + Xcode Gauges

Xcode debugger gauge panel shows live Energy Impact. For reproducible measurements:

  1. Product → Profile → Energy Log template (requires a physical device, ideally unplugged — use wireless debugging).

  2. Record for 2–5 minutes under the scenario.

  3. Track views:

    • Energy Usage — high/low bars per second.
    • CPU Activity — user vs kernel.
    • Networking — bytes in/out and connection lifetime.
    • Location — GPS/Wi-Fi scan activity.
    • Display Brightness, Bluetooth, etc.
  4. Generate a diagnostic .logarchive:

    xcrun simctl spawn booted log collect
    

MetricKit in production:

class Delegate: NSObject, MXMetricManagerSubscriber {
    func didReceive(_ payloads: [MXMetricPayload]) {
        for p in payloads {
            let cpu = p.cpuMetrics.cumulativeCPUTime
            let cells = p.cellularConditionMetrics
            // ship to telemetry
        }
    }
}

5. Common Drain Sources

SymptomLikely causeFix
High radio time even when idleChatty polling, small requests every 5–30 sBatch, lengthen interval, use silent push.
Sustained wakelockPARTIAL_WAKE_LOCK held across network retry loopsUse WorkManager with NetworkType.CONNECTED; drop explicit lock.
High CPU while screen offInfinite timers, MQTT reconnect stormExponential backoff, FCM push instead of polling.
GPS active for minutes"Always" location permission, foreground tracking bugsUse significant-change / geofence APIs; stop when not needed.
Bluetooth always scanningBLE scan without filtersUse ScanFilter + SCAN_MODE_LOW_POWER.
iOS "high energy" from WebViewAnimated GIFs, complex CSS, autoplay videoPause WebView on disappear; freeze animations.

6. Guardrails in Code

Kotlin — prefer coroutines with cancellation and network constraints:

val req = OneTimeWorkRequestBuilder<SyncWorker>()
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)
            .setRequiresBatteryNotLow(true)
            .setRequiresCharging(false)
            .build()
    ).build()
WorkManager.getInstance(ctx).enqueue(req)

Swift — use BGProcessingTaskRequest with requiresExternalPower/requiresNetworkConnectivity:

let req = BGProcessingTaskRequest(identifier: "com.app.sync")
req.requiresNetworkConnectivity = true
req.requiresExternalPower = false
try BGTaskScheduler.shared.submit(req)

7. Compare Before/After

Always compare two runs with the same workload, same starting battery level, same network conditions. Tools:

  • Android Automator + monkey for reproducible workloads.
  • XCUITest + XCTApplicationLaunchMetric/custom metrics for iOS.

Checklist

  • Energy baseline captured with an identical, scripted workload.
  • Battery Historian shows no unexpected wakelock > 30 s.
  • Energy Log / MetricKit MXCPUMetric shows CPU time within budget.
  • No radio-on polling on the background path; push or batched sync only.
  • GPS / BLE scanning uses filtered, low-power APIs.
  • Background work uses WorkManager / BGTaskScheduler with constraints.
  • Regression dashboard fed by MetricKit payloads in production.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.