summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml7
-rw-r--r--src/com/android/camera/Thumbnail.java62
-rwxr-xr-xsrc/com/android/camera/panorama/PanoramaActivity.java40
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 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
+ <!-- Suppose users enter panorama from launcher, turn off the screen,
+ turn on the screen, and enter the camera from the lock screen.
+ They can switch to panorama from there. Use singleTask so there
+ will be only one panorama activity. -->
<activity android:name="com.android.camera.panorama.PanoramaActivity"
android:label="@string/pano_dialog_title"
android:configChanges="orientation|screenSize|keyboardHidden"
android:clearTaskOnLaunch="true"
- android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
+ android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
+ android:launchMode="singleTask">
</activity>
</application>
</manifest>
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 02816f4..46f9e34 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;
@@ -153,6 +154,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;
@@ -278,6 +280,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);
@@ -302,6 +306,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();
@@ -454,7 +461,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();
}
}
@@ -815,11 +826,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);
@@ -979,7 +1002,6 @@ public class PanoramaActivity extends ActivityBase implements
super.onPause();
mPausing = true;
- cancelHighResComputation();
// Stop the capturing first.
if (mCaptureState == CAPTURE_STATE_MOSAIC) {
stopCapture(true);
@@ -987,9 +1009,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();
@@ -1120,6 +1140,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);