Android 9 ve önceki sürümlerde, sistemin askıya alınmasını başlatmaktan sorumlu bir mesaj dizisi libsuspend içinde bulunur. 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 yayınlanır.
libsuspend
'teki mantık büyük ölçüde aynı kalır. Bununla birlikte, sistem askıya alma işlemini engelleyen her kullanıcı alanı işleminin SystemSuspend ile iletişim kurması gerekir.
libsuspend ve libpower
Android 10'da SystemSuspend hizmeti, libsuspend
hizmetinin yerini alır. libpower
, C API'si değiştirilmeden /sys/power/wake[un]lock
yerine SystemSuspend hizmetini kullanacak şekilde yeniden uygulandı.
Bu sözde kodda, acquire_wake_lock
ve release_wake_lock
işlevlerinin 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 mesaj dizileri
SystemSuspend hizmeti, askıya alma sayacı ile verilen uyanma kilitlerinin sayısını izler. İki yürütme iş parçacığı vardır:
- Ana ileti dizisi, bağlayıcı çağrılarını yanıtlar.
- suspend mesaj dizisi, sistemin askıya alınmasını kontrol eder.
Ana iş parçacığı
Ana mesaj dizisi, istemcilerden gelen yeni uyanma kilidi ayırma isteklerini yanıtlayarak askıya alma sayacını artırır/azaltır.
Mesaj dizisini askıya alma
Askıya alma iş parçacığı, bir döngüde aşağıdakileri gerçekleştirir:
/sys/power/wakeup_count
'ten okuyun.- Müşteriye özel kilidi alın. Bu sayede, ana iş parçacığı askıya alma sayacını artırmaya veya azaltmaya çalışırken askıya alma iş parçacığı bu sayaca dokunmaz. Askıya alma sayacı sıfıra ulaştığında ve askıya alma iş parçacığı çalışmaya çalışırken ana iş parçacığı, uyanma kilitleri verirken veya kaldırırken engellenir.
- Sayaç sıfıra eşit olana kadar bekleyin.
/sys/power /wakeup_count
(1. adımdan) okunan değeri bu dosyaya yazın. Yazma işlemi başarısız olursa döngünün başına dönün./sys/power/state
adresinemem
yazarak sistemi askıya alma işlemini başlatın.- Müşteriye özel kilidi bırakın.
Bir uyanma kilidi isteği başarıyla döndürüldüğünde askıya alma iş parçacığı engellenir.
SystemSuspend API
SystemSuspend API iki arayüzden oluşur. HIDL arayüzü, yerel işlemler tarafından uyanık kalma kilitleri alınırken, AIDL arayüzü ise SystemServer ile Systemsuspended arasındaki iletişim için kullanılır.
ISystemsuspended 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, birden fazla istemcinin aynı ad altında uyanık kalma kilidini kullanmasına izin veren /sys/power/wake_lock
ürününden farklıdır. IWakeLock
örneğini tutan bir istemci sonlandırılırsa bağlayıcı sürücüsü ve SystemSuspend hizmeti bu örneği temizler.
ISuspendControlService AIDL arayüzü
IsuspendedControlService 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 yararlanma şu avantajları sağlar:
- Askıya alma işlemini engelleyen bir işlem sona ererse Systemsuspended bilgilendirilebilir.
- Sistem askıya alma işleminden sorumlu olan ileti dizisine geri çağırma çağrısı verilebilir.