summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/camera/Camera.java51
-rw-r--r--src/com/android/camera/CameraButtonIntentReceiver.java10
-rw-r--r--src/com/android/camera/CameraHardwareException.java5
-rw-r--r--src/com/android/camera/CameraHolder.java16
-rw-r--r--src/com/android/camera/CameraSettings.java12
-rw-r--r--src/com/android/camera/Util.java24
-rw-r--r--src/com/android/camera/VideoCamera.java49
7 files changed, 138 insertions, 29 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index fb2e76d..5ee9128 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
@@ -143,6 +144,7 @@ public class Camera extends Activity implements View.OnClickListener,
private ToneGenerator mFocusToneGenerator;
private ZoomButtonsController mZoomButtons;
private Switcher mSwitcher;
+ private boolean mStartPreviewFail = false;
// mPostCaptureAlert, mLastPictureButton, mThumbController
// are non-null only if isImageCaptureIntent() is true.
@@ -734,7 +736,12 @@ public class Camera extends Activity implements View.OnClickListener,
*/
Thread startPreviewThread = new Thread(new Runnable() {
public void run() {
- startPreview();
+ try {
+ mStartPreviewFail = false;
+ startPreview();
+ } catch (CameraHardwareException e) {
+ mStartPreviewFail = true;
+ }
}
});
startPreviewThread.start();
@@ -766,6 +773,7 @@ public class Camera extends Activity implements View.OnClickListener,
// Make sure preview is started.
try {
startPreviewThread.join();
+ if (mStartPreviewFail) showCameraErrorAndFinish();
} catch (InterruptedException ex) {
// ignore
}
@@ -1009,8 +1017,13 @@ public class Camera extends Activity implements View.OnClickListener,
mImageCapture = new ImageCapture();
// Start the preview if it is not started.
- if (!mPreviewing) {
- startPreview();
+ if (!mPreviewing && !mStartPreviewFail) {
+ try {
+ startPreview();
+ } catch (CameraHardwareException e) {
+ showCameraErrorAndFinish();
+ return;
+ }
}
if (mSurfaceHolder != null) {
@@ -1254,12 +1267,17 @@ public class Camera extends Activity implements View.OnClickListener,
return;
}
+ // The mCameraDevice will be null if it is fail to connect to the
+ // camera hardware. In this case we will show a dialog and then
+ // finish the activity, so it's OK to ignore it.
+ if (mCameraDevice == null) return;
+
mSurfaceHolder = holder;
mViewFinderWidth = w;
mViewFinderHeight = h;
// Sometimes surfaceChanged is called after onPause. Ignore it.
- if (mPausing) return;
+ if (mPausing || isFinishing()) return;
// Set preview display if the surface is being created. Preview was
// already started.
@@ -1293,11 +1311,10 @@ public class Camera extends Activity implements View.OnClickListener,
}
}
- private boolean ensureCameraDevice() {
+ private void ensureCameraDevice() throws CameraHardwareException {
if (mCameraDevice == null) {
mCameraDevice = CameraHolder.instance().open();
}
- return mCameraDevice != null;
}
private void updateLastImage() {
@@ -1318,10 +1335,22 @@ public class Camera extends Activity implements View.OnClickListener,
list.close();
}
+ private void showCameraErrorAndFinish() {
+ Resources ress = getResources();
+ Util.showFatalErrorAndFinish(Camera.this,
+ ress.getString(R.string.camera_error_title),
+ ress.getString(R.string.cannot_connect_camera));
+ }
+
private void restartPreview() {
// make sure the surfaceview fills the whole screen when previewing
mSurfaceView.setAspectRatio(VideoPreview.DONT_CARE);
- startPreview();
+ try {
+ startPreview();
+ } catch (CameraHardwareException e) {
+ showCameraErrorAndFinish();
+ return;
+ }
// Calculate this in advance of each shot so we don't add to shutter
// latency. It's true that someone else could write to the SD card in
@@ -1339,12 +1368,10 @@ public class Camera extends Activity implements View.OnClickListener,
}
}
- private void startPreview() {
- if (mPausing) return;
-
- if (!ensureCameraDevice()) return;
+ private void startPreview() throws CameraHardwareException {
+ if (mPausing || isFinishing()) return;
- if (isFinishing()) return;
+ ensureCameraDevice();
// If we're previewing already, stop the preview first (this will blank
// the screen).
diff --git a/src/com/android/camera/CameraButtonIntentReceiver.java b/src/com/android/camera/CameraButtonIntentReceiver.java
index 3eae965..5926709 100644
--- a/src/com/android/camera/CameraButtonIntentReceiver.java
+++ b/src/com/android/camera/CameraButtonIntentReceiver.java
@@ -26,6 +26,16 @@ public class CameraButtonIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
+ // Try to get the camera hardware
+ try {
+ CameraHolder holder = CameraHolder.instance();
+ android.hardware.Camera device = holder.open();
+ holder.keep();
+ holder.release();
+ } catch (CameraHardwareException e) {
+ // ignore the event if camera hardware cannot be connected
+ return;
+ }
Intent i = new Intent(Intent.ACTION_MAIN);
i.setClass(context, Camera.class);
i.addCategory("android.intent.category.LAUNCHER");
diff --git a/src/com/android/camera/CameraHardwareException.java b/src/com/android/camera/CameraHardwareException.java
new file mode 100644
index 0000000..f746f48
--- /dev/null
+++ b/src/com/android/camera/CameraHardwareException.java
@@ -0,0 +1,5 @@
+package com.android.camera;
+
+public class CameraHardwareException extends Exception {
+
+}
diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java
index 89f02e7..98f2797 100644
--- a/src/com/android/camera/CameraHolder.java
+++ b/src/com/android/camera/CameraHolder.java
@@ -16,6 +16,8 @@
package com.android.camera;
+import static com.android.camera.Util.Assert;
+
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -24,8 +26,6 @@ import android.util.Log;
import java.io.IOException;
-import static com.android.camera.Util.Assert;
-
//
// CameraHolder is used to hold an android.hardware.Camera instance.
//
@@ -41,7 +41,7 @@ public class CameraHolder {
private static final String TAG = "CameraHolder";
private android.hardware.Camera mCameraDevice;
private long mKeepBeforeTime = 0; // Keep the Camera before this time.
- private Handler mHandler;
+ private final Handler mHandler;
private int mUsers = 0; // number of open() - number of release()
// Use a singleton.
@@ -75,10 +75,16 @@ public class CameraHolder {
mHandler = new MyHandler(ht.getLooper());
}
- public synchronized android.hardware.Camera open() {
+ public synchronized android.hardware.Camera open()
+ throws CameraHardwareException {
Assert(mUsers == 0);
if (mCameraDevice == null) {
- mCameraDevice = android.hardware.Camera.open();
+ try {
+ mCameraDevice = android.hardware.Camera.open();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "fail to connect Camera", e);
+ throw new CameraHardwareException();
+ }
} else {
try {
mCameraDevice.reconnect();
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 7ff3310..78e0724 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -18,6 +18,7 @@ package com.android.camera;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.preference.ListPreference;
@@ -80,7 +81,16 @@ public class CameraSettings extends PreferenceActivity implements
registerOnSharedPreferenceChangeListener(this);
// Get parameters.
- android.hardware.Camera device = CameraHolder.instance().open();
+ android.hardware.Camera device;
+ try {
+ device = CameraHolder.instance().open();
+ } catch (CameraHardwareException e) {
+ Resources ress = getResources();
+ Util.showFatalErrorAndFinish(this,
+ ress.getString(R.string.camera_error_title),
+ ress.getString(R.string.cannot_connect_camera));
+ return;
+ }
mParameters = device.getParameters();
CameraHolder.instance().release();
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index 2742247..b1ad8d2 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -16,10 +16,11 @@
package com.android.camera;
-import com.android.camera.gallery.IImage;
-
+import android.app.Activity;
+import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
+import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -34,6 +35,8 @@ import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.camera.gallery.IImage;
+
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileDescriptor;
@@ -512,4 +515,21 @@ public class Util {
options.inNativeAlloc = true;
return options;
}
+
+ public static void showFatalErrorAndFinish(
+ final Activity activity, String title, String message) {
+ DialogInterface.OnClickListener buttonListener =
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ activity.finish();
+ }
+ };
+ new AlertDialog.Builder(activity)
+ .setCancelable(false)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle(title)
+ .setMessage(message)
+ .setNeutralButton(R.string.details_ok, buttonListener)
+ .show();
+ }
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index d596b6f..c5befa6 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.media.MediaRecorder;
@@ -115,6 +116,7 @@ public class VideoCamera extends Activity implements View.OnClickListener,
// are non-null only if mIsVideoCaptureIntent is true.
private ImageView mLastPictureButton;
private ThumbnailController mThumbController;
+ private boolean mStartPreviewFail = false;
private int mStorageStatus = STORAGE_STATUS_OK;
@@ -181,7 +183,9 @@ public class VideoCamera extends Activity implements View.OnClickListener,
}
}
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mReceiver = null;
+
+ private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -202,12 +206,19 @@ public class VideoCamera extends Activity implements View.OnClickListener,
updateAndShowStorageHint(true);
}
}
- };
+ }
private static String createName(long dateTaken) {
return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
}
+ private void showCameraBusyAndFinish() {
+ Resources ress = getResources();
+ Util.showFatalErrorAndFinish(VideoCamera.this,
+ ress.getString(R.string.camera_error_title),
+ ress.getString(R.string.cannot_connect_camera));
+ }
+
/** Called with the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
@@ -222,7 +233,12 @@ public class VideoCamera extends Activity implements View.OnClickListener,
*/
Thread startPreviewThread = new Thread(new Runnable() {
public void run() {
- startPreview();
+ try {
+ mStartPreviewFail = false;
+ startPreview();
+ } catch (CameraHardwareException e) {
+ mStartPreviewFail = true;
+ }
}
});
startPreviewThread.start();
@@ -280,6 +296,7 @@ public class VideoCamera extends Activity implements View.OnClickListener,
// Make sure preview is started.
try {
startPreviewThread.join();
+ if (mStartPreviewFail) showCameraBusyAndFinish();
} catch (InterruptedException ex) {
// ignore
}
@@ -480,10 +497,14 @@ public class VideoCamera extends Activity implements View.OnClickListener,
mPausing = false;
readVideoSizePreference();
- if (!mPreviewing) {
- startPreview();
+ if (!mPreviewing && !mStartPreviewFail) {
+ try {
+ startPreview();
+ } catch (CameraHardwareException e) {
+ showCameraBusyAndFinish();
+ return;
+ }
}
-
setScreenTimeoutLong();
// install an intent filter to receive SD card related events.
@@ -494,6 +515,7 @@ public class VideoCamera extends Activity implements View.OnClickListener,
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
+ mReceiver = new MyBroadcastReceiver();
registerReceiver(mReceiver, intentFilter);
mStorageStatus = getStorageStatus(true);
@@ -525,7 +547,7 @@ public class VideoCamera extends Activity implements View.OnClickListener,
}
}
- private void startPreview() {
+ private void startPreview() throws CameraHardwareException {
Log.v(TAG, "startPreview");
if (mPreviewing) {
// After recording a video, preview is not stopped. So just return.
@@ -597,7 +619,10 @@ public class VideoCamera extends Activity implements View.OnClickListener,
}
closeCamera();
- unregisterReceiver(mReceiver);
+ if (mReceiver != null) {
+ unregisterReceiver(mReceiver);
+ mReceiver = null;
+ }
setScreenTimeoutSystemDefault();
if (!mIsVideoCaptureIntent) {
@@ -678,6 +703,11 @@ public class VideoCamera extends Activity implements View.OnClickListener,
return;
}
+ // The mCameraDevice will be null if it is fail to connect to the
+ // camera hardware. In this case we will show a dialog and then
+ // finish the activity, so it's OK to ignore it.
+ if (mCameraDevice == null) return;
+
if (mMediaRecorderRecording) {
stopVideoRecording();
}
@@ -791,7 +821,8 @@ public class VideoCamera extends Activity implements View.OnClickListener,
if (mRecorderInitialized) return true;
// We will call initializeRecorder() again when the alert is hidden.
- if (isAlertVisible()) {
+ // If the mCameraDevice is null, then this activity is going to finish
+ if (isAlertVisible() || mCameraDevice == null) {
return false;
}