[PointerIcon]
이번편은 PointerIcon을 어떻게 변경시키는지 동작에 대해 알아보려 한다. 연관 파일
- PointerController.cpp
- MouseCursorController.cpp
- com_android_server_input_InputManagerService.cpp
- InputManagerService.java
Icon Resource들을 load하는 부분.
loadPointerIcon loadPointerResources loadAdditionalMouseResources
먼저 PointerIcon을 사용하기 위해 view에서 Resocure들을 native로 가져오는 선행작업들.
앱단에서 PointerIcon 변경 위해 호출하면서 시작 setPointerIconType(int iconId).
1.InputManager.java
public void setPointerIconType(int iconId) {
try {
mIm.setPointerIconType(iconId);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
2. InputManagerService.java
// Binder call
@Override
public void setPointerIconType(int iconId) {
nativeSetPointerIconType(mPtr, iconId);
}
3. com_android_server_input_InputManagerService.cpp (setPointerIconType)
void NativeInputManager::setPointerIconType(int32_t iconId) {
AutoMutex _l(mLock);
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
controller->updatePointerIcon(iconId);
}
}
4. PointerController.cpp (updatePointerIcon)
void PointerController::updatePointerIcon(int32_t iconId) {
std::scoped_lock lock(mLock);
mCursorController.updatePointerIcon(iconId);
}
5. MouseCursorController.cpp (updatePointerIcon)
void MouseCursorController::updatePointerIcon(int32_t iconId) {
std::scoped_lock lock(mLock);
// iconId가 변경되었으면 update
if (mLocked.requestedPointerType != iconId) {
mLocked.requestedPointerType = iconId;
mLocked.updatePointerIcon = true;
updatePointerLocked();
}
}
6. MouseCursorController.cpp (updatePointerLocked)
void MouseCursorController::updatePointerLocked() REQUIRES(mLock) {
if (!mLocked.viewport.isValid()) {
return;
}
sp<SpriteController> spriteController = mContext.getSpriteController();
spriteController->openTransaction();
mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
mLocked.pointerSprite->setDisplayId(mLocked.viewport.displayId);
if (mLocked.pointerAlpha > 0) {
mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
mLocked.pointerSprite->setVisible(true);
} else {
mLocked.pointerSprite->setVisible(false);
}
// updatePointerIcon을 true인 상태로 와야 변경이 됨.
/*
mLocked.updatePointerIcon = true 시켜주는 부분.
1. updatePointerIcon(int32_t iconId)
2. setCustomPointerIcon(const SpriteIcon& icon)
3. loadResourcesLocked(bool getAdditionalMouseResources)
4. getAdditionalMouseResources
*/
// additionalMouseResources는 IMS_JNI보면 처음에 모든 리소스를 다 로드해놓음.
// 요청값이 기본값이라면 mLocked.pointerIcon로 바로 set해주고 아니라면 리소스에서 찾아서 셋해줌.
if (mLocked.updatePointerIcon) {
if (mLocked.requestedPointerType == mContext.getPolicy()->getDefaultPointerIconId()) {
mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
} else {
std::map<int32_t, SpriteIcon>::const_iterator iter =
mLocked.additionalMouseResources.find(mLocked.requestedPointerType);
if (iter != mLocked.additionalMouseResources.end()) {
std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
mLocked.animationResources.find(mLocked.requestedPointerType);
if (anim_iter != mLocked.animationResources.end()) {
mLocked.animationFrameIndex = 0;
mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
startAnimationLocked();
}
mLocked.pointerSprite->setIcon(iter->second);
} else {
ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerType);
mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
}
}
mLocked.updatePointerIcon = false;
}
spriteController->closeTransaction();
}