From 62bbca8320c3861fa9b18a7eab26a42116bef9df Mon Sep 17 00:00:00 2001 From: Angus Kong Date: Thu, 5 Jan 2012 19:23:58 +0800 Subject: Allow saving panorama after the activity is paused. (do not merge) bug: 5541182 Change-Id: I42237d8dd4f8c39ddc2041ae32b886328a9c45c0 --- AndroidManifest.xml | 7 ++- src/com/android/camera/Thumbnail.java | 62 ++++++++++++---------- .../android/camera/panorama/PanoramaActivity.java | 40 +++++++++++--- 3 files changed, 75 insertions(+), 34 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1a64093..ee57c31 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -61,11 +61,16 @@ + + android:windowSoftInputMode="stateAlwaysHidden|adjustPan" + android:launchMode="singleTask"> diff --git a/src/com/android/camera/Thumbnail.java b/src/com/android/camera/Thumbnail.java index 165614b..7775c37 100644 --- a/src/com/android/camera/Thumbnail.java +++ b/src/com/android/camera/Thumbnail.java @@ -52,6 +52,10 @@ public class Thumbnail { // whether this thumbnail is read from file private boolean mFromFile = false; + // Camera, VideoCamera, and Panorama share the same thumbnail. Use sLock + // to serialize the access. + private static Object sLock = new Object(); + public Thumbnail(Uri uri, Bitmap bitmap, int orientation) { mUri = uri; mBitmap = rotateImage(bitmap, orientation); @@ -100,19 +104,21 @@ public class Thumbnail { FileOutputStream f = null; BufferedOutputStream b = null; DataOutputStream d = null; - try { - f = new FileOutputStream(file); - b = new BufferedOutputStream(f, BUFSIZE); - d = new DataOutputStream(b); - d.writeUTF(mUri.toString()); - mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, d); - d.close(); - } catch (IOException e) { - Log.e(TAG, "Fail to store bitmap. path=" + file.getPath(), e); - } finally { - Util.closeSilently(f); - Util.closeSilently(b); - Util.closeSilently(d); + synchronized (sLock) { + try { + f = new FileOutputStream(file); + b = new BufferedOutputStream(f, BUFSIZE); + d = new DataOutputStream(b); + d.writeUTF(mUri.toString()); + mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, d); + d.close(); + } catch (IOException e) { + Log.e(TAG, "Fail to store bitmap. path=" + file.getPath(), e); + } finally { + Util.closeSilently(f); + Util.closeSilently(b); + Util.closeSilently(d); + } } } @@ -124,20 +130,22 @@ public class Thumbnail { FileInputStream f = null; BufferedInputStream b = null; DataInputStream d = null; - try { - f = new FileInputStream(file); - b = new BufferedInputStream(f, BUFSIZE); - d = new DataInputStream(b); - uri = Uri.parse(d.readUTF()); - bitmap = BitmapFactory.decodeStream(d); - d.close(); - } catch (IOException e) { - Log.i(TAG, "Fail to load bitmap. " + e); - return null; - } finally { - Util.closeSilently(f); - Util.closeSilently(b); - Util.closeSilently(d); + synchronized (sLock) { + try { + f = new FileInputStream(file); + b = new BufferedInputStream(f, BUFSIZE); + d = new DataInputStream(b); + uri = Uri.parse(d.readUTF()); + bitmap = BitmapFactory.decodeStream(d); + d.close(); + } catch (IOException e) { + Log.i(TAG, "Fail to load bitmap. " + e); + return null; + } finally { + Util.closeSilently(f); + Util.closeSilently(b); + Util.closeSilently(d); + } } Thumbnail thumbnail = createThumbnail(uri, bitmap, 0); if (thumbnail != null) thumbnail.setFromFile(true); diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java index 1a5a5aa..e45a841 100755 --- a/src/com/android/camera/panorama/PanoramaActivity.java +++ b/src/com/android/camera/panorama/PanoramaActivity.java @@ -59,6 +59,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.os.PowerManager; import android.util.Log; import android.view.Gravity; import android.view.Menu; @@ -152,6 +153,7 @@ public class PanoramaActivity extends ActivityBase implements private int mCaptureState; private SensorManager mSensorManager; private Sensor mSensor; + private PowerManager.WakeLock mPartialWakeLock; private ModePicker mModePicker; private MosaicFrameProcessor mMosaicFrameProcessor; private long mTimeTaken; @@ -263,6 +265,8 @@ public class PanoramaActivity extends ActivityBase implements if (mSensor == null) { mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); } + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Panorama"); mOrientationEventListener = new PanoOrientationEventListener(this); @@ -287,6 +291,9 @@ public class PanoramaActivity extends ActivityBase implements break; case MSG_RESET_TO_PREVIEW_WITH_THUMBNAIL: onBackgroundThreadFinished(); + // If the activity is paused, save the thumbnail to the file here. + // If not, it will be saved in onPause. + if (mPausing) saveThumbnailToFile(); // Set the thumbnail bitmap here because mThumbnailView must be accessed // from the UI thread. updateThumbnailButton(); @@ -439,7 +446,11 @@ public class PanoramaActivity extends ActivityBase implements runOnUiThread(new Runnable() { @Override public void run() { - if (!mPausing) { + // If panorama is generating low res or high res mosaic, it + // means users exit and come back to panorama. Do not start the + // preview. Preview will be started after final mosaic is + // generated. + if (!mPausing && !mThreadRunning) { startCameraPreview(); } } @@ -800,11 +811,23 @@ public class PanoramaActivity extends ActivityBase implements } } + private void saveThumbnailToFile() { + if (mThumbnail != null && !mThumbnail.fromFile()) { + mThumbnail.saveTo(new File(getFilesDir(), Thumbnail.LAST_THUMB_FILENAME)); + } + } + public void saveHighResMosaic() { runBackgroundThread(new Thread() { @Override public void run() { - MosaicJpeg jpeg = generateFinalMosaic(true); + mPartialWakeLock.acquire(); + MosaicJpeg jpeg; + try { + jpeg = generateFinalMosaic(true); + } finally { + mPartialWakeLock.release(); + } if (jpeg == null) { // Cancelled by user. mMainHandler.sendEmptyMessage(MSG_RESET_TO_PREVIEW); @@ -964,7 +987,6 @@ public class PanoramaActivity extends ActivityBase implements super.onPause(); mPausing = true; - cancelHighResComputation(); // Stop the capturing first. if (mCaptureState == CAPTURE_STATE_MOSAIC) { stopCapture(true); @@ -972,9 +994,7 @@ public class PanoramaActivity extends ActivityBase implements } if (mSharePopup != null) mSharePopup.dismiss(); - if (mThumbnail != null && !mThumbnail.fromFile()) { - mThumbnail.saveTo(new File(getFilesDir(), Thumbnail.LAST_THUMB_FILENAME)); - } + saveThumbnailToFile(); releaseCamera(); mMosaicView.onPause(); @@ -1105,6 +1125,14 @@ public class PanoramaActivity extends ActivityBase implements if (mCaptureState != CAPTURE_STATE_MOSAIC) keepScreenOnAwhile(); } + @Override + public void onBackPressed() { + // If panorama is generating low res or high res mosaic, ignore back + // key. So the activity will not be destroyed. + if (mThreadRunning) return; + super.onBackPressed(); + } + private void resetScreenOn() { mMainHandler.removeMessages(MSG_CLEAR_SCREEN_DELAY); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); -- cgit v1.1