SystemSuspend-Dienst

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:

  1. Aus /sys/power/wakeup_count lesen.
  2. 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.
  3. Warten Sie, bis der Zähler gleich null ist.
  4. 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.
  5. Starten Sie den Systemsperrvorgang durch Schreiben von mem in /sys/power/state.
  6. 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">
</ph>
Abbildung 1: Thread-Schleife aussetzen

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.