1aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy/* 2aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Copyright (C) 2011 The Android Open Source Project 3aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 4aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * you may not use this file except in compliance with the License. 6aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * You may obtain a copy of the License at 7aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 8aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 10aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Unless required by applicable law or agreed to in writing, software 11aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * See the License for the specific language governing permissions and 14aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * limitations under the License. 15aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 16aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 17aa6c24c21c727a196451332448d4e3b11a80be69Romain Guypackage com.android.test.hwui; 18aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 19aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.app.Activity; 20a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport android.graphics.Bitmap; 21302a9df1d50373c82923bb84ff665dfce584fb22Romain Guyimport android.graphics.Matrix; 22aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.graphics.SurfaceTexture; 23aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.hardware.Camera; 24aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.os.Bundle; 25a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport android.os.Environment; 26aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.view.Gravity; 27a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport android.view.Surface; 28aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.view.TextureView; 29aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.view.View; 30451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guyimport android.widget.Button; 31aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.widget.FrameLayout; 32aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 33a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport java.io.BufferedOutputStream; 34a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport java.io.File; 35a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport java.io.FileNotFoundException; 36a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guyimport java.io.FileOutputStream; 37aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport java.io.IOException; 38aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 39aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy@SuppressWarnings({"UnusedDeclaration"}) 40aa6c24c21c727a196451332448d4e3b11a80be69Romain Guypublic class TextureViewActivity extends Activity implements TextureView.SurfaceTextureListener { 41aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy private Camera mCamera; 42aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy private TextureView mTextureView; 43451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy private FrameLayout mContent; 44302a9df1d50373c82923bb84ff665dfce584fb22Romain Guy private Matrix mMatrix = new Matrix(); 45aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 46aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 47aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy protected void onCreate(Bundle savedInstanceState) { 48aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy super.onCreate(savedInstanceState); 49aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 50451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mContent = new FrameLayout(this); 51451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 52aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mTextureView = new TextureView(this); 53aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mTextureView.setSurfaceTextureListener(this); 54a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy mTextureView.setOnClickListener(new View.OnClickListener() { 55a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy @Override 56a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy public void onClick(View v) { 57a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy Bitmap b = mTextureView.getBitmap(800, 800); 58a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy BufferedOutputStream out = null; 59a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy try { 60a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy File dump = new File(Environment.getExternalStorageDirectory(), "out.png"); 61a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy out = new BufferedOutputStream(new FileOutputStream(dump)); 62a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy b.compress(Bitmap.CompressFormat.PNG, 100, out); 63a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } catch (FileNotFoundException e) { 64a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy e.printStackTrace(); 65a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } finally { 66a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy if (out != null) try { 67a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy out.close(); 68a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } catch (IOException e) { 69a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy e.printStackTrace(); 70a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 71a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 72a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 73a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy }); 74aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 75451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Button button = new Button(this); 76451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy button.setText("Remove/Add"); 77451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy button.setOnClickListener(new View.OnClickListener() { 78451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy private boolean mAdded = true; 79aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 80451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy @Override 81451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy public void onClick(View v) { 82451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy if (mAdded) { 83451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mContent.removeView(mTextureView); 84451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } else { 85451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mContent.addView(mTextureView); 86451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 87451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mAdded = !mAdded; 88451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 89451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy }); 90aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 919ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy mContent.addView(mTextureView, new FrameLayout.LayoutParams( 929ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, 939ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy Gravity.CENTER)); 94451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mContent.addView(button, new FrameLayout.LayoutParams( 95451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT, 96451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM)); 97451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy setContentView(mContent); 98aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 99aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 100aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 101451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 102aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mCamera = Camera.open(); 103a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy mCamera.setDisplayOrientation(getCameraOrientation()); 104a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy 1059ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy Camera.Size previewSize = mCamera.getParameters().getPreviewSize(); 1069ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy mTextureView.setLayoutParams(new FrameLayout.LayoutParams( 1079ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy previewSize.width, previewSize.height, Gravity.CENTER)); 108aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 109aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy try { 110aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mCamera.setPreviewTexture(surface); 111aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } catch (IOException t) { 112aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy android.util.Log.e("TextureView", "Cannot set preview texture target!", t); 113aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 114aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 115aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy mCamera.startPreview(); 116aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 1178f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy 118a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy private int getCameraOrientation() { 119a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy Camera.CameraInfo info = new Camera.CameraInfo(); 120a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy for (int i = 0; i < Camera.getNumberOfCameras(); i++) { 121a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy Camera.getCameraInfo(i, info); 122a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) break; 123a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 124a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy 125a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy int rotation = getWindowManager().getDefaultDisplay().getRotation(); 126a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy int degrees = 0; 127a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy 128a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy switch (rotation) { 129a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy case Surface.ROTATION_0: 130a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy degrees = 0; 131a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy break; 132a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy case Surface.ROTATION_90: 133a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy degrees = 90; 134a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy break; 135a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy case Surface.ROTATION_180: 136a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy degrees = 180; 137a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy break; 138a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy case Surface.ROTATION_270: 139a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy degrees = 270; 140a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy break; 141a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 142a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy 143a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy return (info.orientation - degrees + 360) % 360; 144a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy } 145a9dc86b21defc26db0d71f276aff5c3af0b62ff5Romain Guy 1468f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy @Override 1478f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 1488f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy // Ignored, the Camera does all the work for us 1498f0095cd33558e9cc8a440047908e53b68906f5fRomain Guy } 150451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy 151451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy @Override 152402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 153451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mCamera.stopPreview(); 154451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy mCamera.release(); 155402f05530352f34d5320c2d23be43c274d97c4e2Grace Kloba return true; 156451ce44a18e4c48f8a43aa250957f76967a35d31Romain Guy } 157cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba 158cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba @Override 159cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba public void onSurfaceTextureUpdated(SurfaceTexture surface) { 160cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba // Ignored 161cf559377b750271472aa0a717bf3b7d34abc0b39Grace Kloba } 162aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy} 163