private boolean captureScreenshotTextureAndSetViewport() {
    if (!attachEglContext()) {
      return false;
    }
    try {
      if (!mTexNamesGenerated) {
        GLES10.glGenTextures(1, mTexNames, 0);
        if (checkGlErrors("glGenTextures")) {
          return false;
        }
        mTexNamesGenerated = true;
      }

      final SurfaceTexture st = new SurfaceTexture(mTexNames[0]);
      final Surface s = new Surface(st);
      try {
        SurfaceControl.screenshot(
            SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s);
      } finally {
        s.release();
      }

      st.updateTexImage();
      st.getTransformMatrix(mTexMatrix);

      // Set up texture coordinates for a quad.
      // We might need to change this if the texture ends up being
      // a different size from the display for some reason.
      mTexCoordBuffer.put(0, 0f);
      mTexCoordBuffer.put(1, 0f);
      mTexCoordBuffer.put(2, 0f);
      mTexCoordBuffer.put(3, 1f);
      mTexCoordBuffer.put(4, 1f);
      mTexCoordBuffer.put(5, 1f);
      mTexCoordBuffer.put(6, 1f);
      mTexCoordBuffer.put(7, 0f);

      // Set up our viewport.
      GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight);
      GLES10.glMatrixMode(GLES10.GL_PROJECTION);
      GLES10.glLoadIdentity();
      GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1);
      GLES10.glMatrixMode(GLES10.GL_MODELVIEW);
      GLES10.glLoadIdentity();
      GLES10.glMatrixMode(GLES10.GL_TEXTURE);
      GLES10.glLoadIdentity();
      GLES10.glLoadMatrixf(mTexMatrix, 0);
    } finally {
      detachEglContext();
    }
    return true;
  }
    @Override
    public void onDisplayTransaction() {
      synchronized (this) {
        if (mSurfaceControl == null) {
          return;
        }

        DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY);
        switch ((displayInfo.rotation + mHWRotation) % 4) {
          case Surface.ROTATION_0:
            mSurfaceControl.setPosition(0, 0);
            mSurfaceControl.setMatrix(1, 0, 0, 1);
            break;
          case Surface.ROTATION_90:
            mSurfaceControl.setPosition(0, displayInfo.logicalHeight);
            mSurfaceControl.setMatrix(0, -1, 1, 0);
            break;
          case Surface.ROTATION_180:
            mSurfaceControl.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight);
            mSurfaceControl.setMatrix(-1, 0, 0, -1);
            break;
          case Surface.ROTATION_270:
            mSurfaceControl.setPosition(displayInfo.logicalWidth, 0);
            mSurfaceControl.setMatrix(0, 1, -1, 0);
            break;
        }
      }
    }
 private boolean showSurface(float alpha) {
   if (!mSurfaceVisible || mSurfaceAlpha != alpha) {
     SurfaceControl.openTransaction();
     try {
       mSurfaceControl.setLayer(ELECTRON_BEAM_LAYER);
       mSurfaceControl.setAlpha(alpha);
       mSurfaceControl.show();
     } finally {
       SurfaceControl.closeTransaction();
     }
     mSurfaceVisible = true;
     mSurfaceAlpha = alpha;
   }
   return true;
 }
 public void updateSize() {
   synchronized (mWindowManagerService.mWindowMap) {
     mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
     mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y);
     invalidate(mDirtyRect);
   }
 }
 private void destroySurface() {
   if (mSurfaceControl != null) {
     mSurfaceLayout.dispose();
     mSurfaceLayout = null;
     SurfaceControl.openTransaction();
     try {
       mSurfaceControl.destroy();
       mSurface.release();
     } finally {
       SurfaceControl.closeTransaction();
     }
     mSurfaceControl = null;
     mSurfaceVisible = false;
     mSurfaceAlpha = 0f;
   }
 }
 /**
  * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but includes all Surfaces
  * in the screenshot.
  *
  * @param width The desired width of the returned bitmap; the raw screen will be scaled down to
  *     this size.
  * @param height The desired height of the returned bitmap; the raw screen will be scaled down to
  *     this size.
  * @return Returns a Bitmap containing the screen contents, or null if an error occurs. Make sure
  *     to call Bitmap.recycle() as soon as possible, once its content is not needed anymore.
  */
 public static Bitmap screenshot(int width, int height) {
   // TODO: should take the display as a parameter
   IBinder displayToken =
       SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
   return nativeScreenshot(
       displayToken, new Rect(), width, height, 0, 0, true, false, Surface.ROTATION_0);
 }
 public void setBlurMaskSurface(SurfaceControl maskSurface) {
   checkNotReleased();
   if (maskSurface != null) {
     maskSurface.checkNotReleased();
   }
   nativeSetBlurMaskSurface(mNativeObject, maskSurface == null ? 0 : maskSurface.mNativeObject);
 }
      /** NOTE: This has to be called within a surface transaction. */
      public void drawIfNeeded() {
        synchronized (mWindowManagerService.mWindowMap) {
          if (!mInvalidated) {
            return;
          }
          mInvalidated = false;
          Canvas canvas = null;
          try {
            // Empty dirty rectangle means unspecified.
            if (mDirtyRect.isEmpty()) {
              mBounds.getBounds(mDirtyRect);
            }
            mDirtyRect.inset(-mHalfBorderWidth, -mHalfBorderWidth);
            canvas = mSurface.lockCanvas(mDirtyRect);
            if (DEBUG_VIEWPORT_WINDOW) {
              Slog.i(LOG_TAG, "Dirty rect: " + mDirtyRect);
            }
          } catch (IllegalArgumentException iae) {
            /* ignore */
          } catch (Surface.OutOfResourcesException oore) {
            /* ignore */
          }
          if (canvas == null) {
            return;
          }
          if (DEBUG_VIEWPORT_WINDOW) {
            Slog.i(LOG_TAG, "Bounds: " + mBounds);
          }
          canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
          mPaint.setAlpha(mAlpha);
          Path path = mBounds.getBoundaryPath();
          canvas.drawPath(path, mPaint);

          mSurface.unlockCanvasAndPost(canvas);

          if (mAlpha > 0) {
            mSurfaceControl.show();
          } else {
            mSurfaceControl.hide();
          }
        }
      }
      public ViewportWindow(Context context) {
        SurfaceControl surfaceControl = null;
        try {
          mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
          surfaceControl =
              new SurfaceControl(
                  mWindowManagerService.mFxSession,
                  SURFACE_TITLE,
                  mTempPoint.x,
                  mTempPoint.y,
                  PixelFormat.TRANSLUCENT,
                  SurfaceControl.HIDDEN);
        } catch (OutOfResourcesException oore) {
          /* ignore */
        }
        mSurfaceControl = surfaceControl;
        mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay().getLayerStack());
        mSurfaceControl.setLayer(
            mWindowManagerService.mPolicy.windowTypeToLayerLw(
                    WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
                * WindowManagerService.TYPE_LAYER_MULTIPLIER);
        mSurfaceControl.setPosition(0, 0);
        mSurface.copyFrom(mSurfaceControl);

        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight, typedValue, true);
        final int borderColor = context.getResources().getColor(typedValue.resourceId);

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mBorderWidth);
        mPaint.setColor(borderColor);

        Interpolator interpolator = new DecelerateInterpolator(2.5f);
        final long longAnimationDuration =
            context.getResources().getInteger(com.android.internal.R.integer.config_longAnimTime);

        mShowHideFrameAnimator =
            ObjectAnimator.ofInt(this, PROPERTY_NAME_ALPHA, MIN_ALPHA, MAX_ALPHA);
        mShowHideFrameAnimator.setInterpolator(interpolator);
        mShowHideFrameAnimator.setDuration(longAnimationDuration);
        mInvalidated = true;
      }
Beispiel #10
0
  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,
                  "ElectronBeam",
                  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(mDisplayManager, mSurfaceControl, mHWRotation);
      mSurfaceLayout.onDisplayTransaction();
    } finally {
      SurfaceControl.closeTransaction();
    }
    return true;
  }
 @Override
 public void clearWindowAnimationFrameStats() {
   synchronized (mLock) {
     throwIfCalledByNotTrustedUidLocked();
     throwIfShutdownLocked();
     throwIfNotConnectedLocked();
   }
   final long identity = Binder.clearCallingIdentity();
   try {
     SurfaceControl.clearAnimationFrameStats();
   } finally {
     Binder.restoreCallingIdentity(identity);
   }
 }
 @Override
 public Bitmap takeScreenshot(int width, int height) {
   synchronized (mLock) {
     throwIfCalledByNotTrustedUidLocked();
     throwIfShutdownLocked();
     throwIfNotConnectedLocked();
   }
   final long identity = Binder.clearCallingIdentity();
   try {
     return SurfaceControl.screenshot(width, height);
   } finally {
     Binder.restoreCallingIdentity(identity);
   }
 }
 @Override
 public WindowAnimationFrameStats getWindowAnimationFrameStats() {
   synchronized (mLock) {
     throwIfCalledByNotTrustedUidLocked();
     throwIfShutdownLocked();
     throwIfNotConnectedLocked();
   }
   final long identity = Binder.clearCallingIdentity();
   try {
     WindowAnimationFrameStats stats = new WindowAnimationFrameStats();
     SurfaceControl.getAnimationFrameStats(stats);
     return stats;
   } finally {
     Binder.restoreCallingIdentity(identity);
   }
 }
Beispiel #14
0
  private static Bitmap surfaceControlScreenshot(int width, int height) throws Exception {
    // if (mSurfaceControlScreenshotMethod == null) {
    //     Class<?> clazz = Class.forName(SURFACE_CONTROL_CLASS_NAME);
    //     if (clazz != null)
    //         mSurfaceControlScreenshotMethod = clazz.getDeclaredMethod("screenshot", Integer.TYPE,
    // Integer.TYPE);
    // }

    // Object object = mSurfaceControlScreenshotMethod.invoke(null, width, height);

    // if (object != null) {
    //     return (Bitmap) object;
    // }
    // return null;
    return SurfaceControl.screenshot(width, height);
  }
 /**
  * Copy the current screen contents into a bitmap and return it.
  *
  * <p>CAVEAT: Versions of screenshot that return a {@link Bitmap} can be extremely slow; avoid use
  * unless absolutely necessary; prefer the versions that use a {@link Surface} instead, such as
  * {@link SurfaceControl#screenshot(IBinder, Surface)}.
  *
  * @param sourceCrop The portion of the screen to capture into the Bitmap; caller may pass in 'new
  *     Rect()' if no cropping is desired.
  * @param width The desired width of the returned bitmap; the raw screen will be scaled down to
  *     this size.
  * @param height The desired height of the returned bitmap; the raw screen will be scaled down to
  *     this size.
  * @param minLayer The lowest (bottom-most Z order) surface layer to include in the screenshot.
  * @param maxLayer The highest (top-most Z order) surface layer to include in the screenshot.
  * @param useIdentityTransform Replace whatever transformation (rotation, scaling, translation)
  *     the surface layers are currently using with the identity transformation while taking the
  *     screenshot.
  * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
  *     Surface.ROTATION_0,90,180,270. Surfaceflinger will always take screenshots in its native
  *     portrait orientation by default, so this is useful for returning screenshots that are
  *     independent of device orientation.
  * @return Returns a Bitmap containing the screen contents, or null if an error occurs. Make sure
  *     to call Bitmap.recycle() as soon as possible, once its content is not needed anymore.
  */
 public static Bitmap screenshot(
     Rect sourceCrop,
     int width,
     int height,
     int minLayer,
     int maxLayer,
     boolean useIdentityTransform,
     int rotation) {
   // TODO: should take the display as a parameter
   IBinder displayToken =
       SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
   return nativeScreenshot(
       displayToken,
       sourceCrop,
       width,
       height,
       minLayer,
       maxLayer,
       false,
       useIdentityTransform,
       rotation);
 }
 public void releaseSurface() {
   mSurfaceControl.release();
   mSurface.release();
 }