PhotoUI.java revision 5596b4c902dcb685928b43678f428746ca5ffd08
1d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb/* 26432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu * Copyright (C) 2012 The Android Open Source Project 3d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * 4d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 5d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * you may not use this file except in compliance with the License. 6d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * You may obtain a copy of the License at 7d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * 8d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * http://www.apache.org/licenses/LICENSE-2.0 9d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * 10d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * Unless required by applicable law or agreed to in writing, software 11d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 12d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * See the License for the specific language governing permissions and 14d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb * limitations under the License. 15d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb */ 16d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 17d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbpackage com.android.camera; 18d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 196a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liuimport android.app.AlertDialog; 2037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.graphics.Bitmap; 216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.Matrix; 226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.SurfaceTexture; 23d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.hardware.Camera; 24d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.hardware.Camera.Face; 2537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.os.AsyncTask; 26f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liuimport android.view.GestureDetector; 27f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liuimport android.view.MotionEvent; 28d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.View; 29d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport android.view.ViewGroup; 30d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 31d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.FocusOverlayManager.FocusUI; 3220fad249cbb587b8cf03e8e53bc64ff8e0bec7fdAngus Kongimport com.android.camera.app.CameraManager; 335596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log; 34d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolbimport com.android.camera.ui.FaceView; 35f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liuimport com.android.camera.ui.PreviewOverlay; 3606db742814dd635d100639f977fcfdc904deb778Doris Liuimport com.android.camera.ui.PreviewStatusListener; 37b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil; 388e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R; 39b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong 40b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport java.util.List; 41d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 42482de029dc20e0a577388a602985fb31c3200309Doris Liupublic class PhotoUI implements PreviewStatusListener, 439e76552adff6ecf8b8e4070ecd61699cb6d18269Angus Kong CameraManager.CameraFaceDetectionCallback { 44d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 455596b4c902dcb685928b43678f428746ca5ffd08Angus Kong private static final Log.Tag TAG = new Log.Tag("PhotoUI"); 4637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling private static final int DOWN_SAMPLE_FACTOR = 4; 4770da918464276b110c43868caa272c97baadb89eDoris Liu private static final float UNSET = 0f; 480f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague 49f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu private final PreviewOverlay mPreviewOverlay; 50482de029dc20e0a577388a602985fb31c3200309Doris Liu private final FocusUI mFocusUI; 51e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling private final CameraActivity mActivity; 52e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling private final PhotoController mController; 53d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 54e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling private final View mRootView; 55d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 56d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu // TODO: Remove face view logic if UX does not bring it back within a month. 57d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu private FaceView mFaceView = null; 5836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu private DecodeImageForReview mDecodeTaskForReview = null; 59d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 60d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb private int mZoomMax; 61d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb private List<Integer> mZoomRatios; 62d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 63d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb private int mPreviewWidth = 0; 64d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb private int mPreviewHeight = 0; 6570da918464276b110c43868caa272c97baadb89eDoris Liu private float mAspectRatio = UNSET; 660744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 6706db742814dd635d100639f977fcfdc904deb778Doris Liu private final GestureDetector.OnGestureListener mPreviewGestureListener 6806db742814dd635d100639f977fcfdc904deb778Doris Liu = new GestureDetector.SimpleOnGestureListener() { 6906db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 7006db742814dd635d100639f977fcfdc904deb778Doris Liu public boolean onSingleTapUp(MotionEvent ev) { 7106db742814dd635d100639f977fcfdc904deb778Doris Liu mController.onSingleTapUp(null, (int) ev.getX(), (int) ev.getY()); 7206db742814dd635d100639f977fcfdc904deb778Doris Liu return true; 7306db742814dd635d100639f977fcfdc904deb778Doris Liu } 7406db742814dd635d100639f977fcfdc904deb778Doris Liu }; 750744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 7606db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 7706db742814dd635d100639f977fcfdc904deb778Doris Liu public GestureDetector.OnGestureListener getGestureListener() { 7806db742814dd635d100639f977fcfdc904deb778Doris Liu return mPreviewGestureListener; 7906db742814dd635d100639f977fcfdc904deb778Doris Liu } 8006db742814dd635d100639f977fcfdc904deb778Doris Liu 814a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu @Override 82d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public View.OnTouchListener getTouchListener() { 83d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return null; 84d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 85d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 86d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren @Override 874a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu public void onPreviewLayoutChanged(View v, int left, int top, int right, 884a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 894a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu int width = right - left; 904a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu int height = bottom - top; 914a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu if (mPreviewWidth != width || mPreviewHeight != height) { 924a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu mPreviewWidth = width; 934a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu mPreviewHeight = height; 94d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 954a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu } 96d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 9770da918464276b110c43868caa272c97baadb89eDoris Liu @Override 9870da918464276b110c43868caa272c97baadb89eDoris Liu public boolean shouldAutoAdjustTransformMatrixOnLayout() { 9970da918464276b110c43868caa272c97baadb89eDoris Liu return true; 10070da918464276b110c43868caa272c97baadb89eDoris Liu } 10170da918464276b110c43868caa272c97baadb89eDoris Liu 10270da918464276b110c43868caa272c97baadb89eDoris Liu @Override 10370da918464276b110c43868caa272c97baadb89eDoris Liu public boolean shouldAutoAdjustBottomBar() { 10470da918464276b110c43868caa272c97baadb89eDoris Liu return true; 10570da918464276b110c43868caa272c97baadb89eDoris Liu } 10670da918464276b110c43868caa272c97baadb89eDoris Liu 10711ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu @Override 10811ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu public void onPreviewFlipped() { 10911ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu mController.updateCameraOrientation(); 11011ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 11111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 11236e56fba281292255a01ee00b4bee067fa09ab59Doris Liu private class DecodeTask extends AsyncTask<Void, Void, Bitmap> { 11337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling private final byte [] mData; 114e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling private final int mOrientation; 115e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling private final boolean mMirror; 116c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu 11729da2db13029f8896018836693139a05d1139362Doris Liu public DecodeTask(byte[] data, int orientation, boolean mirror) { 11837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling mData = data; 119ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu mOrientation = orientation; 12029da2db13029f8896018836693139a05d1139362Doris Liu mMirror = mirror; 121c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu } 122c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu 123c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu @Override 12436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu protected Bitmap doInBackground(Void... params) { 12537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling // Decode image in background. 126ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu Bitmap bitmap = CameraUtil.downSample(mData, DOWN_SAMPLE_FACTOR); 12729da2db13029f8896018836693139a05d1139362Doris Liu if (mOrientation != 0 || mMirror) { 128ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu Matrix m = new Matrix(); 12929da2db13029f8896018836693139a05d1139362Doris Liu if (mMirror) { 13029da2db13029f8896018836693139a05d1139362Doris Liu // Flip horizontally 13129da2db13029f8896018836693139a05d1139362Doris Liu m.setScale(-1f, 1f); 13229da2db13029f8896018836693139a05d1139362Doris Liu } 133cec75e408a2d451b90bac5f06e10906ffcafff33Andy Huibers m.preRotate(mOrientation); 134ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, 135ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu false); 136ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu } 137ce2acbcb77225b6d429a23e00f69aadde8c2378bDoris Liu return bitmap; 13837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 13937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling } 140c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu 14136e56fba281292255a01ee00b4bee067fa09ab59Doris Liu private class DecodeImageForReview extends DecodeTask { 14236e56fba281292255a01ee00b4bee067fa09ab59Doris Liu public DecodeImageForReview(byte[] data, int orientation, boolean mirror) { 14336e56fba281292255a01ee00b4bee067fa09ab59Doris Liu super(data, orientation, mirror); 14436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu } 14536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu 14636e56fba281292255a01ee00b4bee067fa09ab59Doris Liu @Override 14736e56fba281292255a01ee00b4bee067fa09ab59Doris Liu protected void onPostExecute(Bitmap bitmap) { 14836e56fba281292255a01ee00b4bee067fa09ab59Doris Liu if (isCancelled()) { 14936e56fba281292255a01ee00b4bee067fa09ab59Doris Liu return; 15036e56fba281292255a01ee00b4bee067fa09ab59Doris Liu } 15136e56fba281292255a01ee00b4bee067fa09ab59Doris Liu mDecodeTaskForReview = null; 15236e56fba281292255a01ee00b4bee067fa09ab59Doris Liu } 15336e56fba281292255a01ee00b4bee067fa09ab59Doris Liu } 15436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu 155d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public PhotoUI(CameraActivity activity, PhotoController controller, View parent) { 156d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mActivity = activity; 157d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mController = controller; 158d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mRootView = parent; 159d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 160f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu ViewGroup moduleRoot = (ViewGroup) mRootView.findViewById(R.id.module_layout); 161d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mActivity.getLayoutInflater().inflate(R.layout.photo_module, 162e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling moduleRoot, true); 163d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb initIndicators(); 164482de029dc20e0a577388a602985fb31c3200309Doris Liu mFocusUI = (FocusUI) mRootView.findViewById(R.id.focus_overlay); 165f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mPreviewOverlay = (PreviewOverlay) mRootView.findViewById(R.id.preview_overlay); 1666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 1676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu 168482de029dc20e0a577388a602985fb31c3200309Doris Liu public FocusUI getFocusUI() { 169482de029dc20e0a577388a602985fb31c3200309Doris Liu return mFocusUI; 170482de029dc20e0a577388a602985fb31c3200309Doris Liu } 171482de029dc20e0a577388a602985fb31c3200309Doris Liu 172d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu public void updatePreviewAspectRatio(float aspectRatio) { 173d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu if (aspectRatio <= 0) { 174d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu Log.e(TAG, "Invalid aspect ratio: " + aspectRatio); 175d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu return; 176d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu } 177d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu if (aspectRatio < 1f) { 178d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu aspectRatio = 1f / aspectRatio; 179d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu } 180d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu 181d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu if (mAspectRatio != aspectRatio) { 182d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu mAspectRatio = aspectRatio; 183d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu // Update transform matrix with the new aspect ratio. 18470da918464276b110c43868caa272c97baadb89eDoris Liu mController.updatePreviewAspectRatio(mAspectRatio); 185d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu } 186d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu } 187d053a5b2aa8cd9cb09bd40962b305ef34e7d404bDoris Liu 188dcccc510652b835fdbd39310a07849af8203052aAngus Kong @Override 1896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 190d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mController.onPreviewUIReady(); 1916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 192d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 193dcccc510652b835fdbd39310a07849af8203052aAngus Kong @Override 1946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 1956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu // Ignored, Camera does all the work for us 1966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 1976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu 198dcccc510652b835fdbd39310a07849af8203052aAngus Kong @Override 1996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 200d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mController.onPreviewUIDestroyed(); 201d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return true; 2026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 2036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu 2047b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui @Override 2056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void onSurfaceTextureUpdated(SurfaceTexture surface) { 206d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 207d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 208d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public View getRootView() { 209d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb return mRootView; 210d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 211d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 212d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb private void initIndicators() { 2130744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen // TODO init toggle buttons on bottom bar here 214d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 215d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 216b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public void onCameraOpened(Camera.Parameters params) { 217eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague initializeZoom(params); 218eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague } 219eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague 2200a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren public void animateCapture(final byte[] jpegData, int orientation, boolean mirror) { 2210a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren // Decode jpeg byte array and then animate the jpeg 2220a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren DecodeTask task = new DecodeTask(jpegData, orientation, mirror); 2230a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren task.execute(); 224eb3134f6ecc42f7d98625ca2c0ddfb06c9f07c43Spike Sprague } 225d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 226d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // called from onResume but only the first time 227ffbc43c3dd3c94a968a41431fb07645a13696c4aKevin Gabayan public void initializeFirstTime() { 2280744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 229d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 230d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 231d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // called from onResume every other time 232d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void initializeSecondTime(Camera.Parameters params) { 233d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb initializeZoom(params); 234d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mController.isImageCaptureIntent()) { 235d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb hidePostCaptureAlert(); 236d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 237357b7673f03d9b45d281d585cc3f4f87dc7d727bErin Dahlgren // Removes pie menu. 238d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 239d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 2406a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu public void showLocationDialog() { 241491c628441a58f2dd4b5a5745147552d3f3d9decErin Dahlgren AlertDialog alert = mActivity.getFirstTimeLocationAlert(); 242491c628441a58f2dd4b5a5745147552d3f3d9decErin Dahlgren alert.show(); 2436a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu } 2446a83d528b09c55ade6ad44b82c81d4476ac57441Doris Liu 245d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void initializeZoom(Camera.Parameters params) { 246f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu if ((params == null) || !params.isZoomSupported()) return; 247d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mZoomMax = params.getMaxZoom(); 248d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mZoomRatios = params.getZoomRatios(); 249d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // Currently we use immediate zoom for fast zooming to get better UX and 250d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // there is no plan to take advantage of the smooth zoom. 251f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu // TODO: Need to setup a path to AppUI to do this 252f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mPreviewOverlay.setupZoom(mZoomMax, params.getZoom(), mZoomRatios, new ZoomChangeListener()); 253d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 254d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 255c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu public void animateFlash() { 2561dfe7828fd60741b9752553af3ee439c04e758a0Doris Liu mController.startPreCaptureAnimation(); 257c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu } 258c2e9abdcb39a9b8070889ff7a7d829b3eda0c51bDoris Liu 259d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public boolean onBackPressed() { 260d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // In image capture mode, back button should: 261d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // 1) if there is any popup, dismiss them, 2) otherwise, get out of 262d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // image capture 263d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mController.isImageCaptureIntent()) { 264c3679c0961521165499380c77344acc69072b2acDoris Liu mController.onCaptureCancelled(); 265d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb return true; 266d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } else if (!mController.isCameraIdle()) { 267d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // ignore backs while we're taking a picture 268d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb return true; 269d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } else { 270c3679c0961521165499380c77344acc69072b2acDoris Liu return false; 271d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 272d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 273d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 27436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu protected void showCapturedImageForReview(byte[] jpegData, int orientation, boolean mirror) { 27536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu mDecodeTaskForReview = new DecodeImageForReview(jpegData, orientation, mirror); 27636e56fba281292255a01ee00b4bee067fa09ab59Doris Liu mDecodeTaskForReview.execute(); 2774efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2784efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mActivity.getCameraAppUI().transitionToIntentReviewLayout(); 279d31cdfeb1035df8ba939e877031769f0df247aa6Doris Liu pauseFaceDetection(); 280d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 281d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 282d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb protected void hidePostCaptureAlert() { 28336e56fba281292255a01ee00b4bee067fa09ab59Doris Liu if (mDecodeTaskForReview != null) { 28436e56fba281292255a01ee00b4bee067fa09ab59Doris Liu mDecodeTaskForReview.cancel(true); 28536e56fba281292255a01ee00b4bee067fa09ab59Doris Liu } 286d31cdfeb1035df8ba939e877031769f0df247aa6Doris Liu resumeFaceDetection(); 287d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 288d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 289d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void setDisplayOrientation(int orientation) { 290d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mFaceView != null) { 291d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb mFaceView.setDisplayOrientation(orientation); 292d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 293d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 294d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 295d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb // shutter button handling 296d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 297d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public boolean isShutterPressed() { 2980744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen return false; 299d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 300d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 3018890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling /** 3028890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling * Enables or disables the shutter button. 3038890194726507573fd230fba7d4042ed00b363e4Sascha Haeberling */ 3046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void enableShutter(boolean enabled) { 3050744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 3066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 307d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 3086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void pressShutterButton() { 3090744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 3106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu } 311d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 312f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu private class ZoomChangeListener implements PreviewOverlay.OnZoomChangedListener { 313d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb @Override 314d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onZoomValueChanged(int index) { 315f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mController.onZoomChanged(index); 316d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 317d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 318d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb @Override 319d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onZoomStart() { 320d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 321d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 322d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb @Override 323d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onZoomEnd() { 324d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 325d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 326d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 3276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu public void setSwipingEnabled(boolean enable) { 3286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu mActivity.setSwipingEnabled(enable); 329d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 330d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 331d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onPause() { 332d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mFaceView != null) mFaceView.clear(); 333d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 334d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 335d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void clearFaces() { 3360744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen if (mFaceView != null) { 3370744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen mFaceView.clear(); 3380744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 339d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 340d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 341d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void pauseFaceDetection() { 342d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mFaceView != null) mFaceView.pause(); 343d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 344d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 345d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void resumeFaceDetection() { 346d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb if (mFaceView != null) mFaceView.resume(); 347d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 348d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 349d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb public void onStartFaceDetection(int orientation, boolean mirror) { 350d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu if (mFaceView != null) { 351d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.clear(); 352d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.setVisibility(View.VISIBLE); 353d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.setDisplayOrientation(orientation); 354d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.setMirror(mirror); 355d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.resume(); 356d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu } 357d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 358d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 359d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb @Override 3609e76552adff6ecf8b8e4070ecd61699cb6d18269Angus Kong public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) { 361d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu if (mFaceView != null) { 362d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu mFaceView.setFaces(faces); 363d27ea7be496ae823fa88b98760c1a9d9ce0d554dDoris Liu } 364d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb } 365d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb 36659401045bf479b2617c981075aec92190ec59aebDoris Liu /** 3672bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong * Returns a {@link com.android.camera.ui.PreviewStatusListener.PreviewAreaChangedListener} 36859401045bf479b2617c981075aec92190ec59aebDoris Liu * that should be registered to listen to preview area change. 36959401045bf479b2617c981075aec92190ec59aebDoris Liu */ 3702bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong public PreviewAreaChangedListener getPreviewAreaSizeChangedListener() { 37159401045bf479b2617c981075aec92190ec59aebDoris Liu return mFaceView; 37259401045bf479b2617c981075aec92190ec59aebDoris Liu } 37359401045bf479b2617c981075aec92190ec59aebDoris Liu 374d6954f337e20365fc24ecffdd6f30e17c6b31effMichael Kolb} 375