use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WallpaperController method updateWallpaperOffsetLocked.
void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
final DisplayContent displayContent = changingTarget.getDisplayContent();
if (displayContent == null) {
return;
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int dw = displayInfo.logicalWidth;
final int dh = displayInfo.logicalHeight;
WindowState target = mWallpaperTarget;
if (target != null) {
if (target.mWallpaperX >= 0) {
mLastWallpaperX = target.mWallpaperX;
} else if (changingTarget.mWallpaperX >= 0) {
mLastWallpaperX = changingTarget.mWallpaperX;
}
if (target.mWallpaperY >= 0) {
mLastWallpaperY = target.mWallpaperY;
} else if (changingTarget.mWallpaperY >= 0) {
mLastWallpaperY = changingTarget.mWallpaperY;
}
if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
} else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
}
if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
} else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
}
if (target.mWallpaperXStep >= 0) {
mLastWallpaperXStep = target.mWallpaperXStep;
} else if (changingTarget.mWallpaperXStep >= 0) {
mLastWallpaperXStep = changingTarget.mWallpaperXStep;
}
if (target.mWallpaperYStep >= 0) {
mLastWallpaperYStep = target.mWallpaperYStep;
} else if (changingTarget.mWallpaperYStep >= 0) {
mLastWallpaperYStep = changingTarget.mWallpaperYStep;
}
}
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
WindowState wallpaper = windows.get(wallpaperNdx);
if (updateWallpaperOffset(wallpaper, dw, dh, sync)) {
WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
winAnimator.computeShownFrameLocked();
// No need to lay out the windows - we can just set the wallpaper position
// directly.
winAnimator.setWallpaperOffset(wallpaper.mShownPosition);
// We only want to be synchronous with one wallpaper.
sync = false;
}
}
}
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowManagerService method updateDisplayAndOrientationLocked.
/** Do not call if mDisplayReady == false */
DisplayInfo updateDisplayAndOrientationLocked(int uiMode) {
// 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;
}
}
}
// Update application display metrics.
final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode);
final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode);
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
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);
if (displayContent.mDisplayScalingDisabled) {
displayInfo.flags |= Display.FLAG_SCALING_DISABLED;
} else {
displayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
}
mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayContent.getDisplayId(), displayInfo);
displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
if (false) {
Slog.i(TAG_WM, "Set app display size: " + appWidth + " x " + appHeight);
}
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics, mCompatDisplayMetrics);
return displayInfo;
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowManagerService method screenshotApplicationsInner.
/**
* Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
* In portrait mode, it grabs the full screenshot.
*
* @param displayId the Display to take a screenshot of.
* @param width the width of the target bitmap
* @param height the height of the target bitmap
* @param includeFullDisplay true if the screen should not be cropped before capture
* @param frameScale the scale to apply to the frame, only used when width = -1 and height = -1
* @param config of the output bitmap
* @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot
*/
Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width, int height, boolean includeFullDisplay, float frameScale, Bitmap.Config config, boolean wallpaperOnly) {
final DisplayContent displayContent;
synchronized (mWindowMap) {
displayContent = getDisplayContentLocked(displayId);
if (displayContent == null) {
if (DEBUG_SCREENSHOT)
Slog.i(TAG_WM, "Screenshot of " + appToken + ": returning null. No Display for displayId=" + displayId);
return null;
}
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
int dw = displayInfo.logicalWidth;
int dh = displayInfo.logicalHeight;
if (dw == 0 || dh == 0) {
if (DEBUG_SCREENSHOT)
Slog.i(TAG_WM, "Screenshot of " + appToken + ": returning null. logical widthxheight=" + dw + "x" + dh);
return null;
}
Bitmap bm = null;
int maxLayer = 0;
final Rect frame = new Rect();
final Rect stackBounds = new Rect();
boolean screenshotReady;
int minLayer;
if (appToken == null && !wallpaperOnly) {
screenshotReady = true;
minLayer = 0;
} else {
screenshotReady = false;
minLayer = Integer.MAX_VALUE;
}
WindowState appWin = null;
boolean includeImeInScreenshot;
synchronized (mWindowMap) {
final AppWindowToken imeTargetAppToken = mInputMethodTarget != null ? mInputMethodTarget.mAppToken : null;
// We only include the Ime in the screenshot if the app we are screenshoting is the IME
// target and isn't in multi-window mode. We don't screenshot the IME in multi-window
// mode because the frame of the IME might not overlap with that of the app.
// E.g. IME target app at the top in split-screen mode and the IME at the bottom
// overlapping with the bottom app.
includeImeInScreenshot = imeTargetAppToken != null && imeTargetAppToken.appToken != null && imeTargetAppToken.appToken.asBinder() == appToken && !mInputMethodTarget.isInMultiWindowMode();
}
final int aboveAppLayer = (mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
synchronized (mWindowMap) {
// Figure out the part of the screen that is actually the app.
appWin = null;
final WindowList windows = displayContent.getWindowList();
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState ws = windows.get(i);
if (!ws.mHasSurface) {
continue;
}
if (ws.mLayer >= aboveAppLayer) {
continue;
}
if (wallpaperOnly && !ws.mIsWallpaper) {
continue;
}
if (ws.mIsImWindow) {
if (!includeImeInScreenshot) {
continue;
}
} else if (ws.mIsWallpaper) {
// then the target window state is this one.
if (wallpaperOnly) {
appWin = ws;
}
if (appWin == null) {
// the layer of the target window.
continue;
}
// Fall through. The target window is in front of the wallpaper. For this
// case we want to include the wallpaper layer in the screenshot because
// the target window might have some transparent areas.
} else if (appToken != null) {
if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
// screenshot app.
continue;
}
appWin = ws;
}
// Include this window.
final WindowStateAnimator winAnim = ws.mWinAnimator;
int layer = winAnim.mSurfaceController.getLayer();
if (maxLayer < layer) {
maxLayer = layer;
}
if (minLayer > layer) {
minLayer = layer;
}
// Don't include wallpaper in bounds calculation
if (!includeFullDisplay && !ws.mIsWallpaper) {
final Rect wf = ws.mFrame;
final Rect cr = ws.mContentInsets;
int left = wf.left + cr.left;
int top = wf.top + cr.top;
int right = wf.right - cr.right;
int bottom = wf.bottom - cr.bottom;
frame.union(left, top, right, bottom);
ws.getVisibleBounds(stackBounds);
if (!Rect.intersects(frame, stackBounds)) {
// Set frame empty if there's no intersection.
frame.setEmpty();
}
}
final boolean foundTargetWs = (ws.mAppToken != null && ws.mAppToken.token == appToken) || (appWin != null && wallpaperOnly);
if (foundTargetWs && ws.isDisplayedLw() && winAnim.getShown()) {
screenshotReady = true;
}
if (ws.isObscuringFullscreen(displayInfo)) {
break;
}
}
if (appToken != null && appWin == null) {
// Can't find a window to snapshot.
if (DEBUG_SCREENSHOT)
Slog.i(TAG_WM, "Screenshot: Couldn't find a surface matching " + appToken);
return null;
}
if (!screenshotReady) {
Slog.i(TAG_WM, "Failed to capture screenshot of " + appToken + " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
return null;
}
if (maxLayer == 0) {
if (DEBUG_SCREENSHOT)
Slog.i(TAG_WM, "Screenshot of " + appToken + ": returning null maxLayer=" + maxLayer);
return null;
}
if (!includeFullDisplay) {
// Constrain frame to the screen size.
if (!frame.intersect(0, 0, dw, dh)) {
frame.setEmpty();
}
} else {
// Caller just wants entire display.
frame.set(0, 0, dw, dh);
}
if (frame.isEmpty()) {
return null;
}
if (width < 0) {
width = (int) (frame.width() * frameScale);
}
if (height < 0) {
height = (int) (frame.height() * frameScale);
}
// Tell surface flinger what part of the image to crop. Take the top
// right part of the application, and crop the larger dimension to fit.
Rect crop = new Rect(frame);
if (width / (float) frame.width() < height / (float) frame.height()) {
int cropWidth = (int) ((float) width / (float) height * frame.height());
crop.right = crop.left + cropWidth;
} else {
int cropHeight = (int) ((float) height / (float) width * frame.width());
crop.bottom = crop.top + cropHeight;
}
// The screenshot API does not apply the current screen rotation.
int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
}
// Surfaceflinger is not aware of orientation, so convert our logical
// crop to surfaceflinger's portrait orientation.
convertCropForSurfaceFlinger(crop, rot, dw, dh);
if (DEBUG_SCREENSHOT) {
Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to " + maxLayer + " appToken=" + appToken);
for (int i = 0; i < windows.size(); i++) {
WindowState win = windows.get(i);
WindowSurfaceController controller = win.mWinAnimator.mSurfaceController;
Slog.i(TAG_WM, win + ": " + win.mLayer + " animLayer=" + win.mWinAnimator.mAnimLayer + " surfaceLayer=" + ((controller == null) ? "null" : controller.getLayer()));
}
}
ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
final boolean inRotation = screenRotationAnimation != null && screenRotationAnimation.isAnimating();
if (DEBUG_SCREENSHOT && inRotation)
Slog.v(TAG_WM, "Taking screenshot while rotating");
// We force pending transactions to flush before taking
// the screenshot by pushing an empty synchronous transaction.
SurfaceControl.openTransaction();
SurfaceControl.closeTransactionSync();
bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer, inRotation, rot);
if (bm == null) {
Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh + ") to layer " + maxLayer);
return null;
}
}
if (DEBUG_SCREENSHOT) {
// TEST IF IT's ALL BLACK
int[] buffer = new int[bm.getWidth() * bm.getHeight()];
bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
boolean allBlack = true;
final int firstColor = buffer[0];
for (int i = 0; i < buffer.length; i++) {
if (buffer[i] != firstColor) {
allBlack = false;
break;
}
}
if (allBlack) {
Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" + Integer.toHexString(firstColor) + ")! mSurfaceLayer=" + (appWin != null ? appWin.mWinAnimator.mSurfaceController.getLayer() : "null") + " minLayer=" + minLayer + " maxLayer=" + maxLayer);
}
}
// Create a copy of the screenshot that is immutable and backed in ashmem.
// This greatly reduces the overhead of passing the bitmap between processes.
Bitmap ret = bm.createAshmemBitmap(config);
bm.recycle();
return ret;
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowManagerService method getNonDecorInsetsLocked.
private void getNonDecorInsetsLocked(Rect outInsets) {
final DisplayInfo di = getDefaultDisplayInfoLocked();
mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, outInsets);
}
use of android.view.DisplayInfo in project platform_frameworks_base by android.
the class WindowManagerService method addWindow.
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
int[] appOp = new int[1];
int res = mPolicy.checkAddPermission(attrs, appOp);
if (res != WindowManagerGlobal.ADD_OKAY) {
return res;
}
boolean reportNewConfig = false;
WindowState attachedWindow = null;
long origId;
final int callingUid = Binder.getCallingUid();
final int type = attrs.type;
synchronized (mWindowMap) {
if (!mDisplayReady) {
throw new IllegalStateException("Display has not been initialialized");
}
final DisplayContent displayContent = getDisplayContentLocked(displayId);
if (displayContent == null) {
Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: " + displayId + ". Aborting.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
if (!displayContent.hasAccess(session.mUid)) {
Slog.w(TAG_WM, "Attempted to add window to a display for which the application " + "does not have access: " + displayId + ". Aborting.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
if (mWindowMap.containsKey(client.asBinder())) {
Slog.w(TAG_WM, "Window " + client + " is already added");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
attachedWindow = windowForClientLocked(null, attrs.token, false);
if (attachedWindow == null) {
Slog.w(TAG_WM, "Attempted to add window with token that is not a window: " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
}
if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display. Aborting.");
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
}
boolean addToken = false;
WindowToken token = mTokenMap.get(attrs.token);
AppWindowToken atoken = null;
boolean addToastWindowRequiresToken = false;
if (token == null) {
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
Slog.w(TAG_WM, "Attempted to add application window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_INPUT_METHOD) {
Slog.w(TAG_WM, "Attempted to add input method window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_VOICE_INTERACTION) {
Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_WALLPAPER) {
Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_DREAM) {
Slog.w(TAG_WM, "Attempted to add Dream window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_QS_DIALOG) {
Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_ACCESSIBILITY_OVERLAY) {
Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_TOAST) {
// Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
if (doesAddToastWindowRequireToken(attrs.packageName, callingUid, attachedWindow)) {
Slog.w(TAG_WM, "Attempted to add a toast window with unknown token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
}
token = new WindowToken(this, attrs.token, -1, false);
addToken = true;
} else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
atoken = token.appWindowToken;
if (atoken == null) {
Slog.w(TAG_WM, "Attempted to add window with non-application token " + token + ". Aborting.");
return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
} else if (atoken.removed) {
Slog.w(TAG_WM, "Attempted to add window with exiting application token " + token + ". Aborting.");
return WindowManagerGlobal.ADD_APP_EXITING;
}
if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
// No need for this guy!
if (DEBUG_STARTING_WINDOW || localLOGV)
Slog.v(TAG_WM, "**** NO NEED TO START: " + attrs.getTitle());
return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
}
} else if (type == TYPE_INPUT_METHOD) {
if (token.windowType != TYPE_INPUT_METHOD) {
Slog.w(TAG_WM, "Attempted to add input method window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_VOICE_INTERACTION) {
if (token.windowType != TYPE_VOICE_INTERACTION) {
Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_WALLPAPER) {
if (token.windowType != TYPE_WALLPAPER) {
Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_DREAM) {
if (token.windowType != TYPE_DREAM) {
Slog.w(TAG_WM, "Attempted to add Dream window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_ACCESSIBILITY_OVERLAY) {
if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_TOAST) {
// Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName, callingUid, attachedWindow);
if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
Slog.w(TAG_WM, "Attempted to add a toast window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_QS_DIALOG) {
if (token.windowType != TYPE_QS_DIALOG) {
Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token " + attrs.token + ". Aborting.");
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (token.appWindowToken != null) {
Slog.w(TAG_WM, "Non-null appWindowToken for system window of type=" + type);
// It is not valid to use an app token with other system types; we will
// instead make a new token for it (as if null had been passed in for the token).
attrs.token = null;
token = new WindowToken(this, null, -1, false);
addToken = true;
}
WindowState win = new WindowState(this, session, client, token, attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
Slog.w(TAG_WM, "Adding window client " + client.asBinder() + " that is dead, aborting.");
return WindowManagerGlobal.ADD_APP_EXITING;
}
if (win.getDisplayContent() == null) {
Slog.w(TAG_WM, "Adding window to Display that has been removed.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
mPolicy.adjustWindowParamsLw(win.mAttrs);
win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
res = mPolicy.prepareAddWindowLw(win, attrs);
if (res != WindowManagerGlobal.ADD_OKAY) {
return res;
}
final boolean openInputChannels = (outInputChannel != null && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
if (openInputChannels) {
win.openInputChannel(outInputChannel);
}
// schedule hiding all of its toast windows.
if (type == TYPE_TOAST) {
if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
// the screen after the activity goes away.
if (addToastWindowRequiresToken || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0 || mCurrentFocus == null || mCurrentFocus.mOwnerUid != callingUid) {
mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win), win.mAttrs.hideTimeoutMilliseconds);
}
}
// From now on, no exceptions or errors allowed!
res = WindowManagerGlobal.ADD_OKAY;
if (excludeWindowTypeFromTapOutTask(type)) {
displayContent.mTapExcludedWindows.add(win);
}
origId = Binder.clearCallingIdentity();
if (addToken) {
mTokenMap.put(attrs.token, token);
}
win.attach();
mWindowMap.put(client.asBinder(), win);
if (win.mAppOp != AppOpsManager.OP_NONE) {
int startOpResult = mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
if ((startOpResult != AppOpsManager.MODE_ALLOWED) && (startOpResult != AppOpsManager.MODE_DEFAULT)) {
win.setAppOpVisibilityLw(false);
}
}
if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
token.appWindowToken.startingWindow = win;
if (DEBUG_STARTING_WINDOW)
Slog.v(TAG_WM, "addWindow: " + token.appWindowToken + " startingWindow=" + win);
}
boolean imMayMove = true;
if (type == TYPE_INPUT_METHOD) {
win.mGivenInsetsPending = true;
mInputMethodWindow = win;
addInputMethodWindowToListLocked(win);
imMayMove = false;
} else if (type == TYPE_INPUT_METHOD_DIALOG) {
mInputMethodDialogs.add(win);
addWindowToListInOrderLocked(win, true);
moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
imMayMove = false;
} else {
addWindowToListInOrderLocked(win, true);
if (type == TYPE_WALLPAPER) {
mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
} else if ((attrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
} else if (mWallpaperControllerLocked.isBelowWallpaperTarget(win)) {
// If there is currently a wallpaper being shown, and
// the base layer of the new window is below the current
// layer of the target window, then adjust the wallpaper.
// This is to avoid a new window being placed between the
// wallpaper and its target.
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
}
// If the window is being added to a task that's docked but non-resizeable,
// we need to update this new window's scroll position when it's added.
win.applyScrollIfNeeded();
// If the window is being added to a stack that's currently adjusted for IME,
// make sure to apply the same adjust to this new window.
win.applyAdjustForImeIfNeeded();
if (type == TYPE_DOCK_DIVIDER) {
getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
}
final WindowStateAnimator winAnimator = win.mWinAnimator;
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
// Check if we need to prepare a transition for replacing window first.
if (atoken != null && !prepareWindowReplacementTransition(atoken)) {
// If not, check if need to set up a dummy transition during display freeze
// so that the unfreeze wait for the apps to draw. This might be needed if
// the app is relaunching.
prepareNoneTransitionForRelaunching(atoken);
}
if (displayContent.isDefaultDisplay) {
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final Rect taskBounds;
if (atoken != null && atoken.mTask != null) {
taskBounds = mTmpRect;
atoken.mTask.getBounds(mTmpRect);
} else {
taskBounds = null;
}
if (mPolicy.getInsetHintLw(win.mAttrs, taskBounds, mRotation, displayInfo.logicalWidth, displayInfo.logicalHeight, outContentInsets, outStableInsets, outOutsets)) {
res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR;
}
} else {
outContentInsets.setEmpty();
outStableInsets.setEmpty();
}
if (mInTouchMode) {
res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
}
if (win.mAppToken == null || !win.mAppToken.clientHidden) {
res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
}
mInputMonitor.setUpdateInputWindowsNeededLw();
boolean focusChanged = false;
if (win.canReceiveKeys()) {
focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, false);
if (focusChanged) {
imMayMove = false;
}
}
if (imMayMove) {
moveInputMethodWindowsIfNeededLocked(false);
}
mLayersController.assignLayersLocked(displayContent.getWindowList());
if (focusChanged) {
mInputMonitor.setInputFocusLw(mCurrentFocus, false);
}
mInputMonitor.updateInputWindowsLw(false);
if (localLOGV || DEBUG_ADD_REMOVE)
Slog.v(TAG_WM, "addWindow: New client " + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
reportNewConfig = true;
}
}
if (reportNewConfig) {
sendNewConfiguration();
}
Binder.restoreCallingIdentity(origId);
return res;
}
Aggregations