安卓系统有的app做了强制横屏或者强制竖屏功能,但是当前系统有重力感应传感器,他又要实现app能随重力感应旋转适配,修改如下:
系统更新旋转流程如下:
boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
long ident = Binder.clearCallingIdentity();
try {
int req = getOrientationLocked();
if (req != mLastOrientation) {
mLastOrientation = req;
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
mPolicy.setCurrentOrientationLw(req);
if (updateRotationUncheckedLocked(inTransaction)) {
// changed
return true;
}
}
return false;
} finally {
Binder.restoreCallingIdentity(ident);
}
}
public int getOrientationLocked() {
if (mDisplayFrozen) {
if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
"Display is frozen, return " + mLastWindowForcedOrientation);
// If the display is frozen, some activities may be in the middle
// of restarting, and thus have removed their old window. If the
// window has the flag to hide the lock screen, then the lock screen
// can re-appear and inflict its own orientation on us. Keep the
// orientation stable until this all settles down.
return mLastWindowForcedOrientation;
} else if (mPolicy.isKeyguardLocked()) {
// Use the last orientation the while the display is frozen with the
// keyguard locked. This could be the keyguard forced orientation or
// from a SHOW_WHEN_LOCKED window. We don't want to check the show when
// locked window directly though as things aren't stable while
// the display is frozen, for example the window could be momentarily unavailable
// due to activity relaunch.
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
+ "return " + mLastOrientation);
return mLastOrientation;
}
} else {
// TODO(multidisplay): Change to the correct display.
final WindowList windows = getDefaultWindowListLocked();
for (int pos = windows.size() - 1; pos >= 0; --pos) {
WindowState win = windows.get(pos);
if (win.mAppToken != null) {
// We hit an application window. so the orientation will be determined by the
// app window. No point in continuing further.
break;
}
if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
continue;
}
int req = win.mAttrs.screenOrientation;
if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
continue;
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
if (mPolicy.isKeyguardHostWindow(win.mAttrs)) {
mLastKeyguardForcedOrientation = req;
}
return (mLastWindowForcedOrientation = req);
}
mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
if (mPolicy.isKeyguardLocked()) {
// The screen is locked and no top system window is requesting an orientation.
// Return either the orientation of the show-when-locked app (if there is any) or
// the orientation of the keyguard. No point in searching from the rest of apps.
WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
null : winShowWhenLocked.mAppToken;
if (appShowWhenLocked != null) {
int req = appShowWhenLocked.requestedOrientation;
if (req == SCREEN_ORIENTATION_BEHIND) {
req = mLastKeyguardForcedOrientation;
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
+ " -- show when locked, return " + req);
return req;
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
"No one is requesting an orientation when the screen is locked");
return mLastKeyguardForcedOrientation;
}
}
// Top system windows are not requesting an orientation. Start searching from apps.
return getAppSpecifiedOrientation(); //在这里处理app旋转功能
}
```c
Index: frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
===================================================================
--- frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java (revision 1877)
+++ frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java (working copy)
@@ -4199,7 +4199,8 @@
|| isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID);
final boolean dockMinimized =
getDefaultDisplayContentLocked().mDividerControllerLocked.isMinimizedDock();
- for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+ if(true) return SCREEN_ORIENTATION_UNSPECIFIED;
+ for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
if(mSecondDisplayTaskId != -1) { //dual screen
if(DEBUG) Log.i(TAG_DUALSCREEN,"getAppSpecifiedOrientation taskId = "+tasks.get(taskNdx).mTaskId +" mSecondDisplayTaskId = "+mSecondDisplayTaskId);
@@ -7405,12 +7406,13 @@
mRotation = Surface.ROTATION_0;
rotation = Surface.ROTATION_90;
}
+ Log.i("fan","rotation="+rotation +" mRotation ="+mRotation);
if (mRotation == rotation && mAltOrientation == altOrientation) {
// No change.
return false;
}
-
+
if (DEBUG_ORIENTATION) {
Slog.v(TAG_WM,
"Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")