1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.camera.captureintent.resource; 18 19import com.google.common.logging.eventprotos; 20 21import com.android.camera.SoundPlayer; 22import com.android.camera.async.MainThread; 23import com.android.camera.async.RefCountBase; 24import com.android.camera.captureintent.CaptureIntentModuleUI; 25import com.android.camera.captureintent.CaptureIntentSessionFactory; 26import com.android.camera.debug.Log; 27import com.android.camera.hardware.HeadingSensor; 28import com.android.camera.one.OneCamera; 29import com.android.camera.session.CaptureSession; 30import com.android.camera.session.CaptureSessionManager; 31import com.android.camera.session.CaptureSessionManagerImpl; 32import com.android.camera.session.SessionStorageManagerImpl; 33import com.android.camera.settings.Keys; 34import com.android.camera.settings.SettingsManager; 35import com.android.camera.ui.focus.FocusController; 36import com.android.camera.ui.focus.FocusSound; 37import com.android.camera.util.AndroidServices; 38import com.android.camera.util.CameraUtil; 39import com.android.camera2.R; 40 41import android.media.MediaActionSound; 42 43public final class ResourceCaptureToolsImpl implements ResourceCaptureTools { 44 private static final Log.Tag TAG = new Log.Tag("ResCapTools"); 45 46 private final RefCountBase<ResourceConstructed> mResourceConstructed; 47 private final RefCountBase<ResourceSurfaceTexture> mResourceSurfaceTexture; 48 private final RefCountBase<ResourceOpenedCamera> mResourceOpenedCamera; 49 50 private final CaptureSessionManager mCaptureSessionManager; 51 private final FocusController mFocusController; 52 private final HeadingSensor mHeadingSensor; 53 private final SoundPlayer mSoundPlayer; 54 private final MediaActionSound mMediaActionSound; 55 56 /** 57 * Creates a reference counted {@link ResourceCaptureToolsImpl} object. 58 */ 59 public static RefCountBase<ResourceCaptureTools> create( 60 RefCountBase<ResourceConstructed> resourceConstructed, 61 RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture, 62 RefCountBase<ResourceOpenedCamera> resourceOpenedCamera) { 63 CaptureSessionManager captureSessionManager = new CaptureSessionManagerImpl( 64 new CaptureIntentSessionFactory(), 65 SessionStorageManagerImpl.create(resourceConstructed.get().getContext()), 66 resourceConstructed.get().getMainThread()); 67 HeadingSensor headingSensor = 68 new HeadingSensor(AndroidServices.instance().provideSensorManager()); 69 SoundPlayer soundPlayer = new SoundPlayer(resourceConstructed.get().getContext()); 70 FocusSound focusSound = new FocusSound(soundPlayer, R.raw.material_camera_focus); 71 FocusController focusController = new FocusController( 72 resourceConstructed.get().getModuleUI().getFocusRing(), 73 focusSound, 74 resourceConstructed.get().getMainThread()); 75 MediaActionSound mediaActionSound = new MediaActionSound(); 76 ResourceCaptureTools resourceCaptureTools = new ResourceCaptureToolsImpl( 77 resourceConstructed, resourceSurfaceTexture, resourceOpenedCamera, 78 captureSessionManager, focusController, headingSensor, soundPlayer, 79 mediaActionSound); 80 return new RefCountBase<>(resourceCaptureTools); 81 } 82 83 private ResourceCaptureToolsImpl( 84 RefCountBase<ResourceConstructed> resourceConstructed, 85 RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture, 86 RefCountBase<ResourceOpenedCamera> resourceOpenedCamera, 87 CaptureSessionManager captureSessionManager, 88 FocusController focusController, 89 HeadingSensor headingSensor, 90 SoundPlayer soundPlayer, 91 MediaActionSound mediaActionSound) { 92 mResourceConstructed = resourceConstructed; 93 mResourceConstructed.addRef(); // Will be balanced in close(). 94 mResourceSurfaceTexture = resourceSurfaceTexture; 95 mResourceSurfaceTexture.addRef(); // Will be balanced in close(). 96 mResourceOpenedCamera = resourceOpenedCamera; 97 mResourceOpenedCamera.addRef(); // Will be balanced in close(). 98 mCaptureSessionManager = captureSessionManager; 99 mHeadingSensor = headingSensor; 100 mHeadingSensor.activate(); // Will be balanced in close(). 101 mSoundPlayer = soundPlayer; 102 mSoundPlayer.loadSound(R.raw.timer_final_second); // Will be balanced in close(). 103 mSoundPlayer.loadSound(R.raw.timer_increment); // Will be balanced in close(). 104 mMediaActionSound = mediaActionSound; 105 mFocusController = focusController; 106 } 107 108 @Override 109 public void close() { 110 Log.d(TAG, "close"); 111 mResourceConstructed.close(); 112 mResourceSurfaceTexture.close(); 113 mResourceOpenedCamera.close(); 114 mHeadingSensor.deactivate(); 115 mSoundPlayer.unloadSound(R.raw.timer_increment); 116 mSoundPlayer.unloadSound(R.raw.timer_final_second); 117 } 118 119 @Override 120 public RefCountBase<ResourceConstructed> getResourceConstructed() { 121 return mResourceConstructed; 122 } 123 124 @Override 125 public RefCountBase<ResourceSurfaceTexture> getResourceSurfaceTexture() { 126 return mResourceSurfaceTexture; 127 } 128 129 @Override 130 public RefCountBase<ResourceOpenedCamera> getResourceOpenedCamera() { 131 return mResourceOpenedCamera; 132 } 133 134 @Override 135 public CaptureSessionManager getCaptureSessionManager() { 136 return mCaptureSessionManager; 137 } 138 139 @Override 140 public FocusController getFocusController() { 141 return mFocusController; 142 } 143 144 @Override 145 public MediaActionSound getMediaActionSound() { 146 return mMediaActionSound; 147 } 148 149 @Override 150 public void takePictureNow( 151 OneCamera.PictureCallback pictureCallback, 152 CaptureLoggingInfo captureLoggingInfo) { 153 final ResourceConstructed resource = mResourceConstructed.get(); 154 final ResourceOpenedCamera openedCamera = mResourceOpenedCamera.get(); 155 156 /** 157 * Disable the shutter button immediately. The button will be 158 * re-enabled when users press re-take button. 159 */ 160 resource.getMainThread().execute(new Runnable() { 161 @Override 162 public void run() { 163 resource.getModuleUI().setShutterButtonEnabled(false); 164 } 165 }); 166 167 /** Create a new capture session. */ 168 final long timestamp = System.currentTimeMillis(); 169 final String fileName = CameraUtil.instance().createJpegName(timestamp); 170 final android.location.Location location = 171 resource.getLocationManager().getCurrentLocation(); 172 final CaptureSession session = 173 mCaptureSessionManager.createNewSession(fileName, timestamp, location); 174 session.startEmpty(null, openedCamera.getPictureSize()); 175 176 /** Logging */ 177 final SettingsManager settingsManager = resource.getSettingsManager(); 178 boolean isGridLinesOn = Keys.areGridLinesOn(settingsManager); 179 session.getCollector().decorateAtTimeCaptureRequest( 180 eventprotos.NavigationChange.Mode.PHOTO_CAPTURE, 181 session.getTitle() + ".jpg", 182 (openedCamera.getCameraFacing() == OneCamera.Facing.FRONT), 183 false, /** hdrPlusEnabled */ 184 openedCamera.getZoomRatio(), 185 openedCamera.getCaptureSetting().getFlashSetting().get().encodeSettingsString(), 186 isGridLinesOn, 187 (float) captureLoggingInfo.getCountDownDuration(), 188 captureLoggingInfo.getTouchPointInsideShutterButton(), 189 null /* TODO: Implement Volume Button Shutter Click Instrumentation */, 190 openedCamera.getCameraCharacteristics().getSensorInfoActiveArraySize() 191 ); 192 193 OneCamera.PhotoCaptureParameters params = new OneCamera.PhotoCaptureParameters( 194 session.getTitle(), 195 resource.getOrientationManager().getDeviceOrientation().getDegrees(), 196 session.getLocation(), 197 resource.getContext().getExternalCacheDir(), 198 pictureCallback, 199 mPictureSaverCallback, 200 mHeadingSensor.getCurrentHeading(), 201 openedCamera.getZoomRatio(), 202 0); 203 openedCamera.getCamera().takePicture(params, session); 204 } 205 206 @Override 207 public void playCountDownSound(int remainingSeconds) { 208 if (remainingSeconds == 1) { 209 mSoundPlayer.play(R.raw.timer_final_second, 0.6f); 210 } else if (remainingSeconds == 2 || remainingSeconds == 3) { 211 mSoundPlayer.play(R.raw.timer_increment, 0.6f); 212 } 213 } 214 215 @Override 216 public MainThread getMainThread() { 217 return mResourceConstructed.get().getMainThread(); 218 } 219 220 @Override 221 public CaptureIntentModuleUI getModuleUI() { 222 return mResourceConstructed.get().getModuleUI(); 223 } 224 225 @Override 226 public OneCamera getCamera() { 227 return mResourceOpenedCamera.get().getCamera(); 228 } 229 230 private final OneCamera.PictureSaverCallback mPictureSaverCallback = 231 new OneCamera.PictureSaverCallback() { 232 @Override 233 public void onRemoteThumbnailAvailable(byte[] jpegImage) { 234 } 235 }; 236} 237