summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]AndroidManifest.xml1
-rw-r--r--assets/dependency.json12
-rw-r--r--res/values/camera2arrays.xml11
-rw-r--r--res/values/qcomstrings.xml12
-rw-r--r--res/xml/capture_preferences.xml7
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/CameraActivity.java2
-rw-r--r--src/com/android/camera/CaptureModule.java216
-rw-r--r--src/com/android/camera/CaptureUI.java1
-rw-r--r--src/com/android/camera/PermissionsActivity.java12
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/PhotoMenu.java20
-rw-r--r--src/com/android/camera/PhotoModule.java1
-rwxr-xr-x[-rw-r--r--]src/com/android/camera/SDCard.java47
-rw-r--r--src/com/android/camera/SettingsManager.java3
-rwxr-xr-xsrc/com/android/camera/VideoModule.java17
-rw-r--r--src/com/android/camera/VideoUI.java9
-rw-r--r--src/com/android/camera/ui/CameraControls.java8
-rw-r--r--src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java18
-rw-r--r--src/org/codeaurora/snapcam/filter/ClearSightNativeEngine.java14
-rwxr-xr-x[-rw-r--r--]src_pd/com/android/camera/util/IntentHelper.java23
19 files changed, 365 insertions, 69 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 53ebaa39d..37ce25f8b 100644..100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -121,6 +121,7 @@
android:label="@string/snapcam_app_name"
android:launchMode="singleInstance"
android:logo="@mipmap/ic_launcher_gallery"
+ android:screenOrientation="portrait"
android:taskAffinity="com.android.camera.SecureCameraActivity"
android:theme="@style/Theme.Camera"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan" >
diff --git a/assets/dependency.json b/assets/dependency.json
index 763549320..390adcde4 100644
--- a/assets/dependency.json
+++ b/assets/dependency.json
@@ -35,7 +35,8 @@
"pref_camera2_whitebalance_key":"1",
"pref_camera2_exposure_key":"0",
"pref_camera2_clearsight_key":"off",
- "pref_camera2_mono_preview_key":"off"}
+ "pref_camera2_mono_preview_key":"off",
+ "pref_camera2_mpo_key":"off"}
,
"100":
{"pref_camera2_longshot_key":"off",
@@ -44,6 +45,13 @@
,
"0":
{"pref_camera2_clearsight_key":"off",
- "pref_camera2_mono_preview_key":"off"}
+ "pref_camera2_mono_preview_key":"off",
+ "pref_camera2_mpo_key":"off"}
+ },
+ "pref_camera2_clearsight_key":
+ {
+ "off":{},
+ "on":
+ {"pref_camera2_mpo_key":"on"}
}
}
diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml
index 25105ba65..37a33ec17 100644
--- a/res/values/camera2arrays.xml
+++ b/res/values/camera2arrays.xml
@@ -100,6 +100,17 @@
<item>@string/pref_camera2_clearsight_value_on</item>
</string-array>
+ <string-array name="pref_camera2_mpo_entries" translatable="true">
+ <item>@string/pref_camera2_mpo_entry_off</item>
+ <item>@string/pref_camera2_mpo_entry_on</item>
+ </string-array>
+
+ <string-array name="pref_camera2_mpo_entryvalues" translatable="false">
+ <item>@string/pref_camera2_mpo_value_off</item>
+ <item>@string/pref_camera2_mpo_value_on</item>
+ </string-array>
+
+
<!-- Refer to CONTROL_SCENE_MODE of Camera2 API for values
-1 refers to ones not supported in Camera2 API
0 is special case added for auto (meaning off)
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index e8917f3ee..0fb750590 100644
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -968,8 +968,8 @@
<string name="pref_camera2_clearsight_title" translatable="true">ClearSight</string>
<string name="pref_camera2_clearsight_default" translatable="false">on</string>
- <string name="pref_camera2_clearsight_entry_on" translatable="false">On</string>
- <string name="pref_camera2_clearsight_entry_off" translatable="false">Off</string>
+ <string name="pref_camera2_clearsight_entry_on" translatable="true">On</string>
+ <string name="pref_camera2_clearsight_entry_off" translatable="true">Off</string>
<string name="pref_camera2_clearsight_value_on" translatable="false">on</string>
<string name="pref_camera2_clearsight_value_off" translatable="false">off</string>
@@ -977,6 +977,14 @@
<string name="clearsight_capture_success">ClearSight capture successful</string>
<string name="clearsight_capture_fail">ClearSight capture failed</string>
+ <string name="pref_camera2_mpo_title" translatable="true">MPO Format</string>
+ <string name="pref_camera2_mpo_default" translatable="false">off</string>
+ <string name="pref_camera2_mpo_entry_on" translatable="true">On</string>
+ <string name="pref_camera2_mpo_entry_off" translatable="true">Off</string>
+
+ <string name="pref_camera2_mpo_value_on" translatable="false">on</string>
+ <string name="pref_camera2_mpo_value_off" translatable="false">off</string>
+
<string name="pref_camera2_scenemode_default" translatable="false">0</string>
<string name="pref_camera2_whitebalance_default" translatable="false">1</string>
<string name="pref_camera2_coloreffect_default" translatable="false">0</string>
diff --git a/res/xml/capture_preferences.xml b/res/xml/capture_preferences.xml
index c5aab1a7d..2f0849442 100644
--- a/res/xml/capture_preferences.xml
+++ b/res/xml/capture_preferences.xml
@@ -107,6 +107,13 @@
camera:key="pref_camera2_clearsight_key"
camera:title="@string/pref_camera2_clearsight_title"/>
+ <ListPreference
+ camera:defaultValue="@string/pref_camera2_mpo_default"
+ camera:entries="@array/pref_camera2_mpo_entries"
+ camera:entryValues="@array/pref_camera2_mpo_entryvalues"
+ camera:key="pref_camera2_mpo_key"
+ camera:title="@string/pref_camera2_mpo_title"/>
+
<IconListPreference
camera:defaultValue="@string/pref_camera2_coloreffect_default"
camera:entries="@array/pref_camera2_coloreffect_entries"
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index e015d9c25..5666331fa 100644..100755
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -601,8 +601,8 @@ public class CameraActivity extends Activity
try {
Log.w(TAG, "Gallery not found");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- startActivity(intent);
intent.putExtra(KEY_FROM_SNAPCAM, true);
+ startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(TAG, "No Activity could be found to open image or video");
}
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index bf63de271..4edf3ab9e 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -72,6 +72,8 @@ import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;
+import com.android.camera.exif.ExifInterface;
+import com.android.camera.Exif;
import com.android.camera.imageprocessor.filter.ImageFilter;
import com.android.camera.imageprocessor.PostProcessor;
import com.android.camera.imageprocessor.FrameProcessor;
@@ -144,6 +146,10 @@ public class CaptureModule implements CameraModule, PhotoController,
* Camera state: Waiting for the touch-to-focus to converge.
*/
private static final int STATE_WAITING_TOUCH_FOCUS = 5;
+ /**
+ * Camera state: Focus and exposure has been locked and converged.
+ */
+ private static final int STATE_AF_AE_LOCKED = 6;
private static final String TAG = "SnapCam_CaptureModule";
// Used for check memory status for longshot mode
@@ -214,6 +220,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private HandlerThread mCameraThread;
private HandlerThread mImageAvailableThread;
private HandlerThread mCaptureCallbackThread;
+ private HandlerThread mMpoSaveThread;
/**
* A {@link Handler} for running tasks in the background.
@@ -227,6 +234,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private Handler mCameraHandler;
private Handler mImageAvailableHandler;
private Handler mCaptureCallbackHandler;
+ private Handler mMpoSaveHandler;
/**
* An {@link ImageReader} that handles still image capture.
@@ -516,8 +524,7 @@ public class CaptureModule implements CameraModule, PhotoController,
// CONTROL_AE_STATE can be null on some devices
if (aeState == null || (aeState == CaptureResult
.CONTROL_AE_STATE_CONVERGED) && isFlashOff(id)) {
- mState[id] = STATE_PICTURE_TAKEN;
- captureStillPicture(id);
+ checkAfAeStatesAndCapture(id);
} else {
runPrecaptureSequence(id);
}
@@ -542,8 +549,7 @@ public class CaptureModule implements CameraModule, PhotoController,
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
Log.d(TAG, "STATE_WAITING_NON_PRECAPTURE id: " + id + " aeState:" + aeState);
if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
- mState[id] = STATE_PICTURE_TAKEN;
- captureStillPicture(id);
+ checkAfAeStatesAndCapture(id);
}
break;
}
@@ -552,12 +558,33 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ private void checkAfAeStatesAndCapture(int id) {
+ if(isBackCamera() && getCameraMode() == DUAL_MODE) {
+ mState[id] = STATE_AF_AE_LOCKED;
+ if(mState[BAYER_ID] == STATE_AF_AE_LOCKED &&
+ mState[MONO_ID] == STATE_AF_AE_LOCKED) {
+ mState[BAYER_ID] = STATE_PICTURE_TAKEN;
+ mState[MONO_ID] = STATE_PICTURE_TAKEN;
+ captureStillPicture(BAYER_ID);
+ captureStillPicture(MONO_ID);
+ }
+ } else {
+ mState[id] = STATE_PICTURE_TAKEN;
+ captureStillPicture(id);
+ }
+ }
+
public void startFaceDetection() {
mUI.onStartFaceDetection(mDisplayOrientation,
mSettingsManager.isFacingFront(getMainCameraId()),
mSettingsManager.getSensorActiveArraySize(getMainCameraId()));
}
+ private boolean canStartMonoPreview() {
+ return getCameraMode() == MONO_MODE ||
+ (getCameraMode() == DUAL_MODE && isMonoPreviewOn());
+ }
+
private boolean isMonoPreviewOn() {
String value = mSettingsManager.getValue(SettingsManager.KEY_MONO_PREVIEW);
if (value == null) return false;
@@ -586,6 +613,12 @@ public class CaptureModule implements CameraModule, PhotoController,
return isBackCamera() && getCameraMode() == DUAL_MODE && value.equals("on");
}
+ private boolean isMpoOn() {
+ String value = mSettingsManager.getValue(SettingsManager.KEY_MPO);
+ if (value == null) return false;
+ return isBackCamera() && getCameraMode() == DUAL_MODE && value.equals("on");
+ }
+
public static int getQualityNumber(String jpegQuality) {
try {
int qualityPercentile = Integer.parseInt(jpegQuality);
@@ -720,8 +753,15 @@ public class CaptureModule implements CameraModule, PhotoController,
mIsLinked = true;
}
// Finally, we start displaying the camera preview.
- mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
- .build(), mCaptureCallback, mCameraHandler);
+ // for cases where we are in dual mode with mono preview off,
+ // don't set repeating request for mono
+ if(id == MONO_ID && !canStartMonoPreview()) {
+ mCaptureSession[id].capture(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
if (isClearSightOn()) {
ClearSightImageProcessor.getInstance().onCaptureSessionConfigured(id == BAYER_ID, cameraCaptureSession);
}
@@ -807,8 +847,13 @@ public class CaptureModule implements CameraModule, PhotoController,
mPreviewRequestBuilder[id].set(CaptureRequest.LENS_FOCUS_DISTANCE, fd);
mPreviewRequestBuilder[id].setTag(id);
try {
- mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
- .build(), mCaptureCallback, mCameraHandler);
+ if(id == MONO_ID && !canStartMonoPreview()) {
+ mCaptureSession[id].capture(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
} catch (CameraAccessException e) {
e.printStackTrace();
}
@@ -1076,6 +1121,11 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}, mCaptureCallbackHandler);
} else {
+ if(isMpoOn()) {
+ mCaptureStartTime = System.currentTimeMillis();
+ mMpoSaveHandler.obtainMessage(MpoSaveHandler.MSG_CONFIGURE,
+ Long.valueOf(mCaptureStartTime)).sendToTarget();
+ }
mCaptureSession[id].capture(captureBuilder.build(),
new CameraCaptureSession.CaptureCallback() {
@@ -1225,21 +1275,28 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onImageAvailable(ImageReader reader) {
Log.d(TAG, "image available for cam: " + mCamId);
Image image = reader.acquireNextImage();
- mCaptureStartTime = System.currentTimeMillis();
- mNamedImages.nameNewImage(mCaptureStartTime);
- NamedEntity name = mNamedImages.getNextNameEntity();
- String title = (name == null) ? null : name.title;
- long date = (name == null) ? -1 : name.date;
-
- ByteBuffer buffer = image.getPlanes()[0].getBuffer();
- byte[] bytes = new byte[buffer.remaining()];
- mLastJpegData = bytes;
- buffer.get(bytes);
-
- mActivity.getMediaSaveService().addImage(bytes, title, date,
- null, image.getWidth(), image.getHeight(), 0, null,
- mOnMediaSavedListener, mContentResolver, "jpeg");
- image.close();
+
+ if(isMpoOn()) {
+ mMpoSaveHandler.obtainMessage(
+ MpoSaveHandler.MSG_NEW_IMG, mCamId, 0, image).sendToTarget();
+ } else {
+ mCaptureStartTime = System.currentTimeMillis();
+ mNamedImages.nameNewImage(mCaptureStartTime);
+ NamedEntity name = mNamedImages.getNextNameEntity();
+ String title = (name == null) ? null : name.title;
+ long date = (name == null) ? -1 : name.date;
+
+ byte[] bytes = getJpegData(image);
+ mLastJpegData = bytes;
+
+ ExifInterface exif = Exif.getExif(bytes);
+ int orientation = Exif.getOrientation(exif);
+
+ mActivity.getMediaSaveService().addImage(bytes, title, date,
+ null, image.getWidth(), image.getHeight(), orientation, null,
+ mOnMediaSavedListener, mContentResolver, "jpeg");
+ image.close();
+ }
}
}, mImageAvailableHandler);
}
@@ -1275,8 +1332,11 @@ public class CaptureModule implements CameraModule, PhotoController,
mLastJpegData = bytes;
buffer.get(bytes);
+ ExifInterface exif = Exif.getExif(bytes);
+ int orientation = Exif.getOrientation(exif);
+
mActivity.getMediaSaveService().addImage(bytes, title, date,
- null, image.getWidth(), image.getHeight(), 0, null,
+ null, image.getWidth(), image.getHeight(), orientation, null,
mOnMediaSavedListener, mContentResolver, "jpeg");
image.close();
}
@@ -1300,8 +1360,13 @@ public class CaptureModule implements CameraModule, PhotoController,
mState[id] = STATE_PREVIEW;
mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
setAFModeToPreview(id, mControlAFMode);
- mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id].build(),
- mCaptureCallback, mCameraHandler);
+ if(id == MONO_ID && !canStartMonoPreview()) {
+ mCaptureSession[id].capture(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id].build(),
+ mCaptureCallback, mCameraHandler);
+ }
mTakingPicture[id] = false;
mActivity.runOnUiThread(new Runnable() {
@Override
@@ -1454,10 +1519,13 @@ public class CaptureModule implements CameraModule, PhotoController,
mImageAvailableThread.start();
mCaptureCallbackThread = new HandlerThread("CameraCaptureCallback");
mCaptureCallbackThread.start();
+ mMpoSaveThread = new HandlerThread("MpoSaveHandler");
+ mMpoSaveThread.start();
mCameraHandler = new MyCameraHandler(mCameraThread.getLooper());
mImageAvailableHandler = new Handler(mImageAvailableThread.getLooper());
mCaptureCallbackHandler = new Handler(mCaptureCallbackThread.getLooper());
+ mMpoSaveHandler = new MpoSaveHandler(mMpoSaveThread.getLooper());
}
/**
@@ -1467,6 +1535,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mCameraThread.quitSafely();
mImageAvailableThread.quitSafely();
mCaptureCallbackThread.quitSafely();
+ mMpoSaveThread.quitSafely();
try {
mCameraThread.join();
@@ -1489,6 +1558,13 @@ public class CaptureModule implements CameraModule, PhotoController,
} catch (InterruptedException e) {
e.printStackTrace();
}
+ try {
+ mMpoSaveThread.join();
+ mMpoSaveThread = null;
+ mMpoSaveHandler = null;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
private void openCamera(int id) {
@@ -2625,8 +2701,13 @@ public class CaptureModule implements CameraModule, PhotoController,
private void applyZoomAndUpdate(int id) {
applyZoom(mPreviewRequestBuilder[id], id);
try {
- mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
- .build(), mCaptureCallback, mCameraHandler);
+ if(id == MONO_ID && !canStartMonoPreview()) {
+ mCaptureSession[id].capture(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
} catch (CameraAccessException e) {
e.printStackTrace();
}
@@ -2961,8 +3042,13 @@ public class CaptureModule implements CameraModule, PhotoController,
}
if (updatePreviewMono) {
try {
- mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID]
- .build(), mCaptureCallback, mCameraHandler);
+ if(canStartMonoPreview()) {
+ mCaptureSession[MONO_ID].setRepeatingRequest(mPreviewRequestBuilder[MONO_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ } else {
+ mCaptureSession[MONO_ID].capture(mPreviewRequestBuilder[MONO_ID]
+ .build(), mCaptureCallback, mCameraHandler);
+ }
} catch (CameraAccessException e) {
e.printStackTrace();
}
@@ -3096,6 +3182,69 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ private class MpoSaveHandler extends Handler {
+ static final int MSG_CONFIGURE = 0;
+ static final int MSG_NEW_IMG = 1;
+
+ private Image monoImage;
+ private Image bayerImage;
+ private Long captureStartTime;
+
+ public MpoSaveHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CONFIGURE:
+ captureStartTime = (Long) msg.obj;
+ break;
+ case MSG_NEW_IMG:
+ processNewImage(msg);
+ break;
+ }
+ }
+
+ private void processNewImage(Message msg) {
+ Log.d(TAG, "MpoSaveHandler:processNewImage for cam id: " + msg.arg1);
+ if(msg.arg1 == MONO_ID) {
+ monoImage = (Image)msg.obj;
+ } else if(bayerImage == null){
+ bayerImage = (Image)msg.obj;
+ }
+
+ if(monoImage != null && bayerImage != null) {
+ saveMpoImage();
+ }
+ }
+
+ private void saveMpoImage() {
+ mNamedImages.nameNewImage(captureStartTime);
+ NamedEntity namedEntity = mNamedImages.getNextNameEntity();
+ String title = (namedEntity == null) ? null : namedEntity.title;
+ long date = (namedEntity == null) ? -1 : namedEntity.date;
+ int width = bayerImage.getWidth();
+ int height = bayerImage.getHeight();
+ byte[] bayerBytes = getJpegData(bayerImage);
+ byte[] monoBytes = getJpegData(monoImage);
+
+ mLastJpegData = bayerBytes;
+ ExifInterface exif = Exif.getExif(bayerBytes);
+ int orientation = Exif.getOrientation(exif);
+
+ mActivity.getMediaSaveService().addMpoImage(
+ null, bayerBytes, monoBytes, width, height, title,
+ date, null, orientation, mOnMediaSavedListener, mContentResolver, "jpeg");
+
+ bayerImage.close();
+ bayerImage = null;
+ monoImage.close();
+ monoImage = null;
+ namedEntity = null;
+ }
+ }
+
@Override
public void onClearSightSuccess() {
Log.d(TAG, "onClearSightSuccess");
@@ -3149,4 +3298,11 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onErrorListener(int error) {
enableRecordingLocation(false);
}
+
+ private byte[] getJpegData(Image image) {
+ ByteBuffer buffer = image.getPlanes()[0].getBuffer();
+ byte[] bytes = new byte[buffer.remaining()];
+ buffer.get(bytes);
+ return bytes;
+ }
}
diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java
index d455fa41c..dadbb3144 100644
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -122,6 +122,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
SettingsManager.KEY_MONO_ONLY,
SettingsManager.KEY_CLEARSIGHT,
SettingsManager.KEY_MONO_PREVIEW,
+ SettingsManager.KEY_MPO,
SettingsManager.KEY_NOISE_REDUCTION,
SettingsManager.KEY_DIS,
SettingsManager.KEY_VIDEO_ENCODER,
diff --git a/src/com/android/camera/PermissionsActivity.java b/src/com/android/camera/PermissionsActivity.java
index 2b5901a58..c5e43e56d 100644
--- a/src/com/android/camera/PermissionsActivity.java
+++ b/src/com/android/camera/PermissionsActivity.java
@@ -119,21 +119,24 @@ public class PermissionsActivity extends Activity {
String permissions[], int[] grantResults) {
if (mShouldRequestCameraPermission) {
- if (grantResults[mIndexPermissionRequestCamera] == PackageManager.PERMISSION_GRANTED) {
+ if ((grantResults.length >= mIndexPermissionRequestCamera + 1) &&
+ (grantResults[mIndexPermissionRequestCamera] == PackageManager.PERMISSION_GRANTED)) {
mFlagHasCameraPermission = true;
} else {
mCriticalPermissionDenied = true;
}
}
if (mShouldRequestMicrophonePermission) {
- if (grantResults[mIndexPermissionRequestMicrophone] == PackageManager.PERMISSION_GRANTED) {
+ if ((grantResults.length >= mIndexPermissionRequestMicrophone + 1) &&
+ (grantResults[mIndexPermissionRequestMicrophone] == PackageManager.PERMISSION_GRANTED)) {
mFlagHasMicrophonePermission = true;
} else {
mCriticalPermissionDenied = true;
}
}
if (mShouldRequestStoragePermission) {
- if (grantResults[mIndexPermissionRequestStorage] == PackageManager.PERMISSION_GRANTED) {
+ if ((grantResults.length >= mIndexPermissionRequestStorage + 1) &&
+ (grantResults[mIndexPermissionRequestStorage] == PackageManager.PERMISSION_GRANTED)) {
mFlagHasStoragePermission = true;
} else {
mCriticalPermissionDenied = true;
@@ -141,7 +144,8 @@ public class PermissionsActivity extends Activity {
}
if (mShouldRequestLocationPermission) {
- if (grantResults[mIndexPermissionRequestLocation] == PackageManager.PERMISSION_GRANTED) {
+ if ((grantResults.length >= mIndexPermissionRequestLocation + 1) &&
+ (grantResults[mIndexPermissionRequestLocation] == PackageManager.PERMISSION_GRANTED)) {
// Do nothing
} else {
// Do nothing
diff --git a/src/com/android/camera/PhotoMenu.java b/src/com/android/camera/PhotoMenu.java
index 8988e8e2a..c2f9a538b 100644..100755
--- a/src/com/android/camera/PhotoMenu.java
+++ b/src/com/android/camera/PhotoMenu.java
@@ -693,6 +693,7 @@ public class PhotoMenu extends MenuController
popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false);
popup1.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE, false);
popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false);
+ popup1.setPreferenceEnabled(CameraSettings.KEY_QC_CHROMA_FLASH, false);
}
if ((autohdr != null) && autohdr.equals("enable")) {
popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false);
@@ -788,7 +789,11 @@ public class PhotoMenu extends MenuController
|| (notSame(hdrPref, CameraSettings.KEY_CAMERA_HDR, mSettingOff))) {
buttonSetEnabled(mFilterModeSwitcher, false);
changeFilterModeControlIcon("none");
- } else {
+ } else if (same(scenePref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)
+ && (same(hdrPref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)
+ || !hdrPref.getKey().equals(CameraSettings.KEY_CAMERA_HDR))) {
+ //mFilterModeSwitcher can be enabled only when scene mode is set to auto
+ // and HDR is set to off,
buttonSetEnabled(mFilterModeSwitcher, true);
}
}
@@ -820,7 +825,6 @@ public class PhotoMenu extends MenuController
.findPreference(prefKey);
if (pref == null)
return;
-
if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) {
// Hide the camera control while switching the camera.
// The camera control will be added back when
@@ -1457,6 +1461,18 @@ public class PhotoMenu extends MenuController
}
}
+ String chromaFlashOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_chromaflash_on);
+ if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) {
+ ListPreference lp = mPreferenceGroup
+ .findPreference(CameraSettings.KEY_ADVANCED_FEATURES);
+ if (lp != null && chromaFlashOn.equals(lp.getValue())) {
+ setPreference(CameraSettings.KEY_QC_CHROMA_FLASH, mSettingOff);
+ setPreference(CameraSettings.KEY_ADVANCED_FEATURES,
+ mActivity.getString(R.string.pref_camera_advanced_feature_default));
+ }
+ }
+
if (notSame(pref, CameraSettings.KEY_SCENE_MODE, "auto")) {
setPreference(CameraSettings.KEY_COLOR_EFFECT,
mActivity.getString(R.string.pref_camera_coloreffect_default));
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 27ea62947..b4f8c3a74 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -2232,6 +2232,7 @@ public class PhotoModule
public synchronized void onShutterButtonClick() {
if ((mCameraDevice == null)
|| mPaused || mUI.collapseCameraControls()
+ || !mUI.mMenuInitialized
|| (mCameraState == SWITCHING_CAMERA)
|| (mCameraState == PREVIEW_STOPPED)
|| (mCameraState == LONGSHOT)
diff --git a/src/com/android/camera/SDCard.java b/src/com/android/camera/SDCard.java
index 8fda17c67..b88e32245 100644..100755
--- a/src/com/android/camera/SDCard.java
+++ b/src/com/android/camera/SDCard.java
@@ -28,8 +28,10 @@
package com.android.camera;
+import android.content.BroadcastReceiver;
import android.content.Context;
-import android.os.UserHandle;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.os.Environment;
import android.os.storage.StorageVolume;
import android.os.storage.StorageManager;
@@ -42,8 +44,8 @@ public class SDCard {
private StorageManager mStorageManager = null;
private StorageVolume mVolume = null;
- private String path = null;
- private String rawpath = null;
+ private String mPath = null;
+ private String mRawpath = null;
private static SDCard sSDCard;
public boolean isWriteable() {
@@ -59,20 +61,20 @@ public class SDCard {
if (mVolume == null) {
return null;
}
- if (path == null) {
- path = mVolume.getPath() + "/DCIM/Camera";
+ if (mPath == null) {
+ mPath = mVolume.getPath() + "/DCIM/Camera";
}
- return path;
+ return mPath;
}
public String getRawDirectory() {
if (mVolume == null) {
return null;
}
- if (rawpath == null) {
- rawpath = mVolume.getPath() + "/DCIM/Camera/raw";
+ if (mRawpath == null) {
+ mRawpath = mVolume.getPath() + "/DCIM/Camera/raw";
}
- return rawpath;
+ return mRawpath;
}
public static void initialize(Context context) {
@@ -92,13 +94,32 @@ public class SDCard {
private SDCard(Context context) {
try {
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
- final StorageVolume[] volumes = mStorageManager.getVolumeList();
- if (volumes.length > VOLUME_SDCARD_INDEX) {
- mVolume = volumes[VOLUME_SDCARD_INDEX];
- }
+ initVolume();
+ registerMediaBroadcastreceiver(context);
} catch (Exception e) {
Log.e(TAG, "couldn't talk to MountService", e);
}
}
+ private void initVolume() {
+ final StorageVolume[] volumes = mStorageManager.getVolumeList();
+ mVolume = (volumes.length > VOLUME_SDCARD_INDEX) ?
+ volumes[VOLUME_SDCARD_INDEX] : null;
+ mPath = null;
+ mRawpath = null;
+ }
+
+ private void registerMediaBroadcastreceiver(Context context) {
+ IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
+ filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+ filter.addDataScheme("file");
+ context.registerReceiver(mMediaBroadcastReceiver , filter);
+ }
+
+ private BroadcastReceiver mMediaBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ initVolume();
+ }
+ };
}
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 90f426090..7e2e3bf6a 100644
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -88,6 +88,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final String KEY_MONO_ONLY = "pref_camera2_mono_only_key";
public static final String KEY_MONO_PREVIEW = "pref_camera2_mono_preview_key";
public static final String KEY_CLEARSIGHT = "pref_camera2_clearsight_key";
+ public static final String KEY_MPO = "pref_camera2_mpo_key";
public static final String KEY_FILTER_MODE = "pref_camera2_filter_mode_key";
public static final String KEY_COLOR_EFFECT = "pref_camera2_coloreffect_key";
public static final String KEY_SCENE_MODE = "pref_camera2_scenemode_key";
@@ -490,6 +491,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
ListPreference clearsight = mPreferenceGroup.findPreference(KEY_CLEARSIGHT);
ListPreference monoPreview = mPreferenceGroup.findPreference(KEY_MONO_PREVIEW);
ListPreference monoOnly = mPreferenceGroup.findPreference(KEY_MONO_ONLY);
+ ListPreference mpo = mPreferenceGroup.findPreference(KEY_MPO);
ListPreference redeyeReduction = mPreferenceGroup.findPreference(KEY_REDEYE_REDUCTION);
ListPreference videoQuality = mPreferenceGroup.findPreference(KEY_VIDEO_QUALITY);
ListPreference videoEncoder = mPreferenceGroup.findPreference(KEY_VIDEO_ENCODER);
@@ -543,6 +545,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
if (clearsight != null) removePreference(mPreferenceGroup, KEY_CLEARSIGHT);
if (monoPreview != null) removePreference(mPreferenceGroup, KEY_MONO_PREVIEW);
if (monoOnly != null) removePreference(mPreferenceGroup, KEY_MONO_ONLY);
+ if (mpo != null) removePreference(mPreferenceGroup, KEY_MPO);
}
if (redeyeReduction != null) {
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 6b26a9c88..a93cff611 100755
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -220,6 +220,9 @@ public class VideoModule implements CameraModule,
private static final boolean PERSIST_4K_NO_LIMIT =
android.os.SystemProperties.getBoolean("persist.camcorder.4k.nolimit", false);
+ private static final int PERSIST_EIS_MAX_FPS =
+ android.os.SystemProperties.getInt("persist.camcorder.eis.maxfps", 30);
+
private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener =
new MediaSaveService.OnMediaSavedListener() {
@Override
@@ -1807,7 +1810,11 @@ public class VideoModule implements CameraModule,
mUI.cancelAnimations();
mUI.setSwipingEnabled(false);
mUI.hideUIwhileRecording();
-
+ // When recording request is sent before starting preview, onPreviewFrame()
+ // callback doesn't happen so removing preview cover here, instead.
+ if (mUI.isPreviewCoverVisible()) {
+ mUI.hidePreviewCover();
+ }
mActivity.updateStorageSpaceAndHint();
if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
Log.v(TAG, "Storage issue, ignore the start request");
@@ -2523,8 +2530,14 @@ public class VideoModule implements CameraModule,
CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
mActivity.getString(R.string.pref_video_time_lapse_frame_interval_default));
int timeLapseInterval = Integer.parseInt(frameIntervalStr);
+ int rate = 0;
+ if (!hfr.equals("off"))
+ rate = Integer.parseInt(hfr);
+ else
+ rate = Integer.parseInt(hsr);
+ Log.v(TAG, "rate = "+rate);
if ( (timeLapseInterval != 0) ||
- (disMode.equals("enable")) ||
+ (disMode.equals("enable") && (rate > PERSIST_EIS_MAX_FPS)) ||
((hdr != null) && (!hdr.equals("off"))) ) {
Log.v(TAG,"HDR/DIS/Time Lapse ON for HFR/HSR selection, turning HFR/HSR off");
mParameters.setVideoHighFrameRate("off");
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index 5203d9e35..cf93feeac 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -145,6 +145,15 @@ public class VideoUI implements PieRenderer.PieListener,
}
}
+ public boolean isPreviewCoverVisible() {
+ if ((mPreviewCover != null) &&
+ (mPreviewCover.getVisibility() == View.VISIBLE)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private class SettingsPopup extends PopupWindow {
public SettingsPopup(View popup) {
super(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java
index 5de05dca9..48a5492e3 100644
--- a/src/com/android/camera/ui/CameraControls.java
+++ b/src/com/android/camera/ui/CameraControls.java
@@ -87,7 +87,6 @@ public class CameraControls extends RotatableLayout {
private static final int ANIME_DURATION = 300;
private float[][] mLocX = new float[4][11];
private float[][] mLocY = new float[4][11];
- private boolean[] mTempEnabled = new boolean[11];
private boolean mLocSet = false;
private boolean mHideRemainingPhoto = false;
private LinearLayout mRemainingPhotos;
@@ -223,10 +222,9 @@ public class CameraControls extends RotatableLayout {
mHdrSwitcher.setPressed(false);
}
mSceneModeSwitcher.setPressed(false);
- mFilterModeSwitcher.setPressed(false);
- } else {
- mTempEnabled[FILTER_MODE_INDEX] = mFilterModeSwitcher.isEnabled();
}
+
+
((ShutterButton) mShutter).enableTouch(enable);
mVideoShutter.setClickable(enable);
((ModuleSwitcher) mSwitcher).enableTouch(enable);
@@ -240,7 +238,7 @@ public class CameraControls extends RotatableLayout {
}
mSceneModeSwitcher.setEnabled(enable);
mPreview.setEnabled(enable);
- mFilterModeSwitcher.setEnabled(enable && mTempEnabled[FILTER_MODE_INDEX]);
+
}
private void markVisibility() {
diff --git a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
index c64a0de2a..3a94baec9 100644
--- a/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
+++ b/src/org/codeaurora/snapcam/filter/ClearSightImageProcessor.java
@@ -29,6 +29,7 @@
package org.codeaurora.snapcam.filter;
+import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
@@ -65,6 +66,8 @@ import android.util.Log;
import android.view.Surface;
import com.android.camera.CaptureModule;
+import com.android.camera.Exif;
+import com.android.camera.exif.ExifInterface;
import com.android.camera.MediaSaveService;
import com.android.camera.MediaSaveService.OnMediaSavedListener;
import com.android.camera.PhotoModule.NamedImages;
@@ -529,6 +532,13 @@ public class ClearSightImageProcessor {
.createReprocessCaptureRequest(reprocImg.mCaptureResult);
reprocRequest.addTarget(mImageReader[camId]
.getSurface());
+ reprocRequest.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
+ CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
+ reprocRequest.set(CaptureRequest.EDGE_MODE,
+ CaptureRequest.EDGE_MODE_HIGH_QUALITY);
+ reprocRequest.set(CaptureRequest.NOISE_REDUCTION_MODE,
+ CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
+
if(reprocRequests.size() == 0) {
reprocRequest.setTag(new Object());
}
@@ -814,11 +824,15 @@ public class ClearSightImageProcessor {
height = mClearSightImage.getHeight();
}
+ byte[] bayerBytes = getJpegData(mBayerImage);
+ ExifInterface exif = Exif.getExif(bayerBytes);
+ int orientation = Exif.getOrientation(exif);
+
mMediaSaveService.addMpoImage(
getJpegData(mClearSightImage),
- getJpegData(mBayerImage),
+ bayerBytes,
getJpegData(mMonoImage), width, height, title,
- date, null, 0, mMediaSavedListener,
+ date, null, orientation, mMediaSavedListener,
mMediaSaveService.getContentResolver(), "jpeg");
mBayerImage.close();
diff --git a/src/org/codeaurora/snapcam/filter/ClearSightNativeEngine.java b/src/org/codeaurora/snapcam/filter/ClearSightNativeEngine.java
index f2793c822..18e7671b9 100644
--- a/src/org/codeaurora/snapcam/filter/ClearSightNativeEngine.java
+++ b/src/org/codeaurora/snapcam/filter/ClearSightNativeEngine.java
@@ -35,6 +35,7 @@ import java.util.ArrayList;
import java.util.List;
import android.graphics.Rect;
+import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.media.Image.Plane;
@@ -256,13 +257,20 @@ public class ClearSightNativeEngine {
Log.d(TAG, "processImage - dst size - y: "
+ dstY.capacity() + " vu: " + dstVU.capacity());
+ int iso = mRefMonoResult.get(CaptureResult.SENSOR_SENSITIVITY);
+ long exposure = mRefMonoResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+ // capture result stores exposure time in NS and we need MS.
+ exposure /= 100000;
+
+ Log.d(TAG, "processImage - iso: " + iso + " exposure ms: " + exposure);
boolean result = nativeClearSightProcess(numImages, srcColorY, srcColorVU,
metadataColor, mRefColorImage.getWidth(),
mRefColorImage.getHeight(),
colorPlanes[Y_PLANE].getRowStride(),
colorPlanes[VU_PLANE].getRowStride(), srcMonoY, metadataMono,
mRefMonoImage.getWidth(), mRefMonoImage.getHeight(),
- monoPlanes[Y_PLANE].getRowStride(), mOtpCalibData, dstY, dstVU,
+ monoPlanes[Y_PLANE].getRowStride(), mOtpCalibData,
+ (int)exposure, iso, dstY, dstVU,
colorPlanes[Y_PLANE].getRowStride(),
colorPlanes[VU_PLANE].getRowStride(), roiRect);
@@ -287,8 +295,8 @@ public class ClearSightNativeEngine {
int[][] metadataColor, int srcColorWidth, int srcColorHeight,
int srcColorStrideY, int srcColorStrideVU, ByteBuffer[] srcMonoY,
int[][] metadataMono, int srcMonoWidth, int srcMonoHeight,
- int srcMonoStrideY, byte[] otp, ByteBuffer dstY, ByteBuffer dstVU,
- int dstStrideY, int dstStrideVU, int[] roiRect);
+ int srcMonoStrideY, byte[] otp, int exposureMs, int iso,
+ ByteBuffer dstY, ByteBuffer dstVU, int dstStrideY, int dstStrideVU, int[] roiRect);
private class SourceImage {
ByteBuffer mY;
diff --git a/src_pd/com/android/camera/util/IntentHelper.java b/src_pd/com/android/camera/util/IntentHelper.java
index 6f17a624b..7949eca2a 100644..100755
--- a/src_pd/com/android/camera/util/IntentHelper.java
+++ b/src_pd/com/android/camera/util/IntentHelper.java
@@ -17,21 +17,38 @@ package com.android.camera.util;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
public class IntentHelper {
private static final String GALLERY_PACKAGE_NAME = "com.android.gallery3d";
+ private static final String SNAPDRAGON_GALLERY_PACKAGE_NAME = "org.codeaurora.gallery";
private static final String GALLERY_ACTIVITY_CLASS =
- "com.android.gallery3d.app.GalleryActivity";
+ "com.android.gallery3d.app.GalleryActivity";
public static Intent getGalleryIntent(Context context) {
+ String packageName = packageExist(context, SNAPDRAGON_GALLERY_PACKAGE_NAME) ?
+ SNAPDRAGON_GALLERY_PACKAGE_NAME : GALLERY_PACKAGE_NAME;
return new Intent(Intent.ACTION_MAIN)
- .setClassName(GALLERY_PACKAGE_NAME, GALLERY_ACTIVITY_CLASS);
+ .setClassName(packageName, GALLERY_ACTIVITY_CLASS);
}
public static Intent getVideoPlayerIntent(Context context, Uri uri) {
return new Intent(Intent.ACTION_VIEW)
- .setDataAndType(uri, "video/*");
+ .setDataAndType(uri, "video/*");
+ }
+
+ private static boolean packageExist(Context context, String packageName) {
+ if (packageName == null || "".equals(packageName)) {
+ return false;
+ }
+ try {
+ context.getPackageManager().getApplicationInfo(packageName, 0);
+ return true;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
}
}