import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.wm.WindowAnimator.KEYGUARD_SHOWN;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
import static com.android.server.wm.WindowManagerService.dipToPixel;
import static com.android.server.wm.WindowManagerService.localLOGV;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
+import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.view.Display;
import android.view.animation.Animation;
import com.android.internal.util.FastPrintWriter;
+import com.android.internal.view.IInputMethodClient;
import java.io.FileDescriptor;
import java.io.PrintWriter;
}
}
+ boolean checkWaitingForWindows() {
+
+ boolean haveBootMsg = false;
+ boolean haveApp = false;
+ // if the wallpaper service is disabled on the device, we're never going to have
+ // wallpaper, don't bother waiting for it
+ boolean haveWallpaper = false;
+ boolean wallpaperEnabled = mService.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableWallpaperService)
+ && !mService.mOnlyCore;
+ boolean haveKeyguard = true;
+ final int count = mWindows.size();
+ for (int i = 0; i < count; i++) {
+ final WindowState w = mWindows.get(i);
+ if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ return true;
+ }
+ if (w.isDrawnLw()) {
+ if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
+ haveBootMsg = true;
+ } else if (w.mAttrs.type == TYPE_APPLICATION
+ || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
+ haveApp = true;
+ } else if (w.mAttrs.type == TYPE_WALLPAPER) {
+ haveWallpaper = true;
+ } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
+ haveKeyguard = mService.mPolicy.isKeyguardDrawnLw();
+ }
+ }
+ }
+
+ if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM,
+ "******** booted=" + mService.mSystemBooted
+ + " msg=" + mService.mShowingBootMessages
+ + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
+ + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
+ + " haveKeyguard=" + haveKeyguard);
+
+ // If we are turning on the screen to show the boot message, don't do it until the boot
+ // message is actually displayed.
+ if (!mService.mSystemBooted && !haveBootMsg) {
+ return true;
+ }
+
+ // If we are turning on the screen after the boot is completed normally, don't do so until
+ // we have the application and wallpaper.
+ if (mService.mSystemBooted && ((!haveApp && !haveKeyguard) ||
+ (wallpaperEnabled && !haveWallpaper))) {
+ return true;
+ }
+
+ return false;
+ }
+
void updateWindowsForAnimator(WindowAnimator animator) {
final WindowManagerPolicy policy = animator.mPolicy;
final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
}
}
+ boolean inputMethodClientHasFocus(IInputMethodClient client) {
+ // The focus for the client is the window immediately below where we would place the input
+ // method window.
+ int idx = findDesiredInputMethodWindowIndex(false);
+ if (idx <= 0) {
+ return false;
+ }
+
+ WindowState imFocus = mWindows.get(idx - 1);
+ if (DEBUG_INPUT_METHOD) {
+ Slog.i(TAG_WM, "Desired input method target: " + imFocus);
+ Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
+ Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
+ }
+
+ if (imFocus == null) {
+ return false;
+ }
+
+ // This may be a starting window, in which case we still want to count it as okay.
+ if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING && imFocus.mAppToken != null) {
+ // The client has definitely started, so it really should have a window in this app
+ // token. Let's look for it.
+ final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
+ if (w != null) {
+ if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM, "Switching to real app window: " + w);
+ imFocus = w;
+ }
+ }
+
+ final IInputMethodClient imeClient = imFocus.mSession.mClient;
+
+ if (DEBUG_INPUT_METHOD) {
+ Slog.i(TAG_WM, "IM target client: " + imeClient);
+ if (imeClient != null) {
+ Slog.i(TAG_WM, "IM target client binder: " + imeClient.asBinder());
+ Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
+ }
+ }
+
+ return imeClient != null && imeClient.asBinder() == client.asBinder();
+ }
+
+ boolean hasSecureWindowOnScreen() {
+ for (int i = mWindows.size() - 1; i >= 0; --i) {
+ final WindowState ws = mWindows.get(i);
+ if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void updateSystemUiVisibility(int visibility, int globalDiff) {
+ for (int i = mWindows.size() - 1; i >= 0; --i) {
+ final WindowState ws = mWindows.get(i);
+ try {
+ int curValue = ws.mSystemUiVisibility;
+ int diff = (curValue ^ visibility) & globalDiff;
+ int newValue = (curValue & ~diff) | (visibility & diff);
+ if (newValue != curValue) {
+ ws.mSeq++;
+ ws.mSystemUiVisibility = newValue;
+ }
+ if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
+ ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+ visibility, newValue, diff);
+ }
+ } catch (RemoteException e) {
+ // so sorry
+ }
+ }
+ }
+
+ void onWindowFreezeTimeout() {
+ Slog.w(TAG_WM, "Window freeze timeout expired.");
+ mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
+ for (int i = mWindows.size() - 1; i >= 0; --i) {
+ final WindowState w = mWindows.get(i);
+ if (!w.mOrientationChanging) {
+ continue;
+ }
+ w.mOrientationChanging = false;
+ w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+ - mService.mDisplayFreezeTime);
+ Slog.w(TAG_WM, "Force clearing orientation change: " + w);
+ }
+ mService.mWindowPlacerLocked.performSurfacePlacement();
+ }
+
+ void waitForAllWindowsDrawn() {
+ final WindowManagerPolicy policy = mService.mPolicy;
+ for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = mWindows.get(winNdx);
+ final boolean isForceHiding = policy.isForceHiding(win.mAttrs);
+ final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs);
+ if (win.isVisibleLw() && (win.mAppToken != null || isForceHiding || keyguard)) {
+ win.mWinAnimator.mDrawState = DRAW_PENDING;
+ // Force add to mResizingWindows.
+ win.mLastContentInsets.set(-1, -1, -1, -1);
+ mService.mWaitingForDrawn.add(win);
+
+ // No need to wait for the windows below Keyguard.
+ if (isForceHiding) {
+ return;
+ }
+ }
+ }
+ }
+
static final class GetWindowOnDisplaySearchResult {
boolean reachedToken;
WindowState foundWindow;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
// The root of the device window hierarchy.
RootWindowContainer mRoot;
- // TODO: Move several of this states to the RootWindowContainer
+ // TODO: Move several of this states to the RootWindowContainer or DisplayContent
int mRotation = 0;
- int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
boolean mAltOrientation = false;
private boolean mKeyguardWaitingForActivityDrawn;
boolean mForceResizableTasks = false;
int getDragLayerLocked() {
- return mPolicy.windowTypeToLayerLw(LayoutParams.TYPE_DRAG) * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
+ return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
}
class RotationWatcher {
boolean mClientFreezingScreen = false;
int mAppsFreezingScreen = 0;
- int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
- int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ int mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+ int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
int mLayoutSeq = 0;
performEnableScreen();
}
- private boolean checkWaitingForWindowsLocked() {
-
- boolean haveBootMsg = false;
- boolean haveApp = false;
- // if the wallpaper service is disabled on the device, we're never going to have
- // wallpaper, don't bother waiting for it
- boolean haveWallpaper = false;
- boolean wallpaperEnabled = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_enableWallpaperService)
- && !mOnlyCore;
- boolean haveKeyguard = true;
- // TODO(multidisplay): Expand to all displays?
- final WindowList windows = getDefaultWindowListLocked();
- final int N = windows.size();
- for (int i=0; i<N; i++) {
- WindowState w = windows.get(i);
- if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
- return true;
- }
- if (w.isDrawnLw()) {
- if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
- haveBootMsg = true;
- } else if (w.mAttrs.type == TYPE_APPLICATION
- || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
- haveApp = true;
- } else if (w.mAttrs.type == TYPE_WALLPAPER) {
- haveWallpaper = true;
- } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
- haveKeyguard = mPolicy.isKeyguardDrawnLw();
- }
- }
- }
-
- if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
- Slog.i(TAG_WM, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
- + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
- + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
- + " haveKeyguard=" + haveKeyguard);
- }
-
- // If we are turning on the screen to show the boot message,
- // don't do it until the boot message is actually displayed.
- if (!mSystemBooted && !haveBootMsg) {
- return true;
- }
-
- // If we are turning on the screen after the boot is completed
- // normally, don't do so until we have the application and
- // wallpaper.
- if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
- (wallpaperEnabled && !haveWallpaper))) {
- return true;
- }
-
- return false;
- }
-
- public void performEnableScreen() {
+ private void performEnableScreen() {
synchronized(mWindowMap) {
if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+ " mForceDisplayEnabled=" + mForceDisplayEnabled
}
// Don't enable the screen until all existing windows have been drawn.
- if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) {
+ if (!mForceDisplayEnabled
+ // TODO(multidisplay): Expand to all displays?
+ && getDefaultDisplayContentLocked().checkWaitingForWindows()) {
return;
}
case WINDOW_FREEZE_TIMEOUT: {
// TODO(multidisplay): Can non-default displays rotate?
synchronized (mWindowMap) {
- Slog.w(TAG_WM, "Window freeze timeout expired.");
- mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
- final WindowList windows = getDefaultWindowListLocked();
- int i = windows.size();
- while (i > 0) {
- i--;
- WindowState w = windows.get(i);
- if (w.mOrientationChanging) {
- w.mOrientationChanging = false;
- w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
- - mDisplayFreezeTime);
- Slog.w(TAG_WM, "Force clearing orientation change: " + w);
- }
- }
- mWindowPlacerLocked.performSurfacePlacement();
+ getDefaultDisplayContentLocked().onWindowFreezeTimeout();
}
break;
}
@Override
public boolean inputMethodClientHasFocus(IInputMethodClient client) {
synchronized (mWindowMap) {
- // The focus for the client is the window immediately below
- // where we would place the input method window.
// TODO: multi-display
- int idx = getDefaultDisplayContentLocked().findDesiredInputMethodWindowIndex(false);
- if (idx > 0) {
- // TODO(multidisplay): IMEs are only supported on the default display.
- WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
- if (DEBUG_INPUT_METHOD) {
- Slog.i(TAG_WM, "Desired input method target: " + imFocus);
- Slog.i(TAG_WM, "Current focus: " + mCurrentFocus);
- Slog.i(TAG_WM, "Last focus: " + mLastFocus);
- }
- if (imFocus != null) {
- // This may be a starting window, in which case we still want
- // to count it as okay.
- if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING
- && imFocus.mAppToken != null) {
- // The client has definitely started, so it really should
- // have a window in this app token. Let's look for it.
- final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
- if (w != null) {
- if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM,
- "Switching to real app window: " + w);
- imFocus = w;
- }
- }
- if (DEBUG_INPUT_METHOD) {
- Slog.i(TAG_WM, "IM target client: " + imFocus.mSession.mClient);
- if (imFocus.mSession.mClient != null) {
- Slog.i(TAG_WM, "IM target client binder: "
- + imFocus.mSession.mClient.asBinder());
- Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
- }
- }
- if (imFocus.mSession.mClient != null &&
- imFocus.mSession.mClient.asBinder() == client.asBinder()) {
- return true;
- }
- }
+ if (getDefaultDisplayContentLocked().inputMethodClientHasFocus(client)) {
+ return true;
}
// Okay, how about this... what is the current focus?
}
// Check whether the current screen contains any secure content.
- boolean isSecure = false;
- final WindowList windows = getDefaultWindowListLocked();
- final int N = windows.size();
- for (int i = 0; i < N; i++) {
- WindowState ws = windows.get(i);
- if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
- isSecure = true;
- break;
- }
- }
+ boolean isSecure = displayContent.hasSecureWindowOnScreen();
// TODO(multidisplay): rotation on main screen only.
displayContent.updateDisplayInfo();
}
}
- // TOOD(multidisplay): StatusBar on multiple screens?
- boolean updateStatusBarVisibilityLocked(int visibility) {
+ // TODO(multidisplay): StatusBar on multiple screens?
+ private boolean updateStatusBarVisibilityLocked(int visibility) {
if (mLastDispatchedSystemUiVisibility == visibility) {
return false;
}
mLastDispatchedSystemUiVisibility = visibility;
mInputManager.setSystemUiVisibility(visibility);
- final WindowList windows = getDefaultWindowListLocked();
- final int N = windows.size();
- for (int i = 0; i < N; i++) {
- WindowState ws = windows.get(i);
- try {
- int curValue = ws.mSystemUiVisibility;
- int diff = (curValue ^ visibility) & globalDiff;
- int newValue = (curValue&~diff) | (visibility&diff);
- if (newValue != curValue) {
- ws.mSeq++;
- ws.mSystemUiVisibility = newValue;
- }
- if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
- ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
- visibility, newValue, diff);
- }
- } catch (RemoteException e) {
- // so sorry
- }
- }
+ getDefaultDisplayContentLocked().updateSystemUiVisibility(visibility, globalDiff);
return true;
}
return mRoot.getDisplayContentOrCreate(DEFAULT_DISPLAY);
}
- WindowList getDefaultWindowListLocked() {
- return getDefaultDisplayContentLocked().getWindowList();
- }
-
private DisplayInfo getDefaultDisplayInfoLocked() {
return getDefaultDisplayContentLocked().getDisplayInfo();
}
boolean allWindowsDrawn = false;
synchronized (mWindowMap) {
mWaitingForDrawnCallback = callback;
- final WindowList windows = getDefaultWindowListLocked();
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = windows.get(winNdx);
- final boolean isForceHiding = mPolicy.isForceHiding(win.mAttrs);
- final boolean keyguard = mPolicy.isKeyguardHostWindow(win.mAttrs);
- if (win.isVisibleLw()
- && (win.mAppToken != null || isForceHiding || keyguard)) {
- win.mWinAnimator.mDrawState = DRAW_PENDING;
- // Force add to mResizingWindows.
- win.mLastContentInsets.set(-1, -1, -1, -1);
- mWaitingForDrawn.add(win);
-
- // No need to wait for the windows below Keyguard.
- if (isForceHiding) {
- break;
- }
- }
- }
+ getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
mWindowPlacerLocked.requestTraversal();
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
if (mWaitingForDrawn.isEmpty()) {