287 lines
9.8 KiB
Markdown
287 lines
9.8 KiB
Markdown
# Power Management
|
||
|
||
#### Power Saving
|
||
|
||
- Knowledge about the power consumption of each component and app
|
||
- Screen / Network / CPU off or release other device resources as soon as not needed
|
||
- Limit resources for less frequently used apps
|
||
- Set device to sleep as soon as there are no user interactions
|
||
- Global management of running jobs across all apps
|
||
- Perform syncs, uploads & downloads together in a fixed time window
|
||
|
||
#### Battery Consumption Statistics
|
||
|
||
- Framework tracks the time that devices spend in different states
|
||
- e.g. WiFi chip-set: on/off
|
||
- Display: low/high brightness
|
||
- Controlling service **pushes** state changes to `BatteryStats` service
|
||
- Framework **pulls** the data at these transition points
|
||
- App power consumption is calculated based on CPU run time at specific speeds
|
||
|
||
#### Android Power Management Concept
|
||
|
||
- **G0** - working
|
||
- **G1** - sleeping
|
||
- **S1** - CPU stops executing instructions, power to CPU and RAM maintained
|
||
- **S2** - CPU powered off, cache is flushed
|
||
- **S3** - Standby / sleep / suspend power to RAM
|
||
- **S4** - Hibernate, suspend disk, RAM powered off
|
||
- **G2** (S5) - soft off
|
||
- **G3** - mechanical off
|
||
|
||
#### Power Management Design
|
||
|
||
- A wrapper to Linux Power Management
|
||
- Added to the Kernel
|
||
- Wake lock mechanism
|
||
- Apps need to request the CPU & screen to be on with `WakeLocks`; otherwise, Android will shut down the CPU
|
||
- Wake locks and timeouts constantly switch the state of the system’s power
|
||
- Overall system power consumption decreases
|
||
- *Better* use of battery capacity
|
||
|
||

|
||
|
||
### WAKE_LOCK
|
||
|
||
Firstly, request the WAKE_LOCK permission in the manifest
|
||
|
||
```xml
|
||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||
```
|
||
|
||
Use `newWakeLock()` to create a `PowerManager.WakeLock` object
|
||
|
||
```java
|
||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
|
||
wl.acquire();
|
||
..screen will stay on during this section..
|
||
wl.release();
|
||
```
|
||
|
||
| Flag Value | CPU | Screen | Keyboard |
|
||
| :------------------------ | :------------------------------------------------- | ------ | -------- |
|
||
| `PARTIAL_WAKE_LOCK` | On (Don’t sleep even when power button is pressed) | Off | Off |
|
||
| `SCREEN_DIM_WAKE_LOCK` | On | Dim | Off |
|
||
| `SCREEN_BRIGHT_WAKE_LOCK` | On | Bright | Off |
|
||
| `FULL_WAKE_LOCK` | On | Bright | Bright |
|
||
|
||
> Creating and holding wake locks can have a **dramatic impact** on the host device's battery life. Thus you should use wake locks only when **strictly necessary** and hold them for as **short a time as possible**.
|
||
>
|
||
> - If app is performing long-running HTTP downloads, consider `DownloadManager`
|
||
> - If app is synchronising data, consider sync adapter
|
||
> - If your app relies on background services, consider `JobScheduler` to trigger services at specific intervals
|
||
> - One use case for wake lock might be a background service that needs to grab a wake lock to keep the CPU running to do work while the screen is off.
|
||
|
||
#### Battery Life Enhancement in Android 6.0+
|
||
|
||
##### App Standby
|
||
|
||
Defer background activity for apps with no recent user interaction
|
||
|
||
###### Start Conditions:
|
||
|
||
An app that is not actively used for a certain time will be placed in an idle mode
|
||
|
||
- Not doing foreground work (activities, services, pending intents, notifications)
|
||
- Hasn’t been explicitly launched for a certain time (can be days)
|
||
|
||
###### Actions
|
||
|
||
- No network access
|
||
- No background jobs
|
||
- Can set alarms
|
||
- Can use wake locks
|
||
- Is allowed network access once per day
|
||
|
||
###### Exit conditions
|
||
|
||
- When the device is plugged in
|
||
- Notice when your phone is plugged in, the screen will stay on for longer
|
||
- When a foreground task is performed by the user
|
||
|
||
##### Doze
|
||
|
||
A deep sleep if the user has not actively used the device for extended periods of time
|
||
|
||
###### Starts Doze
|
||
|
||
- When device is idle, screen is off, on battery & stationary
|
||
|
||
###### In doze
|
||
|
||
- No network access
|
||
- No CPU-intensive work
|
||
- Wake locks ignored
|
||
- No Wi-Fi scan
|
||
- Deferred alarm manager alarms
|
||
- Only high-priority notifications received
|
||
- No job scheduler
|
||
- No sync adaptors
|
||
|
||
###### Exits Doze
|
||
|
||
- User interaction
|
||
- Device motion
|
||
- Screen on
|
||
- Alarm clock alarm
|
||
- Notifications **do not** cause Doze exit
|
||
|
||
###### Maintenance windows
|
||
|
||
Maintenance windows complete pending activities (syncs, jobs, etc.)
|
||
|
||
- SMS & Telephony services are **excluded** from Doze.
|
||
|
||

|
||
|
||
##### Exemptions
|
||
|
||
System apps and cloud messaging services pre-loaded on the phone are exempt from App Standby and Doze
|
||
|
||
Uses whitelist for apps to be partially exempt from Doze & App standby
|
||
|
||
- `isIgnoringBatterOptimizations()` to check if it's in the whitelist
|
||
- `ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS` intent to redirect user to battery optimisation options
|
||
- `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` allow user to add app to white-list directly
|
||
- White-listed apps can use network and hold partial wake locks during Doze and App standby, but jobs and syncs are still deferred
|
||
- The app should not be on the whitelist unless it cannot use Firebase Cloud Messaging, high-priority messages or the app’s core functionality is affected.
|
||
|
||
#### App Stand-By Buckets
|
||
|
||
Prioritise apps based on how recently and how frequently the apps are used
|
||
|
||
- Active: currently or recently used
|
||
- Working set: regular use
|
||
- Frequent: often used but not every day
|
||
- Rare: not frequently
|
||
- Never: never
|
||
|
||
#### Firebase Cloud Messaging
|
||
|
||
Replaced Google Cloud Messaging
|
||
|
||
- A cross-platform reliable battery-efficient messaging solution that allows messages to be delivered between the server and client.
|
||
- Provides a single and persistent connection to the server.
|
||
- Can notify a client app that a new email or other data is available to sync
|
||
- Can deliver to single device, groups of devices or devices subscribed to topics.
|
||
- Send messages from client apps to the server (e.g. chats, messages, etc.)
|
||
|
||
#### Sustained Performance Mode
|
||
|
||
- Thermal throttling prevents long-running apps from maintaining their performance (e.g. games, cameras, VR, etc.)
|
||
- App can request to enter SPM, and keep a consistent level of performance
|
||
- Set using `Window.setSustainedPerformanceMode()`
|
||
- System automatically disables the mode when no longer in focus
|
||
|
||
# Power 2
|
||
|
||
**Background processes**
|
||
|
||
- Threads
|
||
- Services
|
||
- `AsyncTasks`
|
||
- `AlarmManager`
|
||
- Based on time
|
||
- `JobScheduler`
|
||
- Based on conditions
|
||
- `WorkManager`
|
||
- Requires Google Play service
|
||
- Automatic use of `alarmManager` and `jobScheduler`
|
||
|
||
The bottom three will guarantee completion when we are not worried about when it will happen
|
||
|
||
#### Alarm Manager
|
||
|
||
- Schedule a task to run at a specific time point or time interval
|
||
- `AlarmManager` holds a CPU wake lock, when the `onReceive()` method is executing
|
||
- Alarm manager operates outside of your application, so it can be used to trigger events when the app is not running or the device is asleep.
|
||
- Alarm delivery is inexact
|
||
- Use `setWindow` and `setExact` for exact delivery
|
||
|
||
##### Usage
|
||
|
||
- Specify an intent to be broadcast at some time
|
||
- `setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)`
|
||
- `setExact(int type, long triggerAtMillis, PendingIntent operation)`
|
||
- Extend Broadcast receiver
|
||
- `onReceive` method is called when the alarm goes off
|
||
- Start a service to actually do the work
|
||
|
||
#### Job Scheduler
|
||
|
||
- Many apps perform tasks asynchronously outside the main activity (downloading files)
|
||
- Job Scheduler collects pending jobs across all apps and schedules them to run at about the same time, so that the phone can sleep for longer and save more power
|
||
- Specify requirements for network and timing for each job, then the JS robustly optimises the execution time.
|
||
- May defer jobs that comply with Doze and App StandBy
|
||
- `JobService` **will run on the main thread**; you need to manage any asynchronous tasks yourself (using threads)
|
||
|
||
##### Usage
|
||
|
||
- Construct `JobInfo` objects using `JobInfo.Builder` using schedule conditions
|
||
- Network type (metered/unmetered)
|
||
- Charging and Idle
|
||
- Content Provider update
|
||
- Back-off (retry) criteria
|
||
- Minimum latency and override deadline
|
||
- Periodic
|
||
- Persistent
|
||
- Extras (customised information from app)
|
||
- Pass it to `JobScheduler` using *schedule* (`JobInfo`)
|
||
- Jobs implemented in the app’s `JobService`
|
||
- Jobs will be executed (batch & defer jobs smartly) at a certain time, but not an exact time (minimum period length is 15 minutes for periodic jobs)
|
||
|
||
#### Work Manager
|
||
|
||
- Guaranteed but deferrable
|
||
- Supports one-off or periodic tasks
|
||
- Queryable - check if work is successful
|
||
- Chainable: Job 2 is dependent on the execution of job 1
|
||
- Opportunistic: do the background work as soon as it can
|
||
|
||
##### When to use work manager
|
||
|
||
✓ Upload media to a server
|
||
|
||
✓ Parse data and store it in a database
|
||
|
||
✓ Periodically sync local data with the network
|
||
|
||
✗ Extract paint colour and update image views (use thread pools)
|
||
|
||
✗ Parse data and update contents of a View (use thread pools)
|
||
|
||
✗ Process payment transactions (use a foreground service)
|
||
|
||
##### Usage
|
||
|
||
- Add dependencies
|
||
|
||
```groovy
|
||
dependencies {
|
||
implementation "androidx.work:work-runtime:$versions.work"
|
||
}
|
||
```
|
||
|
||
- Work Request
|
||
|
||
```java
|
||
mWorkManager = WorkManager.getInstance(application);
|
||
mWorkManager.enqueue(OneTimeWorkRequest.from(Worker.class));
|
||
```
|
||
|
||
- Chain workers
|
||
|
||
```java
|
||
WorkContinuation continuation = mWorkManager.beginWith(workA);
|
||
continuation.then(workB).then(workC).enqueue();
|
||
```
|
||
|
||
- Set constraint
|
||
|
||
```java
|
||
Constraints constraints = new Constraints.Builder()
|
||
.setReuiresCharging(false)
|
||
.build();
|
||
```
|