Impact of Android 2.2 slide (LID)

Source: Internet
Author: User

Some time ago, the project encountered the problem that the press button light was not on. I looked at the Framework Code and found that the switch status of the slide had an impact on it.

Phonewindowmanager is defined as follows:

    boolean mLidOpen;

There is no initialization here, so it is false, and the hardware does not have a slide, so phonewindowmanager will not update mlidopen.

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

Here, mlidopen will not be updated, and input events will not be reported.

/** {@ Inheritdoc} */Public Boolean preprocessinputeventtq (rawinputevent event) {Switch (event. type) {Case rawinputevent. ev_sw: If (event. keycode = rawinputevent. sw_lid) {// lid changed state mlidopen = event. value = 0; Boolean awakenow = mkeyguardmediator. dow.changetq (mlidopen); updaterotation (surface. flags_orientation_animation_disable );//... partial Code omitted} return false ;}

Therefore, phonewindowmanager calls the setkeyboardvisibility of powermanagerservice.

/** {@ Inheritdoc} */Public void adjustconfigurationlw (configuration config) {read1_state (); Final Boolean lidopen =! Keyboard_always_hidden & mlidopen; mpowermanager. setkeyboardvisibility (lidopen); //... omitted code}

In powermanagerservice, the visible status of the keyboard is determined based on the slide status.

Public void setkeyboardvisibility (Boolean visible) {synchronized (mlocks) {If (mkeyboardvisible! = Visible) {mkeyboardvisible = visible; //... omitted code }}}

That is to say, if the slide is not opened, the keyboard is invisible (anyone who uses the slide phone knows ).

What's terrible here is that powermanagerservice will decide not to turn on the keyboard Light Based on the visible state of the keyboard. Therefore, our Keyboard light will never turn on.

Private int applykeyboardstate (INT state) {int brightness =-1; if (! Mkeyboardvisible) {brightness = 0;} //... omitting some code}

Now let's look at it. We need to turn on the keyboard light, not the keyboard light. Now we have two lights and so on. There is a difference between the keyboard and the buttons. Android didn't consider the keyboard light. Therefore, we can only use the keyboard lamp as a pressing lamp.

The solution looks simple, that is, back to the source of the problem. In phonewindowmanager, The mlidopen value is initialized to true, so that it remains in the true state, the slider is always on, so the keyboard is only visible and the keyboard light is on.

However, the problem is far from that simple. Since this problem has been fixed, various sensors have become ineffective, and the sensors have just begun to be tuned, therefore, I don't know whether it is caused by changing this value.

1. When the gravity sensor detects a change in the direction, the system will call the rotationfororientationlw method of phonewindowmanager and then update the interface according to the angle.

Public int rotationfororientationlw (INT orientation, int lastrotation, Boolean displayenabled) {synchronized (mlock) {Switch (orientation) {Case activityinfo. screen_orientation_landscape: // always return landscape if orientation set to landscape return mlandscaperotation; Case activityinfo. outputs: // always return portrait if orientation set to portrait return mportraitrotation;} // case for nosensor meaning ignore sensor and consider only lid // or orientation sensor disabled/or case. unspecified if (mlidopen) {return mlidopenrotation ;}//... omitted code }}

Here, because the mlidopen remains in the true state, the screen Rotation Angle remains in the mlidopenrotation. The screen does not rotate as you go.

Mlidopenrotation is read in frameworks/base/CORE/RES/values/config. xml.

Therefore, we can lament how rigorous the android logic is. If you slide the cover and open it all the time, it means that there is a button operation. It is unreasonable to switch the screen at this time.

2. When a phone call is made, if the face is close to the screen, the sensor will turn off the screen backlight (power saving and Misoperation prevention). This is also a very user-friendly operation, but it will not be affected. In incallscreen

    /* package */ void updateProximitySensorMode(Phone.State state) {        if (proximitySensorModeEnabled()) {            synchronized (mProximityWakeLock) {                // turn proximity sensor off and turn screen on immediately if                // we are using a headset, the keyboard is open, or the device                // is being held in a horizontal position.                boolean screenOnImmediately = (isHeadsetPlugged()                            || PhoneUtils.isSpeakerOn(this)                            || ((mBtHandsfree != null) && mBtHandsfree.isAudioOn())                            || mIsHardKeyboardOpen                            || mOrientation != AccelerometerListener.ORIENTATION_VERTICAL);                if (((state == Phone.State.OFFHOOK) || mBeginningCall) && !screenOnImmediately) {                    // Phone is in use!  Arrange for the screen to turn off                    // automatically when the sensor detects a close object.                    if (!mProximityWakeLock.isHeld()) {                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");                        mProximityWakeLock.acquire();                    } else {                        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");                    }                }                        }        }    }

Here the mishardkeyboardopen will always be true, so it will not go to the acquire wake lock, so close to the screen will not turn out the backlight. It is worth noting that it is still dependent on morientation. It is aquire in the vertical direction, because it means that the call is received only when the call is raised.

Mishardkeyboardopen is assigned a value in onconfigurationchanged.

    @Override    public void onConfigurationChanged(Configuration newConfig) {        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {            mIsHardKeyboardOpen = true;        } else {            mIsHardKeyboardOpen = false;        }        // Update the Proximity sensor based on keyboard state        updateProximitySensorMode();        super.onConfigurationChanged(newConfig);    }

Therefore, the application layer determines whether the keyboard is visible Based on the hardkeyboardhidden in configuration.

This value is determined in phonewindowmanager,

    /** {@inheritDoc} */    public void adjustConfigurationLw(Configuration config) {        readLidState();        final boolean lidOpen = !KEYBOARD_ALWAYS_HIDDEN && mLidOpen;        mPowerManager.setKeyboardVisibility(lidOpen);        config.hardKeyboardHidden = determineHiddenState(lidOpen,                mLidKeyboardAccessibility, Configuration.HARDKEYBOARDHIDDEN_YES,                Configuration.HARDKEYBOARDHIDDEN_NO);        config.navigationHidden = determineHiddenState(lidOpen,                mLidNavigationAccessibility, Configuration.NAVIGATIONHIDDEN_YES,                Configuration.NAVIGATIONHIDDEN_NO);        config.keyboardHidden = (config.hardKeyboardHidden                        == Configuration.HARDKEYBOARDHIDDEN_NO || mHasSoftInput)                ? Configuration.KEYBOARDHIDDEN_NO                : Configuration.KEYBOARDHIDDEN_YES;    }

Therefore, powermanagerservice may be different from configuration for the keyboard status, depending on the return value of determinehiddenstate. determinehiddenstate determines the hardkeyboardhidden status based on the slide status and msf-keyboardaccessibility, And the handler reads the data

    <!-- Indicate whether the lid state impacts the accessibility of         the physical keyboard.  0 means it doesn't, 1 means it is accessible         when the lid is open, 2 means it is accessible when the lid is         closed.  The default is 1. -->    <integer name="config_lidKeyboardAccessibility">1</integer>

Check the determinehiddenstate again, which means that when the slider is closed, if the m1_keyboardaccessibility is 1, the keyboard is invisible at the same time.

    private int determineHiddenState(boolean lidOpen,            int mode, int hiddenValue, int visibleValue) {        switch (mode) {            case 1:                return lidOpen ? visibleValue : hiddenValue;            case 2:                return lidOpen ? hiddenValue : visibleValue;        }        return visibleValue;    }

It took me a long time to locate the problem, so I learned a lesson. The framework should never be changed at will, or it would be a mess.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.