В Android 9 и ниже есть поток в libsuspend , отвечающий за инициирование приостановки системы. Android 10 вводит эквивалентную функциональность в службе SystemSuspend HIDL. Эта служба находится в образе системы и обслуживается платформой Android. Логика libsuspend
остается в основном той же, за исключением того, что каждый процесс пользовательского пространства, блокирующий приостановку системы, должен взаимодействовать с SystemSuspend.
libsuspend и libpower
В Android 10 служба SystemSuspend заменяет libsuspend
. libpower
была переработана для использования службы SystemSuspend вместо /sys/ power /wake[un]lock
без изменения C API.
Этот псевдокод показывает, как реализовать acquire_wake_lock
и release_wake_lock
.
static std::unordered_map<std::string, sp<IWakeLock>> gWakeLockMap;
int acquire_wake_lock(int, const char* id) {
...
if (!gWakeLockMap[id]) {
gWakeLockMap[id] = suspendService->acquireWakeLock(WakeLockType::PARTIAL, id);
}
...
return 0;
}
int release_wake_lock(const char* id) {
...
if (gWakeLockMap[id]) {
auto ret = gWakeLockMap[id]->release();
gWakeLockMap[id].clear();
return 0;
}
...
return -1;
}
Потоки выполнения
Служба SystemSuspend отслеживает количество блокировок пробуждения, выданных с помощью счетчика приостановки. Она имеет два потока выполнения:
- Основная тема отвечает на запросы связующего звена.
- Приостановка потока управляет системой приостановки.
Основная тема
Основной поток отвечает на запросы клиентов о выделении новых блокировок пробуждения, увеличивая/уменьшая счетчик приостановки.
Приостановить поток
Приостановленный поток выполняет в цикле следующее:
- Прочитать из
/sys/ power /wakeup_count
. - Получите мьютекс. Это гарантирует, что поток приостановки не коснется счетчика приостановки, пока основной поток пытается увеличить или уменьшить его. Основной поток блокируется при выдаче или снятии блокировок пробуждения, когда счетчик приостановки достиг нуля, а поток приостановки пытается запуститься.
- Подождите, пока счетчик не станет равен нулю.
- Записать значение, считанное из
/sys/ power /wakeup_count
(из шага 1), в этот файл. Если запись не удалась, вернуться к началу цикла - Запустите режим ожидания системы, записав
mem
в/sys/power/ state
. - Освободите мьютекс.
При успешном возврате запроса на блокировку пробуждения поток приостановки блокируется.

API SystemSuspend
API SystemSuspend состоит из двух интерфейсов. Интерфейс HIDL используется собственными процессами для получения блокировок пробуждения, а интерфейс AIDL используется для связи между SystemServer и SystemSuspend.
Интерфейс ISystemSuspend HIDL
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
Каждый клиент, запрашивающий блокировку пробуждения, получает уникальный экземпляр IWakeLock
. Это отличается от /sys/ power /wake_lock
, который позволяет нескольким клиентам использовать блокировку пробуждения под одним и тем же именем. Если клиент, удерживающий экземпляр IWakeLock
, завершает работу, драйвер привязки и служба SystemSuspend очищают его.
Интерфейс ISuspendControlService AIDL
ISuspendControlService предназначен для использования только SystemServer.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
Использование Android HIDL обеспечивает следующие преимущества:
- Если процесс, блокирующий приостановку, завершается, SystemSuspend может быть уведомлен.
- Потоку, отвечающему за приостановку системы, можно назначить обратный вызов.