___2017

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  328 随笔 :: 18 文章 :: 15 评论 :: 18万 阅读
1
2
3
4
5
6
7
受不了xxxx恶心人的行为,遂搬迁至博客园。
始发:2016-12-16 13:08:47
 
 
版本信息:
Linux:3.10
Android: 4.4

 

Android休眠在framework的处理涉及两个系统服务,InputManagerService和PowerManagerService。InputManagerService负责处理PowerKey产生的Input事件,根据事件类型调用PowerManagerService的休眠、唤醒接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
        uint32_t& policyFlags) {
    if (wmActions & WM_ACTION_GO_TO_SLEEP) {
        ALOGD("handleInterceptActions: Going to sleep.");
        android_server_PowerManagerService_goToSleep(when);
    }
  
    if (wmActions & WM_ACTION_WAKE_UP) {
        ALOGD("handleInterceptActions: Waking up.");
        android_server_PowerManagerService_wakeUp(when);
    }
  
    if (wmActions & WM_ACTION_PASS_TO_USER) {
        policyFlags |= POLICY_FLAG_PASS_TO_USER;
    }
}

 

PowerManagerService执行具体的休眠、唤醒动作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private void goToSleepInternal(long eventTime, int reason) {
        Slog.i(TAG, "goToSleepInternal, reason: " + reason);
        synchronized (mLock) {
            if (goToSleepNoUpdateLocked(eventTime, reason)) {
                updatePowerStateLocked();
            }
        }
    }
}
  
private void updatePowerStateLocked() {
    // Phase 0: Basic state updates.
  
    // Phase 1: Update wakefulness.
    // Loop because the wake lock and user activity computations are influenced
    // by changes in wakefulness.
  
    // Phase 2: Update dreams and display power state.
  
    // Phase 3: Send notifications, if needed.
  
    // Phase 4: Update suspend blocker.
    // Because we might release the last suspend blocker here, we need to make sure
    // we finished everything else first!
    updateSuspendBlockerLocked();
}

 

它们之间关系如下图:

由于这两个服务涉及framework最核心的功能且其代码实现繁复,这里只贴出其处理流程,具体细节其他篇幅再续。本篇目的:始知此事要躬行,如果有意弄清流程,提供一个参照。

1、InputManagerService服务加载:

1
2
3
4
SystemServer.java (frameworks\base\services\java\com\android\server)
InputManagerService inputManager = null;
inputManager = new InputManagerService(context, wmHandler);
inputManager.start();

 

2、InputManagerService Java:

1
2
3
4
5
6
InputManagerService.java (frameworks\base\services\java\com\android\server\input)
public class InputManagerService {
    public InputManagerService(Context context, Handler handler) {
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
    }
}

 

3、InputManagerService的JNI:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
com_android_server_input_InputManagerService.cpp (frameworks\base\services\jni)
static jint nativeInit(JNIEnv* env, jclass clazz,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
     
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jint>(im);
}
  
NativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper) {
    mInputManager = new InputManager(eventHub, this, this);
}

 

4、Input事件的Manager:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
InputManager.cpp (frameworks\base\services\input)
InputManager::InputManager(
        const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
    initialize();
}
  
// InputReaderThread:事件读取
// InputDispatcherThread:事件分发
void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
  
status_t InputManager::start() {
    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    return OK;
}

  

5,事件读取、分发:

1
2
3
4
5
6
7
8
9
InputReader.cpp (frameworks\base\services\input)
InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
        Thread(/*canCallJava*/ true), mReader(reader) {
}
  
InputDispatcher.cpp (frameworks\base\services\input)
InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
}

 

6、PowerKey事件上报:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
InputReader.cpp (frameworks\base\services\input)
void InputReader::loopOnce() {
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
    { // acquire lock
        AutoMutex _l(mLock);
  
        if (count) {
            processEventsLocked(mEventBuffer, count);
        }
    } // release lock
}
  
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    int32_t type = rawEvent->type;
       size_t batchSize = 1;
    if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
        ALOGD("BatchSize: %d Count: %d", batchSize, count);
        processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
    }
}
  
void InputReader::processEventsForDeviceLocked(int32_t deviceId,
        const RawEvent* rawEvents, size_t count) {
  
    InputDevice* device = mDevices.valueAt(deviceIndex);
    device->process(rawEvents, count);
}
  
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    ALOGD("InputDevice::process");
    size_t numMappers = mMappers.size();
    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
                rawEvent->when);
        if (mDropUntilNextSync) {
           
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            
        } else {
            ALOGD("InputDevice::process else");
            for (size_t i = 0; i < numMappers; i++) {
                InputMapper* mapper = mMappers[i];
                mapper->process(rawEvent);
            }
        }
    }
}
  
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
    ALOGI("KeyboardInputMapper::process");
    switch (rawEvent->type) {
    case EV_KEY: {// #define EV_KEY                  0x01
        int32_t scanCode = rawEvent->code;
        int32_t usageCode = mCurrentHidUsage;
        mCurrentHidUsage = 0;
  
        if (isKeyboardOrGamepadKey(scanCode)) {
            int32_t keyCode;
            uint32_t flags;
  
            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
        }
        break;
    }
    }
}
  
  
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
        int32_t scanCode, uint32_t policyFlags) {
    // processkey, down=1, keyCode=26, policyFlags=1
    ALOGI("processkey, down=%d, keyCode=%d, policyFlags=%d, ", down, keyCode, policyFlags);
    if (down) {
        // Rotate key codes according to orientation if needed.
    }
  
    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
    getListener()->notifyKey(&args);
}
  
InputListener.cpp (frameworks\base\services\input)
void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
    ALOGD("notify");
    listener->notifyKey(this);
}

  

7、构建KeyEvent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
InputDispatcher.cpp (frameworks\base\services\input)
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
            args->eventTime, args->deviceId, args->source, args->policyFlags,
            args->action, args->flags, args->keyCode, args->scanCode,
            args->metaState, args->downTime);
  
    if (!validateKeyEvent(args->action)) {
        return;
    }
  
    uint32_t policyFlags = args->policyFlags;
    int32_t flags = args->flags;
    int32_t metaState = args->metaState;
  
    KeyEvent event;
    event.initialize(args->deviceId, args->source, args->action,
            flags, args->keyCode, args->scanCode, metaState, 0,
            args->downTime, args->eventTime);
  
    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
}

  

8、KeyEvent处理并调用PowerManagerService的休眠接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
com_android_server_input_InputManagerService.cpp (frameworks\base\services\jni)
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
    ALOGD("interceptKeyBeforeQueueing: policyFlags = %d\n", policyFlags);
    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
        nsecs_t when = keyEvent->getEventTime();
        bool isScreenOn = this->isScreenOn();
        bool isScreenBright = this->isScreenBright();
  
        JNIEnv* env = jniEnv();
        jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
        jint wmActions;
        if (keyEventObj) {
            wmActions = env->CallIntMethod(mServiceObj,
                    gServiceClassInfo.interceptKeyBeforeQueueing,
                    keyEventObj, policyFlags, isScreenOn);
            if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
                wmActions = 0;
            }
            android_view_KeyEvent_recycle(env, keyEventObj);
            env->DeleteLocalRef(keyEventObj);
        }
         
        handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
    }
}
  
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
        uint32_t& policyFlags) {
    if (wmActions & WM_ACTION_GO_TO_SLEEP) {
        ALOGD("handleInterceptActions: Going to sleep.");
        android_server_PowerManagerService_goToSleep(when);
    }
  
    if (wmActions & WM_ACTION_WAKE_UP) {
        ALOGD("handleInterceptActions: Waking up.");
        android_server_PowerManagerService_wakeUp(when);
    }
  
    if (wmActions & WM_ACTION_PASS_TO_USER) {
        policyFlags |= POLICY_FLAG_PASS_TO_USER;
    } else {
        ALOGD("handleInterceptActions: Not passing key to user.");
    }
}
  
com_android_server_power_PowerManagerService.cpp (frameworks\base\services\jni)
void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) {
    if (gPowerManagerServiceObj) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
  
        env->CallVoidMethod(gPowerManagerServiceObj,
                gPowerManagerServiceClassInfo.goToSleepFromNative,
                nanoseconds_to_milliseconds(eventTime), 0);
        checkAndClearExceptionFromCallback(env, "goToSleepFromNative");
    }
}

 

9、由于是从PowerKey发起休眠/唤醒动作,所以使用的是goToSleepFromNative:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
PowerManagerService.java (frameworks\base\services\java\com\android\server\power)
private void goToSleepFromNative(long eventTime, int reason) {
    Slog.i(TAG, "goToSleepFromNative, reason: " + reason);
    if (reason != PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN
        && reason != PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) {
        if (mDisplayManager.isWfdConnect()) {
            mHandler.sendEmptyMessage(MSG_DISABLE_WIFI_FOR_WIFIP2P);
            return;
        }
    }
    goToSleepInternal(eventTime, reason);
}
 
private void goToSleepInternal(long eventTime, int reason) {
        Slog.i(TAG, "goToSleepInternal, reason: " + reason);
        synchronized (mLock) {
            if (goToSleepNoUpdateLocked(eventTime, reason)) {
                updatePowerStateLocked();
            }
        }
    }
}
 
/**
 * This is the main function that performs power state transitions.
 * We centralize them here so that we can recompute the power state completely
 * each time something important changes, and ensure that we do it the same
 * way each time.  The point is to gather all of the transition logic here.
 */
private void updatePowerStateLocked() {
    // Phase 0: Basic state updates.
  
    // Phase 1: Update wakefulness.
    // Loop because the wake lock and user activity computations are influenced
    // by changes in wakefulness.
  
    // Phase 2: Update dreams and display power state.
  
    // Phase 3: Send notifications, if needed.
  
    // Phase 4: Update suspend blocker.
    // Because we might release the last suspend blocker here, we need to make sure
    // we finished everything else first!
    updateSuspendBlockerLocked();
}

 

10、PowerManagerService执行休眠,对了,就是释放锁:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * Updates the suspend blocker that keeps the CPU alive.
 */
private void updateSuspendBlockerLocked() {
    final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
    final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker();
  
    // First acquire suspend blockers if needed.
    if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
        mWakeLockSuspendBlocker.acquire();
        mHoldingWakeLockSuspendBlocker = true;
    }
    if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
        mDisplaySuspendBlocker.acquire();
        mHoldingDisplaySuspendBlocker = true;
    }
  
    // Then release suspend blockers if needed.
    if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
        mWakeLockSuspendBlocker.release();
        mHoldingWakeLockSuspendBlocker = false;
    }
    if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
        mDisplaySuspendBlocker.release();
        mHoldingDisplaySuspendBlocker = false;
    }
}

 

至于锁释放是如何和内核交互的,参见:【Android休眠】之休眠锁的获取和释放

posted on   yin'xiang  阅读(686)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示