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 17 package com.android.camera.captureintent; 18 19 import android.graphics.Bitmap; 20 import android.location.Location; 21 import android.net.Uri; 22 23 import com.android.camera.debug.Log; 24 import com.android.camera.exif.ExifInterface; 25 import com.android.camera.session.CaptureSession; 26 import com.android.camera.session.CaptureSessionManager; 27 import com.android.camera.session.SessionNotifier; 28 import com.android.camera.session.StackSaver; 29 import com.android.camera.session.TemporarySessionFile; 30 import com.android.camera.stats.CaptureSessionStatsCollector; 31 import com.android.camera.util.Size; 32 import com.google.common.base.Optional; 33 import com.google.common.util.concurrent.Futures; 34 import com.google.common.util.concurrent.ListenableFuture; 35 36 import java.io.ByteArrayOutputStream; 37 import java.io.IOException; 38 import javax.annotation.Nonnull; 39 40 /** 41 * An implementation of {@link CaptureSession} which is used by 42 * {@link CaptureIntentModule}. 43 */ 44 public class CaptureIntentSession implements CaptureSession { 45 private static final Log.Tag TAG = new Log.Tag("CapIntSession"); 46 47 /** For aggregation of capture information */ 48 // TODO: Implement mCaptureSessionStatsCollector.decorateAtTimeCaptureRequest call. 49 private final CaptureSessionStatsCollector mCaptureSessionStatsCollector = 50 new CaptureSessionStatsCollector(); 51 /** The capture session manager responsible for this session. */ 52 private final CaptureSessionManager mSessionManager; 53 /** Used to inform about session status updates. */ 54 private final SessionNotifier mSessionNotifier; 55 /** The title of the item being processed. */ 56 private final String mTitle; 57 /** The location this session was created at. Used for media store. */ 58 private Location mLocation; 59 /** Whether one of start methods are called. */ 60 private boolean isStarted; 61 62 /** 63 * Creates a new {@link CaptureSession}. 64 * 65 * @param title the title of this session. 66 * @param location the location of this session, used for media store. 67 * @param captureSessionManager the capture session manager responsible for 68 * this session. 69 */ CaptureIntentSession(String title, Location location, CaptureSessionManager captureSessionManager, SessionNotifier sessionNotifier)70 public CaptureIntentSession(String title, Location location, 71 CaptureSessionManager captureSessionManager, SessionNotifier sessionNotifier) { 72 mTitle = title; 73 mLocation = location; 74 mSessionManager = captureSessionManager; 75 mSessionNotifier = sessionNotifier; 76 isStarted = false; 77 } 78 79 @Override getTitle()80 public String getTitle() { 81 return mTitle; 82 } 83 84 @Override getLocation()85 public Location getLocation() { 86 return mLocation; 87 } 88 89 @Override setLocation(Location location)90 public void setLocation(Location location) { 91 mLocation = location; 92 } 93 94 // TODO: Support progress in the future once HDR is enabled for capture intent. 95 @Override getProgress()96 public synchronized int getProgress() { 97 return 0; 98 } 99 100 @Override setProgress(int percent)101 public synchronized void setProgress(int percent) { 102 // Do nothing. 103 } 104 105 @Override getProgressMessageId()106 public synchronized int getProgressMessageId() { 107 return -1; 108 } 109 110 @Override setProgressMessage(int messageId)111 public synchronized void setProgressMessage(int messageId) { 112 } 113 114 @Override updateThumbnail(Bitmap bitmap)115 public void updateThumbnail(Bitmap bitmap) { 116 mSessionNotifier.notifySessionThumbnailAvailable(bitmap); 117 } 118 119 @Override updateCaptureIndicatorThumbnail(Bitmap indicator, int rotationDegrees)120 public void updateCaptureIndicatorThumbnail(Bitmap indicator, int rotationDegrees) { 121 // Do nothing 122 } 123 124 @Override startEmpty(ImageLifecycleListener listener, @Nonnull Size pictureSize)125 public synchronized void startEmpty(ImageLifecycleListener listener, @Nonnull Size pictureSize) { 126 isStarted = true; 127 } 128 129 @Override startSession(ImageLifecycleListener listener, @Nonnull Bitmap placeholder, int progressMessageId)130 public synchronized void startSession(ImageLifecycleListener listener, @Nonnull Bitmap placeholder, 131 int progressMessageId) { 132 throw new RuntimeException("Not supported."); 133 } 134 135 @Override startSession(ImageLifecycleListener listener, @Nonnull byte[] placeholder, int progressMessageId)136 public synchronized void startSession(ImageLifecycleListener listener, @Nonnull byte[] placeholder, 137 int progressMessageId) { 138 throw new RuntimeException("Not supported."); 139 } 140 141 @Override startSession(ImageLifecycleListener listener, @Nonnull Uri uri, @Nonnull int progressMessageId)142 public synchronized void startSession(ImageLifecycleListener listener, @Nonnull Uri uri, 143 @Nonnull int progressMessageId) { 144 throw new RuntimeException("Not supported."); 145 } 146 147 @Override cancel()148 public synchronized void cancel() { 149 } 150 151 @Override saveAndFinish(byte[] data, int width, int height, int orientation, ExifInterface exif)152 public synchronized ListenableFuture<Optional<Uri>> saveAndFinish(byte[] data, int width, 153 int height, int orientation, ExifInterface exif) { 154 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 155 try { 156 exif.writeExif(data, byteArrayOutputStream); 157 } catch (IOException e) { 158 Log.e(TAG, "exception while trying to append exif to jpeg data"); 159 } 160 byte[] dataWithExif = byteArrayOutputStream.toByteArray(); 161 //No need to close byteArrayOutputStream since that has no effect. 162 mSessionNotifier.notifySessionPictureDataAvailable(dataWithExif, orientation); 163 return Futures.immediateFuture(Optional.<Uri> absent()); 164 } 165 166 @Override getStackSaver()167 public StackSaver getStackSaver() { 168 return null; 169 } 170 171 @Override finish()172 public void finish() { 173 // Do nothing. 174 } 175 176 @Override getTempOutputFile()177 public TemporarySessionFile getTempOutputFile() { 178 throw new RuntimeException("Not supported."); 179 } 180 181 @Override getUri()182 public Uri getUri() { 183 throw new RuntimeException("Not supported."); 184 } 185 186 @Override updatePreview()187 public void updatePreview() { 188 throw new RuntimeException("Not supported."); 189 } 190 191 @Override finishWithFailure(int progressMessageId, boolean removeFromFilmstrip)192 public void finishWithFailure(int progressMessageId, boolean removeFromFilmstrip) { 193 throw new RuntimeException("Not supported."); 194 } 195 196 @Override finalizeSession()197 public void finalizeSession() { 198 // Do nothing. 199 } 200 201 @Override addProgressListener(CaptureSession.ProgressListener listener)202 public void addProgressListener(CaptureSession.ProgressListener listener) { 203 // Do nothing. 204 } 205 206 @Override removeProgressListener(CaptureSession.ProgressListener listener)207 public void removeProgressListener(CaptureSession.ProgressListener listener) { 208 // Do nothing. 209 } 210 211 @Override getCollector()212 public CaptureSessionStatsCollector getCollector() { 213 return mCaptureSessionStatsCollector; 214 } 215 isStarted()216 private boolean isStarted() { 217 return isStarted; 218 } 219 } 220