use of android.view.SurfaceControl in project android_frameworks_base by ParanoidAndroid.
the class Session method performDrag.
public boolean performDrag(IWindow window, IBinder dragToken, float touchX, float touchY, float thumbCenterX, float thumbCenterY, ClipData data) {
if (WindowManagerService.DEBUG_DRAG) {
Slog.d(WindowManagerService.TAG, "perform drag: win=" + window + " data=" + data);
}
synchronized (mService.mWindowMap) {
if (mService.mDragState == null) {
Slog.w(WindowManagerService.TAG, "No drag prepared");
throw new IllegalStateException("performDrag() without prepareDrag()");
}
if (dragToken != mService.mDragState.mToken) {
Slog.w(WindowManagerService.TAG, "Performing mismatched drag");
throw new IllegalStateException("performDrag() does not match prepareDrag()");
}
WindowState callingWin = mService.windowForClientLocked(null, window, false);
if (callingWin == null) {
Slog.w(WindowManagerService.TAG, "Bad requesting window " + window);
// !!! TODO: throw here?
return false;
}
// !!! TODO: if input is not still focused on the initiating window, fail
// the drag initiation (e.g. an alarm window popped up just as the application
// called performDrag()
mService.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
// !!! TODO: extract the current touch (x, y) in screen coordinates. That
// will let us eliminate the (touchX,touchY) parameters from the API.
// !!! FIXME: put all this heavy stuff onto the mH looper, as well as
// the actual drag event dispatch stuff in the dragstate
Display display = callingWin.mDisplayContent.getDisplay();
mService.mDragState.register(display);
mService.mInputMonitor.updateInputWindowsLw(true);
if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel, mService.mDragState.mServerChannel)) {
Slog.e(WindowManagerService.TAG, "Unable to transfer touch focus");
mService.mDragState.unregister();
mService.mDragState = null;
mService.mInputMonitor.updateInputWindowsLw(true);
return false;
}
mService.mDragState.mData = data;
mService.mDragState.mCurrentX = touchX;
mService.mDragState.mCurrentY = touchY;
mService.mDragState.broadcastDragStartedLw(touchX, touchY);
// remember the thumb offsets for later
mService.mDragState.mThumbOffsetX = thumbCenterX;
mService.mDragState.mThumbOffsetY = thumbCenterY;
// Make the surface visible at the proper location
final SurfaceControl surfaceControl = mService.mDragState.mSurfaceControl;
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS)
Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
SurfaceControl.openTransaction();
try {
surfaceControl.setPosition(touchX - thumbCenterX, touchY - thumbCenterY);
surfaceControl.setAlpha(.7071f);
surfaceControl.setLayer(mService.mDragState.getDragLayerLw());
surfaceControl.setLayerStack(display.getLayerStack());
surfaceControl.show();
} finally {
SurfaceControl.closeTransaction();
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS)
Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
}
}
// success!
return true;
}
use of android.view.SurfaceControl in project android_frameworks_base by ParanoidAndroid.
the class WindowManagerService method relayoutWindow.
public int relayoutWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
boolean toBeDisplayed = false;
boolean inTouchMode;
boolean configChanged;
boolean surfaceChanged = false;
boolean animating;
// if they don't have this permission, mask out the status bar bits
int systemUiVisibility = 0;
if (attrs != null) {
systemUiVisibility = (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility);
if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) {
systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
}
}
}
long origId = Binder.clearCallingIdentity();
synchronized (mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return 0;
}
WindowStateAnimator winAnimator = win.mWinAnimator;
if (win.mRequestedWidth != requestedWidth || win.mRequestedHeight != requestedHeight) {
win.mLayoutNeeded = true;
win.mRequestedWidth = requestedWidth;
win.mRequestedHeight = requestedHeight;
}
if (attrs != null && seq == win.mSeq) {
win.mSystemUiVisibility = systemUiVisibility;
}
if (attrs != null) {
mPolicy.adjustWindowParamsLw(attrs);
}
winAnimator.mSurfaceDestroyDeferred = (flags & WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
if (win.mAttrs.type != attrs.type) {
throw new IllegalArgumentException("Window type can not be changed after the window is added.");
}
flagChanges = win.mAttrs.flags ^= attrs.flags;
attrChanges = win.mAttrs.copyFrom(attrs);
if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
win.mLayoutNeeded = true;
}
}
if (DEBUG_LAYOUT)
Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
win.mEnforceSizeCompat = (win.mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
winAnimator.mAlpha = attrs.alpha;
}
final boolean scaledWindow = ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
if (scaledWindow) {
// requested{Width|Height} Surface's physical size
// attrs.{width|height} Size on screen
win.mHScale = (attrs.width != requestedWidth) ? (attrs.width / (float) requestedWidth) : 1.0f;
win.mVScale = (attrs.height != requestedHeight) ? (attrs.height / (float) requestedHeight) : 1.0f;
} else {
win.mHScale = win.mVScale = 1;
}
boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
final boolean isDefaultDisplay = win.isDefaultDisplay();
boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) || (!win.mRelayoutCalled));
boolean wallpaperMayMove = win.mViewVisibility != viewVisibility && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
win.mViewVisibility = viewVisibility;
if (DEBUG_SCREEN_ON) {
RuntimeException stack = new RuntimeException();
stack.fillInStackTrace();
Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility + " newVis=" + viewVisibility, stack);
}
if (viewVisibility == View.VISIBLE && (win.mAppToken == null || !win.mAppToken.clientHidden)) {
toBeDisplayed = !win.isVisibleLw();
if (win.mExiting) {
winAnimator.cancelExitAnimationForNextAnimationLocked();
win.mExiting = false;
}
if (win.mDestroying) {
win.mDestroying = false;
mDestroySurface.remove(win);
}
if (oldVisibility == View.GONE) {
winAnimator.mEnterAnimationPending = true;
}
if (toBeDisplayed) {
if (win.isDrawnLw() && okToDisplay()) {
winAnimator.applyEnterAnimationLocked();
}
if ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
if (DEBUG_VISIBILITY)
Slog.v(TAG, "Relayout window turning screen on: " + win);
win.mTurnOnScreen = true;
}
if (win.isConfigChanged()) {
if (DEBUG_CONFIGURATION)
Slog.i(TAG, "Window " + win + " visible with new config: " + mCurConfiguration);
outConfig.setTo(mCurConfiguration);
}
}
if ((attrChanges & WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
// To change the format, we need to re-build the surface.
winAnimator.destroySurfaceLocked();
toBeDisplayed = true;
surfaceChanged = true;
}
try {
if (!win.mHasSurface) {
surfaceChanged = true;
}
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
if (surfaceControl != null) {
outSurface.copyFrom(surfaceControl);
if (SHOW_TRANSACTIONS)
Slog.i(TAG, " OUT SURFACE " + outSurface + ": copied");
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
outSurface.release();
}
} catch (Exception e) {
mInputMonitor.updateInputWindowsLw(true);
Slog.w(TAG, "Exception thrown when creating surface for client " + client + " (" + win.mAttrs.getTitle() + ")", e);
Binder.restoreCallingIdentity(origId);
return 0;
}
if (toBeDisplayed) {
focusMayChange = isDefaultDisplay;
}
if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
mInputMethodWindow = win;
imMayMove = true;
}
if (win.mAttrs.type == TYPE_BASE_APPLICATION && win.mAppToken != null && win.mAppToken.startingWindow != null) {
// Special handling of starting window over the base
// window of the app: propagate lock screen flags to it,
// to provide the correct semantics while starting.
final int mask = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
sa.flags = (sa.flags & ~mask) | (win.mAttrs.flags & mask);
}
} else {
winAnimator.mEnterAnimationPending = false;
if (winAnimator.mSurfaceControl != null) {
if (DEBUG_VISIBILITY)
Slog.i(TAG, "Relayout invis " + win + ": mExiting=" + win.mExiting);
// need to see about starting one.
if (!win.mExiting) {
surfaceChanged = true;
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
focusMayChange = isDefaultDisplay;
win.mExiting = true;
} else if (win.mWinAnimator.isAnimating()) {
// Currently in a hide animation... turn this into
// an exit.
win.mExiting = true;
} else if (win == mWallpaperTarget) {
// If the wallpaper is currently behind this
// window, we need to change both of them inside
// of a transaction to avoid artifacts.
win.mExiting = true;
win.mWinAnimator.mAnimating = true;
} else {
if (mInputMethodWindow == win) {
mInputMethodWindow = null;
}
winAnimator.destroySurfaceLocked();
}
//TODO (multidisplay): Magnification is supported only for the default
if (mDisplayMagnifier != null && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
mDisplayMagnifier.onWindowTransitionLocked(win, transit);
}
}
}
outSurface.release();
if (DEBUG_VISIBILITY)
Slog.i(TAG, "Releasing surface in: " + win);
}
if (focusMayChange) {
//System.out.println("Focus may change: " + win.mAttrs.getTitle());
if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false)) {
imMayMove = false;
}
//System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
}
// reassign them at this point if the IM window state gets shuffled
if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
// Little hack here -- we -should- be able to rely on the
// function to return true if the IME has moved and needs
// its layer recomputed. However, if the IME was hidden
// and isn't actually moved in the list, its layer may be
// out of data so we make sure to recompute it.
assignLayersLocked(win.getWindowList());
}
if (wallpaperMayMove) {
getDefaultDisplayContentLocked().pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
win.mDisplayContent.layoutNeeded = true;
win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
configChanged = updateOrientationFromAppTokensLocked(false);
performLayoutAndPlaceSurfacesLocked();
if (toBeDisplayed && win.mIsWallpaper) {
DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
updateWallpaperOffsetLocked(win, displayInfo.appWidth, displayInfo.appHeight, false);
}
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
}
outFrame.set(win.mCompatFrame);
outOverscanInsets.set(win.mOverscanInsets);
outContentInsets.set(win.mContentInsets);
outVisibleInsets.set(win.mVisibleInsets);
if (localLOGV)
Slog.v(TAG, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility + "\nRelayout returning frame=" + outFrame + ", surface=" + outSurface);
if (localLOGV || DEBUG_FOCUS)
Slog.v(TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
inTouchMode = mInTouchMode;
animating = mAnimator.mAnimating;
if (animating && !mRelayoutWhileAnimating.contains(win)) {
mRelayoutWhileAnimating.add(win);
}
mInputMonitor.updateInputWindowsLw(true);
if (DEBUG_LAYOUT) {
Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
}
}
if (configChanged) {
sendNewConfiguration();
}
Binder.restoreCallingIdentity(origId);
return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0) | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0) | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0) | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
}
use of android.view.SurfaceControl in project android_frameworks_base by ParanoidAndroid.
the class WindowStateAnimator method createSurfaceLocked.
SurfaceControl createSurfaceLocked() {
if (mSurfaceControl == null) {
if (DEBUG_ANIM || DEBUG_ORIENTATION)
Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING");
mDrawState = DRAW_PENDING;
if (mWin.mAppToken != null) {
if (mWin.mAppToken.mAppAnimator.animation == null) {
mWin.mAppToken.allDrawn = false;
mWin.mAppToken.deferClearAllDrawn = false;
} else {
// Currently animating, persist current state of allDrawn until animation
// is complete.
mWin.mAppToken.deferClearAllDrawn = true;
}
}
mService.makeWindowFreezingScreenIfNeededLocked(mWin);
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = mWin.mAttrs;
if ((attrs.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
flags |= SurfaceControl.SECURE;
}
if (WindowState.DEBUG_VISIBILITY)
Slog.v(TAG, "Creating surface in session " + mSession.mSurfaceSession + " window " + this + " w=" + mWin.mCompatFrame.width() + " h=" + mWin.mCompatFrame.height() + " format=" + attrs.format + " flags=" + flags);
int w = mWin.mCompatFrame.width();
int h = mWin.mCompatFrame.height();
if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
// for a scaled surface, we always want the requested
// size.
w = mWin.mRequestedWidth;
h = mWin.mRequestedHeight;
}
// try to revert to sane values
if (w <= 0)
w = 1;
if (h <= 0)
h = 1;
mSurfaceShown = false;
mSurfaceLayer = 0;
mSurfaceAlpha = 0;
mSurfaceX = 0;
mSurfaceY = 0;
mSurfaceW = w;
mSurfaceH = h;
mWin.mLastSystemDecorRect.set(0, 0, 0, 0);
try {
final boolean isHwAccelerated = (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
if (!PixelFormat.formatHasAlpha(attrs.format)) {
flags |= SurfaceControl.OPAQUE;
}
if (DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(mSession.mSurfaceSession, attrs.getTitle().toString(), w, h, format, flags);
} else {
mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession, attrs.getTitle().toString(), w, h, format, flags);
}
mWin.mHasSurface = true;
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC)
Slog.i(TAG, " CREATE SURFACE " + mSurfaceControl + " IN SESSION " + mSession.mSurfaceSession + ": pid=" + mSession.mPid + " format=" + attrs.format + " flags=0x" + Integer.toHexString(flags) + " / " + this);
} catch (SurfaceControl.OutOfResourcesException e) {
mWin.mHasSurface = false;
Slog.w(TAG, "OutOfResourcesException creating surface");
mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
mDrawState = NO_SURFACE;
return null;
} catch (Exception e) {
mWin.mHasSurface = false;
Slog.e(TAG, "Exception creating surface", e);
mDrawState = NO_SURFACE;
return null;
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "Got surface: " + mSurfaceControl + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top + ", animLayer=" + mAnimLayer);
if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
WindowManagerService.logSurface(mWin, "CREATE pos=(" + mWin.mFrame.left + "," + mWin.mFrame.top + ") (" + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height() + "), layer=" + mAnimLayer + " HIDE", null);
}
SurfaceControl.openTransaction();
try {
try {
mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
mSurfaceControl.setPosition(mSurfaceX, mSurfaceY);
mSurfaceLayer = mAnimLayer;
mSurfaceControl.setLayerStack(mLayerStack);
mSurfaceControl.setLayer(mAnimLayer);
mSurfaceControl.setAlpha(0);
mSurfaceShown = false;
} catch (RuntimeException e) {
Slog.w(TAG, "Error creating surface in " + w, e);
mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
}
mLastHidden = true;
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS)
Slog.i(TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "Created surface " + this);
}
return mSurfaceControl;
}
use of android.view.SurfaceControl in project android_frameworks_base by ParanoidAndroid.
the class WindowManagerService method prepareDragSurface.
// -------------------------------------------------------------
// Drag and drop
// -------------------------------------------------------------
IBinder prepareDragSurface(IWindow window, SurfaceSession session, int flags, int width, int height, Surface outSurface) {
if (DEBUG_DRAG) {
Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height + " flags=" + Integer.toHexString(flags) + " win=" + window + " asbinder=" + window.asBinder());
}
final int callerPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
IBinder token = null;
try {
synchronized (mWindowMap) {
try {
if (mDragState == null) {
// TODO(multi-display): support other displays
final DisplayContent displayContent = getDefaultDisplayContentLocked();
final Display display = displayContent.getDisplay();
SurfaceControl surface = new SurfaceControl(session, "drag surface", width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
surface.setLayerStack(display.getLayerStack());
if (SHOW_TRANSACTIONS)
Slog.i(TAG, " DRAG " + surface + ": CREATE");
outSurface.copyFrom(surface);
final IBinder winBinder = window.asBinder();
token = new Binder();
mDragState = new DragState(this, token, surface, /*flags*/
0, winBinder);
token = mDragState.mToken = new Binder();
// 5 second timeout for this window to actually begin the drag
mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
mH.sendMessageDelayed(msg, 5000);
} else {
Slog.w(TAG, "Drag already in progress");
}
} catch (SurfaceControl.OutOfResourcesException e) {
Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
if (mDragState != null) {
mDragState.reset();
mDragState = null;
}
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
return token;
}
use of android.view.SurfaceControl in project platform_frameworks_base by android.
the class ColorFade method createSurface.
private boolean createSurface() {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
}
SurfaceControl.openTransaction();
try {
if (mSurfaceControl == null) {
try {
int flags;
if (mMode == MODE_FADE) {
flags = SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN;
} else {
flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN;
}
mSurfaceControl = new SurfaceControl(mSurfaceSession, "ColorFade", mDisplayWidth, mDisplayHeight, PixelFormat.OPAQUE, flags);
} catch (OutOfResourcesException ex) {
Slog.e(TAG, "Unable to create surface.", ex);
return false;
}
mSurfaceControl.setLayerStack(mDisplayLayerStack);
mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight);
mSurface = new Surface();
mSurface.copyFrom(mSurfaceControl);
mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManagerInternal, mDisplayId, mSurfaceControl);
mSurfaceLayout.onDisplayTransaction();
}
} finally {
SurfaceControl.closeTransaction();
}
return true;
}
Aggregations