boolean
computeScreenConfigurationLocked
(
Configuration
config
)
{
if
(!
mDisplayReady
)
{
return
false
;
}
// TODO(multidisplay): For now, apply Configuration to main screen only.
final
DisplayContent
displayContent
=
getDefaultDisplayContentLocked
();
// Use the effective "visual" dimensions based on current rotation
final
boolean
rotated
=
(
mRotation
==
Surface
.
ROTATION_90
||
mRotation
==
Surface
.
ROTATION_270
);
final
int
realdw
=
rotated
?
displayContent
.
mBaseDisplayHeight
:
displayContent
.
mBaseDisplayWidth
;
final
int
realdh
=
rotated
?
displayContent
.
mBaseDisplayWidth
:
displayContent
.
mBaseDisplayHeight
;
int
dw
=
realdw
;
int
dh
=
realdh
;
if
(
mAltOrientation
)
{
if
(
realdw
>
realdh
)
{
// Turn landscape into portrait.
int
maxw
=
(
int
)(
realdh
/
1.3f
);
if
(
maxw
<
realdw
)
{
dw
=
maxw
;
}
}
else
{
// Turn portrait into landscape.
int
maxh
=
(
int
)(
realdw
/
1.3f
);
if
(
maxh
<
realdh
)
{
dh
=
maxh
;
}
}
}
if
(
config
!=
null
)
{
config
.
orientation
=
(
dw
<=
dh
)
?
Configuration
.
ORIENTATION_PORTRAIT
:
Configuration
.
ORIENTATION_LANDSCAPE
;
}
// Update application display metrics.
final
int
appWidth
=
mPolicy
.
getNonDecorDisplayWidth
(
dw
,
dh
,
mRotation
);
final
int
appHeight
=
mPolicy
.
getNonDecorDisplayHeight
(
dw
,
dh
,
mRotation
);
final
DisplayInfo
displayInfo
=
displayContent
.
getDisplayInfo
();
synchronized
(
displayContent
.
mDisplaySizeLock
)
{
displayInfo
.
rotation
=
mRotation
;
displayInfo
.
logicalWidth
=
dw
;
displayInfo
.
logicalHeight
=
dh
;
displayInfo
.
logicalDensityDpi
=
displayContent
.
mBaseDisplayDensity
;
displayInfo
.
appWidth
=
appWidth
;
displayInfo
.
appHeight
=
appHeight
;
displayInfo
.
getLogicalMetrics
(
mRealDisplayMetrics
,
CompatibilityInfo
.
DEFAULT_COMPATIBILITY_INFO
,
null
);
displayInfo
.
getAppMetrics
(
mDisplayMetrics
);
mDisplayManagerInternal
.
setDisplayInfoOverrideFromWindowManager
(
displayContent
.
getDisplayId
(),
displayInfo
);
}
if
(
false
)
{
Slog
.
i
(
TAG
,
"Set app display size: "
+
appWidth
+
" x "
+
appHeight
);
}
final
DisplayMetrics
dm
=
mDisplayMetrics
;
mCompatibleScreenScale
=
CompatibilityInfo
.
computeCompatibleScaling
(
dm
,
mCompatDisplayMetrics
);
if
(
config
!=
null
)
{
config
.
screenWidthDp
=
(
int
)(
mPolicy
.
getConfigDisplayWidth
(
dw
,
dh
,
mRotation
)
/
dm
.
density
);
config
.
screenHeightDp
=
(
int
)(
mPolicy
.
getConfigDisplayHeight
(
dw
,
dh
,
mRotation
)
/
dm
.
density
);
computeSizeRangesAndScreenLayout
(
displayInfo
,
rotated
,
dw
,
dh
,
dm
.
density
,
config
);
config
.
compatScreenWidthDp
=
(
int
)(
config
.
screenWidthDp
/
mCompatibleScreenScale
);
config
.
compatScreenHeightDp
=
(
int
)(
config
.
screenHeightDp
/
mCompatibleScreenScale
);
config
.
compatSmallestScreenWidthDp
=
computeCompatSmallestWidth
(
rotated
,
dm
,
dw
,
dh
);
config
.
densityDpi
=
displayContent
.
mBaseDisplayDensity
;
// Update the configuration based on available input devices, lid switch,
// and platform configuration.
config
.
touchscreen
=
Configuration
.
TOUCHSCREEN_NOTOUCH
;
config
.
keyboard
=
Configuration
.
KEYBOARD_NOKEYS
;
config
.
navigation
=
Configuration
.
NAVIGATION_NONAV
;
int
keyboardPresence
=
0
;
int
navigationPresence
=
0
;
final
InputDevice
[]
devices
=
mInputManager
.
getInputDevices
();
final
int
len
=
devices
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
InputDevice
device
=
devices
[
i
];
if
(!
device
.
isVirtual
())
{
final
int
sources
=
device
.
getSources
();
final
int
presenceFlag
=
device
.
isExternal
()
?
WindowManagerPolicy
.
PRESENCE_EXTERNAL
:
WindowManagerPolicy
.
PRESENCE_INTERNAL
;
if
(
mIsTouchDevice
)
{
if
((
sources
&
InputDevice
.
SOURCE_TOUCHSCREEN
)
==
InputDevice
.
SOURCE_TOUCHSCREEN
)
{
config
.
touchscreen
=
Configuration
.
TOUCHSCREEN_FINGER
;
}
}
else
{
config
.
touchscreen
=
Configuration
.
TOUCHSCREEN_NOTOUCH
;
}
if
((
sources
&
InputDevice
.
SOURCE_TRACKBALL
)
==
InputDevice
.
SOURCE_TRACKBALL
)
{
config
.
navigation
=
Configuration
.
NAVIGATION_TRACKBALL
;
navigationPresence
|=
presenceFlag
;
}
else
if
((
sources
&
InputDevice
.
SOURCE_DPAD
)
==
InputDevice
.
SOURCE_DPAD
&&
config
.
navigation
==
Configuration
.
NAVIGATION_NONAV
)
{
config
.
navigation
=
Configuration
.
NAVIGATION_DPAD
;
navigationPresence
|=
presenceFlag
;
}
// 判断该物理设备的类型, InputDevice.KEYBOARD_TYPE_ALPHABETIC 是表示物理键盘设备
if
(
device
.
getKeyboardType
()
==
InputDevice
.
KEYBOARD_TYPE_ALPHABETIC
)
{
config
.
keyboard
=
Configuration
.
KEYBOARD_QWERTY
;
keyboardPresence
|=
presenceFlag
;
}
// 获取物理设备名称,判断是否是指定的名称,如果是则把 config.keyboard
// 的属性置为 Configuration.KEYBOARD_NOKEYS ,如此则可以同时兼容软键盘
// 物理键盘与软键盘可以同时启用
// Add by Janning start
// for show IME with HardKeyboard
if
(
device
.
getName
().
equals
(
"XXX-vinput-keypad"
))
{
Slog
.
w
(
"SLCODE"
,
"the hard device name is: "
+
device
.
getName
());
config
.
keyboard
=
Configuration
.
KEYBOARD_NOKEYS
;
}
// Add by Janning end
}
}
if
(
config
.
navigation
==
Configuration
.
NAVIGATION_NONAV
&&
mHasPermanentDpad
)
{
config
.
navigation
=
Configuration
.
NAVIGATION_DPAD
;
navigationPresence
|=
WindowManagerPolicy
.
PRESENCE_INTERNAL
;
}
// Determine whether a hard keyboard is available and enabled.
boolean
hardKeyboardAvailable
=
config
.
keyboard
!=
Configuration
.
KEYBOARD_NOKEYS
;
if
(
hardKeyboardAvailable
!=
mHardKeyboardAvailable
)
{
mHardKeyboardAvailable
=
hardKeyboardAvailable
;
mH
.
removeMessages
(
H
.
REPORT_HARD_KEYBOARD_STATUS_CHANGE
);
mH
.
sendEmptyMessage
(
H
.
REPORT_HARD_KEYBOARD_STATUS_CHANGE
);
}
if
(
mShowImeWithHardKeyboard
)
{
config
.
keyboard
=
Configuration
.
KEYBOARD_NOKEYS
;
}
// Let the policy update hidden states.
config
.
keyboardHidden
=
Configuration
.
KEYBOARDHIDDEN_NO
;
config
.
hardKeyboardHidden
=
Configuration
.
HARDKEYBOARDHIDDEN_NO
;
config
.
navigationHidden
=
Configuration
.
NAVIGATIONHIDDEN_NO
;
mPolicy
.
adjustConfigurationLw
(
config
,
keyboardPresence
,
navigationPresence
);
}
return
true
;
}
public
boolean
isHardKeyboardAvailable
()
{
synchronized
(
mWindowMap
)
{
return
mHardKeyboardAvailable
;
}
}
public
void
updateShowImeWithHardKeyboard
()
{
// 此处修改也可以实现物理键盘与软键盘的同时启用,即把showImeWithHardKeyboard 直接置为 true,
// 但此方法影响太大,不推荐该方案,建议根据设备名称判断 修改config.keyboard 属性值(代码见上文)
//changed by Janning start
//modified by Janning for enble the HardKeyboard start
final
boolean
showImeWithHardKeyboard
=
Settings
.
Secure
.
getIntForUser
(
mContext
.
getContentResolver
(),
Settings
.
Secure
.
SHOW_IME_WITH_HARD_KEYBOARD
,
0
,
mCurrentUserId
)
==
1
;
//final boolean showImeWithHardKeyboard = true;
//modified by Janning for enble the HardKeyboard end
//changed by Janning end
synchronized
(
mWindowMap
)
{
if
(
mShowImeWithHardKeyboard
!=
showImeWithHardKeyboard
)
{
mShowImeWithHardKeyboard
=
showImeWithHardKeyboard
;
mH
.
sendEmptyMessage
(
H
.
SEND_NEW_CONFIGURATION
);
}
}
}