1f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu/* 2f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Copyright (C) 2013 The Android Open Source Project 3f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * 4f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Licensed under the Apache License, Version 2.0 (the "License"); 5f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * you may not use this file except in compliance with the License. 6f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * You may obtain a copy of the License at 7f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * 8f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * http://www.apache.org/licenses/LICENSE-2.0 9f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * 10f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Unless required by applicable law or agreed to in writing, software 11f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * distributed under the License is distributed on an "AS IS" BASIS, 12f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * See the License for the specific language governing permissions and 14f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * limitations under the License. 15f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 16f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 17f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liupackage com.android.camera.app; 18f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1928a2950939614a0c1c83787960ce1a218fb69a5eDoris Liuimport android.content.res.Resources; 20213a4a086b54904cee543adf60b16fc1a61efe38Doris Liuimport android.graphics.Bitmap; 21213a4a086b54904cee543adf60b16fc1a61efe38Doris Liuimport android.graphics.Canvas; 22f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.graphics.Matrix; 23213a4a086b54904cee543adf60b16fc1a61efe38Doris Liuimport android.graphics.RectF; 2406db742814dd635d100639f977fcfdc904deb778Doris Liuimport android.graphics.SurfaceTexture; 2511ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liuimport android.hardware.display.DisplayManager; 265052117cc429d85cf446421ca74859f4365747d3Angus Kongimport android.util.CameraPerformanceTracker; 27f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.GestureDetector; 28f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.LayoutInflater; 29f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.MotionEvent; 30f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.TextureView; 31f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.View; 32f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport android.view.ViewConfiguration; 33e0aff89f3e05eb6008651b290ba79d484de55970Angus Kongimport android.view.ViewGroup; 34c6c9740d996bf073a157721aa3eb2a1aa60c477dDoris Liuimport android.widget.FrameLayout; 3564d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.widget.ImageButton; 36f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 37971ad50c0f220a396ffce50245617ff59ed0a09ezafirimport com.android.camera.AccessibilityUtil; 38f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport com.android.camera.AnimationManager; 39b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgrenimport com.android.camera.ButtonManager; 4028a2950939614a0c1c83787960ce1a218fb69a5eDoris Liuimport com.android.camera.CaptureLayoutHelper; 41b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgrenimport com.android.camera.ShutterButton; 42e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberlingimport com.android.camera.TextureViewHelper; 435596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log; 44b2510252fb020f3ccb88787c870930427377b9dfAngus Kongimport com.android.camera.filmstrip.FilmstripContentPanel; 45b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgrenimport com.android.camera.hardware.HardwareSpec; 46b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgrenimport com.android.camera.module.ModuleController; 476190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgrenimport com.android.camera.settings.Keys; 48b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgrenimport com.android.camera.settings.SettingsManager; 49c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberlingimport com.android.camera.ui.AbstractTutorialOverlay; 500f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Spragueimport com.android.camera.ui.BottomBar; 511dfe7828fd60741b9752553af3ee439c04e758a0Doris Liuimport com.android.camera.ui.CaptureAnimationOverlay; 52b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgrenimport com.android.camera.ui.GridLines; 53f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport com.android.camera.ui.MainActivityLayout; 54f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport com.android.camera.ui.ModeListView; 55f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport com.android.camera.ui.ModeTransitionView; 56f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liuimport com.android.camera.ui.PreviewOverlay; 5706db742814dd635d100639f977fcfdc904deb778Doris Liuimport com.android.camera.ui.PreviewStatusListener; 58427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Huimport com.android.camera.ui.StickyBottomCaptureLayout; 59b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibersimport com.android.camera.ui.TouchCoordinate; 60987ee64612e2510004fdf08536746c87234d01c1Paul Rohdeimport com.android.camera.ui.focus.FocusRing; 618be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohdeimport com.android.camera.util.AndroidServices; 6211ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liuimport com.android.camera.util.ApiHelper; 6311ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liuimport com.android.camera.util.CameraUtil; 649d264309a341c52601bdccdeff6647e0ce58c31fDoris Liuimport com.android.camera.util.Gusterpolator; 65d706ea69a87229dca5cb8f16125decfbcbc5303dErin Dahlgrenimport com.android.camera.util.PhotoSphereHelper; 66e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liuimport com.android.camera.widget.Cling; 67ab05a742fb03b2016d2792c7b06f268d3dd82701Sascha Haeberlingimport com.android.camera.widget.FilmstripLayout; 688793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberlingimport com.android.camera.widget.IndicatorIconController; 69165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgrenimport com.android.camera.widget.ModeOptionsOverlay; 70427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Huimport com.android.camera.widget.RoundedThumbnailView; 71f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liuimport com.android.camera2.R; 72772951602f9cfccd097283e3b78d188838c82138Erin Dahlgren 73f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu/** 74f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * CameraAppUI centralizes control of views shared across modules. Whereas module 75f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * specific views will be handled in each Module UI. For example, we can now 76f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * bring the flash animation and capture animation up from each module to app 77f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * level, as these animations are largely the same for all modules. 78f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * 79f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * This class also serves to disambiguate touch events. It recognizes all the 80f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * swipe gestures that happen on the preview by attaching a touch listener to 81f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * a full-screen view on top of preview TextureView. Since CameraAppUI has knowledge 82f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * of how swipe from each direction should be handled, it can then redirect these 83f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * events to appropriate recipient views. 84f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 8506db742814dd635d100639f977fcfdc904deb778Doris Liupublic class CameraAppUI implements ModeListView.ModeSwitchListener, 863c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren TextureView.SurfaceTextureListener, 873c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren ModeListView.ModeListOpenListener, 88a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren SettingsManager.OnSettingChangedListener, 89a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren ShutterButton.OnShutterButtonListener { 90e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 91e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 92e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * The bottom controls on the filmstrip. 93e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 947ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong public static interface BottomPanel { 95e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** Values for the view state of the button. */ 9600b3371ca5c3340a81174ea5443443a9176d5130Angus Kong public final int VIEWER_NONE = 0; 9700b3371ca5c3340a81174ea5443443a9176d5130Angus Kong public final int VIEWER_PHOTO_SPHERE = 1; 9800b3371ca5c3340a81174ea5443443a9176d5130Angus Kong public final int VIEWER_REFOCUS = 2; 9900b3371ca5c3340a81174ea5443443a9176d5130Angus Kong public final int VIEWER_OTHER = 3; 100e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 101e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 102e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Sets a new or replaces an existing listener for bottom control events. 103e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 104e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong void setListener(Listener listener); 105e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 106e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 107e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * Sets cling for external viewer button. 108e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu */ 109e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu void setClingForViewer(int viewerType, Cling cling); 110e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 111e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu /** 112e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * Clears cling for external viewer button. 113e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu */ 114e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu void clearClingForViewer(int viewerType); 115e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 116e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu /** 117e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * Returns a cling for the specified viewer type. 118e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu */ 119e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu Cling getClingForViewer(int viewerType); 120e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 121e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu /** 122e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Set if the bottom controls are visible. 123e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * @param visible {@code true} if visible. 124e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 125e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong void setVisible(boolean visible); 126e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 127e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 128e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * @param visible Whether the button is visible. 129e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 130e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong void setEditButtonVisibility(boolean visible); 131e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 132e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 133e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong * @param enabled Whether the button is enabled. 134e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong */ 135e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong void setEditEnabled(boolean enabled); 136e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong 137e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong /** 138e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Sets the visibility of the view-photosphere button. 139e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * 14000b3371ca5c3340a81174ea5443443a9176d5130Angus Kong * @param state one of {@link #VIEWER_NONE}, {@link #VIEWER_PHOTO_SPHERE}, 14100b3371ca5c3340a81174ea5443443a9176d5130Angus Kong * {@link #VIEWER_REFOCUS}. 142e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 14300b3371ca5c3340a81174ea5443443a9176d5130Angus Kong void setViewerButtonVisibility(int state); 144e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 145e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 146e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong * @param enabled Whether the button is enabled. 147e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong */ 148e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong void setViewEnabled(boolean enabled); 149e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong 150e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong /** 151e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong * @param enabled Whether the button is enabled. 152e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong */ 153e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong void setTinyPlanetEnabled(boolean enabled); 154e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong 155e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong /** 156e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * @param visible Whether the button is visible. 157e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 158e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong void setDeleteButtonVisibility(boolean visible); 159e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 160e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 161e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong * @param enabled Whether the button is enabled. 162e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong */ 163e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong void setDeleteEnabled(boolean enabled); 164e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong 165e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong /** 166e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * @param visible Whether the button is visible. 167e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 168e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong void setShareButtonVisibility(boolean visible); 169e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 170e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 171e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong * @param enabled Whether the button is enabled. 172e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong */ 173e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong void setShareEnabled(boolean enabled); 174e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong 175e4002f3a703a1835dce30d74ccfc22e00956e13fAngus Kong /** 1767ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * Sets the texts for progress UI. 1777ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * 1787ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * @param text The text to show. 1797ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong */ 1807ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong void setProgressText(CharSequence text); 1817ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong 1827ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong /** 1837ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * Sets the progress. 1847ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * 1857ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * @param progress The progress value. Should be between 0 and 100. 1867ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong */ 1877ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong void setProgress(int progress); 1887ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong 1897ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong /** 190597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling * Replaces the progress UI with an error message. 191597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling */ 192597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling void showProgressError(CharSequence message); 193597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling 194597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling /** 195597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling * Hide the progress error message. 196597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling */ 197597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling void hideProgressError(); 198597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling 199597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling /** 200001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong * Shows the progress. 2017ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong */ 2027ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong void showProgress(); 2037ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong 2047ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong /** 205001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong * Hides the progress. 206001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong */ 207001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong void hideProgress(); 208001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong 209001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong /** 210001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong * Shows the controls. 2117ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong */ 2127ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong void showControls(); 2137ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong 2147ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong /** 215001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong * Hides the controls. 216001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong */ 217001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong void hideControls(); 218001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong 219001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong /** 220e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Classes implementing this interface can listen for events on the bottom 221e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * controls. 222e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 223e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong public static interface Listener { 224e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 225e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Called when the user pressed the "view" button to e.g. view a photo 226e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * sphere or RGBZ image. 227e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 2288a2350a3d557465b53445685db0f9ac838cf90c5Angus Kong public void onExternalViewer(); 229e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 230e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 231e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Called when the "edit" button is pressed. 232e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 233e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong public void onEdit(); 234e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 235e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 236e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Called when the "tiny planet" button is pressed. 237e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 238e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong public void onTinyPlanet(); 239e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 240e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 241e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Called when the "delete" button is pressed. 242e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 243e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong public void onDelete(); 244e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 245e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong /** 246e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong * Called when the "share" button is pressed. 247e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong */ 248e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong public void onShare(); 249597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling 250597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling /** 251597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling * Called when the progress error message is clicked. 252597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling */ 253597c1a093f840af3c42e00af05da01ef124dc846Sascha Haeberling public void onProgressErrorClicked(); 254e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong } 255e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong } 256e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong 257b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 258b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * BottomBarUISpec provides a structure for modules 259b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * to specify their ideal bottom bar mode options layout. 260b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 261b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Once constructed by a module, this class should be 262b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * treated as read only. 263b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 264b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * The application then edits this spec according to 265b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * hardware limitations and displays the final bottom 266b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * bar ui. 267b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 268b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public static class BottomBarUISpec { 269b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** Mode options UI */ 270b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 271b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 272b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the camera option should be enabled. 273b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If not set or false, and multiple cameras are supported, 274b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * the camera option will be disabled. 275b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 276b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If multiple cameras are not supported, this preference 277b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * is ignored and the camera option will not be visible. 278b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 279b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean enableCamera; 280b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 281b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 282a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren * Set true if the camera option should not be visible, regardless 283a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren * of hardware limitations. 284a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren */ 285a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren public boolean hideCamera; 286a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren 287a9ceaf76b72cb4b499d3d9d90f979bae93bd593dErin Dahlgren /** 288b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the photo flash option should be enabled. 289b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If not set or false, the photo flash option will be 290b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * disabled. 291b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 292b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If the hardware does not support multiple flash values, 293b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * this preference is ignored and the flash option will 294b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * be disabled. It will not be made invisible in order to 295b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * preserve a consistent experience across devices and between 296b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * front and back cameras. 297b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 298b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean enableFlash; 299b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 300b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 301b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the video flash option should be enabled. 302b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Same disable rules apply as the photo flash option. 303b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 304b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean enableTorchFlash; 305b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 306b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 30715473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren * Set true if the HDR+ flash option should be enabled. 30815473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren * Same disable rules apply as the photo flash option. 30915473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren */ 31015473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren public boolean enableHdrPlusFlash; 31115473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren 31215473d4b69f4ad619aa10430e4bc86ab4fa815d0Erin Dahlgren /** 313d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * Set true if flash should not be visible, regardless of 314d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * hardware limitations. 315d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren */ 316d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public boolean hideFlash; 317d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren 318d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren /** 319b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the hdr/hdr+ option should be enabled. 320b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If not set or false, the hdr/hdr+ option will be disabled. 321b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 322b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Hdr or hdr+ will be chosen based on hardware limitations, 323b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * with hdr+ prefered. 324b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 325b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * If hardware supports neither hdr nor hdr+, then the hdr/hdr+ 326b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * will not be visible. 327b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 328b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean enableHdr; 329b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 330b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 331d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * Set true if hdr/hdr+ should not be visible, regardless of 332b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * hardware limitations. 333b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 334d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public boolean hideHdr; 335b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 336b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 337d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * Set true if grid lines should be visible. Not setting this 338d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * causes grid lines to be disabled. This option is agnostic to 339d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * the hardware. 340b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 341d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public boolean enableGridLines; 342d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren 343d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren /** 344d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * Set true if grid lines should not be visible. 345d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren */ 346d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public boolean hideGridLines; 347b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 348a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren /** 349f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * Set true if the panorama orientation option should be visible. 350a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren * 351a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren * This option is not constrained by hardware limitations. 352a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren */ 353f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren public boolean enablePanoOrientation; 354a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren 35557c889d4b88517dd0996547dbae4f314c2a3fcdfzafir /** 35657c889d4b88517dd0996547dbae4f314c2a3fcdfzafir * Set true if manual exposure compensation should be visible. 35757c889d4b88517dd0996547dbae4f314c2a3fcdfzafir * 35857c889d4b88517dd0996547dbae4f314c2a3fcdfzafir * This option is not constrained by hardware limitations. 35957c889d4b88517dd0996547dbae4f314c2a3fcdfzafir * For example, this is false in HDR+ mode. 36057c889d4b88517dd0996547dbae4f314c2a3fcdfzafir */ 361abf54e2994961395a0feb0b08353e62718443f23Spike Sprague public boolean enableExposureCompensation; 362abf54e2994961395a0feb0b08353e62718443f23Spike Sprague 36357c889d4b88517dd0996547dbae4f314c2a3fcdfzafir /** 3646ffdeac1670c8938d0331c89d9269b68f361d6fazafir * Set true if the device and module support exposure compensation. 3656ffdeac1670c8938d0331c89d9269b68f361d6fazafir * Used only to show exposure button in disabled (greyed out) state. 36657c889d4b88517dd0996547dbae4f314c2a3fcdfzafir */ 36757c889d4b88517dd0996547dbae4f314c2a3fcdfzafir public boolean isExposureCompensationSupported; 36857c889d4b88517dd0996547dbae4f314c2a3fcdfzafir 369b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** Intent UI */ 370b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 371b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 372b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the intent ui cancel option should be visible. 373b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 374b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean showCancel; 375b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 376b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the intent ui done option should be visible. 377b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 378b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean showDone; 379b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 380b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the intent ui retake option should be visible. 381b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 382b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean showRetake; 383b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 384b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Set true if the intent ui review option should be visible. 385b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 386b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public boolean showReview; 387b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 388b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** Mode options callbacks */ 389b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 390b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 391f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * A {@link com.android.camera.ButtonManager.ButtonCallback} 392b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * that will be executed when the camera option is pressed. This 393b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * callback can be null. 394b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 395b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public ButtonManager.ButtonCallback cameraCallback; 396b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 397b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 398f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * A {@link com.android.camera.ButtonManager.ButtonCallback} 399b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * that will be executed when the flash option is pressed. This 400b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * callback can be null. 401b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 402b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public ButtonManager.ButtonCallback flashCallback; 403b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 404b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 405f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * A {@link com.android.camera.ButtonManager.ButtonCallback} 406b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * that will be executed when the hdr/hdr+ option is pressed. This 407b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * callback can be null. 408b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 409b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public ButtonManager.ButtonCallback hdrCallback; 410b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 411b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 412f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * A {@link com.android.camera.ButtonManager.ButtonCallback} 413d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * that will be executed when the grid lines option is pressed. This 414b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * callback can be null. 415b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 416d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public ButtonManager.ButtonCallback gridLinesCallback; 417b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 418a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren /** 419f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * A {@link com.android.camera.ButtonManager.ButtonCallback} 420f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren * that will execute when the panorama orientation option is pressed. 421a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren * This callback can be null. 422a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren */ 423f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren public ButtonManager.ButtonCallback panoOrientationCallback; 424a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren 425b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** Intent UI callbacks */ 426b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 427b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 428b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * A {@link android.view.View.OnClickListener} that will execute 429b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * when the cancel option is pressed. This callback can be null. 430b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 431b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public View.OnClickListener cancelCallback; 432b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 433b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 434b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * A {@link android.view.View.OnClickListener} that will execute 435b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * when the done option is pressed. This callback can be null. 436b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 437b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public View.OnClickListener doneCallback; 438b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 439b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 440b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * A {@link android.view.View.OnClickListener} that will execute 441b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * when the retake option is pressed. This callback can be null. 442b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 443b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public View.OnClickListener retakeCallback; 444b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 445b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 446b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * A {@link android.view.View.OnClickListener} that will execute 447b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * when the review option is pressed. This callback can be null. 448b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 449b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren public View.OnClickListener reviewCallback; 450abf54e2994961395a0feb0b08353e62718443f23Spike Sprague 451abf54e2994961395a0feb0b08353e62718443f23Spike Sprague /** 452abf54e2994961395a0feb0b08353e62718443f23Spike Sprague * A ExposureCompensationSetCallback that will execute 453abf54e2994961395a0feb0b08353e62718443f23Spike Sprague * when an expsosure button is pressed. This callback can be null. 454abf54e2994961395a0feb0b08353e62718443f23Spike Sprague */ 455abf54e2994961395a0feb0b08353e62718443f23Spike Sprague public interface ExposureCompensationSetCallback { 456a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague public void setExposure(int value); 457abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 458abf54e2994961395a0feb0b08353e62718443f23Spike Sprague public ExposureCompensationSetCallback exposureCompensationSetCallback; 459a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague 460a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague /** 461a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague * Exposure compensation parameters. 462a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague */ 463a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague public int minExposureCompensation; 464a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague public int maxExposureCompensation; 465a479fcaad5b83c8fbb881f491d93145531b25cbaSpike Sprague public float exposureCompensationStep; 4666c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu 4676c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu /** 4684333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling * Whether self-timer is enabled. 4696c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu */ 4706c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu public boolean enableSelfTimer = false; 4714333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling 4724333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling /** 4734333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling * Whether the option for self-timer should show. If true and 4744333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling * {@link #enableSelfTimer} is false, then the option should be shown 4754333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling * disabled. 4764333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling */ 4774333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling public boolean showSelfTimer = false; 478b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 479b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 480b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 4815596b4c902dcb685928b43678f428746ca5ffd08Angus Kong private final static Log.Tag TAG = new Log.Tag("CameraAppUI"); 482f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 483f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final AppController mController; 484f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final boolean mIsCaptureIntent; 485f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final AnimationManager mAnimationManager; 486f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 487f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Swipe states: 4882b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int IDLE = 0; 4892b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int SWIPE_UP = 1; 4902b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int SWIPE_DOWN = 2; 4912b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int SWIPE_LEFT = 3; 4922b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int SWIPE_RIGHT = 4; 4938793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling private boolean mSwipeEnabled = true; 494f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 495d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren // Shared Surface Texture properities. 496d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren private SurfaceTexture mSurface; 497d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren private int mSurfaceWidth; 498d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren private int mSurfaceHeight; 499d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 500f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Touch related measures: 501f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final int mSlop; 5022b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int SWIPE_TIME_OUT_MS = 500; 5032b906b8c9754b564d5113c7a342654c82f97f180Doris Liu 5042b906b8c9754b564d5113c7a342654c82f97f180Doris Liu // Mode cover states: 5052b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int COVER_HIDDEN = 0; 5062b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int COVER_SHOWN = 1; 5072b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private final static int COVER_WILL_HIDE_AT_NEXT_FRAME = 2; 5087e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin private final static int COVER_WILL_HIDE_AFTER_NEXT_TEXTURE_UPDATE = 3; 5097e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin private final static int COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE = 4; 510f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 5116809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu /** 5126809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * Preview down-sample rate when taking a screenshot. 5136809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu */ 5146809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu private final static int DOWN_SAMPLE_RATE_FOR_SCREENSHOT = 2; 5156809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu 516f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // App level views: 517b41034b16b0dce997544d2592db5029e7db4e238Doris Liu private final FrameLayout mCameraRootView; 518f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final ModeTransitionView mModeTransitionView; 519f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final MainActivityLayout mAppRootView; 520f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private final ModeListView mModeListView; 521166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong private final FilmstripLayout mFilmstripLayout; 522f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private TextureView mTextureView; 523c6c9740d996bf073a157721aa3eb2a1aa60c477dDoris Liu private FrameLayout mModuleUI; 5245d18769f53db81d401488811250570290a73626bErin Dahlgren private ShutterButton mShutterButton; 52564d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling private ImageButton mCountdownCancelButton; 52670da918464276b110c43868caa272c97baadb89eDoris Liu private BottomBar mBottomBar; 527165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren private ModeOptionsOverlay mModeOptionsOverlay; 528e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren private IndicatorIconController mIndicatorIconController; 529987ee64612e2510004fdf08536746c87234d01c1Paul Rohde private FocusRing mFocusRing; 5301e0810c88e791d0f658eb5a6f95d771ee03a7631Sascha Haeberling private FrameLayout mTutorialsPlaceHolderWrapper; 531427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu private StickyBottomCaptureLayout mStickyBottomCaptureLayout; 53270da918464276b110c43868caa272c97baadb89eDoris Liu private TextureViewHelper mTextureViewHelper; 533ab05a742fb03b2016d2792c7b06f268d3dd82701Sascha Haeberling private final GestureDetector mGestureDetector; 53411ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu private DisplayManager.DisplayListener mDisplayListener; 53511ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu private int mLastRotation; 536f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private int mSwipeState = IDLE; 537f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu private PreviewOverlay mPreviewOverlay; 538b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren private GridLines mGridLines; 5391dfe7828fd60741b9752553af3ee439c04e758a0Doris Liu private CaptureAnimationOverlay mCaptureOverlay; 54006db742814dd635d100639f977fcfdc904deb778Doris Liu private PreviewStatusListener mPreviewStatusListener; 5412b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private int mModeCoverState = COVER_HIDDEN; 5427ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong private final FilmstripBottomPanel mFilmstripBottomControls; 543ab05a742fb03b2016d2792c7b06f268d3dd82701Sascha Haeberling private final FilmstripContentPanel mFilmstripPanel; 544b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu private Runnable mHideCoverRunnable; 5454a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu private final View.OnLayoutChangeListener mPreviewLayoutChangeListener 5464a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu = new View.OnLayoutChangeListener() { 5474a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu @Override 5484a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, 5494a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu int oldTop, int oldRight, int oldBottom) { 5504a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu if (mPreviewStatusListener != null) { 5514a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu mPreviewStatusListener.onPreviewLayoutChanged(v, left, top, right, bottom, oldLeft, 5524a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu oldTop, oldRight, oldBottom); 5534a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu } 5544a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu } 5554a010db8a60008b2bf67b93b64f77f63affc29f3Doris Liu }; 5569d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu private View mModeOptionsToggle; 557427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu private final RoundedThumbnailView mRoundedThumbnailView; 55828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu private final CaptureLayoutHelper mCaptureLayoutHelper; 559256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling private final View mAccessibilityAffordances; 560971ad50c0f220a396ffce50245617ff59ed0a09ezafir private AccessibilityUtil mAccessibilityUtil; 561f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 562d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague private boolean mDisableAllUserInteractions; 563ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu /** Whether to prevent capture indicator from being triggered. */ 564ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu private boolean mSuppressCaptureIndicator; 565ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu 5664368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava /** Supported HDR mode (none, hdr, hdr+). */ 5674368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava private String mHdrSupportMode; 568ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 569ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava /** Used to track the last scope used to update the bottom bar UI. */ 570ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava private String mCurrentCameraScope; 571ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava private String mCurrentModuleScope; 572ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 573213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu /** 574213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * Provides current preview frame and the controls/overlay from the module that 575213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * are shown on top of the preview. 576213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu */ 577213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public interface CameraModuleScreenShotProvider { 578213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu /** 579213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * Returns the current preview frame down-sampled using the given down-sample 580213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * factor. 581213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * 582213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * @param downSampleFactor the down sample factor for down sampling the 583213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * preview frame. (e.g. a down sample factor of 584213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * 2 means to scale down the preview frame to 1/2 585213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * the width and height.) 586213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * @return down-sampled preview frame 587213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu */ 588213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public Bitmap getPreviewFrame(int downSampleFactor); 589213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu 590213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu /** 591213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * @return the controls and overlays that are currently showing on top of 592213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu * the preview drawn into a bitmap with no scaling applied. 593213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu */ 594213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public Bitmap getPreviewOverlayAndControls(); 5956809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu 5966809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu /** 5976809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * Returns a bitmap containing the current screenshot. 5986809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * 5996809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * @param previewDownSampleFactor the downsample factor applied on the 6006809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * preview frame when taking the screenshot 6016809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu */ 6026809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu public Bitmap getScreenShot(int previewDownSampleFactor); 603213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu } 604213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu 6059d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu /** 60628a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu * This listener gets called when the size of the window (excluding the system 60728a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu * decor such as status bar and nav bar) has changed. 6089d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu */ 60928a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu public interface NonDecorWindowSizeChangedListener { 610344320c90639f823451ddac42e8f39b74727787cDoris Liu public void onNonDecorWindowSizeChanged(int width, int height, int rotation); 6119d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu } 6129d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu 613213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu private final CameraModuleScreenShotProvider mCameraModuleScreenShotProvider = 614213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu new CameraModuleScreenShotProvider() { 615213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu @Override 616213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public Bitmap getPreviewFrame(int downSampleFactor) { 617213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu if (mCameraRootView == null || mTextureView == null) { 618213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu return null; 619213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu } 620213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu // Gets the bitmap from the preview TextureView. 621274f6e962e9e7f94cfc4ceb9cad3fa8dc0a80abbSeth Raphael Bitmap preview = mTextureViewHelper.getPreviewBitmap(downSampleFactor); 622213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu return preview; 623213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu } 624213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu 625213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu @Override 626213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public Bitmap getPreviewOverlayAndControls() { 627213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu Bitmap overlays = Bitmap.createBitmap(mCameraRootView.getWidth(), 628213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu mCameraRootView.getHeight(), Bitmap.Config.ARGB_8888); 629213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu Canvas canvas = new Canvas(overlays); 630213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu mCameraRootView.draw(canvas); 631213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu return overlays; 632213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu } 6336809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu 6346809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu @Override 6356809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu public Bitmap getScreenShot(int previewDownSampleFactor) { 6366809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu Bitmap screenshot = Bitmap.createBitmap(mCameraRootView.getWidth(), 6376809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu mCameraRootView.getHeight(), Bitmap.Config.ARGB_8888); 6386809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu Canvas canvas = new Canvas(screenshot); 6396809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu canvas.drawARGB(255, 0, 0, 0); 640274f6e962e9e7f94cfc4ceb9cad3fa8dc0a80abbSeth Raphael Bitmap preview = mTextureViewHelper.getPreviewBitmap(previewDownSampleFactor); 6416809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu if (preview != null) { 6426809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu canvas.drawBitmap(preview, null, mTextureViewHelper.getPreviewArea(), null); 6436809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu } 6446809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu Bitmap overlay = getPreviewOverlayAndControls(); 6456809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu if (overlay != null) { 6466809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu canvas.drawBitmap(overlay, 0f, 0f, null); 6476809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu } 6486809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu return screenshot; 6496809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu } 650213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu }; 651213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu 652a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan private long mCoverHiddenTime = -1; // System time when preview cover was hidden. 653a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan 654a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan public long getCoverHiddenTime() { 655a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan return mCoverHiddenTime; 656a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan } 657a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan 658d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 659d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * This resets the preview to have no applied transform matrix. 660d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 661d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void clearPreviewTransform() { 662d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mTextureViewHelper.clearTransform(); 663d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 664d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 66570da918464276b110c43868caa272c97baadb89eDoris Liu public void updatePreviewAspectRatio(float aspectRatio) { 66670da918464276b110c43868caa272c97baadb89eDoris Liu mTextureViewHelper.updateAspectRatio(aspectRatio); 6670f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague } 6680f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague 6697bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk /** 6707bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * WAR: Reset the SurfaceTexture's default buffer size to the current view dimensions of 6717bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * its TextureView. This is necessary to get the expected behavior for the TextureView's 6727bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * HardwareLayer transform matrix (set by TextureView#setTransform) after configuring the 6737bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * SurfaceTexture as an output for the Camera2 API (which involves changing the default buffer 6747bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * size). 6757bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * 6767bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk * b/17286155 - Tracking a fix for this in HardwareLayer. 6777bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk */ 6787bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk public void setDefaultBufferSizeToViewDimens() { 6797bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk if (mSurface == null || mTextureView == null) { 6807bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk Log.w(TAG, "Could not set SurfaceTexture default buffer dimensions, not yet setup"); 6817bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk return; 6827bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk } 6837bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk mSurface.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight()); 6847bae31a17a7913b58b96787185cd965baef97f76Ruben Brunk } 68502c129a598b6a165885fe950275675d62993d2eeSeth Raphael 68602c129a598b6a165885fe950275675d62993d2eeSeth Raphael /** 6876382c70a769b9ec94a3b0372ee27c0cd075e8be8Seth Raphael * Updates the preview matrix without altering it. 688159e6e9ca0d0ecb53d49765c75fd7a0b2afef965Spike Sprague * 68902c129a598b6a165885fe950275675d62993d2eeSeth Raphael * @param matrix 6906382c70a769b9ec94a3b0372ee27c0cd075e8be8Seth Raphael * @param aspectRatio the desired aspect ratio for the preview. 69102c129a598b6a165885fe950275675d62993d2eeSeth Raphael */ 6926382c70a769b9ec94a3b0372ee27c0cd075e8be8Seth Raphael public void updatePreviewTransformFullscreen(Matrix matrix, float aspectRatio) { 6936382c70a769b9ec94a3b0372ee27c0cd075e8be8Seth Raphael mTextureViewHelper.updateTransformFullScreen(matrix, aspectRatio); 69402c129a598b6a165885fe950275675d62993d2eeSeth Raphael } 69502c129a598b6a165885fe950275675d62993d2eeSeth Raphael 69602c129a598b6a165885fe950275675d62993d2eeSeth Raphael /** 69702c129a598b6a165885fe950275675d62993d2eeSeth Raphael * @return the rect that will display the preview. 69802c129a598b6a165885fe950275675d62993d2eeSeth Raphael */ 69902c129a598b6a165885fe950275675d62993d2eeSeth Raphael public RectF getFullscreenRect() { 70002c129a598b6a165885fe950275675d62993d2eeSeth Raphael return mTextureViewHelper.getFullscreenRect(); 70102c129a598b6a165885fe950275675d62993d2eeSeth Raphael } 70202c129a598b6a165885fe950275675d62993d2eeSeth Raphael 703b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu /** 704b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu * This is to support modules that calculate their own transform matrix because 705b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu * they need to use a transform matrix to rotate the preview. 706b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu * 707b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu * @param matrix transform matrix to be set on the TextureView 708b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu */ 70970da918464276b110c43868caa272c97baadb89eDoris Liu public void updatePreviewTransform(Matrix matrix) { 71070da918464276b110c43868caa272c97baadb89eDoris Liu mTextureViewHelper.updateTransform(matrix); 711b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu } 712b897a1e924394cb2196929975cf0c5cb542dd85cDoris Liu 713f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public interface AnimationFinishedListener { 714f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void onAnimationFinished(boolean success); 715f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 716f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 717f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private class MyTouchListener implements View.OnTouchListener { 718f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu private boolean mScaleStarted = false; 719f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu @Override 720f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public boolean onTouch(View v, MotionEvent event) { 721f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 722f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mScaleStarted = false; 723f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu } else if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { 724f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mScaleStarted = true; 725f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu } 726f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu return (!mScaleStarted) && mGestureDetector.onTouchEvent(event); 727f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 728f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 729f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 730f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 731f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * This gesture listener finds out the direction of the scroll gestures and 732f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * sends them to CameraAppUI to do further handling. 733f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 734f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { 735f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private MotionEvent mDown; 736f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 737f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu @Override 738f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public boolean onScroll(MotionEvent e1, MotionEvent ev, float distanceX, float distanceY) { 7392b906b8c9754b564d5113c7a342654c82f97f180Doris Liu if (ev.getEventTime() - ev.getDownTime() > SWIPE_TIME_OUT_MS 740c050a9475312db95bcd6d3ec8480065ee8104954Spike Sprague || mSwipeState != IDLE 7418793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling || mIsCaptureIntent 7428793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling || !mSwipeEnabled) { 743b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu return false; 744f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 745f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 746f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu int deltaX = (int) (ev.getX() - mDown.getX()); 747f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu int deltaY = (int) (ev.getY() - mDown.getY()); 748f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { 749f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (Math.abs(deltaX) > mSlop || Math.abs(deltaY) > mSlop) { 750f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Calculate the direction of the swipe. 751f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (deltaX >= Math.abs(deltaY)) { 752f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Swipe right. 753f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu setSwipeState(SWIPE_RIGHT); 754f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } else if (deltaX <= -Math.abs(deltaY)) { 755f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Swipe left. 756f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu setSwipeState(SWIPE_LEFT); 757f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 758f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 759f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 760f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu return true; 761f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 762f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 763f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private void setSwipeState(int swipeState) { 764f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mSwipeState = swipeState; 765f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Notify new swipe detected. 766f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu onSwipeDetected(swipeState); 767f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 768f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 769f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu @Override 770f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public boolean onDown(MotionEvent ev) { 771f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mDown = MotionEvent.obtain(ev); 772f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mSwipeState = IDLE; 773f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu return false; 774f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 775f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 776f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 777f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public CameraAppUI(AppController controller, MainActivityLayout appRootView, 7788793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling boolean isCaptureIntent) { 779f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mSlop = ViewConfiguration.get(controller.getAndroidContext()).getScaledTouchSlop(); 780f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mController = controller; 781f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mIsCaptureIntent = isCaptureIntent; 782f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 783f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAppRootView = appRootView; 784166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong mFilmstripLayout = (FilmstripLayout) appRootView.findViewById(R.id.filmstrip_layout); 785b41034b16b0dce997544d2592db5029e7db4e238Doris Liu mCameraRootView = (FrameLayout) appRootView.findViewById(R.id.camera_app_root); 786f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mModeTransitionView = (ModeTransitionView) 787f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAppRootView.findViewById(R.id.mode_transition_view); 7887ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong mFilmstripBottomControls = new FilmstripBottomPanel(controller, 789001dc31f0b6e78b70db83c6d9b8cc7872e540965Angus Kong (ViewGroup) mAppRootView.findViewById(R.id.filmstrip_bottom_panel)); 790b2510252fb020f3ccb88787c870930427377b9dfAngus Kong mFilmstripPanel = (FilmstripContentPanel) mAppRootView.findViewById(R.id.filmstrip_layout); 791f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mGestureDetector = new GestureDetector(controller.getAndroidContext(), 792f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu new MyGestureListener()); 79328a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu Resources res = controller.getAndroidContext().getResources(); 79428a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mCaptureLayoutHelper = new CaptureLayoutHelper( 79528a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu res.getDimensionPixelSize(R.dimen.bottom_bar_height_min), 79628a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu res.getDimensionPixelSize(R.dimen.bottom_bar_height_max), 79728a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu res.getDimensionPixelSize(R.dimen.bottom_bar_height_optimal)); 798f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mModeListView = (ModeListView) appRootView.findViewById(R.id.mode_list_layout); 799f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (mModeListView != null) { 800f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mModeListView.setModeSwitchListener(this); 8012c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu mModeListView.setModeListOpenListener(this); 802213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu mModeListView.setCameraModuleScreenShotProvider(mCameraModuleScreenShotProvider); 80328a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mModeListView.setCaptureLayoutHelper(mCaptureLayoutHelper); 80426aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu boolean shouldShowSettingsCling = mController.getSettingsManager().getBoolean( 8056190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren SettingsManager.SCOPE_GLOBAL, 8066190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren Keys.KEY_SHOULD_SHOW_SETTINGS_BUTTON_CLING); 80726aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mModeListView.setShouldShowSettingsCling(shouldShowSettingsCling); 808f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } else { 809f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu Log.e(TAG, "Cannot find mode list in the view hierarchy"); 810f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 811f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAnimationManager = new AnimationManager(); 812427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mRoundedThumbnailView = (RoundedThumbnailView) appRootView.findViewById(R.id.rounded_thumbnail_view); 813cb8f66b4953e4fed4a0cd5133c2914b26097c133Senpo Hu mRoundedThumbnailView.setCallback(new RoundedThumbnailView.Callback() { 814427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu @Override 815cb8f66b4953e4fed4a0cd5133c2914b26097c133Senpo Hu public void onHitStateFinished() { 816427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mFilmstripLayout.showFilmstrip(); 817427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu } 818427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu }); 819427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu 82028a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mAppRootView.setNonDecorWindowSizeChangedListener(mCaptureLayoutHelper); 82111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu initDisplayListener(); 822256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mAccessibilityAffordances = mAppRootView.findViewById(R.id.accessibility_affordances); 823dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu View modeListToggle = mAppRootView.findViewById(R.id.accessibility_mode_toggle_button); 824dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu modeListToggle.setOnClickListener(new View.OnClickListener() { 825dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu @Override 826dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu public void onClick(View view) { 827256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling openModeList(); 828dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } 829dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu }); 830dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu View filmstripToggle = mAppRootView.findViewById( 831dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu R.id.accessibility_filmstrip_toggle_button); 832dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu filmstripToggle.setOnClickListener(new View.OnClickListener() { 833dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu @Override 834dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu public void onClick(View view) { 835256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling showFilmstrip(); 836dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } 837dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu }); 838ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu 839ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu mSuppressCaptureIndicator = false; 84011ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 84111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 8426809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu 8436809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu /** 8446809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * Freeze what is currently shown on screen until the next preview frame comes 8456809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu * in. 8466809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu */ 8476809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu public void freezeScreenUntilPreviewReady() { 848c91c8d273b8884468dfd66a5b82526dc8245934eAlan Newberger Log.v(TAG, "freezeScreenUntilPreviewReady"); 8496809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu mModeTransitionView.setupModeCover(mCameraModuleScreenShotProvider 8506809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu .getScreenShot(DOWN_SAMPLE_RATE_FOR_SCREENSHOT)); 8516809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu mHideCoverRunnable = new Runnable() { 8526809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu @Override 8536809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu public void run() { 8546809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu mModeTransitionView.hideImageCover(); 8556809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu } 8566809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu }; 8576809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu mModeCoverState = COVER_SHOWN; 8586809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu } 8596809eb840f358430d3032c0532fb42d6dcfd06efDoris Liu 86011ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu /** 861e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * Creates a cling for the specific viewer and links the cling to the corresponding 862e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * button for layout position. 863e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * 864e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * @param viewerType defines which viewer the cling is for. 865e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu */ 866e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu public void setupClingForViewer(int viewerType) { 867e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu if (viewerType == BottomPanel.VIEWER_REFOCUS) { 868e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu FrameLayout filmstripContent = (FrameLayout) mAppRootView 869e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu .findViewById(R.id.camera_filmstrip_content_layout); 870e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu if (filmstripContent != null) { 871e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu // Creates refocus cling. 8728be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde LayoutInflater inflater = AndroidServices.instance().provideLayoutInflater(); 873e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu Cling refocusCling = (Cling) inflater.inflate(R.layout.cling_widget, null, false); 874e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu // Sets instruction text in the cling. 875e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu refocusCling.setText(mController.getAndroidContext().getResources() 876e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu .getString(R.string.cling_text_for_refocus_editor_button)); 877e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 878e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu // Adds cling into view hierarchy. 879e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu int clingWidth = mController.getAndroidContext() 880e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu .getResources().getDimensionPixelSize(R.dimen.default_cling_width); 881e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu filmstripContent.addView(refocusCling, clingWidth, 882e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu ViewGroup.LayoutParams.WRAP_CONTENT); 883e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu mFilmstripBottomControls.setClingForViewer(viewerType, refocusCling); 884e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu } 885e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu } 886e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu } 887e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 888e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu /** 889e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * Clears the listeners for the cling and remove it from the view hierarchy. 890e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * 891e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu * @param viewerType defines which viewer the cling is for. 892e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu */ 893e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu public void clearClingForViewer(int viewerType) { 894e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu Cling clingToBeRemoved = mFilmstripBottomControls.getClingForViewer(viewerType); 895e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu if (clingToBeRemoved == null) { 896e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu // No cling is created for the specific viewer type. 897e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu return; 898e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu } 899e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu mFilmstripBottomControls.clearClingForViewer(viewerType); 900e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu clingToBeRemoved.setVisibility(View.GONE); 901e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu mAppRootView.removeView(clingToBeRemoved); 902e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu } 903e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu 904e7d7b9ef5e09ba464306565c6c62302a4d9bbe5eDoris Liu /** 9058793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling * Enable or disable swipe gestures. We want to disable them e.g. while we 9068793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling * record a video. 9078793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling */ 9088793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling public void setSwipeEnabled(boolean enabled) { 9098793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling mSwipeEnabled = enabled; 9109eb517f4c4bcf00fbe435a56f89d3abcaaa4d881Doris Liu // TODO: This can be removed once we come up with a new design for handling swipe 9119eb517f4c4bcf00fbe435a56f89d3abcaaa4d881Doris Liu // on shutter button and mode options. (More details: b/13751653) 9129eb517f4c4bcf00fbe435a56f89d3abcaaa4d881Doris Liu mAppRootView.setSwipeEnabled(enabled); 9138793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling } 9148793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling 915846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling public void onDestroy() { 9168be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde AndroidServices.instance().provideDisplayManager() 917846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling .unregisterDisplayListener(mDisplayListener); 918846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling } 919846d3abfe3da2fa2a5593c7d40a196005408bed1Sascha Haeberling 9208793eff1b85bda89047316fed36cdc1161a8b811Sascha Haeberling /** 92111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu * Initializes the display listener to listen to display changes such as 92211ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu * 180-degree rotation change, which will not have an onConfigurationChanged 92311ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu * callback. 92411ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu */ 92511ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu private void initDisplayListener() { 92611ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu if (ApiHelper.HAS_DISPLAY_LISTENER) { 9278be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde mLastRotation = CameraUtil.getDisplayRotation(); 92811ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 92911ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu mDisplayListener = new DisplayManager.DisplayListener() { 93011ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu @Override 93111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu public void onDisplayAdded(int arg0) { 93211ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu // Do nothing. 93311ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 93411ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 93511ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu @Override 93611ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu public void onDisplayChanged(int displayId) { 93711ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu int rotation = CameraUtil.getDisplayRotation( 9388be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde ); 9396365bad43ff3e3e93d4e8c7e6dc22cbc96eb1aafDoris Liu if ((rotation - mLastRotation + 360) % 360 == 180 9406365bad43ff3e3e93d4e8c7e6dc22cbc96eb1aafDoris Liu && mPreviewStatusListener != null) { 94111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu mPreviewStatusListener.onPreviewFlipped(); 942427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mStickyBottomCaptureLayout.requestLayout(); 943344320c90639f823451ddac42e8f39b74727787cDoris Liu mModeListView.requestLayout(); 944344320c90639f823451ddac42e8f39b74727787cDoris Liu mTextureView.requestLayout(); 94511ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 94611ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu mLastRotation = rotation; 94711ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 94811ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 94911ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu @Override 95011ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu public void onDisplayRemoved(int arg0) { 95111ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu // Do nothing. 95211ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 95311ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu }; 95411ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu 9558be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde AndroidServices.instance().provideDisplayManager() 9568be316c7a8caf962cf3fcf5e49d332fb2718319fPaul Rohde .registerDisplayListener(mDisplayListener, null); 95711ddd7389b89e9a876eba607e246e8b8d0dfecdfDoris Liu } 958f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 959f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 960f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 961f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Redirects touch events to appropriate recipient views based on swipe direction. 962f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * More specifically, swipe up and swipe down will be handled by the view that handles 963f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * mode transition; swipe left will be send to filmstrip; swipe right will be redirected 964f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * to mode list in order to bring up mode list. 965f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 966f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu private void onSwipeDetected(int swipeState) { 967f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (swipeState == SWIPE_UP || swipeState == SWIPE_DOWN) { 9689d52fc9e1a529012de83d1fea415c2fb4cba836cDoris Liu // TODO: Polish quick switch after this release. 969bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu // Quick switch between modes. 970bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu int currentModuleIndex = mController.getCurrentModuleIndex(); 971bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu final int moduleToTransitionTo = 972bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu mController.getQuickSwitchToModuleId(currentModuleIndex); 973bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu if (currentModuleIndex != moduleToTransitionTo) { 974f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAppRootView.redirectTouchEventsTo(mModeTransitionView); 9758992a26dd589310b2f45cbb01c158f324fd10289Alan Newberger int shadeColorId = R.color.camera_gray_background; 976b520b97b89b0cf0389ea00d7e080971628cf6290Doris Liu int iconRes = CameraUtil.getCameraModeCoverIconResId(moduleToTransitionTo, 977bd1b8f910d6f2c94daac304f4bd1a098939474c3Doris Liu mController.getAndroidContext()); 978f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 979f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu AnimationFinishedListener listener = new AnimationFinishedListener() { 980ab05a742fb03b2016d2792c7b06f268d3dd82701Sascha Haeberling @Override 981f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void onAnimationFinished(boolean success) { 982f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (success) { 983e038c161389b5d1c0476e315736df31562328894Doris Liu mHideCoverRunnable = new Runnable() { 984e038c161389b5d1c0476e315736df31562328894Doris Liu @Override 985e038c161389b5d1c0476e315736df31562328894Doris Liu public void run() { 986e038c161389b5d1c0476e315736df31562328894Doris Liu mModeTransitionView.startPeepHoleAnimation(); 987e038c161389b5d1c0476e315736df31562328894Doris Liu } 988e038c161389b5d1c0476e315736df31562328894Doris Liu }; 989e038c161389b5d1c0476e315736df31562328894Doris Liu mModeCoverState = COVER_SHOWN; 990f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Go to new module when the previous operation is successful. 991f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mController.onModeSelected(moduleToTransitionTo); 992f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 993f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 994f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu }; 995f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 996f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } else if (swipeState == SWIPE_LEFT) { 997166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong // Pass the touch sequence to filmstrip layout. 998166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong mAppRootView.redirectTouchEventsTo(mFilmstripLayout); 999f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } else if (swipeState == SWIPE_RIGHT) { 1000f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu // Pass the touch to mode switcher 1001f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAppRootView.redirectTouchEventsTo(mModeListView); 1002f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1003f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1004f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1005f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 10062b906b8c9754b564d5113c7a342654c82f97f180Doris Liu * Gets called when activity resumes in preview. 10072b906b8c9754b564d5113c7a342654c82f97f180Doris Liu */ 10082b906b8c9754b564d5113c7a342654c82f97f180Doris Liu public void resume() { 1009b00d64307ae77541f8576593a29214d649fb94e9Doris Liu // Show mode theme cover until preview is ready 1010b00d64307ae77541f8576593a29214d649fb94e9Doris Liu showModeCoverUntilPreviewReady(); 1011b00d64307ae77541f8576593a29214d649fb94e9Doris Liu 1012b2510252fb020f3ccb88787c870930427377b9dfAngus Kong // Hide action bar first since we are in full screen mode first, and 1013b2510252fb020f3ccb88787c870930427377b9dfAngus Kong // switch the system UI to lights-out mode. 1014b2510252fb020f3ccb88787c870930427377b9dfAngus Kong mFilmstripPanel.hide(); 1015dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu 1016d4c3333c99ece20b3125e86e1e3f6105b2bc9bddSascha Haeberling // Show UI that is meant to only be used when spoken feedback is 1017d4c3333c99ece20b3125e86e1e3f6105b2bc9bddSascha Haeberling // enabled. 1018b45f618d4a3aa068766be8741213080532feaaffSpike Sprague mAccessibilityAffordances.setVisibility( 1019971ad50c0f220a396ffce50245617ff59ed0a09ezafir (!mIsCaptureIntent && mAccessibilityUtil.isAccessibilityEnabled()) ? View.VISIBLE 1020971ad50c0f220a396ffce50245617ff59ed0a09ezafir : View.GONE); 1021256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling } 1022dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu 1023256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling /** 1024256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling * Opens the mode list (e.g. because of the menu button being pressed) and 1025256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling * adapts the rest of the UI. 1026256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling */ 1027256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling public void openModeList() { 1028256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mModeOptionsOverlay.closeModeOptions(); 1029256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mModeListView.onMenuPressed(); 10302b906b8c9754b564d5113c7a342654c82f97f180Doris Liu } 10312b906b8c9754b564d5113c7a342654c82f97f180Doris Liu 1032971ad50c0f220a396ffce50245617ff59ed0a09ezafir public void showAccessibilityZoomUI(float maxZoom) { 1033971ad50c0f220a396ffce50245617ff59ed0a09ezafir mAccessibilityUtil.showZoomUI(maxZoom); 1034971ad50c0f220a396ffce50245617ff59ed0a09ezafir } 1035971ad50c0f220a396ffce50245617ff59ed0a09ezafir 1036971ad50c0f220a396ffce50245617ff59ed0a09ezafir public void hideAccessibilityZoomUI() { 1037971ad50c0f220a396ffce50245617ff59ed0a09ezafir mAccessibilityUtil.hideZoomUI(); 1038971ad50c0f220a396ffce50245617ff59ed0a09ezafir } 1039971ad50c0f220a396ffce50245617ff59ed0a09ezafir 10402b906b8c9754b564d5113c7a342654c82f97f180Doris Liu /** 10412b906b8c9754b564d5113c7a342654c82f97f180Doris Liu * A cover view showing the mode theme color and mode icon will be visible on 10422b906b8c9754b564d5113c7a342654c82f97f180Doris Liu * top of preview until preview is ready (i.e. camera preview is started and 10432b906b8c9754b564d5113c7a342654c82f97f180Doris Liu * the first frame has been received). 10442b906b8c9754b564d5113c7a342654c82f97f180Doris Liu */ 10452b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private void showModeCoverUntilPreviewReady() { 10462b906b8c9754b564d5113c7a342654c82f97f180Doris Liu int modeId = mController.getCurrentModuleIndex(); 10478992a26dd589310b2f45cbb01c158f324fd10289Alan Newberger int colorId = R.color.camera_gray_background;; 1048b520b97b89b0cf0389ea00d7e080971628cf6290Doris Liu int iconId = CameraUtil.getCameraModeCoverIconResId(modeId, mController.getAndroidContext()); 10492b906b8c9754b564d5113c7a342654c82f97f180Doris Liu mModeTransitionView.setupModeCover(colorId, iconId); 1050b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu mHideCoverRunnable = new Runnable() { 1051b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu @Override 1052b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu public void run() { 1053b00d64307ae77541f8576593a29214d649fb94e9Doris Liu mModeTransitionView.hideModeCover(null); 10544c96d840aeff669011a9e8697cbac77fe8f4eda2Spike Sprague if (!mDisableAllUserInteractions) { 10554c96d840aeff669011a9e8697cbac77fe8f4eda2Spike Sprague showShimmyDelayed(); 10564c96d840aeff669011a9e8697cbac77fe8f4eda2Spike Sprague } 1057b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu } 1058b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu }; 10592b906b8c9754b564d5113c7a342654c82f97f180Doris Liu mModeCoverState = COVER_SHOWN; 10602b906b8c9754b564d5113c7a342654c82f97f180Doris Liu } 10612b906b8c9754b564d5113c7a342654c82f97f180Doris Liu 10622c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu private void showShimmyDelayed() { 10632c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu if (!mIsCaptureIntent) { 10642c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu // Show shimmy in SHIMMY_DELAY_MS 10652ed67843b7eb5cb67eaec51561770262f5fd36c7Angus Kong mModeListView.showModeSwitcherHint(); 10662c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu } 10672c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu } 10682c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu 10692b906b8c9754b564d5113c7a342654c82f97f180Doris Liu private void hideModeCover() { 1070b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu if (mHideCoverRunnable != null) { 1071b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu mAppRootView.post(mHideCoverRunnable); 1072b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu mHideCoverRunnable = null; 1073b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu } 1074e038c161389b5d1c0476e315736df31562328894Doris Liu mModeCoverState = COVER_HIDDEN; 1075a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan if (mCoverHiddenTime < 0) { 1076a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan mCoverHiddenTime = System.currentTimeMillis(); 1077a0e8347f9cfb583f90543635c5c86dc9252526e1Kevin Gabayan } 10782b906b8c9754b564d5113c7a342654c82f97f180Doris Liu } 10792b906b8c9754b564d5113c7a342654c82f97f180Doris Liu 1080dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu 1081dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu public void onPreviewVisiblityChanged(int visibility) { 1082dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu if (visibility == ModuleController.VISIBILITY_HIDDEN) { 1083dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu setIndicatorBottomBarWrapperVisible(false); 1084256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mAccessibilityAffordances.setVisibility(View.GONE); 1085dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } else { 1086dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu setIndicatorBottomBarWrapperVisible(true); 1087971ad50c0f220a396ffce50245617ff59ed0a09ezafir if (!mIsCaptureIntent && mAccessibilityUtil.isAccessibilityEnabled()) { 1088256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mAccessibilityAffordances.setVisibility(View.VISIBLE); 1089dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } else { 1090256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mAccessibilityAffordances.setVisibility(View.GONE); 1091dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } 1092dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } 1093dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu } 1094dfb5a6f356f3287c5cc9cac20948ec14c1f68a35Doris Liu 10951b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd /** 1096d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * Call to stop the preview from being rendered. Sets the entire capture 1097d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * root view to invisible which includes the preview plus focus indicator 1098d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * and any other auxiliary views for capture modes. 10991b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd */ 11001b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd public void pausePreviewRendering() { 1101d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger mCameraRootView.setVisibility(View.INVISIBLE); 11021b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd } 11031b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd 11041b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd /** 1105d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * Call to begin rendering the preview and auxiliary views again. 11061b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd */ 11071b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd public void resumePreviewRendering() { 1108d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger mCameraRootView.setVisibility(View.VISIBLE); 11091b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd } 11101b1253241a5a9b3a59037ba7a626bca68a9b06d8Sam Judd 111108b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling /** 111208b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling * Returns the transform associated with the preview view. 111308b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling * 111408b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling * @param m the Matrix in which to copy the current transform. 111508b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling * @return The specified matrix if not null or a new Matrix instance 111608b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling * otherwise. 111708b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling */ 111808b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling public Matrix getPreviewTransform(Matrix m) { 111908b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling return mTextureView.getTransform(m); 112008b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling } 112108b3c94a7d7aff30b5da8e99649346e37b67a5c5Sascha Haeberling 11222c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu @Override 11232c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu public void onOpenFullScreen() { 11242ed67843b7eb5cb67eaec51561770262f5fd36c7Angus Kong // Do nothing. 11252c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu } 11262c559c4bd3c65e0cb0bca06f30e3bc979038e6f7Doris Liu 11279d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu @Override 11289d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu public void onModeListOpenProgress(float progress) { 11291908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde // When the mode list is in transition, ensure the large layers are 11301908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde // hardware accelerated. 11317543914f2de33b1be25626afb31fa979b06dd582Paul Rohde if (progress >= 1.0f || progress <= 0.0f) { 11327543914f2de33b1be25626afb31fa979b06dd582Paul Rohde // Convert hardware layers back to default layer types when animation stops 11337543914f2de33b1be25626afb31fa979b06dd582Paul Rohde // to prevent accidental artifacting. 11347543914f2de33b1be25626afb31fa979b06dd582Paul Rohde if(mModeOptionsToggle.getLayerType() == View.LAYER_TYPE_HARDWARE || 11357543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mShutterButton.getLayerType() == View.LAYER_TYPE_HARDWARE) { 11367543914f2de33b1be25626afb31fa979b06dd582Paul Rohde Log.v(TAG, "Disabling hardware layer for the Mode Options Toggle Button."); 11377543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mModeOptionsToggle.setLayerType(View.LAYER_TYPE_NONE, null); 11387543914f2de33b1be25626afb31fa979b06dd582Paul Rohde Log.v(TAG, "Disabling hardware layer for the Shutter Button."); 11397543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mShutterButton.setLayerType(View.LAYER_TYPE_NONE, null); 11407543914f2de33b1be25626afb31fa979b06dd582Paul Rohde } 11417543914f2de33b1be25626afb31fa979b06dd582Paul Rohde } else { 11427543914f2de33b1be25626afb31fa979b06dd582Paul Rohde if(mModeOptionsToggle.getLayerType() != View.LAYER_TYPE_HARDWARE || 11437543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mShutterButton.getLayerType() != View.LAYER_TYPE_HARDWARE) { 11447543914f2de33b1be25626afb31fa979b06dd582Paul Rohde Log.v(TAG, "Enabling hardware layer for the Mode Options Toggle Button."); 11457543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mModeOptionsToggle.setLayerType(View.LAYER_TYPE_HARDWARE, null); 11467543914f2de33b1be25626afb31fa979b06dd582Paul Rohde Log.v(TAG, "Enabling hardware layer for the Shutter Button."); 11477543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mShutterButton.setLayerType(View.LAYER_TYPE_HARDWARE, null); 11487543914f2de33b1be25626afb31fa979b06dd582Paul Rohde } 11491908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde } 11501908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde 11519d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu progress = 1 - progress; 11529d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu float interpolatedProgress = Gusterpolator.INSTANCE.getInterpolation(progress); 11539d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu mModeOptionsToggle.setAlpha(interpolatedProgress); 1154948de99e58b72e815224d4e12761863dfceffae0Doris Liu // Change shutter button alpha linearly based on the mode list open progress: 1155948de99e58b72e815224d4e12761863dfceffae0Doris Liu // set the alpha to disabled alpha when list is fully open, to enabled alpha 1156948de99e58b72e815224d4e12761863dfceffae0Doris Liu // when the list is fully closed. 1157948de99e58b72e815224d4e12761863dfceffae0Doris Liu mShutterButton.setAlpha(progress * ShutterButton.ALPHA_WHEN_ENABLED 1158948de99e58b72e815224d4e12761863dfceffae0Doris Liu + (1 - progress) * ShutterButton.ALPHA_WHEN_DISABLED); 11599d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu } 11609d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu 11619d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu @Override 11629d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu public void onModeListClosed() { 11631908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde // Convert hardware layers back to default layer types when animation stops 11641908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde // to prevent accidental artifacting. 11657543914f2de33b1be25626afb31fa979b06dd582Paul Rohde if(mModeOptionsToggle.getLayerType() == View.LAYER_TYPE_HARDWARE || 11667543914f2de33b1be25626afb31fa979b06dd582Paul Rohde mShutterButton.getLayerType() == View.LAYER_TYPE_HARDWARE) { 11671908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde Log.v(TAG, "Disabling hardware layer for the Mode Options Toggle Button."); 11681908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde mModeOptionsToggle.setLayerType(View.LAYER_TYPE_NONE, null); 11691908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde Log.v(TAG, "Disabling hardware layer for the Shutter Button."); 11701908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde mShutterButton.setLayerType(View.LAYER_TYPE_NONE, null); 11711908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde } 11721908beee07fe9792338dbf8e0c36a5f1e3e9401fPaul Rohde 11739d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu // Make sure the alpha on mode options ellipse is reset when mode drawer 11749d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu // is closed. 11759d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu mModeOptionsToggle.setAlpha(1f); 1176948de99e58b72e815224d4e12761863dfceffae0Doris Liu mShutterButton.setAlpha(ShutterButton.ALPHA_WHEN_ENABLED); 11779d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu } 11789d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu 11792b906b8c9754b564d5113c7a342654c82f97f180Doris Liu /** 1180166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * Called when the back key is pressed. 1181166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * 1182166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong * @return Whether the UI responded to the key event. 1183166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong */ 1184166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong public boolean onBackPressed() { 1185b9b7240d62dd2ad245f2c0e09fd1056a28687978Doris Liu if (mFilmstripLayout.getVisibility() == View.VISIBLE) { 1186b9b7240d62dd2ad245f2c0e09fd1056a28687978Doris Liu return mFilmstripLayout.onBackPressed(); 1187b9b7240d62dd2ad245f2c0e09fd1056a28687978Doris Liu } else { 1188b9b7240d62dd2ad245f2c0e09fd1056a28687978Doris Liu return mModeListView.onBackPressed(); 1189b9b7240d62dd2ad245f2c0e09fd1056a28687978Doris Liu } 1190166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong } 1191166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong 1192166e36fb6e04d40a1bef0459ee6b96c9c736039bAngus Kong /** 119306db742814dd635d100639f977fcfdc904deb778Doris Liu * Sets a {@link com.android.camera.ui.PreviewStatusListener} that 11941648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * listens to SurfaceTexture changes. In addition, listeners are set on 11951648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * dependent app ui elements. 119606db742814dd635d100639f977fcfdc904deb778Doris Liu * 119706db742814dd635d100639f977fcfdc904deb778Doris Liu * @param previewStatusListener the listener that gets notified when SurfaceTexture 119806db742814dd635d100639f977fcfdc904deb778Doris Liu * changes 119906db742814dd635d100639f977fcfdc904deb778Doris Liu */ 120006db742814dd635d100639f977fcfdc904deb778Doris Liu public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) { 120106db742814dd635d100639f977fcfdc904deb778Doris Liu mPreviewStatusListener = previewStatusListener; 120206db742814dd635d100639f977fcfdc904deb778Doris Liu if (mPreviewStatusListener != null) { 12031648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren onPreviewListenerChanged(); 12041648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren } 12051648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren } 12061648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren 12071648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren /** 12081648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * When the PreviewStatusListener changes, listeners need to be 12091648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * set on the following app ui elements: 12101648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * {@link com.android.camera.ui.PreviewOverlay}, 12111648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * {@link com.android.camera.ui.BottomBar}, 1212e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren * {@link com.android.camera.ui.IndicatorIconController}. 12131648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren */ 12141648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren private void onPreviewListenerChanged() { 12151648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren // Set a listener for recognizing preview gestures. 12161648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren GestureDetector.OnGestureListener gestureListener 12171648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren = mPreviewStatusListener.getGestureListener(); 12181648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren if (gestureListener != null) { 12191648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren mPreviewOverlay.setGestureListener(gestureListener); 12201648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren } 1221d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren View.OnTouchListener touchListener = mPreviewStatusListener.getTouchListener(); 1222d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren if (touchListener != null) { 1223d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mPreviewOverlay.setTouchListener(touchListener); 1224d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 12251648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren 12261648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren mTextureViewHelper.setAutoAdjustTransform( 1227b259701e4f421b10404425d2a827cbe9d2571585Angus Kong mPreviewStatusListener.shouldAutoAdjustTransformMatrixOnLayout()); 12281648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren } 12291648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren 12301648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren /** 12311648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * This method should be called in onCameraOpened. It defines CameraAppUI 12321648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren * specific changes that depend on the camera or camera settings. 12331648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren */ 12341648c36927501ff32bf2918e8a445118d5208731Erin Dahlgren public void onChangeCamera() { 1235b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren ModuleController moduleController = mController.getCurrentModuleController(); 1236ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava HardwareSpec hardwareSpec = moduleController.getHardwareSpec(); 1237ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 1238ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava /** 1239ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * The current UI requires that the flash option visibility in front- 1240ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * facing camera be 1241ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * * disabled if back facing camera supports flash 1242ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * * hidden if back facing camera does not support flash 1243ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * We save whether back facing camera supports flash because we cannot 1244ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * get this in front facing camera without a camera switch. 1245ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * 1246ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * If this preference is cleared, we also need to clear the camera 1247ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * facing setting so we default to opening the camera in back facing 1248ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava * camera, and can save this flash support value again. 1249ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava */ 1250f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava if (hardwareSpec != null) { 1251f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava if (!mController.getSettingsManager().isSet(SettingsManager.SCOPE_GLOBAL, 1252f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava Keys.KEY_FLASH_SUPPORTED_BACK_CAMERA)) { 1253f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava mController.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL, 1254f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava Keys.KEY_FLASH_SUPPORTED_BACK_CAMERA, 1255f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava hardwareSpec.isFlashSupported()); 1256f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava } 1257f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava /** Similar logic applies to the HDR option. */ 1258f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava if (!mController.getSettingsManager().isSet(SettingsManager.SCOPE_GLOBAL, 1259f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava Keys.KEY_HDR_SUPPORT_MODE_BACK_CAMERA)) { 1260f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava String hdrSupportMode; 1261f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava if (hardwareSpec.isHdrPlusSupported()) { 1262f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava hdrSupportMode = getResourceString( 1263f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava R.string.pref_camera_hdr_supportmode_hdr_plus); 1264f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava } else if (hardwareSpec.isHdrSupported()) { 1265f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava hdrSupportMode = getResourceString(R.string.pref_camera_hdr_supportmode_hdr); 1266f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava } else { 1267f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava hdrSupportMode = getResourceString(R.string.pref_camera_hdr_supportmode_none); 1268f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava } 1269f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava mController.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL, 1270f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava Keys.KEY_HDR_SUPPORT_MODE_BACK_CAMERA, hdrSupportMode); 1271f361659dd9ab34087276b2514a766eadafe344aeGabriel Nava } 1272ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 1273ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 1274ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava applyModuleSpecs(hardwareSpec, moduleController.getBottomBarSpec(), 1275ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava true /*skipScopeCheck*/); 12768c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu syncModeOptionIndicators(); 12778c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu } 1278b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 12798c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu /** 12808c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu * Updates the mode option indicators according to the current settings. 12818c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu */ 12828c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu public void syncModeOptionIndicators() { 1283e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren if (mIndicatorIconController != null) { 12841848494bd09c85002d8c59d4feb8a6e0dc32871fErin Dahlgren // Sync the settings state with the indicator state. 1285a906809bd3e67f3ceaa070baefbdca8c9cb3d766Erin Dahlgren mIndicatorIconController.syncIndicators(); 128606db742814dd635d100639f977fcfdc904deb778Doris Liu } 128706db742814dd635d100639f977fcfdc904deb778Doris Liu } 128806db742814dd635d100639f977fcfdc904deb778Doris Liu 128906db742814dd635d100639f977fcfdc904deb778Doris Liu /** 12902bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong * Adds a listener to receive callbacks when preview area changes. 1291482de029dc20e0a577388a602985fb31c3200309Doris Liu */ 12922bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong public void addPreviewAreaChangedListener( 12932bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong PreviewStatusListener.PreviewAreaChangedListener listener) { 1294482de029dc20e0a577388a602985fb31c3200309Doris Liu mTextureViewHelper.addPreviewAreaSizeChangedListener(listener); 1295482de029dc20e0a577388a602985fb31c3200309Doris Liu } 1296482de029dc20e0a577388a602985fb31c3200309Doris Liu 1297482de029dc20e0a577388a602985fb31c3200309Doris Liu /** 12982bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong * Removes a listener that receives callbacks when preview area changes. 1299482de029dc20e0a577388a602985fb31c3200309Doris Liu */ 13002bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong public void removePreviewAreaChangedListener( 13012bacca795a1b0adb0daf515c43c48234b44bbba5Angus Kong PreviewStatusListener.PreviewAreaChangedListener listener) { 1302482de029dc20e0a577388a602985fb31c3200309Doris Liu mTextureViewHelper.removePreviewAreaSizeChangedListener(listener); 1303482de029dc20e0a577388a602985fb31c3200309Doris Liu } 1304482de029dc20e0a577388a602985fb31c3200309Doris Liu 1305482de029dc20e0a577388a602985fb31c3200309Doris Liu /** 1306f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * This inflates generic_module layout, which contains all the shared views across 1307f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * modules. Then each module inflates their own views in the given view group. For 1308f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * now, this is called every time switching from a not-yet-refactored module to a 1309f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * refactored module. In the future, this should only need to be done once per app 1310f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * start. 1311f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1312f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void prepareModuleUI() { 13133c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren mController.getSettingsManager().addListener(this); 1314c6c9740d996bf073a157721aa3eb2a1aa60c477dDoris Liu mModuleUI = (FrameLayout) mCameraRootView.findViewById(R.id.module_layout); 1315f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mTextureView = (TextureView) mCameraRootView.findViewById(R.id.preview_content); 13168c8fb114ad4e121c4c1f3d726632dffbb32bda13Sol Boucher mTextureViewHelper = new TextureViewHelper(mTextureView, mCaptureLayoutHelper, 1317f018bce18af5626bf67e6dcb37ea60b0cc6a53cdI-Jong Lin mController.getCameraProvider(), mController); 131870da918464276b110c43868caa272c97baadb89eDoris Liu mTextureViewHelper.setSurfaceTextureListener(this); 131970da918464276b110c43868caa272c97baadb89eDoris Liu mTextureViewHelper.setOnLayoutChangeListener(mPreviewLayoutChangeListener); 132070da918464276b110c43868caa272c97baadb89eDoris Liu 13210a6a8d8e4e1c9796aac606379a42970cdffb8911Erin Dahlgren mBottomBar = (BottomBar) mCameraRootView.findViewById(R.id.bottom_bar); 1322d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren int unpressedColor = mController.getAndroidContext().getResources() 13238992a26dd589310b2f45cbb01c158f324fd10289Alan Newberger .getColor(R.color.camera_gray_background); 1324d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren setBottomBarColor(unpressedColor); 1325d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague updateModeSpecificUIColors(); 1326d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 132728a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mBottomBar.setCaptureLayoutHelper(mCaptureLayoutHelper); 1328d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1329165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren mModeOptionsOverlay 1330165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren = (ModeOptionsOverlay) mCameraRootView.findViewById(R.id.mode_options_overlay); 1331d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1332d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren // Sets the visibility of the bottom bar and the mode options. 1333d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren resetBottomControls(mController.getCurrentModuleController(), 1334d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mController.getCurrentModuleIndex()); 133528a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mModeOptionsOverlay.setCaptureLayoutHelper(mCaptureLayoutHelper); 133656688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 13375d18769f53db81d401488811250570290a73626bErin Dahlgren mShutterButton = (ShutterButton) mCameraRootView.findViewById(R.id.shutter_button); 13385d18769f53db81d401488811250570290a73626bErin Dahlgren addShutterListener(mController.getCurrentModuleController()); 13395d18769f53db81d401488811250570290a73626bErin Dahlgren addShutterListener(mModeOptionsOverlay); 1340a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren addShutterListener(this); 13415d18769f53db81d401488811250570290a73626bErin Dahlgren 1342b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren mGridLines = (GridLines) mCameraRootView.findViewById(R.id.grid_lines); 1343b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren mTextureViewHelper.addPreviewAreaSizeChangedListener(mGridLines); 1344b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 1345f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mPreviewOverlay = (PreviewOverlay) mCameraRootView.findViewById(R.id.preview_overlay); 1346f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mPreviewOverlay.setOnTouchListener(new MyTouchListener()); 1347165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren mPreviewOverlay.setOnPreviewTouchedListener(mModeOptionsOverlay); 1348971ad50c0f220a396ffce50245617ff59ed0a09ezafir mAccessibilityUtil = new AccessibilityUtil(mPreviewOverlay, mAccessibilityAffordances); 134956688f7019fbe4dee110b7600349f48da9fff601Erin Dahlgren 13501dfe7828fd60741b9752553af3ee439c04e758a0Doris Liu mCaptureOverlay = (CaptureAnimationOverlay) 13511dfe7828fd60741b9752553af3ee439c04e758a0Doris Liu mCameraRootView.findViewById(R.id.capture_overlay); 1352ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu mTextureViewHelper.addPreviewAreaSizeChangedListener(mPreviewOverlay); 1353ca4a5668c5bcda027bd896ebf17c8ef374e2ac75Doris Liu mTextureViewHelper.addPreviewAreaSizeChangedListener(mCaptureOverlay); 13544efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 1355e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren if (mIndicatorIconController == null) { 1356e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren mIndicatorIconController = 1357e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren new IndicatorIconController(mController, mAppRootView); 1358e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren } 1359f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren 1360f1b2e407b20ff16fe793158c598e59799c1990efErin Dahlgren mController.getButtonManager().load(mCameraRootView); 1361e2a1f54fbf6a8a7beff5b7695654ca21e63643afErin Dahlgren mController.getButtonManager().setListener(mIndicatorIconController); 13626e07fe22cf84e9eea02d368bf64ab68d92401f20Erin Dahlgren mController.getSettingsManager().addListener(mIndicatorIconController); 13639d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu 13649d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu mModeOptionsToggle = mCameraRootView.findViewById(R.id.mode_options_toggle); 1365987ee64612e2510004fdf08536746c87234d01c1Paul Rohde mFocusRing = (FocusRing) mCameraRootView.findViewById(R.id.focus_ring); 13661e0810c88e791d0f658eb5a6f95d771ee03a7631Sascha Haeberling mTutorialsPlaceHolderWrapper = (FrameLayout) mCameraRootView 13671e0810c88e791d0f658eb5a6f95d771ee03a7631Sascha Haeberling .findViewById(R.id.tutorials_placeholder_wrapper); 1368427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mStickyBottomCaptureLayout = (StickyBottomCaptureLayout) mAppRootView 1369427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu .findViewById(R.id.sticky_bottom_capture_layout); 1370427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mStickyBottomCaptureLayout.setCaptureLayoutHelper(mCaptureLayoutHelper); 137164d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling mCountdownCancelButton = (ImageButton) mStickyBottomCaptureLayout 137264d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling .findViewById(R.id.shutter_cancel_button); 1373b259701e4f421b10404425d2a827cbe9d2571585Angus Kong 1374b908d933736a4ec042aad065b7ebf2059bbcac97Doris Liu mTextureViewHelper.addPreviewAreaSizeChangedListener(mModeListView); 137528a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mTextureViewHelper.addAspectRatioChangedListener( 137628a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu new PreviewStatusListener.PreviewAspectRatioChangedListener() { 137728a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu @Override 137828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu public void onPreviewAspectRatioChanged(float aspectRatio) { 137928a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mModeOptionsOverlay.requestLayout(); 138028a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mBottomBar.requestLayout(); 138128a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu } 1382344320c90639f823451ddac42e8f39b74727787cDoris Liu } 1383344320c90639f823451ddac42e8f39b74727787cDoris Liu ); 1384f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1385f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1386f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 1387f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Called indirectly from each module in their initialization to get a view group 1388f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * to inflate the module specific views in. 1389f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * 1390f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * @return a view group for modules to attach views to 1391f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1392c6c9740d996bf073a157721aa3eb2a1aa60c477dDoris Liu public FrameLayout getModuleRootView() { 1393b41034b16b0dce997544d2592db5029e7db4e238Doris Liu // TODO: Change it to mModuleUI when refactor is done 1394b41034b16b0dce997544d2592db5029e7db4e238Doris Liu return mCameraRootView; 1395f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1396f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1397f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 1398f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Remove all the module specific views. 1399f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1400f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void clearModuleUI() { 1401f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu if (mModuleUI != null) { 1402f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mModuleUI.removeAllViews(); 1403f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 14045d18769f53db81d401488811250570290a73626bErin Dahlgren removeShutterListener(mController.getCurrentModuleController()); 14051e0810c88e791d0f658eb5a6f95d771ee03a7631Sascha Haeberling mTutorialsPlaceHolderWrapper.removeAllViews(); 1406de7633bbcfb08865175126713d97132086bff340Sascha Haeberling mTutorialsPlaceHolderWrapper.setVisibility(View.GONE); 14070744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 140859efb9af8340a5e3500037b23fb3ac16011a1c7eSeth Raphael setShutterButtonEnabled(true); 140906db742814dd635d100639f977fcfdc904deb778Doris Liu mPreviewStatusListener = null; 1410f9e4f8fbd1f761443d7a1eecbb5aa221ed3a06a8Doris Liu mPreviewOverlay.reset(); 1411987ee64612e2510004fdf08536746c87234d01c1Paul Rohde 1412987ee64612e2510004fdf08536746c87234d01c1Paul Rohde Log.v(TAG, "mFocusRing.stopFocusAnimations()"); 1413987ee64612e2510004fdf08536746c87234d01c1Paul Rohde mFocusRing.stopFocusAnimations(); 1414f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1415f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 14162b906b8c9754b564d5113c7a342654c82f97f180Doris Liu /** 14175a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * Gets called when preview is ready to start. It sets up one shot preview callback 14185a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * in order to receive a callback when the preview frame is available, so that 14195a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * the preview cover can be hidden to reveal preview. 14205a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * 14215a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * An alternative for getting the timing to hide preview cover is through 14225a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * {@link CameraAppUI#onSurfaceTextureUpdated(android.graphics.SurfaceTexture)}, 14235a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * which is less accurate but therefore is the fallback for modules that manage 14245a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * their own preview callbacks (as setting one preview callback will override 14255a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu * any other installed preview callbacks), or use camera2 API. 14265a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu */ 14275a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu public void onPreviewReadyToStart() { 14285a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu if (mModeCoverState == COVER_SHOWN) { 14295a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu mModeCoverState = COVER_WILL_HIDE_AT_NEXT_FRAME; 14305a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu mController.setupOneShotPreviewListener(); 14315a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu } 14325a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu } 14335a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu 14345a367545ab931a308c8d8555ef5a747dc9565cafDoris Liu /** 14352b906b8c9754b564d5113c7a342654c82f97f180Doris Liu * Gets called when preview is started. 14362b906b8c9754b564d5113c7a342654c82f97f180Doris Liu */ 14372b906b8c9754b564d5113c7a342654c82f97f180Doris Liu public void onPreviewStarted() { 1438c91c8d273b8884468dfd66a5b82526dc8245934eAlan Newberger Log.v(TAG, "onPreviewStarted"); 14392b906b8c9754b564d5113c7a342654c82f97f180Doris Liu if (mModeCoverState == COVER_SHOWN) { 14407e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // This is a work around of the face detection failure in b/20724126. 14417e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // In particular, we need to drop the first preview frame in order to 14427e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // make face detection work and also need to hide this preview frame to 14437e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // avoid potential janks. We do this only for L, Nexus 6 and Haleakala. 14447e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin if (ApiHelper.isLorLMr1() && ApiHelper.IS_NEXUS_6) { 14457e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin mModeCoverState = COVER_WILL_HIDE_AFTER_NEXT_TEXTURE_UPDATE; 14467e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin } else { 14477e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin mModeCoverState = COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE; 14487e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin } 14492b906b8c9754b564d5113c7a342654c82f97f180Doris Liu } 1450a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren enableModeOptions(); 14512b906b8c9754b564d5113c7a342654c82f97f180Doris Liu } 14522b906b8c9754b564d5113c7a342654c82f97f180Doris Liu 1453b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu /** 14544d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu * Gets notified when next preview frame comes in. 14554d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu */ 14564d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu public void onNewPreviewFrame() { 1457c91c8d273b8884468dfd66a5b82526dc8245934eAlan Newberger Log.v(TAG, "onNewPreviewFrame"); 14587cbeceed6d03d0550797c435f3db6205714cd49fDoris Liu CameraPerformanceTracker.onEvent(CameraPerformanceTracker.FIRST_PREVIEW_FRAME); 14594d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu hideModeCover(); 14604d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu } 14614d4a4bc8891bbfc5a7ca842f2981829ac3a716e8Doris Liu 1462a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren @Override 1463a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren public void onShutterButtonClick() { 1464a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren /* 1465a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * Set the mode options toggle unclickable, generally 1466a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * throughout the app, whenever the shutter button is clicked. 1467a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * 1468a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * This could be done in the OnShutterButtonListener of the 1469a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * ModeOptionsOverlay, but since it is very important that we 1470a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * can clearly see when the toggle becomes clickable again, 1471a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren * keep all of that logic at this level. 1472a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren */ 14730d32f29b2a82c2afa87b46e309c38f67f8b5e54cPuneet Lall // disableModeOptions(); 1474a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren } 1475a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren 1476a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren @Override 1477b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers public void onShutterCoordinate(TouchCoordinate coord) { 1478b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers // Do nothing. 1479b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers } 1480b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers 1481b7c7d9a067cd52a27cfbaf0714a2074f972d836dAndy Huibers @Override 1482a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren public void onShutterButtonFocus(boolean pressed) { 1483a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren // noop 1484a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren } 1485a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren 148682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar @Override 148782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar public void onShutterButtonLongPressed() { 148882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar // noop 148982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar } 149082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar 1491a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren /** 1492c19d97b385261312399b67b538f8faa074314bebSpike Sprague * Set the mode options toggle clickable. 1493c19d97b385261312399b67b538f8faa074314bebSpike Sprague */ 1494c19d97b385261312399b67b538f8faa074314bebSpike Sprague public void enableModeOptions() { 1495c19d97b385261312399b67b538f8faa074314bebSpike Sprague /* 1496c19d97b385261312399b67b538f8faa074314bebSpike Sprague * For modules using camera 1 api, this gets called in 1497c19d97b385261312399b67b538f8faa074314bebSpike Sprague * onSurfaceTextureUpdated whenever the preview gets stopped and 1498c19d97b385261312399b67b538f8faa074314bebSpike Sprague * started after each capture. This also takes care of the 1499c19d97b385261312399b67b538f8faa074314bebSpike Sprague * case where the mode options might be unclickable when we 1500c19d97b385261312399b67b538f8faa074314bebSpike Sprague * switch modes 1501c19d97b385261312399b67b538f8faa074314bebSpike Sprague * 1502c19d97b385261312399b67b538f8faa074314bebSpike Sprague * For modules using camera 2 api, they're required to call this 1503c19d97b385261312399b67b538f8faa074314bebSpike Sprague * method when a capture is "completed". Unfortunately this differs 1504c19d97b385261312399b67b538f8faa074314bebSpike Sprague * per module implementation. 1505c19d97b385261312399b67b538f8faa074314bebSpike Sprague */ 1506d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague if (!mDisableAllUserInteractions) { 1507d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague mModeOptionsOverlay.setToggleClickable(true); 1508d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } 1509c19d97b385261312399b67b538f8faa074314bebSpike Sprague } 1510c19d97b385261312399b67b538f8faa074314bebSpike Sprague 1511c19d97b385261312399b67b538f8faa074314bebSpike Sprague /** 1512c19d97b385261312399b67b538f8faa074314bebSpike Sprague * Set the mode options toggle not clickable. 1513c19d97b385261312399b67b538f8faa074314bebSpike Sprague */ 1514c19d97b385261312399b67b538f8faa074314bebSpike Sprague public void disableModeOptions() { 1515c19d97b385261312399b67b538f8faa074314bebSpike Sprague mModeOptionsOverlay.setToggleClickable(false); 1516c19d97b385261312399b67b538f8faa074314bebSpike Sprague } 1517c19d97b385261312399b67b538f8faa074314bebSpike Sprague 1518d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague public void setDisableAllUserInteractions(boolean disable) { 1519d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague if (disable) { 1520d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague disableModeOptions(); 1521d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague setShutterButtonEnabled(false); 1522d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague setSwipeEnabled(false); 15234c96d840aeff669011a9e8697cbac77fe8f4eda2Spike Sprague mModeListView.hideAnimated(); 1524d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } else { 1525d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague enableModeOptions(); 1526d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague setShutterButtonEnabled(true); 1527d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague setSwipeEnabled(true); 1528d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } 1529d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague mDisableAllUserInteractions = disable; 1530d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } 1531d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague 1532427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu @Override 1533427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu public void onModeButtonPressed(int modeIndex) { 1534427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu // TODO: Make CameraActivity listen to ModeListView's events. 1535427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu int pressedModuleId = mController.getModuleId(modeIndex); 1536427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu int currentModuleId = mController.getCurrentModuleIndex(); 1537427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu if (pressedModuleId != currentModuleId) { 1538427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu hideCaptureIndicator(); 1539427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu } 1540427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu } 1541427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu 1542c19d97b385261312399b67b538f8faa074314bebSpike Sprague /** 1543b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu * Gets called when a mode is selected from {@link com.android.camera.ui.ModeListView} 1544b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu * 1545b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu * @param modeIndex mode index of the selected mode 1546b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu */ 1547f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu @Override 1548f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void onModeSelected(int modeIndex) { 1549b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu mHideCoverRunnable = new Runnable() { 1550b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu @Override 1551b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu public void run() { 1552b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu mModeListView.startModeSelectionAnimation(); 1553b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu } 1554b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu }; 1555a16219d51937bda5f3e69c0e77171ae0fb893823Spike Sprague mShutterButton.setAlpha(ShutterButton.ALPHA_WHEN_ENABLED); 1556e038c161389b5d1c0476e315736df31562328894Doris Liu mModeCoverState = COVER_SHOWN; 1557e038c161389b5d1c0476e315736df31562328894Doris Liu 1558e038c161389b5d1c0476e315736df31562328894Doris Liu int lastIndex = mController.getCurrentModuleIndex(); 15590496fcaa51f88f6c753975473b971941e4090cfaSpike Sprague // Actual mode teardown / new mode initialization happens here 1560e038c161389b5d1c0476e315736df31562328894Doris Liu mController.onModeSelected(modeIndex); 1561e038c161389b5d1c0476e315736df31562328894Doris Liu int currentIndex = mController.getCurrentModuleIndex(); 1562b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu 1563d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren if (lastIndex == currentIndex) { 1564b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu hideModeCover(); 1565b6eaa8c70da19fb3233c3c4b1a2625ce90fc35afDoris Liu } 1566d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 1567d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague updateModeSpecificUIColors(); 1568d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 1569d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 1570d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void updateModeSpecificUIColors() { 1571d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setBottomBarColorsForModeIndex(mController.getCurrentModuleIndex()); 1572f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1573f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1574213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu @Override 15759d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu public void onSettingsSelected() { 15766190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren mController.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL, 15776190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren Keys.KEY_SHOULD_SHOW_SETTINGS_BUTTON_CLING, false); 157826aa92bf5942bfde16621c6833c14ba0e1ea8b5eDoris Liu mModeListView.setShouldShowSettingsCling(false); 15799d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu mController.onSettingsSelected(); 15809d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu } 15819d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu 15829d264309a341c52601bdccdeff6647e0ce58c31fDoris Liu @Override 1583213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu public int getCurrentModeIndex() { 1584213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu return mController.getCurrentModuleIndex(); 1585213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu } 1586213a4a086b54904cee543adf60b16fc1a61efe38Doris Liu 1587f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /********************** Capture animation **********************/ 1588f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /* TODO: This session is subject to UX changes. In addition to the generic 1589f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu flash animation and post capture animation, consider designating a parameter 1590f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu for specifying the type of animation, as well as an animation finished listener 1591f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu so that modules can have more knowledge of the status of the animation. */ 1592f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1593f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 1594ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu * Turns on or off the capture indicator suppression. 1595ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu */ 1596ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu public void setShouldSuppressCaptureIndicator(boolean suppress) { 1597ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu mSuppressCaptureIndicator = suppress; 1598ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu } 1599ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu 1600ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu /** 1601427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * Starts the capture indicator pop-out animation. 16025052117cc429d85cf446421ca74859f4365747d3Angus Kong * 1603427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * @param accessibilityString An accessibility String to be announced during the peek animation. 16045052117cc429d85cf446421ca74859f4365747d3Angus Kong */ 1605427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu public void startCaptureIndicatorRevealAnimation(String accessibilityString) { 1606ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu if (mSuppressCaptureIndicator || mFilmstripLayout.getVisibility() == View.VISIBLE) { 16075052117cc429d85cf446421ca74859f4365747d3Angus Kong return; 16085052117cc429d85cf446421ca74859f4365747d3Angus Kong } 1609427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mRoundedThumbnailView.startRevealThumbnailAnimation(accessibilityString); 16105052117cc429d85cf446421ca74859f4365747d3Angus Kong } 16115052117cc429d85cf446421ca74859f4365747d3Angus Kong 16125052117cc429d85cf446421ca74859f4365747d3Angus Kong /** 1613427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * Updates the thumbnail image in the capture indicator. 161417d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers * 1615427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * @param thumbnailBitmap The thumbnail image to be shown. 1616427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu */ 16173830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling public void updateCaptureIndicatorThumbnail(Bitmap thumbnailBitmap, int rotation) { 1618ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu if (mSuppressCaptureIndicator || mFilmstripLayout.getVisibility() == View.VISIBLE) { 1619ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu return; 1620ecb546aca4093beb60a3d40171b5038693dc7d05Senpo Hu } 162104aab100674dfdd11bffabc46e6a199f5e9a5267Paul Rohde mRoundedThumbnailView.setThumbnail(thumbnailBitmap, rotation); 1622427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu } 1623427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu 1624427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu /** 1625427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * Hides the capture indicator. 1626427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu */ 1627427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu public void hideCaptureIndicator() { 1628427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mRoundedThumbnailView.hideThumbnail(); 1629427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu } 1630427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu 1631427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu /** 1632427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu * Starts the flash animation. 1633f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1634427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu public void startFlashAnimation(boolean shortFlash) { 163517d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers mCaptureOverlay.startFlashAnimation(shortFlash); 1636f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1637f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1638f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 1639f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Cancels the pre-capture animation. 1640f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1641f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void cancelPreCaptureAnimation() { 1642f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAnimationManager.cancelAnimations(); 1643f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 1644f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu 1645f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu /** 1646f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu * Cancels the post-capture animation. 1647f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu */ 1648f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu public void cancelPostCaptureAnimation() { 1649f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu mAnimationManager.cancelAnimations(); 1650f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu } 165106db742814dd635d100639f977fcfdc904deb778Doris Liu 1652b2510252fb020f3ccb88787c870930427377b9dfAngus Kong public FilmstripContentPanel getFilmstripContentPanel() { 1653b2510252fb020f3ccb88787c870930427377b9dfAngus Kong return mFilmstripPanel; 1654b2510252fb020f3ccb88787c870930427377b9dfAngus Kong } 1655b2510252fb020f3ccb88787c870930427377b9dfAngus Kong 1656b2510252fb020f3ccb88787c870930427377b9dfAngus Kong /** 16577ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong * @return The {@link com.android.camera.app.CameraAppUI.BottomPanel} on the 1658b2510252fb020f3ccb88787c870930427377b9dfAngus Kong * bottom of the filmstrip. 1659b2510252fb020f3ccb88787c870930427377b9dfAngus Kong */ 16607ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong public BottomPanel getFilmstripBottomControls() { 1661e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong return mFilmstripBottomControls; 1662b2510252fb020f3ccb88787c870930427377b9dfAngus Kong } 1663b2510252fb020f3ccb88787c870930427377b9dfAngus Kong 1664ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague public void showBottomControls() { 1665ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague mFilmstripBottomControls.show(); 1666ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague } 1667ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague 1668ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague public void hideBottomControls() { 1669ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague mFilmstripBottomControls.hide(); 1670ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague } 1671ba97d192b63ea81edf2dd6ca5cfbf6646a1f25a2Spike Sprague 1672b2510252fb020f3ccb88787c870930427377b9dfAngus Kong /** 1673b2510252fb020f3ccb88787c870930427377b9dfAngus Kong * @param listener The listener for bottom controls. 1674b2510252fb020f3ccb88787c870930427377b9dfAngus Kong */ 16757ae25c21fefd8b7fd4c4e1c207631f751167cb0aAngus Kong public void setFilmstripBottomControlsListener(BottomPanel.Listener listener) { 1676e0aff89f3e05eb6008651b290ba79d484de55970Angus Kong mFilmstripBottomControls.setListener(listener); 1677b2510252fb020f3ccb88787c870930427377b9dfAngus Kong } 1678b2510252fb020f3ccb88787c870930427377b9dfAngus Kong 1679d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /***************************SurfaceTexture Api and Listener*********************************/ 1680d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1681d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1682d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Return the shared surface texture. 1683d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1684d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public SurfaceTexture getSurfaceTexture() { 1685d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return mSurface; 1686d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1687d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1688d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1689d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Return the shared {@link android.graphics.SurfaceTexture}'s width. 1690d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1691d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public int getSurfaceWidth() { 1692d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return mSurfaceWidth; 1693d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1694d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1695d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1696d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Return the shared {@link android.graphics.SurfaceTexture}'s height. 1697d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1698d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public int getSurfaceHeight() { 1699d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return mSurfaceHeight; 1700d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 170106db742814dd635d100639f977fcfdc904deb778Doris Liu 170206db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 170306db742814dd635d100639f977fcfdc904deb778Doris Liu public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 1704d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurface = surface; 1705d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurfaceWidth = width; 1706d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurfaceHeight = height; 17072b906b8c9754b564d5113c7a342654c82f97f180Doris Liu Log.v(TAG, "SurfaceTexture is available"); 170806db742814dd635d100639f977fcfdc904deb778Doris Liu if (mPreviewStatusListener != null) { 170906db742814dd635d100639f977fcfdc904deb778Doris Liu mPreviewStatusListener.onSurfaceTextureAvailable(surface, width, height); 171006db742814dd635d100639f977fcfdc904deb778Doris Liu } 1711a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren enableModeOptions(); 171206db742814dd635d100639f977fcfdc904deb778Doris Liu } 171306db742814dd635d100639f977fcfdc904deb778Doris Liu 171406db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 171506db742814dd635d100639f977fcfdc904deb778Doris Liu public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 1716d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurface = surface; 1717d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurfaceWidth = width; 1718d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurfaceHeight = height; 171906db742814dd635d100639f977fcfdc904deb778Doris Liu if (mPreviewStatusListener != null) { 172006db742814dd635d100639f977fcfdc904deb778Doris Liu mPreviewStatusListener.onSurfaceTextureSizeChanged(surface, width, height); 172106db742814dd635d100639f977fcfdc904deb778Doris Liu } 172206db742814dd635d100639f977fcfdc904deb778Doris Liu } 172306db742814dd635d100639f977fcfdc904deb778Doris Liu 172406db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 172506db742814dd635d100639f977fcfdc904deb778Doris Liu public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 1726d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurface = null; 17272b906b8c9754b564d5113c7a342654c82f97f180Doris Liu Log.v(TAG, "SurfaceTexture is destroyed"); 172806db742814dd635d100639f977fcfdc904deb778Doris Liu if (mPreviewStatusListener != null) { 172906db742814dd635d100639f977fcfdc904deb778Doris Liu return mPreviewStatusListener.onSurfaceTextureDestroyed(surface); 173006db742814dd635d100639f977fcfdc904deb778Doris Liu } 173106db742814dd635d100639f977fcfdc904deb778Doris Liu return false; 173206db742814dd635d100639f977fcfdc904deb778Doris Liu } 173306db742814dd635d100639f977fcfdc904deb778Doris Liu 173406db742814dd635d100639f977fcfdc904deb778Doris Liu @Override 173506db742814dd635d100639f977fcfdc904deb778Doris Liu public void onSurfaceTextureUpdated(SurfaceTexture surface) { 1736d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mSurface = surface; 17373c3b31dfd5ec7a43e89cd4695cc8c498afc3a91dSpike Sprague if (mPreviewStatusListener != null) { 17383c3b31dfd5ec7a43e89cd4695cc8c498afc3a91dSpike Sprague mPreviewStatusListener.onSurfaceTextureUpdated(surface); 17393c3b31dfd5ec7a43e89cd4695cc8c498afc3a91dSpike Sprague } 17407e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // Do not show the first preview frame. Due to the bug b/20724126, we need to have 17417e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // a WAR to request a preview frame followed by 5-frame ZSL burst before the repeating 17427e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // preview and ZSL streams. Need to hide the first preview frame since it is janky. 17437e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin // We do this only for L, Nexus 6 and Haleakala. 17447e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin if (mModeCoverState == COVER_WILL_HIDE_AFTER_NEXT_TEXTURE_UPDATE) { 17457e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin mModeCoverState = COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE; 17467e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin } else if (mModeCoverState == COVER_WILL_HIDE_AT_NEXT_TEXTURE_UPDATE){ 1747c91c8d273b8884468dfd66a5b82526dc8245934eAlan Newberger Log.v(TAG, "hiding cover via onSurfaceTextureUpdated"); 17487cbeceed6d03d0550797c435f3db6205714cd49fDoris Liu CameraPerformanceTracker.onEvent(CameraPerformanceTracker.FIRST_PREVIEW_FRAME); 17492b906b8c9754b564d5113c7a342654c82f97f180Doris Liu hideModeCover(); 175006db742814dd635d100639f977fcfdc904deb778Doris Liu } 175106db742814dd635d100639f977fcfdc904deb778Doris Liu } 17524efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 1753b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren /****************************Grid lines api ******************************/ 1754b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 1755b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren /** 1756b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren * Show a set of evenly spaced lines over the preview. The number 1757b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren * of lines horizontally and vertically is determined by 1758b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren * {@link com.android.camera.ui.GridLines}. 1759b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren */ 1760b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren public void showGridLines() { 1761b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren if (mGridLines != null) { 1762b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren mGridLines.setVisibility(View.VISIBLE); 1763b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren } 1764b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren } 1765b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 1766b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren /** 1767b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren * Hide the set of evenly spaced grid lines overlaying the preview. 1768b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren */ 1769b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren public void hideGridLines() { 1770b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren if (mGridLines != null) { 1771b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren mGridLines.setVisibility(View.INVISIBLE); 1772b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren } 1773b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren } 1774b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 1775d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren /** 1776d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * Return a callback which shows or hide the preview grid lines 1777d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren * depending on whether the grid lines setting is set on. 1778d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren */ 1779d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public ButtonManager.ButtonCallback getGridLinesCallback() { 1780d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren return new ButtonManager.ButtonCallback() { 1781d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren @Override 1782d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren public void onStateChanged(int state) { 17832356bd78cfeb51977845155b580104ce959083f2Alan Newberger if (!mController.isPaused()) { 17842356bd78cfeb51977845155b580104ce959083f2Alan Newberger if (Keys.areGridLinesOn(mController.getSettingsManager())) { 17852356bd78cfeb51977845155b580104ce959083f2Alan Newberger showGridLines(); 17862356bd78cfeb51977845155b580104ce959083f2Alan Newberger } else { 17872356bd78cfeb51977845155b580104ce959083f2Alan Newberger hideGridLines(); 17882356bd78cfeb51977845155b580104ce959083f2Alan Newberger } 1789d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } 1790d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } 1791d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren }; 1792d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } 1793d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren 1794d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /***************************Mode options api *****************************/ 1795d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1796d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1797d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Set the mode options visible. 1798d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1799d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void showModeOptions() { 1800a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren /* Make mode options clickable. */ 1801a7919c720c49d7aa9a033366a92f8b1828619a0fErin Dahlgren enableModeOptions(); 1802d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mModeOptionsOverlay.setVisibility(View.VISIBLE); 1803d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1804d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1805d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1806d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Set the mode options invisible. This is necessary for modes 1807d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * that don't show a bottom bar for the capture UI. 1808d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1809d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void hideModeOptions() { 1810d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mModeOptionsOverlay.setVisibility(View.INVISIBLE); 1811d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1812b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 1813b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren /****************************Bottom bar api ******************************/ 1814b3f59a874f675ceb7542298760a3c813c5e0d9acErin Dahlgren 18154efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 1816d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Sets up the bottom bar and mode options with the correct 1817d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * shutter button and visibility based on the current module. 1818d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1819d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void resetBottomControls(ModuleController module, int moduleIndex) { 1820d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren if (areBottomControlsUsed(module)) { 1821d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren setBottomBarShutterIcon(moduleIndex); 1822344320c90639f823451ddac42e8f39b74727787cDoris Liu mCaptureLayoutHelper.setShowBottomBar(true); 1823344320c90639f823451ddac42e8f39b74727787cDoris Liu } else { 1824344320c90639f823451ddac42e8f39b74727787cDoris Liu mCaptureLayoutHelper.setShowBottomBar(false); 1825d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1826d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1827d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1828d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1829d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Show or hide the mode options and bottom bar, based on 1830d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * whether the current module is using the bottom bar. Returns 1831d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * whether the mode options and bottom bar are used. 1832d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1833d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren private boolean areBottomControlsUsed(ModuleController module) { 1834d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren if (module.isUsingBottomBar()) { 1835d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren showBottomBar(); 1836d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren showModeOptions(); 1837d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return true; 1838d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } else { 1839d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren hideBottomBar(); 1840d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren hideModeOptions(); 1841d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren return false; 1842d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1843d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1844d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1845d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1846d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Set the bottom bar visible. 1847d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1848d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void showBottomBar() { 1849d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mBottomBar.setVisibility(View.VISIBLE); 1850d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1851d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1852d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 1853d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Set the bottom bar invisible. 1854d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1855d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void hideBottomBar() { 1856d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mBottomBar.setVisibility(View.INVISIBLE); 1857d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1858d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1859d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 18604efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Sets the color of the bottom bar. 18614efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 18624efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void setBottomBarColor(int colorId) { 18634efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mBottomBar.setBackgroundColor(colorId); 18644efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 18654efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 18664efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 1867d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Sets the pressed color of the bottom bar for a camera mode index. 1868b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague */ 1869d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague public void setBottomBarColorsForModeIndex(int index) { 1870d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mBottomBar.setColorsForModeIndex(index); 1871b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 1872b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 1873b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague /** 1874d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Sets the shutter button icon on the bottom bar, based on 1875d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * the mode index. 187639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 1877d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void setBottomBarShutterIcon(int modeIndex) { 1878d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren int shutterIconId = CameraUtil.getCameraShutterIconId(modeIndex, 1879d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mController.getAndroidContext()); 1880fecd723c1cfd90332cd2805be79a24f26643ebb9Erin Dahlgren mBottomBar.setShutterButtonIcon(shutterIconId); 188139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 188239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 188345a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague public void animateBottomBarToVideoStop(int shutterIconId) { 188445a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague mBottomBar.animateToVideoStop(shutterIconId); 188539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 188639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 1887fecd723c1cfd90332cd2805be79a24f26643ebb9Erin Dahlgren public void animateBottomBarToFullSize(int shutterIconId) { 1888fecd723c1cfd90332cd2805be79a24f26643ebb9Erin Dahlgren mBottomBar.animateToFullSize(shutterIconId); 188939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 189039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 18910cf4a02c13a7710dc9b26ac39bea15a95ac48bafSascha Haeberling public void setShutterButtonEnabled(final boolean enabled) { 1892d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague if (!mDisableAllUserInteractions) { 1893d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague mBottomBar.post(new Runnable() { 1894d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague @Override 1895d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague public void run() { 1896d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague mBottomBar.setShutterButtonEnabled(enabled); 1897d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } 1898d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague }); 1899d2d8b711c14ee47f6f4ea16cb9fe27128462ad5bSpike Sprague } 1900667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren } 1901667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren 1902b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague public void setShutterButtonImportantToA11y(boolean important) { 1903b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague mBottomBar.setShutterButtonImportantToA11y(important); 1904b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague } 1905b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague 1906667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren public boolean isShutterButtonEnabled() { 1907667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren return mBottomBar.isShutterButtonEnabled(); 1908a93909ffe93c9f5e27e493f32a78aab6fbf3e06eSpike Sprague } 1909a93909ffe93c9f5e27e493f32a78aab6fbf3e06eSpike Sprague 1910b6db6917db367e4ca0992ca8614a4cfc59d68d92Alan Newberger public void setIndicatorBottomBarWrapperVisible(boolean visible) { 1911427a915be4bcc84fa1c32d9e9e1b7473c522f732Senpo Hu mStickyBottomCaptureLayout.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 1912f495ea8ca078fc752b1ed1045ba22817d75e968eAlan Newberger } 1913f495ea8ca078fc752b1ed1045ba22817d75e968eAlan Newberger 191439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 19154efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Set the visibility of the bottom bar. 19164efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 19174efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren // TODO: needed for when panorama is managed by the generic module ui. 19184efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void setBottomBarVisible(boolean visible) { 19194efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mBottomBar.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 19204efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 19214efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 19224efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 19235d18769f53db81d401488811250570290a73626bErin Dahlgren * Add a {@link #ShutterButton.OnShutterButtonListener} to the shutter button. 19244efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 19255d18769f53db81d401488811250570290a73626bErin Dahlgren public void addShutterListener(ShutterButton.OnShutterButtonListener listener) { 19265d18769f53db81d401488811250570290a73626bErin Dahlgren mShutterButton.addOnShutterButtonListener(listener); 19275d18769f53db81d401488811250570290a73626bErin Dahlgren } 19285d18769f53db81d401488811250570290a73626bErin Dahlgren 19295d18769f53db81d401488811250570290a73626bErin Dahlgren /** 19305d18769f53db81d401488811250570290a73626bErin Dahlgren * Remove a {@link #ShutterButton.OnShutterButtonListener} from the shutter button. 19315d18769f53db81d401488811250570290a73626bErin Dahlgren */ 19325d18769f53db81d401488811250570290a73626bErin Dahlgren public void removeShutterListener(ShutterButton.OnShutterButtonListener listener) { 19335d18769f53db81d401488811250570290a73626bErin Dahlgren mShutterButton.removeOnShutterButtonListener(listener); 19344efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 19354efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 19364efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 193764d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling * Sets or replaces the "cancel shutter" button listener. 193864d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling * <p> 193964d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling * TODO: Make this part of the interface the same way shutter button 194064d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling * listeners are. 194164d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling */ 194264d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling public void setCancelShutterButtonListener(View.OnClickListener listener) { 194364d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling mCountdownCancelButton.setOnClickListener(listener); 194464d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling } 194564d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling 194664d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling /** 1947d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren * Performs a transition to the capture layout of the bottom bar. 1948d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren */ 1949d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren public void transitionToCapture() { 1950d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren ModuleController moduleController = mController.getCurrentModuleController(); 1951d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren applyModuleSpecs(moduleController.getHardwareSpec(), 1952d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren moduleController.getBottomBarSpec()); 1953d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mBottomBar.transitionToCapture(); 1954d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren } 1955d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren 1956d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren /** 19572db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael * Displays the Cancel button instead of the capture button. 19582db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael */ 19592db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael public void transitionToCancel() { 19602db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael ModuleController moduleController = mController.getCurrentModuleController(); 19612db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael applyModuleSpecs(moduleController.getHardwareSpec(), 19622db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael moduleController.getBottomBarSpec()); 19632db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael mBottomBar.transitionToCancel(); 19642db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } 19652db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 19662db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael /** 19674efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Performs a transition to the global intent layout. 19684efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 196915690d02da08bda74ed63f260b70076801bf91bfSpike Sprague public void transitionToIntentCaptureLayout() { 1970b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren ModuleController moduleController = mController.getCurrentModuleController(); 1971d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren applyModuleSpecs(moduleController.getHardwareSpec(), 1972d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren moduleController.getBottomBarSpec()); 197315690d02da08bda74ed63f260b70076801bf91bfSpike Sprague mBottomBar.transitionToIntentCaptureLayout(); 1974b45f618d4a3aa068766be8741213080532feaaffSpike Sprague showModeOptions(); 19754efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 19764efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 19774efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 19784efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren * Performs a transition to the global intent review layout. 19794efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 19804efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void transitionToIntentReviewLayout() { 1981b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren ModuleController moduleController = mController.getCurrentModuleController(); 1982d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren applyModuleSpecs(moduleController.getHardwareSpec(), 1983d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren moduleController.getBottomBarSpec()); 1984d8de077f72b04cee1bdf26e5ca1678ac5297bd71Erin Dahlgren mBottomBar.transitionToIntentReviewLayout(); 1985b45f618d4a3aa068766be8741213080532feaaffSpike Sprague hideModeOptions(); 1986e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu 1987e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu // Hide the preview snapshot since the screen is frozen when users tap 1988e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu // shutter button in capture intent. 1989e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu hideModeCover(); 1990b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 1991b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 19929f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague /** 19939f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague * @return whether UI is in intent review mode 19949f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague */ 19959f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague public boolean isInIntentReview() { 19969f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague return mBottomBar.isInIntentReview(); 19979f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague } 19989f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague 19993c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren @Override 20006190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren public void onSettingChanged(SettingsManager settingsManager, String key) { 20013c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren // Update the mode options based on the hardware spec, 20023c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren // when hdr changes to prevent flash from getting out of sync. 20036190c36db653e848f29d1caefc4fa1bb61e8a662Erin Dahlgren if (key.equals(Keys.KEY_CAMERA_HDR)) { 20043c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren ModuleController moduleController = mController.getCurrentModuleController(); 20053c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren applyModuleSpecs(moduleController.getHardwareSpec(), 2006ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava moduleController.getBottomBarSpec(), 2007ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava true /*skipScopeCheck*/); 20083c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren } 20093c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren } 20103c62221afd869828ba867fce15755a582f2c2334Erin Dahlgren 2011b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** 2012b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Applies a {@link com.android.camera.CameraAppUI.BottomBarUISpec} 2013b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * to the bottom bar mode options based on limitations from a 2014b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * {@link com.android.camera.hardware.HardwareSpec}. 2015b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 2016b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Options not supported by the hardware are either hidden 2017b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * or disabled, depending on the option. 2018b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * 2019b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren * Otherwise, the option is fully enabled and clickable. 2020b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren */ 2021ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava public void applyModuleSpecs(HardwareSpec hardwareSpec, 2022ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava BottomBarUISpec bottomBarSpec) { 2023ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava applyModuleSpecs(hardwareSpec, bottomBarSpec, false /*skipScopeCheck*/); 2024ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2025ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 2026ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava private void applyModuleSpecs(final HardwareSpec hardwareSpec, 2027ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava final BottomBarUISpec bottomBarSpec, boolean skipScopeCheck) { 202849ab922e8e1e7535286392fc667312ec419403fdErin Dahlgren if (hardwareSpec == null || bottomBarSpec == null) { 202949ab922e8e1e7535286392fc667312ec419403fdErin Dahlgren return; 2030b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2031b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 2032b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren ButtonManager buttonManager = mController.getButtonManager(); 2033b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren SettingsManager settingsManager = mController.getSettingsManager(); 2034b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 203559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague buttonManager.setToInitialState(); 203659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague 2037ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (skipScopeCheck 2038ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava || !mController.getModuleScope().equals(mCurrentModuleScope) 2039ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava || !mController.getCameraScope().equals(mCurrentCameraScope)) { 2040ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 2041ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Scope dependent options, update only if the module or the 2042ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // camera scope changed or scope-check skip was requested. 2043ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava mCurrentModuleScope = mController.getModuleScope(); 2044ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava mCurrentCameraScope = mController.getCameraScope(); 2045ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 20464368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava mHdrSupportMode = settingsManager.getString(SettingsManager.SCOPE_GLOBAL, 20474368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava Keys.KEY_HDR_SUPPORT_MODE_BACK_CAMERA); 20489a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava 2049ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava /** Standard mode options */ 2050ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (mController.getCameraProvider().getNumberOfCameras() > 1 && 2051ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava hardwareSpec.isFrontCameraSupported()) { 2052ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.enableCamera) { 20534368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava int hdrButtonId = ButtonManager.BUTTON_HDR; 20544368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava if (mHdrSupportMode.equals(getResourceString( 20554368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava R.string.pref_camera_hdr_supportmode_hdr_plus))) { 20564368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava hdrButtonId = ButtonManager.BUTTON_HDR_PLUS; 20574368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava } 2058ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_CAMERA, 20599a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava bottomBarSpec.cameraCallback, 20604368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava getDisableButtonCallback(hdrButtonId)); 2061ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2062ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_CAMERA); 2063ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2064b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } else { 2065ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Hide camera icon if front camera not available. 2066ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.hideButton(ButtonManager.BUTTON_CAMERA); 2067b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2068b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 2069ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava boolean flashBackCamera = settingsManager.getBoolean(SettingsManager.SCOPE_GLOBAL, 2070ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava Keys.KEY_FLASH_SUPPORTED_BACK_CAMERA); 2071ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.hideFlash 2072ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava || !flashBackCamera) { 2073ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Hide both flash and torch button in flash disable logic 2074ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.hideButton(ButtonManager.BUTTON_FLASH); 2075ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.hideButton(ButtonManager.BUTTON_TORCH); 2076b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } else { 2077ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (hardwareSpec.isFlashSupported()) { 2078ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.enableFlash) { 2079ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_FLASH, 2080ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava bottomBarSpec.flashCallback); 2081ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else if (bottomBarSpec.enableTorchFlash) { 2082ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_TORCH, 2083ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava bottomBarSpec.flashCallback); 2084ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else if (bottomBarSpec.enableHdrPlusFlash) { 2085ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_HDR_PLUS_FLASH, 2086ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava bottomBarSpec.flashCallback); 2087ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2088ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Disable both flash and torch button in flash disable 2089ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // logic. Need to ensure it's visible, it may be hidden 2090ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // from previous non-flash mode. 2091ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.showButton(ButtonManager.BUTTON_FLASH); 2092ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_FLASH); 2093ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_TORCH); 2094ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2095b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } else { 2096ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Flash not supported but another module does. 2097ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Disable flash button. Need to ensure it's visible, 2098ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // it may be hidden from previous non-flash mode. 2099ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.showButton(ButtonManager.BUTTON_FLASH); 2100ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_FLASH); 2101ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_TORCH); 2102b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2103ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2104ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava 2105ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.hideHdr || mIsCaptureIntent) { 2106ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Force hide hdr or hdr plus icon. 2107ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.hideButton(ButtonManager.BUTTON_HDR_PLUS); 2108ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2109ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (hardwareSpec.isHdrPlusSupported()) { 21104368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava mHdrSupportMode = getResourceString( 21114368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava R.string.pref_camera_hdr_supportmode_hdr_plus); 2112ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.enableHdr) { 2113ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_HDR_PLUS, 21149a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava bottomBarSpec.hdrCallback, 21159a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava getDisableButtonCallback(ButtonManager.BUTTON_CAMERA)); 2116ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2117ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_HDR_PLUS); 2118ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2119ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else if (hardwareSpec.isHdrSupported()) { 21204368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava mHdrSupportMode = getResourceString(R.string.pref_camera_hdr_supportmode_hdr); 2121ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava if (bottomBarSpec.enableHdr) { 2122ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.initializeButton(ButtonManager.BUTTON_HDR, 21239a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava bottomBarSpec.hdrCallback, 21249a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava getDisableButtonCallback(ButtonManager.BUTTON_CAMERA)); 2125ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2126ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.disableButton(ButtonManager.BUTTON_HDR); 2127ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2128b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } else { 2129ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Hide hdr plus or hdr icon if neither are supported overall. 21304368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava if (mHdrSupportMode.isEmpty() || mHdrSupportMode 21314368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava .equals(getResourceString(R.string.pref_camera_hdr_supportmode_none))) { 2132ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava buttonManager.hideButton(ButtonManager.BUTTON_HDR_PLUS); 2133ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } else { 2134ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // Disable HDR button. Need to ensure it's visible, 2135ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava // it may be hidden from previous non HDR mode (eg. Video). 21364368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava int buttonId = ButtonManager.BUTTON_HDR; 21374368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava if (mHdrSupportMode.equals( 21384368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava getResourceString(R.string.pref_camera_hdr_supportmode_hdr_plus))) { 21394368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava buttonId = ButtonManager.BUTTON_HDR_PLUS; 21404368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava } 21414368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava buttonManager.showButton(buttonId); 21424368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava buttonManager.disableButton(buttonId); 2143ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2144b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2145b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2146b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren 2147ce9ef4e3528e5599773809f74657b798c370aad2Gabriel Nava } 2148d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren if (bottomBarSpec.hideGridLines) { 2149d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren // Force hide grid lines icon. 2150d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren buttonManager.hideButton(ButtonManager.BUTTON_GRID_LINES); 2151d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren hideGridLines(); 2152d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } else { 2153d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren if (bottomBarSpec.enableGridLines) { 21548ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu buttonManager.initializeButton(ButtonManager.BUTTON_GRID_LINES, 21558ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu bottomBarSpec.gridLinesCallback != null ? 21568ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu bottomBarSpec.gridLinesCallback : getGridLinesCallback() 21578ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu ); 2158d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } else { 2159d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren buttonManager.disableButton(ButtonManager.BUTTON_GRID_LINES); 2160d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren hideGridLines(); 2161d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } 2162d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren } 2163d5e51466a2848f1c937656c8f8185290034c2429Erin Dahlgren 21646c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu if (bottomBarSpec.enableSelfTimer) { 21656c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu buttonManager.initializeButton(ButtonManager.BUTTON_COUNTDOWN, null); 21666c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu } else { 21674333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling if (bottomBarSpec.showSelfTimer) { 21684333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling buttonManager.disableButton(ButtonManager.BUTTON_COUNTDOWN); 21694333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling } else { 21704333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling buttonManager.hideButton(ButtonManager.BUTTON_COUNTDOWN); 21714333fac867f6f6a11235b16d305dd197093b44d5Sascha Haeberling } 21726c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu } 21736c75164c89f3bbd4f894b9c49a7914a24268a999Doris Liu 2174f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren if (bottomBarSpec.enablePanoOrientation 2175f80ac9ee5c66671c3a77ac6628fefc86cd39d57eErin Dahlgren && PhotoSphereHelper.getPanoramaOrientationOptionArrayId() > 0) { 217659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague buttonManager.initializePanoOrientationButtons(bottomBarSpec.panoOrientationCallback); 2177a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren } 2178a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren 217957c889d4b88517dd0996547dbae4f314c2a3fcdfzafir 218057c889d4b88517dd0996547dbae4f314c2a3fcdfzafir 218157c889d4b88517dd0996547dbae4f314c2a3fcdfzafir // If manual exposure is enabled both in SettingsManager and 218257c889d4b88517dd0996547dbae4f314c2a3fcdfzafir // BottomBarSpec,then show the exposure button. 218357c889d4b88517dd0996547dbae4f314c2a3fcdfzafir // If manual exposure is disabled in the BottomBarSpec (eg. HDR+ 21846ffdeac1670c8938d0331c89d9269b68f361d6fazafir // enabled), but the device/module has the feature, then disable the exposure 218557c889d4b88517dd0996547dbae4f314c2a3fcdfzafir // button. 218657c889d4b88517dd0996547dbae4f314c2a3fcdfzafir // Otherwise, hide the button. 21870409c8594fd1629ee07df827cf0d7a0f336b9326zafir if (bottomBarSpec.enableExposureCompensation 21880409c8594fd1629ee07df827cf0d7a0f336b9326zafir && !(bottomBarSpec.minExposureCompensation == 0 && bottomBarSpec.maxExposureCompensation == 0) 21890409c8594fd1629ee07df827cf0d7a0f336b9326zafir && mController.getSettingsManager().getBoolean(SettingsManager.SCOPE_GLOBAL, 21900409c8594fd1629ee07df827cf0d7a0f336b9326zafir Keys.KEY_EXPOSURE_COMPENSATION_ENABLED)) { 2191b6c4a314d0a0a185e6d987298ef9b7f4db8a6a2fSenpo Hu buttonManager.initializePushButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION, 2192b6c4a314d0a0a185e6d987298ef9b7f4db8a6a2fSenpo Hu new View.OnClickListener() { 21930409c8594fd1629ee07df827cf0d7a0f336b9326zafir @Override 21940409c8594fd1629ee07df827cf0d7a0f336b9326zafir public void onClick(View v) { 21950409c8594fd1629ee07df827cf0d7a0f336b9326zafir mModeOptionsOverlay.showExposureOptions(); 21960409c8594fd1629ee07df827cf0d7a0f336b9326zafir } 21970409c8594fd1629ee07df827cf0d7a0f336b9326zafir }); 219846acdc5401956ee4951d25d047ae892b78c13d86Spike Sprague buttonManager.setExposureCompensationParameters( 219957c889d4b88517dd0996547dbae4f314c2a3fcdfzafir bottomBarSpec.minExposureCompensation, 220057c889d4b88517dd0996547dbae4f314c2a3fcdfzafir bottomBarSpec.maxExposureCompensation, 220157c889d4b88517dd0996547dbae4f314c2a3fcdfzafir bottomBarSpec.exposureCompensationStep); 220246acdc5401956ee4951d25d047ae892b78c13d86Spike Sprague 2203abf54e2994961395a0feb0b08353e62718443f23Spike Sprague buttonManager.setExposureCompensationCallback( 2204abf54e2994961395a0feb0b08353e62718443f23Spike Sprague bottomBarSpec.exposureCompensationSetCallback); 2205abf54e2994961395a0feb0b08353e62718443f23Spike Sprague buttonManager.updateExposureButtons(); 22060409c8594fd1629ee07df827cf0d7a0f336b9326zafir } else if (mController.getSettingsManager().getBoolean(SettingsManager.SCOPE_GLOBAL, 220757c889d4b88517dd0996547dbae4f314c2a3fcdfzafir Keys.KEY_EXPOSURE_COMPENSATION_ENABLED) 220857c889d4b88517dd0996547dbae4f314c2a3fcdfzafir && bottomBarSpec.isExposureCompensationSupported) { 22090409c8594fd1629ee07df827cf0d7a0f336b9326zafir buttonManager.disableButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION); 2210abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } else { 2211abf54e2994961395a0feb0b08353e62718443f23Spike Sprague buttonManager.hideButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION); 2212abf54e2994961395a0feb0b08353e62718443f23Spike Sprague buttonManager.setExposureCompensationCallback(null); 2213abf54e2994961395a0feb0b08353e62718443f23Spike Sprague } 2214abf54e2994961395a0feb0b08353e62718443f23Spike Sprague 2215b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren /** Intent UI */ 2216b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren if (bottomBarSpec.showCancel) { 22178ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu buttonManager.initializePushButton(ButtonManager.BUTTON_CANCEL, 22188ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu bottomBarSpec.cancelCallback); 2219b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2220b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren if (bottomBarSpec.showDone) { 22218ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu buttonManager.initializePushButton(ButtonManager.BUTTON_DONE, 22228ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu bottomBarSpec.doneCallback); 2223b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 2224b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren if (bottomBarSpec.showRetake) { 22258ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu buttonManager.initializePushButton(ButtonManager.BUTTON_RETAKE, 2226c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague bottomBarSpec.retakeCallback, 2227c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague R.drawable.ic_back, 2228c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague R.string.retake_button_description); 2229b1641f5df0cf839b54385ea4d2e43521620fc237Erin Dahlgren } 223051c877c56e204ac29a4db72d46168afac3feb239Spike Sprague if (bottomBarSpec.showReview) { 22318ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu buttonManager.initializePushButton(ButtonManager.BUTTON_REVIEW, 22328ad8ad4841f65ee89e3c5e79f57d95cf8e4438b4Doris Liu bottomBarSpec.reviewCallback, 2233c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague R.drawable.ic_play, 2234c989d417a53341b144e9f78304270ac66f8f5813Spike Sprague R.string.review_button_description); 223551c877c56e204ac29a4db72d46168afac3feb239Spike Sprague } 22364efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2237c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling 2238c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling /** 22399a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava * Returns a {@link com.android.camera.ButtonManager.ButtonCallback} that 22409a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava * will disable the button identified by the parameter. 22419a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava * 22429a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava * @param conflictingButton The button id to be disabled. 22439a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava */ 22449a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava private ButtonManager.ButtonCallback getDisableButtonCallback(final int conflictingButton) { 22459a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava return new ButtonManager.ButtonCallback() { 22469a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava @Override 22479a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava public void onStateChanged(int state) { 22489a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava mController.getButtonManager().disableButton(conflictingButton); 22499a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava } 22509a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava }; 22519a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava } 22529a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava 22534368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava private String getResourceString(int stringId) { 22544368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava try { 22554368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava return mController.getAndroidContext().getResources().getString(stringId); 22564368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava } catch (Resources.NotFoundException e) { 22574368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava // String not found, returning empty string. 22584368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava return ""; 22594368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava } 22604368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava } 22614368ec0368f69e7604403b4a6db6f1e3123a1814Gabriel Nava 22629a57f184a6f5be46e93dd2f6c66f4b9ba07bdd75Gabriel Nava /** 2263c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling * Shows the given tutorial on the screen. 2264c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling */ 2265c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling public void showTutorial(AbstractTutorialOverlay tutorial, LayoutInflater inflater) { 22661e0810c88e791d0f658eb5a6f95d771ee03a7631Sascha Haeberling tutorial.show(mTutorialsPlaceHolderWrapper, inflater); 2267c813ce181810a444b6fea4a399e6685aef4103e2Sascha Haeberling } 2268623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger 226914de25b5c502ffb2ac6396014624206562affef2Gabriel Nava /** 227014de25b5c502ffb2ac6396014624206562affef2Gabriel Nava * Whether the capture ratio selector dialog must be shown on this device. 227114de25b5c502ffb2ac6396014624206562affef2Gabriel Nava * */ 227214de25b5c502ffb2ac6396014624206562affef2Gabriel Nava public boolean shouldShowAspectRatioDialog() { 227314de25b5c502ffb2ac6396014624206562affef2Gabriel Nava final boolean isAspectRatioPreferenceSet = mController.getSettingsManager().getBoolean( 227414de25b5c502ffb2ac6396014624206562affef2Gabriel Nava SettingsManager.SCOPE_GLOBAL, Keys.KEY_USER_SELECTED_ASPECT_RATIO); 227514de25b5c502ffb2ac6396014624206562affef2Gabriel Nava final boolean isAspectRatioDevice = 227614de25b5c502ffb2ac6396014624206562affef2Gabriel Nava ApiHelper.IS_NEXUS_4 || ApiHelper.IS_NEXUS_5 || ApiHelper.IS_NEXUS_6; 227714de25b5c502ffb2ac6396014624206562affef2Gabriel Nava return isAspectRatioDevice && !isAspectRatioPreferenceSet; 227814de25b5c502ffb2ac6396014624206562affef2Gabriel Nava } 227914de25b5c502ffb2ac6396014624206562affef2Gabriel Nava 228014de25b5c502ffb2ac6396014624206562affef2Gabriel Nava 2281623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger /***************************Filmstrip api *****************************/ 2282623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger 2283623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger public void showFilmstrip() { 2284256427babcb93dd3cdb11b6e23c47ecf82e5af19Sascha Haeberling mModeListView.onBackPressed(); 2285623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger mFilmstripLayout.showFilmstrip(); 2286623dd0c68d64038ed2bcfd264348d9b6f1a13c8aAlan Newberger } 22878099a371048e45b9161ac63e4d6bd9644fcad5b5Alan Newberger 22888099a371048e45b9161ac63e4d6bd9644fcad5b5Alan Newberger public void hideFilmstrip() { 22898099a371048e45b9161ac63e4d6bd9644fcad5b5Alan Newberger mFilmstripLayout.hideFilmstrip(); 22908099a371048e45b9161ac63e4d6bd9644fcad5b5Alan Newberger } 229186f1d1f3664c909d1d949951056c7bb1e9627324Alan Newberger 229286f1d1f3664c909d1d949951056c7bb1e9627324Alan Newberger public int getFilmstripVisibility() { 229386f1d1f3664c909d1d949951056c7bb1e9627324Alan Newberger return mFilmstripLayout.getVisibility(); 229486f1d1f3664c909d1d949951056c7bb1e9627324Alan Newberger } 2295f55f3c461c5a6ae6b61fa75562ca01683aa93f9aDoris Liu} 2296