summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzafir <zafir@google.com>2015-03-04 14:02:47 -0800
committerzafir <zafir@google.com>2015-03-06 16:06:25 -0800
commit698e271d2b263778bfa73d1e67d6e2cd2783c89e (patch)
treeec25bfbde4132e50c7b1cfc18414e9206608d72d
parent4a1378acfdebc4c2959bf68ee31e44dc9d131ae8 (diff)
downloadandroid_packages_apps_Camera2-698e271d2b263778bfa73d1e67d6e2cd2783c89e.tar.gz
android_packages_apps_Camera2-698e271d2b263778bfa73d1e67d6e2cd2783c89e.tar.bz2
android_packages_apps_Camera2-698e271d2b263778bfa73d1e67d6e2cd2783c89e.zip
Added more error handling for camera access and picture storage issues.
Implemented onFailure() method in the OpenCallback interface and onPictureTakingFailed() in the PictureCallback interface. OnFailure() routes through showErrorAndFinish() in the AppController. Bug: 19452391 Change-Id: I3c19a274cc7664f7d1834899a486c57d0585dc9a
-rw-r--r--res/values/strings.xml6
-rw-r--r--src/com/android/camera/CameraActivity.java50
-rw-r--r--src/com/android/camera/CaptureModule.java10
-rw-r--r--src/com/android/camera/FatalErrorHandler.java38
-rw-r--r--src/com/android/camera/FatalErrorHandlerImpl.java77
-rw-r--r--src/com/android/camera/PhotoModule.java20
-rw-r--r--src/com/android/camera/app/AppController.java10
-rw-r--r--src/com/android/camera/captureintent/CaptureIntentModule.java6
-rw-r--r--src/com/android/camera/captureintent/CaptureIntentSession.java2
-rw-r--r--src/com/android/camera/captureintent/state/StateFatal.java6
-rw-r--r--src/com/android/camera/captureintent/state/StateReadyForCapture.java3
-rw-r--r--src/com/android/camera/captureintent/state/StateReviewingPicture.java3
-rw-r--r--src/com/android/camera/captureintent/state/StateStartingPreview.java2
-rw-r--r--src/com/android/camera/one/v2/photo/PictureTakerImpl.java5
-rw-r--r--src/com/android/camera/session/CaptureSession.java2
-rw-r--r--src/com/android/camera/session/CaptureSessionImpl.java9
-rw-r--r--src/com/android/camera/session/CaptureSessionManager.java2
-rw-r--r--src/com/android/camera/session/CaptureSessionManagerImpl.java5
-rw-r--r--src/com/android/camera/session/SessionNotifier.java3
19 files changed, 176 insertions, 83 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e8c89284a..1e2becbf1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -128,13 +128,13 @@
<string name="camera_error_title">Camera error</string>
<!-- message for the dialog showing the error of camera hardware -->
- <string name="cannot_connect_camera">Can\'t connect to the camera.</string>
+ <string name="error_cannot_connect_camera">Can\'t connect to the camera.</string>
<!-- message for the dialog showing the camera is disabled because of security policies. Camera cannot be used. -->
- <string name="camera_disabled">Camera has been disabled because of security policies.</string>
+ <string name="error_camera_disabled">Camera has been disabled because of security policies.</string>
<!-- message for the dialog showing that the user's photo could not be saved [CHAR LIMIT=NONE] -->
- <string name="media_storage_failure">There was a problem saving your photo or video.</string>
+ <string name="error_media_storage_failure">There was a problem saving your photo or video.</string>
<!-- Reason used for session failure which is visible in UI [CHAR LIMIT=NONE] -->
<string name="reason_storage_failure">Photo storage failure.</string>
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 1861bfe3a..c513547fe 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -240,6 +240,7 @@ public class CameraActivity extends QuickActivity
private ViewGroup mUndoDeletionBar;
private boolean mIsUndoingDeletion = false;
private boolean mIsActivityRunning = false;
+ private FatalErrorHandler mFatalErrorHandler;
private final Uri[] mNfcPushUris = new Uri[1];
@@ -527,35 +528,26 @@ public class CameraActivity extends QuickActivity
@Override
public void onCameraDisabled(int cameraId) {
- UsageStatistics.instance().cameraFailure(
- eventprotos.CameraFailure.FailureReason.SECURITY, null,
- UsageStatistics.NONE, UsageStatistics.NONE);
Log.w(TAG, "Camera disabled: " + cameraId);
- CameraUtil.showError(this, R.string.camera_disabled, R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onCameraDisabledFailure();
}
@Override
public void onDeviceOpenFailure(int cameraId, String info) {
- UsageStatistics.instance().cameraFailure(
- eventprotos.CameraFailure.FailureReason.OPEN_FAILURE, info,
- UsageStatistics.NONE, UsageStatistics.NONE);
Log.w(TAG, "Camera open failure: " + info);
- CameraUtil.showError(this, R.string.camera_disabled, R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onCameraOpenFailure();
}
@Override
public void onDeviceOpenedAlready(int cameraId, String info) {
Log.w(TAG, "Camera open already: " + cameraId + "," + info);
- CameraUtil.showError(this, R.string.camera_disabled, R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onGenericCameraAccessFailure();
}
@Override
public void onReconnectionFailure(CameraAgent mgr, String info) {
- UsageStatistics.instance().cameraFailure(
- eventprotos.CameraFailure.FailureReason.RECONNECT_FAILURE, null,
- UsageStatistics.NONE, UsageStatistics.NONE);
Log.w(TAG, "Camera reconnection failure:" + info);
- CameraUtil.showError(this, R.string.camera_disabled, R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onCameraReconnectFailure();
}
private static class MainHandler extends Handler {
@@ -966,7 +958,7 @@ public class CameraActivity extends QuickActivity
}
@Override
- public void onSessionFailed(Uri uri, CharSequence reason) {
+ public void onSessionFailed(Uri uri, CharSequence reason, boolean removeFromFilmstrip) {
Log.v(TAG, "onSessionFailed:" + uri);
int failedIndex = mDataAdapter.findByContentUri(uri);
@@ -975,15 +967,12 @@ public class CameraActivity extends QuickActivity
if (currentIndex == failedIndex) {
updateSessionProgress(0);
showProcessError(reason);
+ mDataAdapter.refresh(uri);
}
- if (reason.equals("content")) {
- UsageStatistics.instance().storageWarning(Storage.ACCESS_FAILURE);
- CameraUtil.showError(CameraActivity.this, R.string.media_storage_failure,
- R.string.feedback_description_save_photo, false);
+ if (removeFromFilmstrip) {
+ mFatalErrorHandler.onMediaStorageFailure();
+ mDataAdapter.removeAt(failedIndex);
}
-
- // HERE
- mDataAdapter.refresh(uri);
}
@Override
@@ -1396,8 +1385,7 @@ public class CameraActivity extends QuickActivity
Log.e(TAG, "Fatal error during onPause, call Activity.finish()");
finish();
} else {
- CameraUtil.showError(CameraActivity.this, R.string.camera_disabled,
- R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.handleFatalError(FatalErrorHandler.Reason.CANNOT_CONNECT_TO_CAMERA);
}
}
};
@@ -1420,6 +1408,7 @@ public class CameraActivity extends QuickActivity
mSoundPlayer = new SoundPlayer(mAppContext);
mFeatureConfig = OneCameraFeatureConfigCreator.createDefault(getContentResolver(),
getServices().getMemoryManager());
+ mFatalErrorHandler = new FatalErrorHandlerImpl(this);
profile.mark();
if (!Glide.isSetup()) {
@@ -1451,10 +1440,9 @@ public class CameraActivity extends QuickActivity
mCameraManager = OneCameraManager.get(
mFeatureConfig, mAppContext, ResolutionUtil.getDisplayMetrics(this));
} catch (OneCameraException e) {
- // Log error and continue. Modules requiring OneCamera should check
- // and handle if null by showing error dialog or other treatment.
+ // Log error and continue start process while showing error dialog..
Log.e(TAG, "Creating camera manager failed.", e);
- CameraUtil.showError(this, R.string.camera_disabled, R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onGenericCameraAccessFailure();
}
profile.mark("OneCameraManager.get");
mCameraController = new CameraController(mAppContext, this, mMainHandler,
@@ -1679,8 +1667,7 @@ public class CameraActivity extends QuickActivity
@Override
public void onCameraAccessException() {
- CameraUtil.showError(CameraActivity.this, R.string.camera_disabled,
- R.string.feedback_description_camera_access, true);
+ mFatalErrorHandler.onGenericCameraAccessFailure();
}
});
profile.stop();
@@ -2409,7 +2396,7 @@ public class CameraActivity extends QuickActivity
@Override
public FatalErrorHandler getFatalErrorHandler() {
- return new FatalErrorHandlerImpl(this);
+ return mFatalErrorHandler;
}
public List<String> getSupportedModeNames() {
@@ -2699,11 +2686,6 @@ public class CameraActivity extends QuickActivity
}
@Override
- public void showErrorAndFinish(int messageId) {
- CameraUtil.showError(this, messageId, R.string.feedback_description_camera_access, true);
- }
-
- @Override
public void finishActivityWithIntentCompleted(Intent resultIntent) {
finishActivityWithIntentResult(Activity.RESULT_OK, resultIntent);
}
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 46062d02f..9ddb7b8fd 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -83,6 +83,7 @@ import com.android.camera.util.GcamHelper;
import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgent.CameraProxy;
+import com.google.common.logging.eventprotos;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -372,7 +373,7 @@ public class CaptureModule extends CameraModule implements
try {
mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraFacing);
} catch (OneCameraAccessException ocae) {
- mAppController.showErrorAndFinish(R.string.cannot_connect_camera);
+ mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
return;
}
}
@@ -949,6 +950,7 @@ public class CaptureModule extends CameraModule implements
@Override
public void onPictureTakingFailed() {
+ mAppController.getFatalErrorHandler().onMediaStorageFailure();
}
/**
@@ -1246,7 +1248,7 @@ public class CaptureModule extends CameraModule implements
if (mCameraManager == null) {
Log.e(TAG, "no available OneCameraManager, showing error dialog");
mCameraOpenCloseLock.release();
- mAppController.showErrorAndFinish(R.string.cannot_connect_camera);
+ mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
guard.stop("No OneCameraManager");
return;
}
@@ -1273,7 +1275,7 @@ public class CaptureModule extends CameraModule implements
mCameraFacing, mAppController.getResolutionSetting(), mSettingsManager,
mAppController.getCameraScope(), useHdr);
} catch (OneCameraAccessException ex) {
- mAppController.showErrorAndFinish(R.string.cannot_connect_camera);
+ mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
return;
}
mPictureSize = captureSetting.getCaptureSize();
@@ -1286,7 +1288,7 @@ public class CaptureModule extends CameraModule implements
Log.e(TAG, "Could not open camera.");
mCamera = null;
mCameraOpenCloseLock.release();
- mAppController.showErrorAndFinish(R.string.cannot_connect_camera);
+ mAppController.getFatalErrorHandler().onCameraOpenFailure();
}
@Override
diff --git a/src/com/android/camera/FatalErrorHandler.java b/src/com/android/camera/FatalErrorHandler.java
index 305202a70..4d548c46e 100644
--- a/src/com/android/camera/FatalErrorHandler.java
+++ b/src/com/android/camera/FatalErrorHandler.java
@@ -34,19 +34,19 @@ import com.android.camera2.R;
public interface FatalErrorHandler {
public static enum Reason {
CANNOT_CONNECT_TO_CAMERA(
- R.string.cannot_connect_camera,
+ R.string.error_cannot_connect_camera,
R.string.feedback_description_camera_access,
true),
CAMERA_HAL_FAILED(
- R.string.cannot_connect_camera,
+ R.string.error_cannot_connect_camera,
R.string.feedback_description_camera_access,
true),
CAMERA_DISABLED_BY_SECURITY_POLICY(
- R.string.camera_disabled,
+ R.string.error_camera_disabled,
R.string.feedback_description_camera_access,
true),
MEDIA_STORAGE_FAILURE(
- R.string.media_storage_failure,
+ R.string.error_media_storage_failure,
R.string.feedback_description_save_photo,
false);
@@ -118,8 +118,38 @@ public interface FatalErrorHandler {
}
/**
+ * Handles Media Storage Failures - ie. images aren't being saved to disk.
+ */
+ public void onMediaStorageFailure();
+
+ /**
+ * Handles error where the camera cannot be opened.
+ */
+ public void onCameraOpenFailure();
+
+ /**
+ * Handles error where the camera cannot be reconnected.
+ */
+ public void onCameraReconnectFailure();
+
+ /**
+ * Handles generic error where the camera is unavailable. Only use this if
+ * you are unsure what caused the error, such as a reconnection or open.
+ * failure
+ */
+ public void onGenericCameraAccessFailure();
+
+ /**
+ * Handles error where the camera is disabled due to security.
+ */
+ public void onCameraDisabledFailure();
+
+
+ /**
* Handles a fatal error, e.g. by displaying the appropriate dialog and
* exiting the activity.
+ * @deprecated use specific implementations above instead
*/
+ @Deprecated
public void handleFatalError(Reason reason);
}
diff --git a/src/com/android/camera/FatalErrorHandlerImpl.java b/src/com/android/camera/FatalErrorHandlerImpl.java
index 40b064e3a..a8bf69d62 100644
--- a/src/com/android/camera/FatalErrorHandlerImpl.java
+++ b/src/com/android/camera/FatalErrorHandlerImpl.java
@@ -19,7 +19,9 @@ package com.android.camera;
import android.app.Activity;
import com.android.camera.debug.Log;
+import com.android.camera.stats.UsageStatistics;
import com.android.camera.util.CameraUtil;
+import com.google.common.logging.eventprotos;
public final class FatalErrorHandlerImpl implements FatalErrorHandler {
private static final Log.Tag TAG = new Log.Tag("FatalErrorHandler");
@@ -31,6 +33,81 @@ public final class FatalErrorHandlerImpl implements FatalErrorHandler {
}
@Override
+ public void onMediaStorageFailure() {
+ // Log a stack trace to be sure we can track the source.
+ Log.e(TAG, "Handling Media Storage Failure:", new Exception());
+
+ // Log the error
+ UsageStatistics.instance().storageWarning(Storage.ACCESS_FAILURE);
+
+ Reason reason = Reason.MEDIA_STORAGE_FAILURE;
+ boolean finishActivity = reason.doesFinishActivity();
+ CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+ finishActivity);
+ }
+
+ @Override
+ public void onCameraOpenFailure() {
+ // Log a stack trace to be sure we can track the source.
+ Log.e(TAG, "Handling Camera Open Failure:", new Exception());
+
+ UsageStatistics.instance().cameraFailure(
+ eventprotos.CameraFailure.FailureReason.OPEN_FAILURE, null,
+ UsageStatistics.NONE, UsageStatistics.NONE);
+
+ Reason reason = Reason.CANNOT_CONNECT_TO_CAMERA;
+ boolean finishActivity = reason.doesFinishActivity();
+ CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+ finishActivity);
+ }
+
+ @Override
+ public void onCameraReconnectFailure() {
+ // Log a stack trace to be sure we can track the source.
+ Log.e(TAG, "Handling Camera Reconnect Failure:", new Exception());
+
+ UsageStatistics.instance().cameraFailure(
+ eventprotos.CameraFailure.FailureReason.RECONNECT_FAILURE, null,
+ UsageStatistics.NONE, UsageStatistics.NONE);
+
+ Reason reason = Reason.CANNOT_CONNECT_TO_CAMERA;
+ boolean finishActivity = reason.doesFinishActivity();
+ CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+ finishActivity);
+ }
+
+ @Override
+ public void onGenericCameraAccessFailure() {
+ // Log a stack trace to be sure we can track the source.
+ Log.e(TAG, "Handling Camera Access Failure:", new Exception());
+
+ UsageStatistics.instance().cameraFailure(
+ eventprotos.CameraFailure.FailureReason.UNKNOWN_REASON, null,
+ UsageStatistics.NONE, UsageStatistics.NONE);
+
+ Reason reason = Reason.CANNOT_CONNECT_TO_CAMERA;
+ boolean finishActivity = reason.doesFinishActivity();
+ CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+ finishActivity);
+ }
+
+ @Override
+ public void onCameraDisabledFailure() {
+ // Log a stack trace to be sure we can track the source.
+ Log.e(TAG, "Handling Camera Disabled Failure:", new Exception());
+
+ // Log the error
+ UsageStatistics.instance().cameraFailure(
+ eventprotos.CameraFailure.FailureReason.SECURITY, null,
+ UsageStatistics.NONE, UsageStatistics.NONE);
+
+ Reason reason = Reason.CAMERA_DISABLED_BY_SECURITY_POLICY;
+ boolean finishActivity = reason.doesFinishActivity();
+ CameraUtil.showError(mActivity, reason.getDialogMsgId(), reason.getFeedbackMsgId(),
+ finishActivity);
+ }
+
+ @Override
public void handleFatalError(Reason reason) {
// Log a stack trace to be sure we can track the source.
Log.e(TAG, "Handling Fatal Error:", new Exception());
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 9269155a0..653580e72 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -256,19 +256,17 @@ public class PhotoModule
if (uri != null) {
mActivity.notifyNewMedia(uri);
} else {
- onError(false);
+ onError();
}
}
};
/**
- * Displays Feedback dialog on non-fatal errors
- * @param finishActivity indicates whether to finish the activity after the user submits Feedback
+ * Displays error dialog and allows use to enter feedback. Does not shut
+ * down the app.
*/
- private void onError(boolean finishActivity) {
- UsageStatistics.instance().storageWarning(Storage.ACCESS_FAILURE);
- CameraUtil.showError(mActivity, R.string.media_storage_failure,
- R.string.feedback_description_save_photo, finishActivity);
+ private void onError() {
+ mAppController.getFatalErrorHandler().onMediaStorageFailure();
}
private boolean mShouldResizeTo16x9 = false;
@@ -1265,7 +1263,7 @@ public class PhotoModule
mActivity.setResultEx(Activity.RESULT_OK);
mActivity.finish();
} catch (IOException ex) {
- onError(true);
+ onError();
} finally {
CameraUtil.closeSilently(outputStream);
}
@@ -1294,12 +1292,12 @@ public class PhotoModule
} catch (FileNotFoundException ex) {
Log.w(TAG, "error writing temp cropping file to: " + sTempCropFilename, ex);
mActivity.setResultEx(Activity.RESULT_CANCELED);
- onError(true);
+ onError();
return;
} catch (IOException ex) {
Log.w(TAG, "error writing temp cropping file to: " + sTempCropFilename, ex);
mActivity.setResultEx(Activity.RESULT_CANCELED);
- onError(true);
+ onError();
return;
} finally {
CameraUtil.closeSilently(tempStream);
@@ -1956,7 +1954,7 @@ public class PhotoModule
try {
pictureSize = mAppController.getResolutionSetting().getPictureSize(cameraFacing);
} catch (OneCameraAccessException ex) {
- mAppController.showErrorAndFinish(R.string.cannot_connect_camera);
+ mAppController.getFatalErrorHandler().onGenericCameraAccessFailure();
return;
}
diff --git a/src/com/android/camera/app/AppController.java b/src/com/android/camera/app/AppController.java
index 47ac90e57..e4c046fab 100644
--- a/src/com/android/camera/app/AppController.java
+++ b/src/com/android/camera/app/AppController.java
@@ -381,7 +381,7 @@ public interface AppController {
public CameraServices getServices();
/**
- * @return The error handler to invoke for fatal (app-killing) errors.
+ * @return The error handler to invoke for errors.
*/
public FatalErrorHandler getFatalErrorHandler();
@@ -416,14 +416,6 @@ public interface AppController {
public void showTutorial(AbstractTutorialOverlay tutorial);
/**
- * Shows and error message on the screen and, when dismissed, exits the
- * activity.
- *
- * @param messageId the ID of the message to show on screen before exiting.
- */
- public void showErrorAndFinish(int messageId);
-
- /**
* Finishes the activity since the intent is completed successfully.
*
* @param resultIntent The intent that carries the result.
diff --git a/src/com/android/camera/captureintent/CaptureIntentModule.java b/src/com/android/camera/captureintent/CaptureIntentModule.java
index 823189969..dde0030d6 100644
--- a/src/com/android/camera/captureintent/CaptureIntentModule.java
+++ b/src/com/android/camera/captureintent/CaptureIntentModule.java
@@ -27,6 +27,7 @@ import android.view.View;
import com.android.camera.ButtonManager;
import com.android.camera.CameraActivity;
import com.android.camera.CameraModule;
+import com.android.camera.FatalErrorHandler;
import com.android.camera.app.AppController;
import com.android.camera.app.CameraAppUI;
import com.android.camera.async.MainThread;
@@ -46,11 +47,13 @@ import com.android.camera.one.OneCameraAccessException;
import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.settings.CameraFacingSetting;
import com.android.camera.settings.SettingsManager;
+import com.android.camera.stats.UsageStatistics;
import com.android.camera.ui.PreviewStatusListener;
import com.android.camera.ui.TouchCoordinate;
import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgent;
+import com.google.common.logging.eventprotos;
/**
* The camera module that handles image capture intent.
@@ -181,8 +184,7 @@ public class CaptureIntentModule extends CameraModule {
characteristics = mResourceConstructed.get().getCameraManager()
.getCameraCharacteristics(cameraFacingSetting.getCameraFacing());
} catch (OneCameraAccessException ocae) {
- mResourceConstructed.get().getAppController().showErrorAndFinish(
- R.string.cannot_connect_camera);
+ mResourceConstructed.get().getFatalErrorHandler().onGenericCameraAccessFailure();
return null;
}
diff --git a/src/com/android/camera/captureintent/CaptureIntentSession.java b/src/com/android/camera/captureintent/CaptureIntentSession.java
index d3abe4004..27cf71f06 100644
--- a/src/com/android/camera/captureintent/CaptureIntentSession.java
+++ b/src/com/android/camera/captureintent/CaptureIntentSession.java
@@ -166,7 +166,7 @@ public class CaptureIntentSession implements CaptureSession {
}
@Override
- public void finishWithFailure(CharSequence reason) {
+ public void finishWithFailure(CharSequence reason, boolean removeFromFilmstrip) {
throw new RuntimeException("Not supported.");
}
diff --git a/src/com/android/camera/captureintent/state/StateFatal.java b/src/com/android/camera/captureintent/state/StateFatal.java
index 051825c06..42115da74 100644
--- a/src/com/android/camera/captureintent/state/StateFatal.java
+++ b/src/com/android/camera/captureintent/state/StateFatal.java
@@ -16,6 +16,8 @@
package com.android.camera.captureintent.state;
+import com.android.camera.FatalErrorHandler;
+import com.android.camera.stats.UsageStatistics;
import com.google.common.base.Optional;
import com.android.camera.async.RefCountBase;
@@ -23,6 +25,7 @@ import com.android.camera.captureintent.resource.ResourceConstructed;
import com.android.camera.captureintent.stateful.State;
import com.android.camera.captureintent.stateful.StateImpl;
import com.android.camera2.R;
+import com.google.common.logging.eventprotos;
/**
* Represents a state that app is in an unrecoverable error state. Must show an
@@ -47,8 +50,7 @@ public final class StateFatal extends StateImpl {
mResourceConstructed.get().getMainThread().execute(new Runnable() {
@Override
public void run() {
- mResourceConstructed.get().getAppController()
- .showErrorAndFinish(R.string.cannot_connect_camera);
+ mResourceConstructed.get().getFatalErrorHandler().onGenericCameraAccessFailure();
}
});
return NO_CHANGE;
diff --git a/src/com/android/camera/captureintent/state/StateReadyForCapture.java b/src/com/android/camera/captureintent/state/StateReadyForCapture.java
index 657d2314f..6af321a49 100644
--- a/src/com/android/camera/captureintent/state/StateReadyForCapture.java
+++ b/src/com/android/camera/captureintent/state/StateReadyForCapture.java
@@ -577,7 +577,8 @@ public final class StateReadyForCapture extends StateImpl {
}
@Override
- public void onSessionFailed(Uri sessionUri, CharSequence reason) {
+ public void onSessionFailed(Uri sessionUri, CharSequence reason,
+ boolean removeFromFilmstrip) {
}
@Override
diff --git a/src/com/android/camera/captureintent/state/StateReviewingPicture.java b/src/com/android/camera/captureintent/state/StateReviewingPicture.java
index 49fbcb230..c67e6dde5 100644
--- a/src/com/android/camera/captureintent/state/StateReviewingPicture.java
+++ b/src/com/android/camera/captureintent/state/StateReviewingPicture.java
@@ -258,7 +258,8 @@ public class StateReviewingPicture extends StateImpl {
}
@Override
- public void onSessionFailed(Uri sessionUri, CharSequence reason) {
+ public void onSessionFailed(Uri sessionUri, CharSequence reason,
+ boolean removeFromFilmstrip) {
}
@Override
diff --git a/src/com/android/camera/captureintent/state/StateStartingPreview.java b/src/com/android/camera/captureintent/state/StateStartingPreview.java
index fe99d2d5a..f8fd3e1bb 100644
--- a/src/com/android/camera/captureintent/state/StateStartingPreview.java
+++ b/src/com/android/camera/captureintent/state/StateStartingPreview.java
@@ -159,6 +159,8 @@ public final class StateStartingPreview extends StateImpl {
pictureAspectRatio.toDouble(),
null);
if (previewSize == null) {
+ // TODO: Try to avoid entering StateFatal by seeing if there is
+ // another way to get the correct preview size.
return Optional.of((State) StateFatal.from(this, mResourceConstructed));
}
} catch (OneCameraAccessException ex) {
diff --git a/src/com/android/camera/one/v2/photo/PictureTakerImpl.java b/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
index 0abd091e0..eff847264 100644
--- a/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
+++ b/src/com/android/camera/one/v2/photo/PictureTakerImpl.java
@@ -44,7 +44,7 @@ class PictureTakerImpl implements PictureTaker {
}
@Override
- public void takePicture(OneCamera.PhotoCaptureParameters params, CaptureSession session) {
+ public void takePicture(OneCamera.PhotoCaptureParameters params, final CaptureSession session) {
OneCamera.PictureCallback pictureCallback = params.callback;
// Wrap the pictureCallback with a thread-safe adapter which guarantees
@@ -73,6 +73,9 @@ class PictureTakerImpl implements PictureTaker {
failed = false;
} catch (Exception e) {
failureCallback.update(null);
+ // TODO: add finishWithCancellation and remove from
+ // filmstrip
+ session.finishWithFailure("content", true);
throw e;
}
}
diff --git a/src/com/android/camera/session/CaptureSession.java b/src/com/android/camera/session/CaptureSession.java
index 60b8d50e6..22ea08594 100644
--- a/src/com/android/camera/session/CaptureSession.java
+++ b/src/com/android/camera/session/CaptureSession.java
@@ -176,7 +176,7 @@ public interface CaptureSession {
* notification of finished state, {@link #finalize()} must be called to
* fully complete the session.
*/
- public void finishWithFailure(CharSequence reason);
+ public void finishWithFailure(CharSequence reason, boolean removeFromFilmstrip);
/**
* All processing complete, finalize the session and remove any resources.
diff --git a/src/com/android/camera/session/CaptureSessionImpl.java b/src/com/android/camera/session/CaptureSessionImpl.java
index 1500aaf30..12afe6cdc 100644
--- a/src/com/android/camera/session/CaptureSessionImpl.java
+++ b/src/com/android/camera/session/CaptureSessionImpl.java
@@ -241,14 +241,13 @@ public class CaptureSessionImpl implements CaptureSession {
try {
mContentUri = mPlaceholderManager.finishPlaceholder(mPlaceHolderSession, mLocation,
orientation, exif, data, width, height, FilmstripItemData.MIME_TYPE_JPEG);
+ mSessionNotifier.notifyTaskDone(mUri);
} catch (IOException e) {
Log.e(TAG, "IOException", e);
// TODO: Replace with a sensisble description
// Placeholder string R.string.reason_storage_failure
- finishWithFailure("content");
+ finishWithFailure("content", true);
}
-
- mSessionNotifier.notifyTaskDone(mUri);
}
@Override
@@ -340,14 +339,14 @@ public class CaptureSessionImpl implements CaptureSession {
}
@Override
- public void finishWithFailure(CharSequence reason) {
+ public void finishWithFailure(CharSequence reason, boolean removeFromFilmstrip) {
if (mPlaceHolderSession == null) {
throw new IllegalStateException(
"Cannot call finish without calling startSession first.");
}
mProgressMessage = reason;
mSessionManager.putErrorMessage(mUri, reason);
- mSessionNotifier.notifyTaskFailed(mUri, reason);
+ mSessionNotifier.notifyTaskFailed(mUri, reason, removeFromFilmstrip);
}
@Override
diff --git a/src/com/android/camera/session/CaptureSessionManager.java b/src/com/android/camera/session/CaptureSessionManager.java
index c11f31bbf..56cc2d802 100644
--- a/src/com/android/camera/session/CaptureSessionManager.java
+++ b/src/com/android/camera/session/CaptureSessionManager.java
@@ -56,7 +56,7 @@ public interface CaptureSessionManager {
public void onSessionDone(Uri mediaUri);
/** Called when the session with the given Uri failed processing. */
- public void onSessionFailed(Uri mediaUri, CharSequence reason);
+ public void onSessionFailed(Uri mediaUri, CharSequence reason, boolean removeFromFilmstrip);
/** Called when the session with the given Uri has progressed. */
public void onSessionProgress(Uri mediaUri, int progress);
diff --git a/src/com/android/camera/session/CaptureSessionManagerImpl.java b/src/com/android/camera/session/CaptureSessionManagerImpl.java
index a07bc556b..e46184004 100644
--- a/src/com/android/camera/session/CaptureSessionManagerImpl.java
+++ b/src/com/android/camera/session/CaptureSessionManagerImpl.java
@@ -103,13 +103,14 @@ public class CaptureSessionManagerImpl implements CaptureSessionManager {
* failed to process.
*/
@Override
- public void notifyTaskFailed(final Uri uri, final CharSequence reason) {
+ public void notifyTaskFailed(final Uri uri, final CharSequence reason,
+ final boolean removeFromFilmstrip) {
mMainHandler.execute(new Runnable() {
@Override
public void run() {
synchronized (mTaskListeners) {
for (SessionListener listener : mTaskListeners) {
- listener.onSessionFailed(uri, reason);
+ listener.onSessionFailed(uri, reason, removeFromFilmstrip);
}
}
finalizeSession(uri);
diff --git a/src/com/android/camera/session/SessionNotifier.java b/src/com/android/camera/session/SessionNotifier.java
index bfe770bb3..77e1e00d9 100644
--- a/src/com/android/camera/session/SessionNotifier.java
+++ b/src/com/android/camera/session/SessionNotifier.java
@@ -31,7 +31,8 @@ public interface SessionNotifier {
public void notifyTaskDone(final Uri uri);
/** A task has failed to process. */
- public void notifyTaskFailed(final Uri uri, final CharSequence reason);
+ public void notifyTaskFailed(final Uri uri, final CharSequence reason,
+ boolean removeFromFilmstrip);
/** A task has progressed. */
public void notifyTaskProgress(final Uri uri, final int progressPercent);