代码路径:
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
在PhoneWindowManager.java文件中getNonDecorDisplayHeight()方法中获取应用区域的高度,应用区域分两种情况:1、当导航栏显示的时候,应用区域会减去导航栏的高度。2、当状态栏显示的时候,应用区域的距离会减去状态栏的高度
public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
if (mHasNavigationBar) {
// For a basic navigation bar, when we are in portrait mode we place
// the navigation bar to the bottom.
if (!mNavigationBarCanMove || fullWidth < fullHeight) {
return fullHeight - mNavigationBarHeightForRotation[rotation];
}else {
if(null != mStatusBar && mStatusBar.isVisibleLw()){
return fullHeight - mNavigationBarHeightForRotation[rotation] - mStatusBarHeight ;
}else{
return fullHeight ;
}
}
}else{
if(null != mStatusBar && mStatusBar.isVisibleLw()){
return fullHeight - mStatusBarHeight;
}else{
return fullHeight;
}
}
return fullHeight;
}
在PhoneWindowManager.java文件中getNonDecorDisplayWidth()方法中是获取应用区域的宽度
public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
if (mHasNavigationBar) {
// For a basic navigation bar, when we are in landscape mode we place
// the navigation bar to the side.
if (mNavigationBarCanMove && fullWidth > fullHeight) {
return fullWidth - mNavigationBarWidthForRotation[rotation];
}
}else{
return fullWidth;
}
在PhoneWindowManager.java文件中setInitialDisplaySize()方法中初始化导航栏、状态栏、应用区域等变量
@Override
public void setInitialDisplaySize(Display display, int width, int height, int density) {
// This method might be called before the policy has been fully initialized
// or for other displays we don't care about.
if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
return;
}
mDisplay = display;
final Resources res = mContext.getResources();
int shortSize, longSize;
if (width > height) {
shortSize = height;
longSize = width;
mLandscapeRotation = Surface.ROTATION_0;
mSeascapeRotation = Surface.ROTATION_180;
if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
mPortraitRotation = Surface.ROTATION_90;
mUpsideDownRotation = Surface.ROTATION_270;
} else {
mPortraitRotation = Surface.ROTATION_270;
mUpsideDownRotation = Surface.ROTATION_90;
}
} else {
shortSize = width;
longSize = height;
mPortraitRotation = Surface.ROTATION_0;
mUpsideDownRotation = Surface.ROTATION_180;
if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
mLandscapeRotation = Surface.ROTATION_270;
mSeascapeRotation = Surface.ROTATION_90;
} else {
mLandscapeRotation = Surface.ROTATION_90;
mSeascapeRotation = Surface.ROTATION_270;
}
}
mStatusBarHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
// Height of the navigation bar when presented horizontally at bottom
mNavigationBarHeightForRotation[mPortraitRotation] =
mNavigationBarHeightForRotation[mUpsideDownRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
mNavigationBarHeightForRotation[mLandscapeRotation] =
mNavigationBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape);
// Width of the navigation bar when presented vertically along one side
if("0".equals(systemUIType)){
mNavigationBarWidthForRotation[mPortraitRotation] =
mNavigationBarWidthForRotation[mUpsideDownRotation] =
mNavigationBarWidthForRotation[mLandscapeRotation] =
mNavigationBarWidthForRotation[mSeascapeRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
}
// SystemUI (status bar) layout policy
int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
// Allow the navigation bar to move on small devices (phones).
mNavigationBarCanMove = shortSizeDp < 600;
mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
// Allow a system property to override this. Used by the emulator.
// See also hasNavigationBar().
String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
if ("1".equals(navBarOverride)) {
mHasNavigationBar = false;
} else if ("0".equals(navBarOverride)) {
mHasNavigationBar = true;
}
mHasNavigationBar = true;
mNavigationBarCanMove=true;
}
// For demo purposes, allow the rotation of the HDMI display to be controlled.
// By default, HDMI locks rotation to landscape.
if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
mDemoHdmiRotation = mPortraitRotation;
} else {
mDemoHdmiRotation = mLandscapeRotation;
}
mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
// Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
// http://developer.android.com/guide/practices/screens_support.html#range
mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 &&
res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
// For debug purposes the next line turns this feature off with:
// $ adb shell setprop config.override_forced_orient true
// $ adb shell wm size reset
!"true".equals(SystemProperties.get("config.override_forced_orient"));
}
备注说明:
mHasNavigationBar:判断导航栏是否显示
mNavigationBarWidthForRotation[mSeascapeRotation] = res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);:获取导航栏的宽度
mStatusBarHeight:获取状态栏的高度
在PhoneWindowManager.java文件中setDisplayOverscan()方法中,这个方法的重点就是可以裁剪应用区域顶部和底部
, @Override
public void setDisplayOverscan(Display display, int left, int top, int right, int bottom) {
if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
mOverscanLeft = left;
mOverscanTop = top + 80;
mOverscanRight = right;
mOverscanBottom = bottom- 80;
}
}
备注:上面代码是功能:由于我们的产品模具把屏的顶部挡住了80,所以应用区域距离顶部就要增加80的距离,把应用局域往下移80,底部就要减去80.