SystemSuspend hizmeti

Android 9 ve önceki sürümlerde, sistemin askıya alınmasını başlatmaktan sorumlu libsuspend içinde bir iş parçacığı vardır. Android 10, SystemSuspend HIDL hizmetinde eşdeğer bir işlev sunar. Bu hizmet, sistem görüntüsünde bulunur ve Android platformu tarafından sunulur. libsuspend'daki mantık, sistemin askıya alınmasını engelleyen her kullanıcı alanı işlemi SystemSuspend ile iletişim kurması dışında büyük ölçüde aynı kalır.

libsuspend ve libpower

Android 10'da SystemSuspend hizmeti, libsuspend yerine geçer. libpower, C API'sinde değişiklik yapılmadan /sys/power/wake[un]lock yerine SystemSuspend hizmetini kullanacak şekilde yeniden uygulandı.

Bu sözde kodda, acquire_wake_lock ve release_wake_lock öğelerinin nasıl uygulanacağı gösterilmektedir.


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;
}

Yürütme iş parçacıkları

SystemSuspend hizmeti, askıya alma sayacıyla verilen uyandırma kilidi sayısını takip eder. İki yürütme iş parçacığı vardır:

  • Ana ileti dizisi, bağlayıcı çağrılarını yanıtlar.
  • Askıya alma iş parçacığı, sistemin askıya alınmasını kontrol eder.

Ana iş parçacığı

Ana iş parçacığı, istemcilerin yeni uyandırma kilitleri ayırma, askıya alma sayacını artırma/azaltma isteklerini yanıtlar.

İleti dizisini askıya alma

Askıya alma iş parçacığı, döngü içinde aşağıdaki işlemleri gerçekleştirir:

  1. /sys/power/wakeup_count adlı kullanıcının mesajını okuyun.
  2. Karşılıklı dışlama nesnesini edinin. Bu, askıya alma iş parçacığının, ana iş parçacığı sayacı artırmaya veya azaltmaya çalışırken askıya alma sayacına dokunmamasını sağlar. Askıya alma sayacı sıfıra ulaştığında ve askıya alma iş parçacığı çalışmaya çalıştığında ana iş parçacığı, uyandırma kilitleri verilirken veya kaldırılırken engellenir.
  3. Sayaç sıfıra eşit olana kadar bekleyin.
  4. /sys/power /wakeup_count'dan (1. adım) okunan değeri bu dosyaya yazın. Yazma işlemi başarısız olursa döngünün başına dönün.
  5. mem yazarak sistemi askıya alma işlemini başlatın. /sys/power/state
  6. Karşılıklı dışlama kilidini serbest bırakın.

Uyandırma kilidi isteği başarıyla döndürüldüğünde askıya alma iş parçacığı engellenir.

1. şekil. İş parçacığı döngüsünü askıya alma

SystemSuspend API

SystemSuspend API iki arayüzden oluşur. HIDL arayüzü, yerel işlemler tarafından uyandırma kilitleri almak için kullanılır. AIDL arayüzü ise SystemServer ile SystemSuspend arasındaki iletişim için kullanılır.

ISystemSuspend HIDL arayüzü


enum WakeLockType : uint32_t {
    PARTIAL,
    FULL
};

interface IWakeLock {
    oneway release();
};

interface ISystemSuspend {
    acquireWakeLock(WakeLockType type, string debugName)
        generates (IWakeLock lock);
};

Uyandırma kilidi isteyen her istemci, benzersiz bir IWakeLock örneği alır. Bu, /sys/power/wake_lock özelliğinden farklıdır. Bu özellik, birden fazla istemcinin aynı ad altında uyanık kalma kilidini kullanmasına olanak tanır. IWakeLock örneği barındıran bir istemci sonlandırılırsa bağlayıcı sürücü ve SystemSuspend hizmeti bunu temizler.

ISuspendControlService AIDL arayüzü

ISuspendControlService yalnızca SystemServer tarafından kullanılmak üzere tasarlanmıştır.


interface ISuspendCallback {
     void notifyWakeup(boolean success);
}

interface ISuspendControlService {
    boolean enableAutosuspend();
    boolean registerCallback(ISuspendCallback callback);
    boolean forceSuspend();
}

Android HIDL'den yararlanmak aşağıdaki avantajları sunar:

  • Askıya alma işlemini engelleyen bir işlem sonlanırsa SystemSuspend bilgilendirilebilir.
  • Sistemin askıya alınmasından sorumlu iş parçacığına geri çağırma verilebilir.