포럼 회원으로 등록하신분만 다운로드가 가능합니다. 최대 업로드 가능한 용량은 20MB 입니다.

요청하신 분이 계셔서.....메일로 보낸 내용을 간단하게 다시 올립니다.


아주 자세한 내용은 아니지만, 간단하게나마 대략 아실 수 있을겁니다.


========================================================================


일단 input관련해서 간단하게 EventHub.cpp까지 정리된 자료를 보냅니다.

PhoneWindowManager.java관련은 간단하게만 설명드리겠습니다.

==========================================

0. Event를 받아오는 쪽은 첨부 파일을 보시고요.

1. PhoneWindowManager.java를 일단 open하시고요

mLidOpen 이란 변수를 보시기 바랍니다.
이 변수를 추적하면

다음과 같은 함수가 먼저 나올겁니다.

    void readLidState() {
        try {
            int sw = mWindowManager.getSwitchState(SW_LID);
            if (sw >= 0) {
                mLidOpen = sw == 0;
            }
        } catch (RemoteException e) {
            // Ignore
        }
    }

이 함수는 WindowManager에서부터 getSwitchState함수를 이용해서 SW_LID를 읽어옵니다.

이 함수는 결국은 EventHub.cpp에서도 동일한 함수가 있습니다.

int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
#ifdef EV_SW
    if (sw >= 0 && sw <= SW_MAX) {
        AutoMutex _l(mLock);

        device_t* device = getDeviceLocked(deviceId);
        if (device != NULL) {
            return getSwitchStateLocked(device, sw);
        }
    }
#endif
    return AKEY_STATE_UNKNOWN;
}

이 함수에서 해당 값을 읽어서 WindowManager쪽으로 건네주는 역할을 합니다.

2. mLidOpen 변수가 사용되는 부분은 다음과 같습니다.

    public int rotationForOrientationLw(int orientation, int lastRotation,
            boolean displayEnabled) {

        if (mPortraitRotation < 0) {
            // Initialize the rotation angles for each orientation once.
            Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                    .getDefaultDisplay();
            if (d.getWidth() > d.getHeight()) {
                mPortraitRotation = Surface.ROTATION_90;
                mLandscapeRotation = Surface.ROTATION_0;
                mUpsideDownRotation = Surface.ROTATION_270;
                mSeascapeRotation = Surface.ROTATION_180;
            } else {
                mPortraitRotation = Surface.ROTATION_0;
                mLandscapeRotation = Surface.ROTATION_90;
                mUpsideDownRotation = Surface.ROTATION_180;
                mSeascapeRotation = Surface.ROTATION_270;
            }
        }

        synchronized (mLock) {
            switch (orientation) {
                case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
                    //always return portrait if orientation set to portrait
                    return mPortraitRotation;
                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
                    //always return landscape if orientation set to landscape
                    return mLandscapeRotation;
                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
                    //always return portrait if orientation set to portrait
                    return mUpsideDownRotation;
                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
                    //always return seascape if orientation set to reverse landscape
                    return mSeascapeRotation;
                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
                    //return either landscape rotation based on the sensor
                    mOrientationListener.setAllow180Rotation(
                            isLandscapeOrSeascape(Surface.ROTATION_180));
                    return getCurrentLandscapeRotation(lastRotation);
                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
                    mOrientationListener.setAllow180Rotation(
                            !isLandscapeOrSeascape(Surface.ROTATION_180));
                    return getCurrentPortraitRotation(lastRotation);
            }

            mOrientationListener.setAllow180Rotation(
                    orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

            // case for nosensor meaning ignore sensor and consider only lid
            // or orientation sensor disabled
            //or case.unspecified
            if (mLidOpen) {  //============================================================> 여기서 checking
                return mLidOpenRotation;
            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
                return mCarDockRotation;
            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
                return mDeskDockRotation;
            } else {
                if (useSensorForOrientationLp(orientation)) {
                    return mOrientationListener.getCurrentRotation(lastRotation);
                }
                return Surface.ROTATION_0;
            }
        }
    }

이 함수는 화면 rotation을 처리하는 함수입니다.

모든 app는 이 함수에 물어봐서 현재의 rotation상태를 결정하는 함수입니다.

이 때 mLidOpen 이란 변수를 가지고 적절하게, 회전 상태를 결정하게 되는 데........
이게 Motorola droid 폰이나 HTC G1 phone의 qwerty 자판의 slide와 연결되어 있는 변수입니다.

즉, 뚜껑이 열렸느냐 아니냐에 따라 화면 회전을 결정하는 것입니다.


고도리

2011.08.02 09:40:25
*.200.239.234

mLidOpen 변수는 kernel의 input device 중 EV_SW type 특성을 갖는 드라이버에서 SW_LID란 event가 올라오게 되면 set이 되는 것입니다.

kjbf15

2011.08.02 22:40:31
*.94.41.89

감사합니다 ^^

InputDispatcher 단에서 ViewRoot로 이벤트 처리과정에서 InputPublisher와 InputConsumer를 이용한다는걸

겨우 분석했네요 ㅜㅜ 정말 단순 소스코드 분석은 쉬운 일이 아닌듯합니다.

알려주신 자료는 WindowManager, PhoneWindowManager 부분 분석에 많은 도움이 되었습니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수

사용자 로그인