[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# SystemSuspend service\n\nIn Android 9 and lower there is a thread in [libsuspend](https://android.googlesource.com/platform/system/core/+/pie-dev/libsuspend/autosuspend_wakeup_count.cpp#65)\nresponsible for initiating system suspend. Android 10\nintroduces an equivalent functionality in a SystemSuspend HIDL service.\nThis service is located in the system image and is served by the Android platform.\nThe logic from `libsuspend` remains largely the same, except every userspace\nprocess blocking the system suspend needs to communicate with SystemSuspend.\n\nlibsuspend and libpower\n-----------------------\n\nIn Android 10, SystemSuspend service replaces\n`libsuspend`. `libpower` was reimplemented to rely on\nthe SystemSuspend service instead of\n`/sys/`**power**`/wake[un]lock`\nwithout changing the C API.\n\nThis pseudocode shows how to implement `acquire_wake_lock`\nand `release_wake_lock`. \n\n\n static std::unordered_map\u003cstd::string, sp\u003cIWakeLock\u003e\u003e gWakeLockMap;\n\n int acquire_wake_lock(int, const char* id) {\n ...\n if (!gWakeLockMap[id]) {\n gWakeLockMap[id] = suspendService-\u003eacquireWakeLock(WakeLockType::PARTIAL, id);\n }\n ...\n return 0;\n }\n\n int release_wake_lock(const char* id) {\n ...\n if (gWakeLockMap[id]) {\n auto ret = gWakeLockMap[id]-\u003erelease();\n gWakeLockMap[id].clear();\n return 0;\n }\n ...\n return -1;\n }\n\nExecution threads\n-----------------\n\nThe SystemSuspend service keeps track of the number of wake locks issued with\na suspend counter. It has two threads of execution:\n\n- The **main** thread answers binder calls.\n- The **suspend** thread controls system suspend.\n\n### Main thread\n\nThe main thread answers requests from clients to allocate new wake locks,\nincrementing/decrementing the suspend counter.\n\n### Suspend thread\n\nThe suspend thread performs the following in a loop:\n\n1. Read from `/sys/`**power**`/wakeup_count`.\n2. Acquire the mutex. This makes sure that the suspend thread doesn't touch the suspend counter while the **main** thread is trying to increment or decrement it. The **main** thread is blocked on issuing or removing wake locks when the suspend counter has reached zero and the **suspend** thread is trying to run.\n3. Wait until the counter is equal to zero.\n4. Write the value read from `/sys/`**power**`/wakeup_count` (from step 1) to this file. If the write fails, return to the beginning of the loop\n5. Start the system suspend by writing `mem` to `/sys/power/`**state**.\n6. Release the mutex.\n\nWhen a request for a wake lock successfully returns, the suspend thread is\nblocked.\n**Figure 1.** Suspend thread loop **Note:** The mutex is always released at the end of the loop iteration.\n\n### SystemSuspend API\n\nThe SystemSuspend API consists of two interfaces. The HIDL interface is used\nby native processes to acquire wake locks and the AIDL interface is used for\ncommunication between SystemServer and SystemSuspend.\n\n### ISystemSuspend HIDL interface\n\n\n enum WakeLockType : uint32_t {\n PARTIAL,\n FULL\n };\n\n interface IWakeLock {\n oneway release();\n };\n\n interface ISystemSuspend {\n acquireWakeLock(WakeLockType type, string debugName)\n generates (IWakeLock lock);\n };\n\nEach client that requests a wake lock receives a unique\n`IWakeLock` instance. This is different from\n`/sys/`**power**`/wake_lock`, which allows multiple\nclients to use the wake lock under the same name. If a client holding an\n`IWakeLock` instance terminates, the binder driver and\nSystemSuspend service cleans it up.\n\n### ISuspendControlService AIDL interface\n\nISuspendControlService is intended to be used only by SystemServer. \n\n\n interface ISuspendCallback {\n void notifyWakeup(boolean success);\n }\n\n interface ISuspendControlService {\n boolean enableAutosuspend();\n boolean registerCallback(ISuspendCallback callback);\n boolean forceSuspend();\n }\n\nLeveraging the Android HIDL offers the following benefits:\n\n- If a suspend-blocking process dies, SystemSuspend can be notified.\n- The thread responsible for system suspend can be given a callback."]]