안드로이드 휴면 프로세스의 한 가지 이해
@Override
public void onDisplayStateChange(int state) {
// This method is only needed to support legacy display blanking behavior
// where the display's power state is coupled to suspend or to the power HAL.
// The order of operations matters here.
synchronized (mLock) {
if (mDisplayState != state) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(false);
}
if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
} else {
if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(false);
}
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(true);
}
}
}
}
}
우리 회사의 방안에서는 기본적으로 결합되지 않는 방안이다.그래서 업데이트 PowerState Locked update Suspend Blocker Locked();그곳에서는 휴면 프로세스를 시작하지 않고 디스플레이 state에서change가 발생할 때 디스플레이 상태와 연결됩니다.false
false
2. setHal AutoSuspend Mode Locked는 시스템이 즉시 휴면에 들어가는지 제어할 수 없습니다. 휴면에 들어가는지 깨우는지 여부는 다른native Acquire Suspend Blocker와native Release Suspend Blocker가 Suspend Blocker를 방출하는지 여부에 따라 결정됩니다.함수 이름에서 말한 바와 같이 이것은 1급 제어 스위치입니다. enable or disable, enable가 있어야 휴면을 할 수 있습니다./sys/power/state에서 응용층이 설정한 지원 가능한 휴면 모드입니다. 현재 p의gtvs버전은 항상freeze mem입니다.
static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (enable) {
android::base::Timer t;
autosuspend_enable();
if (t.duration() > 100ms) {
ALOGD("Excessive delay in autosuspend_enable() while turning screen off");
}
} else {
android::base::Timer t;
autosuspend_disable();
if (t.duration() > 100ms) {
ALOGD("Excessive delay in autosuspend_disable() while turning screen on");
}
}
}
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}
static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
release_wake_lock(name.c_str());
}
3.native Acquire Suspend Blocker와native Release Suspend Blocker.BlockSuspender aquire와release에서 이 두 jni의 함수를 호출하고 그 안에서 Hardware/libhardware 를 통과합니다legacy/power.c에 있는 두 개의 광범위한 함수 acquirewake_lock 및 releasewake_lock, 대응하는suspender의 이름을/sys/power/wake 에 쓰기lock 및/sys/power/wakeunlock 안에서 kernel이 상응하는 깨우기와 수면 동작을 모니터링합니다.이전에는 응용층이 계수의 효과일 뿐이라고 오해했다. 이 BlockSuspender는 실제로kernel이 사용자 상태에 개방된 노드를 직접 제어할 수 있다는 것을 무시했다. 처음에 봤을 때도 이 뚜렷한 PMS를 쓴 자물쇠의 위치를 찾지 못했다.
@Override
public void acquire() {
synchronized (this) {
mReferenceCount += 1;
if (mReferenceCount == 1) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
}
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
nativeAcquireSuspendBlocker(mName);
}
}
}
@Override
public void release() {
synchronized (this) {
mReferenceCount -= 1;
if (mReferenceCount == 0) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
}
nativeReleaseSuspendBlocker(mName);
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
} else if (mReferenceCount < 0) {
Slog.wtf(TAG, "Suspend blocker \"" + mName
+ "\" was released without being acquired!", new Throwable());
mReferenceCount = 0;
}
}
}
enum {
ACQUIRE_PARTIAL_WAKE_LOCK = 0,
RELEASE_WAKE_LOCK,
OUR_FD_COUNT
};
const char * const OLD_PATHS[] = {
"/sys/android_power/acquire_partial_wake_lock",
"/sys/android_power/release_wake_lock",
};
const char * const NEW_PATHS[] = {
"/sys/power/wake_lock",
"/sys/power/wake_unlock",
};
int
acquire_wake_lock(int lock, const char* id)
{
initialize_fds();
// ALOGI("acquire_wake_lock lock=%d id='%s'
", lock, id);
if (g_error) return g_error;
int fd;
ssize_t ret;
if (lock != PARTIAL_WAKE_LOCK) {
return -EINVAL;
}
fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
ret = write(fd, id, strlen(id));
if (ret < 0) {
return -errno;
}
return ret;
}
int
release_wake_lock(const char* id)
{
initialize_fds();
// ALOGI("release_wake_lock id='%s'
", id);
if (g_error) return g_error;
ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));
if (len < 0) {
return -errno;
}
return len;
}
4. setHalAutoSuspendModeLocked에서 아래로 내려가면 시스템/core/libsuspend 아래로 이동합니다.enable 및 disable 최종 대응 autosuspend_wakeup_count.cpp 내 autosuspendwakeup_count_enable 및 autosuspendwakeup_count_disable 함수.이 안은 신호량을 통해 동기 스위치를 제어하는 것이고, enable는sempost Wake 열기count의 쓰기 제어,disable는semwait가 막혔습니다.enable에서mem을/sys/power/state에 쓰고sys/power/wakeupcount를 읽고 다시 써도 왜 그런지 모르겠어요.
static int autosuspend_wakeup_count_enable(void) {
LOG(VERBOSE) << "autosuspend_wakeup_count_enable";
int ret = autosuspend_init();
if (ret < 0) {
LOG(ERROR) << "autosuspend_init failed";
return ret;
}
ret = sem_post(&suspend_lockout);
if (ret < 0) {
PLOG(ERROR) << "error changing semaphore";
}
LOG(VERBOSE) << "autosuspend_wakeup_count_enable done";
return ret;
}
static int autosuspend_wakeup_count_disable(void) {
LOG(VERBOSE) << "autosuspend_wakeup_count_disable";
if (!autosuspend_is_init) {
return 0; // always successful if no thread is running yet
}
int ret = sem_wait(&suspend_lockout);
if (ret < 0) {
PLOG(ERROR) << "error changing semaphore";
}
LOG(VERBOSE) << "autosuspend_wakeup_count_disable done";
return ret;
}
LOG(VERBOSE) << "wait";
int ret = sem_wait(&suspend_lockout);
if (ret < 0) {
PLOG(ERROR) << "error waiting on semaphore";
continue;
}
LOG(VERBOSE) << "write " << wakeup_count << " to wakeup_count";
if (WriteStringToFd(wakeup_count, wakeup_count_fd)) {
LOG(VERBOSE) << "write " << sleep_state << " to " << sys_power_state;
success = WriteStringToFd(sleep_state, state_fd);
void (*func)(bool success) = wakeup_func;
if (func != NULL) {
(*func)(success);
}
} else {
PLOG(ERROR) << "error writing to " << sys_power_wakeup_count;
}
LOG(VERBOSE) << "release sem";
ret = sem_post(&suspend_lockout);
5. 위 절차에서 휴면할 때 장치 노드/sys/power/state에mem를 쓰는 작업을 완성했고kernel에 이 장치 노드에 대한 작업 함수를 등록했습니다.후속 각성원의 조건이 충족되면 휴면에 들어갈 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.