Unter Android 9 und niedriger gibt es einen Thread in libsuspend
für die Initiierung der Systemaussetzung verantwortlich. Android 10
führt eine äquivalente Funktion in einen SystemSuspend HIDL-Dienst ein.
Dieser Dienst befindet sich im System-Image und wird von der Android-Plattform bereitgestellt.
Die Logik von libsuspend
bleibt weitgehend gleich, mit der Ausnahme, dass jeder Nutzerbereich
Prozess, der den Systemsperrvorgang blockiert, muss mit „SystemSuspend“ kommunizieren.
libsuspend und libpower
In Android 10 wird der Dienst „SystemSuspend“
libsuspend
libpower
wurde neu implementiert, um sich auf
den Dienst „SystemSuspend“ anstelle von
/sys/power/wake[un]lock
ohne die C API zu ändern.
Dieser Pseudocode zeigt, wie acquire_wake_lock
implementiert wird
und 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;
}
Ausführungsthreads
Der SystemSuspend-Dienst verfolgt die Anzahl der Wakelocks, die mit einen Zähler für die Sperrung. Sie hat zwei Ausführungsthreads:
- Der main-Thread beantwortet Binder-Aufrufe.
- Der Thread suspend steuert den Systemsperrvorgang.
Hauptthread
Der Hauptthread beantwortet Anfragen von Clients, um neue Wakelocks zuzuweisen, Erhöhung/Dekrementieren des Aussetzungszählers.
Thread aussetzen
Der Sperren-Thread führt in einer Schleife Folgendes aus:
- Aus
/sys/power/wakeup_count
lesen. - Erwerben Sie den Mutex. Dadurch wird sichergestellt, dass der Sperren-Thread nicht berührt wird. dem Sperren-Zähler, während der main-Thread versucht, erhöhen oder verringern. Der main-Thread ist blockiert beim Ausstellen oder Entfernen von Wakelocks, wenn der Zähler für das Anhalten den Wert Null erreicht hat und der suspend-Thread versucht, ausgeführt zu werden.
- Warten Sie, bis der Zähler gleich null ist.
- Schreiben Sie den aus
/sys/power /wakeup_count
(Schritt 1) gelesenen Wert in diese Datei. Wenn der Schreibvorgang fehlschlägt, kehren Sie zum Anfang der Schleife zurück. - Starten Sie den Systemsperrvorgang durch Schreiben von
mem
in/sys/power/state
. - Lassen Sie den Mutex los.
Wenn eine Anfrage für einen Wakelock erfolgreich zurückgegeben wird, ist der Sperrthread blockiert.
<ph type="x-smartling-placeholder">SystemAnhalten-API
Die SystemSuspend API besteht aus zwei Schnittstellen. Die HIDL-Schnittstelle wird nativer Prozesse zum Abrufen von Wakelocks. Die AIDL-Schnittstelle wird für Kommunikation zwischen SystemServer und SystemSuspend.
ISystemSuspend HIDL-Schnittstelle
enum WakeLockType : uint32_t {
PARTIAL,
FULL
};
interface IWakeLock {
oneway release();
};
interface ISystemSuspend {
acquireWakeLock(WakeLockType type, string debugName)
generates (IWakeLock lock);
};
Jeder Client, der einen Wakelock anfordert, erhält eine eindeutige
IWakeLock
-Instanz. Dies unterscheidet sich von
/sys/power/wake_lock
, womit mehrere
Wakelocks unter demselben Namen verwenden. Wenn ein Kunde mit einem
IWakeLock
-Instanz beendet, der Binder-Treiber und
Der Dienst „SystemSuspend“ bereinigt sie.
AIDL-Schnittstelle „ISuspensionControlService“
ISuspendControlService ist nur für die Verwendung durch SystemServer vorgesehen.
interface ISuspendCallback {
void notifyWakeup(boolean success);
}
interface ISuspendControlService {
boolean enableAutosuspend();
boolean registerCallback(ISuspendCallback callback);
boolean forceSuspend();
}
Die Nutzung des Android HIDL bietet folgende Vorteile:
- Wenn ein Prozess zum Blockieren einer Sperrung abgebrochen wird, kann SystemSuspend benachrichtigt werden.
- Der Thread, der für die Systemaussetzung verantwortlich ist, kann einen Rückruf erhalten.