/** * Update preview TextureView rotation to accommodate discrepancy between preview buffer and the * view window orientation. * * <p>Assumptions: - Aspect ratio for the sensor buffers is in landscape orientation, - Dimensions * of buffers received are rotated to the natural device orientation. - The contents of each * buffer are rotated by the inverse of the display rotation. - Surface scales the buffer to fit * the current view bounds. TODO: Make this method works for all orientations */ protected void updatePreviewDisplayRotation(Size previewSize, TextureView textureView) { int rotationDegrees = 0; Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext; int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); Configuration config = activity.getResources().getConfiguration(); // Get UI display rotation switch (displayRotation) { case Surface.ROTATION_0: rotationDegrees = 0; break; case Surface.ROTATION_90: rotationDegrees = 90; break; case Surface.ROTATION_180: rotationDegrees = 180; break; case Surface.ROTATION_270: rotationDegrees = 270; break; } // Get device natural orientation int deviceOrientation = Configuration.ORIENTATION_PORTRAIT; if ((rotationDegrees % 180 == 0 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) || ((rotationDegrees % 180 != 0 && config.orientation == Configuration.ORIENTATION_PORTRAIT))) { deviceOrientation = Configuration.ORIENTATION_LANDSCAPE; } // Rotate the buffer dimensions if device orientation is portrait. int effectiveWidth = previewSize.getWidth(); int effectiveHeight = previewSize.getHeight(); if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) { effectiveWidth = previewSize.getHeight(); effectiveHeight = previewSize.getWidth(); } // Find and center view rect and buffer rect Matrix transformMatrix = textureView.getTransform(null); int viewWidth = textureView.getWidth(); int viewHeight = textureView.getHeight(); RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); RectF bufRect = new RectF(0, 0, effectiveWidth, effectiveHeight); float centerX = viewRect.centerX(); float centerY = viewRect.centerY(); bufRect.offset(centerX - bufRect.centerX(), centerY - bufRect.centerY()); // Undo ScaleToFit.FILL done by the surface transformMatrix.setRectToRect(viewRect, bufRect, Matrix.ScaleToFit.FILL); // Rotate buffer contents to proper orientation transformMatrix.postRotate((360 - rotationDegrees) % 360, centerX, centerY); if ((rotationDegrees % 180) == 90) { int temp = effectiveWidth; effectiveWidth = effectiveHeight; effectiveHeight = temp; } // Scale to fit view, cropping the longest dimension float scale = Math.max(viewWidth / (float) effectiveWidth, viewHeight / (float) effectiveHeight); transformMatrix.postScale(scale, scale, centerX, centerY); Handler handler = new Handler(Looper.getMainLooper()); class TransformUpdater implements Runnable { TextureView mView; Matrix mTransformMatrix; TransformUpdater(TextureView view, Matrix matrix) { mView = view; mTransformMatrix = matrix; } @Override public void run() { mView.setTransform(mTransformMatrix); } } handler.post(new TransformUpdater(textureView, transformMatrix)); }