一、前言
有时候需要系统的某个应用强制衡平显示,不管他是如何配置的。我们只需要简单的拿到top的Task下面的ActivityRecord,并判断包名来强制实现。
二、调整wms
com.android.server.wm.DisplayRotation
/**
* Given an orientation constant, returns the appropriate surface rotation, taking into account
* sensors, docking mode, rotation lock, and other factors.
*
* @param orientation An orientation constant, such as
* {@link ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
* @param lastRotation The most recently used rotation.
* @return The surface rotation to use.
*/
@Surface.Rotation
int rotationForOrientation(@ScreenOrientation int orientation,
@Surface.Rotation int lastRotation) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"rotationForOrientation(orient=%s (%d), last=%s (%d)); user=%s (%d) %s",
ActivityInfo.screenOrientationToString(orientation), orientation,
Surface.rotationToString(lastRotation), lastRotation,
Surface.rotationToString(mUserRotation), mUserRotation,
mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
? "USER_ROTATION_LOCKED" : "");
if (isFixedToUserRotation()) {
return mUserRotation;
}
+ if(isTopActivityIsMyPackage()){
+ return Surface.ROTATION_90;
+ }
@Surface.Rotation
int sensorRotation = mOrientationListener != null
? mOrientationListener.getProposedRotation() // may be -1
: -1;
if (mFoldController != null && mFoldController.shouldIgnoreSensorRotation()) {
sensorRotation = -1;
}
if (mDeviceStateController.shouldReverseRotationDirectionAroundZAxis(mDisplayContent)) {
sensorRotation = RotationUtils.reverseRotationDirectionAroundZAxis(sensorRotation);
}
mLastSensorRotation = sensorRotation;
if (sensorRotation < 0) {
sensorRotation = lastRotation;
}
final int lidState = mDisplayPolicy.getLidState();
final int dockMode = mDisplayPolicy.getDockMode();
final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
final boolean carDockEnablesAccelerometer =
mDisplayPolicy.isCarDockEnablesAccelerometer();
final boolean deskDockEnablesAccelerometer =
mDisplayPolicy.isDeskDockEnablesAccelerometer();
@Surface.Rotation
final int preferredRotation;
if (!isDefaultDisplay) {
// For secondary displays we ignore things like displays sensors, docking mode and
// rotation lock, and always prefer user rotation.
preferredRotation = mUserRotation;
} else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
// Ignore sensor when lid switch is open and rotation is forced.
preferredRotation = mLidOpenRotation;
} else if (dockMode == Intent.EXTRA_DOCK_STATE_CAR
&& (carDockEnablesAccelerometer || mCarDockRotation >= 0)) {
// Ignore sensor when in car dock unless explicitly enabled.
// This case can override the behavior of NOSENSOR, and can also
// enable 180 degree rotation while docked.
preferredRotation = carDockEnablesAccelerometer ? sensorRotation : mCarDockRotation;
} else if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
|| dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
|| dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
&& (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)
&& !(orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED
|| orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)) {
// Ignore sensor when in desk dock unless explicitly enabled.
// This case can enable 180 degree rotation while docked.
preferredRotation = deskDockEnablesAccelerometer ? sensorRotation : mDeskDockRotation;
} else if (hdmiPlugged && mDemoHdmiRotationLock) {
// Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
// Note that the dock orientation overrides the HDMI orientation.
preferredRotation = mDemoHdmiRotation;
} else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
&& mUndockedHdmiRotation >= 0) {
// Ignore sensor when plugged into HDMI and an undocked orientation has
// been specified in the configuration (only for legacy devices without
// full multi-display support).
// Note that the dock orientation overrides the HDMI orientation.
preferredRotation = mUndockedHdmiRotation;
} else if (mDemoRotationLock) {
// Ignore sensor when demo rotation lock is enabled.
// Note that the dock orientation and HDMI rotation lock override this.
preferredRotation = mDemoRotation;
} else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
// While in VR, apps always prefer a portrait rotation. This does not change
// any apps that explicitly set landscape, but does cause sensors be ignored,
// and ignored any orientation lock that the user has set (this conditional
// should remain above the ORIENTATION_LOCKED conditional below).
preferredRotation = mPortraitRotation;
} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
// Application just wants to remain locked in the last rotation.
preferredRotation = lastRotation;
} else if (!mSupportAutoRotation) {
if (mFixedToUserRotation == IWindowManager.FIXED_TO_USER_ROTATION_IF_NO_AUTO_ROTATION) {
preferredRotation = mUserRotation;
} else {
// If we don't support auto-rotation then bail out here and ignore
// the sensor and any rotation lock settings.
preferredRotation = -1;
}
} else if (((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
|| isTabletopAutoRotateOverrideEnabled())
&& (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
|| orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|| orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|| orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
|| orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
|| orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|| orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
// Otherwise, use sensor only if requested by the application or enabled
// by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
boolean allowed = true;
if (orientation != ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
&& orientation != ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
allowed = RotationPolicy.isRotationAllowed(sensorRotation, mUserRotationAngles,
getAllowAllRotations() != ALLOW_ALL_ROTATIONS_DISABLED);
}
if (allowed) {
preferredRotation = sensorRotation;
} else {
preferredRotation = lastRotation;
}
} else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
&& orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
&& orientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
&& orientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
&& orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
&& orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
// Apply rotation lock. Does not apply to NOSENSOR or specific rotations.
// The idea is that the user rotation expresses a weak preference for the direction
// of gravity and as NOSENSOR is never affected by gravity, then neither should
// NOSENSOR be affected by rotation lock (although it will be affected by docks).
// Also avoid setting user rotation when app has preference over one particular rotation
// to avoid leaving the rotation to the reverse of it which has the compatible
// orientation, but isn't what app wants, when the user rotation is the reverse of the
// preferred rotation.
preferredRotation = mUserRotation;
} else {
// No overriding preference.
// We will do exactly what the application asked us to do.
preferredRotation = -1;
}
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
// Return portrait unless overridden.
if (isAnyPortrait(preferredRotation)) {
return preferredRotation;
}
return mPortraitRotation;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
// Return landscape unless overridden.
if (isLandscapeOrSeascape(preferredRotation)) {
return preferredRotation;
}
return mLandscapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
// Return reverse portrait unless overridden.
if (isAnyPortrait(preferredRotation)) {
return preferredRotation;
}
return mUpsideDownRotation;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
// Return seascape unless overridden.
if (isLandscapeOrSeascape(preferredRotation)) {
return preferredRotation;
}
return mSeascapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
// Return either landscape rotation.
if (isLandscapeOrSeascape(preferredRotation)) {
return preferredRotation;
}
if (isLandscapeOrSeascape(lastRotation)) {
return lastRotation;
}
return mLandscapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
// Return either portrait rotation.
if (isAnyPortrait(preferredRotation)) {
return preferredRotation;
}
if (isAnyPortrait(lastRotation)) {
return lastRotation;
}
return mPortraitRotation;
default:
// For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
// just return the preferred orientation we already calculated.
if (preferredRotation >= 0) {
return preferredRotation;
}
return Surface.ROTATION_0;
}
}
这里是传入一个配置的选装方法和当前的方法,来判断后面要进行旋转的操作,我们Activity没有配置横竖屏的时候传入的
orientation都是SCREEN_ORIENTATION_UNSPECIFIED(-1),不过我们强制横屏可以不考虑这么多,加一个方法判断即可。
boolean isTopActivityIsMyPackage(){
try {
Task rootTask = mDisplayContent.getTopRootTask();
if(rootTask!=null&&rootTask.hasChild()&&rootTask.getChildAt(0) instanceof ActivityRecord){
return ((ActivityRecord) rootTask.getChildAt(0)).packageName.equals("com.example.cloudclient");
}
}catch (Exception e){
return false;
}
return false;
}
这里的包名换成自己的就行,然后编译打包重启
make -j12 services
adb push lineageos/out/target/product/blueline/system/framework/services.jar /system/framework/services.jar