LogicalDisplay.java中configureDisplayLocked方法中
//wfy
public boolean mSingleHandModeState = true;
public boolean mSingleHandModeLeft = true;
public void configureDisplayLocked(SurfaceControl.Transaction t,
DisplayDevice device,
boolean isBlanked) {
// Set the layer stack.
device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack);
// Set the color mode and allowed display mode.
if (device == mPrimaryDisplayDevice) {
device.setDesiredDisplayModeSpecsLocked(mDesiredDisplayModeSpecs);
device.setRequestedColorModeLocked(mRequestedColorMode);
} else {
if (SystemProperties.getBoolean("vendor.hwc.enable_display_configs", false)){
if (device.getDisplayDeviceInfoLocked().type==Display.TYPE_EXTERNAL){
//int modeId=SystemProperties.getInt("sys.edisplay.mode-1",0);
//device.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs);
device.setRequestedColorModeLocked(0);
//device.requestDisplayModesLocked(0, modeId);
}else{
device.setDesiredDisplayModeSpecsLocked(
new DisplayModeDirector.DesiredDisplayModeSpecs());
device.setRequestedColorModeLocked(0);
}
}else{
// Reset to default for non primary displays
device.setDesiredDisplayModeSpecsLocked(
new DisplayModeDirector.DesiredDisplayModeSpecs());
device.setRequestedColorModeLocked(0);
}
}
device.setAutoLowLatencyModeLocked(mRequestedMinimalPostProcessing);
device.setGameContentTypeLocked(mRequestedMinimalPostProcessing);
// Only grab the display info now as it may have been changed based on the requests above.
final DisplayInfo displayInfo = getDisplayInfoLocked();
final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
// Set the viewport.
// This is the area of the logical display that we intend to show on the
// display device. For now, it is always the full size of the logical display.
mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
// Set the orientation.
// The orientation specifies how the physical coordinate system of the display
// is rotated when the contents of the logical display are rendered.
int orientation = Surface.ROTATION_0;
if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
orientation = displayInfo.rotation;
}
// Apply the physical rotation of the display device itself.
orientation = (orientation + displayDeviceInfo.rotation) % 4;
// Set the frame.
// The frame specifies the rotated physical coordinates into which the viewport
// is mapped. We need to take care to preserve the aspect ratio of the viewport.
// Currently we maximize the area to fill the display, but we could try to be
// more clever and match resolutions.
boolean rotated = (orientation == Surface.ROTATION_90
|| orientation == Surface.ROTATION_270);
int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
InsetUtils.rotateInsets(maskingInsets, orientation);
// Don't consider the masked area as available when calculating the scaling below.
physWidth -= maskingInsets.left + maskingInsets.right;
physHeight -= maskingInsets.top + maskingInsets.bottom;
// Determine whether the width or height is more constrained to be scaled.
// physWidth / displayInfo.logicalWidth => letter box
// or physHeight / displayInfo.logicalHeight => pillar box
//
// We avoid a division (and possible floating point imprecision) here by
// multiplying the fractions by the product of their denominators before
// comparing them.
int displayRectWidth, displayRectHeight;
if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) {
displayRectWidth = displayInfo.logicalWidth;
displayRectHeight = displayInfo.logicalHeight;
} else if (physWidth * displayInfo.logicalHeight
< physHeight * displayInfo.logicalWidth) {
// Letter box.
displayRectWidth = physWidth;
displayRectHeight = displayInfo.logicalHeight * physWidth / displayInfo.logicalWidth;
} else {
// Pillar box.
displayRectWidth = displayInfo.logicalWidth * physHeight / displayInfo.logicalHeight;
displayRectHeight = physHeight;
}
int displayRectTop = (physHeight - displayRectHeight) / 2;
int displayRectLeft = (physWidth - displayRectWidth) / 2;
//mTempDisplayRect.set(displayRectLeft, displayRectTop,
// displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
//wfy add
final boolean singleHandModeSupported = SystemProperties.get("persist.android.singlehandmode", "false").equals("true");
int displayRectRight = displayRectLeft + displayRectWidth;
int displayRectBottom = displayRectTop + displayRectHeight;
if (singleHandModeSupported) {
if ((mSingleHandModeState == true) && (!isBlanked)) {
if (mSingleHandModeLeft == true) {
displayRectTop = displayRectTop + displayRectHeight * 3 / 4;
displayRectRight = displayRectLeft + displayRectWidth * 3 / 4;
}else{
displayRectLeft = displayRectLeft + displayRectWidth / 4;
displayRectTop = displayRectTop + displayRectHeight / 4;
}
}
}
mTempDisplayRect.set(displayRectLeft, displayRectTop, displayRectRight, displayRectBottom);
//wfy add end
// Now add back the offset for the masked area.
mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
if (orientation == Surface.ROTATION_0) {
mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY);
} else if (orientation == Surface.ROTATION_90) {
mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX);
} else if (orientation == Surface.ROTATION_180) {
mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY);
} else { // Surface.ROTATION_270
mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX);
}
if(SystemProperties.get("ro.board.platform").equals("rk356x")) {
if(displayDeviceInfo.type==Display.TYPE_EXTERNAL) {
int mPhysicalDisplayId = Integer.valueOf(device.getDisplayDeviceInfoLocked().uniqueId.split(":")[1]);
if (mPhysicalDisplayId == 1) {
if (SystemProperties.getBoolean("persist.sys.rotation.efull-1", false)) {
mTempDisplayRect.top = 0;
mTempDisplayRect.left = 0;
mTempDisplayRect.right = physWidth;
mTempDisplayRect.bottom = physHeight;
}
} else if (mPhysicalDisplayId == 2) {
if (SystemProperties.getBoolean("persist.sys.rotation.efull-2", false)) {
mTempDisplayRect.top = 0;
mTempDisplayRect.left = 0;
mTempDisplayRect.right = physWidth;
mTempDisplayRect.bottom = physHeight;
}
}}
}else{
if(device.getDisplayDeviceInfoLocked().type==Display.TYPE_EXTERNAL) {
if (SystemProperties.getBoolean("persist.sys.rotation.efull", false)) {
mTempDisplayRect.top = 0;
mTempDisplayRect.left = 0;
mTempDisplayRect.right = physWidth;
mTempDisplayRect.bottom = physHeight;
}
}
}
mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top);
device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect);
}
中的內部類BinderService中增加方法
final class BinderService extends IDisplayManager.Stub {
private final SurfaceControl.Transaction mDisplayTransaction = new SurfaceControl.Transaction();
//wfy add
@Override // Binder call
public void singleHandModeChange(boolean change, boolean left) {
//mSingleHandModeState = change;
//mSingleHandModeLeft = left;
//Slog.d("SingleHandMode", "singleHandMode singleHandMode singleHandModeState=" + mSingleHandModeState + " left " + mSingleHandModeLeft);
scheduleTraversalLocked(false);
performTraversalInternal(mDisplayTransaction);
//performTraversalInTransactionFromWindowManagerInternal();
}
......
}