现在我们otg连接设备的时候有点亮屏幕的需求。
解决方法我们可以在识别设备的时候,去调用PowerManager的wakeup唤醒(点亮)设备。
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
int32_t deviceId = rawEvent->deviceId;
while (batchSize < count) {
if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
|| rawEvent[batchSize].deviceId != deviceId) {
break;
}
batchSize += 1;
}
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
addDeviceLocked(rawEvent->when, rawEvent->deviceId);//识别设备后添加设备到链表保存
break;
case EventHubInterface::DEVICE_REMOVED:
removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
handleConfigurationChangedLocked(rawEvent->when);
break;
default:
ALOG_ASSERT(false); // can't happen
break;
}
}
count -= batchSize;
rawEvent += batchSize;
}
}
所以我们可以在addDeviceLocked中唤醒设备
void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex >= 0) {
ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
return;
}
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
device->configure(when, &mConfig, 0);
device->reset(when);
if (device->isIgnored()) {
ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
identifier.name.string());
} else {
ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
identifier.name.string(), device->getSources());
}
//when add the device to notify wakeup device.
mPolicy->notifyWakeUpDevice(when);//这里是我们添加的用来唤醒设备
mDevices.add(deviceId, device);
bumpGenerationLocked();
if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
notifyExternalStylusPresenceChanged();
}
}
上面mPolicy实际上是NativeInputManager,所以调用了NativeInputManager的notifyWakeUpDevice,这个函数是我们自己添加的
//notify PhoneWindowManager to wakeup the device.
void NativeInputManager::notifyWakeUpDevice(nsecs_t when) {
uint32_t policyFlags = 0;
policyFlags |= POLICY_FLAG_TRUSTED;
policyFlags |= POLICY_FLAG_WAKE;
JNIEnv* env = jniEnv();
jint wmActions = env->CallIntMethod(mServiceObj,//调用了PhoneWindowManager的interceptMotionBeforeQueueingNonInteractive
gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
when, policyFlags);
checkAndClearExceptionFromCallback(env,
"interceptMotionBeforeQueueingNonInteractive");
}
这个函数主要调用了PhoneWindowManager的interceptMotionBeforeQueueingNonInteractive函数,本来这个函数是在notfifyMotion中调用的,是有Motion事件,比如鼠标按键事件,用来唤醒(点亮)设备的我们来看下这个函数。
@Override
public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
if ((policyFlags & FLAG_WAKE) != 0) {
if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion,
"android.policy:MOTION")) {
return 0;
}
}
if (shouldDispatchInputWhenNonInteractive()) {
return ACTION_PASS_TO_USER;
}
// If we have not passed the action up and we are in theater mode without dreaming,
// there will be no dream to intercept the touch and wake into ambient. The device should
// wake up in this case.
if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming,
"android.policy:MOTION");
}
return 0;
}
这个函数主要调用了wakeup来唤醒设备,这个wakeup最终会调用PowerManager的wakeup函数。
因此我们现在借用了原先有motion事件,用来点亮屏幕的函数。在识别设备的时候,调用这个函数也点亮屏幕。