summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/camera/AndroidCameraManagerImpl.java51
-rw-r--r--src/com/android/camera/CameraActivity.java48
-rw-r--r--src/com/android/camera/CameraErrorCallback.java3
-rw-r--r--src/com/android/camera/CameraHolder.java2
-rw-r--r--src/com/android/camera/CameraManager.java19
-rw-r--r--src/com/android/camera/CameraModule.java2
-rw-r--r--src/com/android/camera/CameraPreference.java1
-rw-r--r--src/com/android/camera/CameraSettings.java455
-rw-r--r--src/com/android/camera/ComboPreferences.java7
-rw-r--r--src/com/android/camera/CountDownTimerPreference.java3
-rw-r--r--src/com/android/camera/FocusOverlayManager.java54
-rw-r--r--src/com/android/camera/ListPreference.java4
-rw-r--r--src/com/android/camera/MediaSaveService.java21
-rw-r--r--src/com/android/camera/PauseButton.java82
-rw-r--r--src/com/android/camera/PhotoController.java4
-rw-r--r--src/com/android/camera/PhotoMenu.java378
-rw-r--r--src/com/android/camera/PhotoModule.java1527
-rw-r--r--src/com/android/camera/PhotoUI.java111
-rw-r--r--src/com/android/camera/PieController.java12
-rw-r--r--src/com/android/camera/SDCard.java107
-rw-r--r--[-rwxr-xr-x]src/com/android/camera/ShutterButton.java14
-rw-r--r--src/com/android/camera/Storage.java118
-rw-r--r--src/com/android/camera/VideoController.java3
-rw-r--r--src/com/android/camera/VideoMenu.java118
-rw-r--r--src/com/android/camera/VideoModule.java693
-rw-r--r--src/com/android/camera/VideoUI.java115
-rw-r--r--src/com/android/camera/WideAnglePanoramaModule.java43
-rw-r--r--src/com/android/camera/WideAnglePanoramaUI.java4
-rw-r--r--src/com/android/camera/app/AppManagerFactory.java2
-rw-r--r--src/com/android/camera/crop/ImageLoader.java4
-rw-r--r--src/com/android/camera/data/CameraDataAdapter.java25
-rw-r--r--src/com/android/camera/data/LocalMediaData.java10
-rw-r--r--src/com/android/camera/tinyplanet/TinyPlanetFragment.java3
-rw-r--r--src/com/android/camera/ui/FaceView.java165
-rw-r--r--src/com/android/camera/ui/FilmStripView.java3
-rw-r--r--src/com/android/camera/ui/MoreSettingPopup.java7
-rw-r--r--src/com/android/camera/ui/PieRenderer.java9
-rw-r--r--src/com/android/camera/util/ApiHelper.java3
-rw-r--r--src/com/android/camera/util/CameraUtil.java16
39 files changed, 3874 insertions, 372 deletions
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
index e26b6a90e..f833cb279 100644
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ b/src/com/android/camera/AndroidCameraManagerImpl.java
@@ -39,6 +39,9 @@ import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
+import android.hardware.Camera.CameraDataCallback;
+import com.android.camera.util.ApiHelper;
+import android.os.ConditionVariable;
/**
* A class to implement {@link CameraManager} of the Android camera framework.
@@ -47,6 +50,9 @@ class AndroidCameraManagerImpl implements CameraManager {
private static final String TAG = "CAM_" +
AndroidCameraManagerImpl.class.getSimpleName();
+ // Thread progress signals
+ private ConditionVariable mSig = new ConditionVariable();
+
private Parameters mParameters;
private boolean mParametersIsDirty;
private IOException mReconnectIOException;
@@ -83,6 +89,11 @@ class AndroidCameraManagerImpl implements CameraManager {
// Presentation
private static final int ENABLE_SHUTTER_SOUND = 501;
private static final int SET_DISPLAY_ORIENTATION = 502;
+ // Histogram
+ private static final int SET_HISTOGRAM_MODE = 601;
+ private static final int SEND_HISTOGRAM_DATA = 602;
+ //LONGSHOT
+ private static final int SET_LONGSHOT = 701;
private CameraHandler mCameraHandler;
private android.hardware.Camera mCamera;
@@ -205,6 +216,9 @@ class AndroidCameraManagerImpl implements CameraManager {
return;
case RELEASE:
+ if (mCamera == null) {
+ return;
+ }
mCamera.release();
mCamera = null;
return;
@@ -294,9 +308,9 @@ class AndroidCameraManagerImpl implements CameraManager {
case SET_PARAMETERS:
mParametersIsDirty = true;
- mParamsToSet.unflatten((String) msg.obj);
- mCamera.setParameters(mParamsToSet);
- return;
+ mCamera.setParameters((Parameters) msg.obj);
+ mSig.open();
+ break;
case GET_PARAMETERS:
if (mParametersIsDirty) {
@@ -317,6 +331,18 @@ class AndroidCameraManagerImpl implements CameraManager {
mParametersIsDirty = true;
return;
+ case SET_HISTOGRAM_MODE:
+ mCamera.setHistogramMode((CameraDataCallback) msg.obj);
+ break;
+
+ case SEND_HISTOGRAM_DATA:
+ mCamera.sendHistogramData();
+ break;
+
+ case SET_LONGSHOT:
+ mCamera.setLongshot((Boolean) msg.obj);
+ break;
+
default:
throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
}
@@ -525,8 +551,10 @@ class AndroidCameraManagerImpl implements CameraManager {
Log.v(TAG, "null parameters in setParameters()");
return;
}
- mCameraHandler.obtainMessage(SET_PARAMETERS, params.flatten())
+ mSig.close();
+ mCameraHandler.obtainMessage(SET_PARAMETERS, params)
.sendToTarget();
+ mSig.block();
}
@Override
@@ -546,6 +574,21 @@ class AndroidCameraManagerImpl implements CameraManager {
mCameraHandler.obtainMessage(
ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0).sendToTarget();
}
+
+ @Override
+ public void setLongshot(boolean enable) {
+ mCameraHandler.obtainMessage(SET_LONGSHOT,
+ new Boolean(enable)).sendToTarget();
+ }
+
+ @Override
+ public void setHistogramMode(CameraDataCallback cb) {
+ mCameraHandler.obtainMessage(SET_HISTOGRAM_MODE, cb).sendToTarget();
+ }
+ @Override
+ public void sendHistogramData() {
+ mCameraHandler.sendEmptyMessage(SEND_HISTOGRAM_DATA);
+ }
}
/**
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 8f2b04b4f..5ade3950a 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -175,6 +175,7 @@ public class CameraActivity extends Activity
private Menu mActionBarMenu;
private ViewGroup mUndoDeletionBar;
private boolean mIsUndoingDeletion = false;
+ private boolean mIsEditActivityInProgress = false;
private Uri[] mNfcPushUris = new Uri[1];
@@ -335,6 +336,9 @@ public class CameraActivity extends Activity
@Override
public void onDataFullScreenChange(int dataID, boolean full) {
boolean isCameraID = isCameraPreview(dataID);
+ if (full && isCameraID && CameraActivity.this.hasWindowFocus()){
+ updateStorageSpaceAndHint();
+ }
if (!isCameraID) {
if (!full) {
// Always show action bar in filmstrip mode
@@ -397,6 +401,16 @@ public class CameraActivity extends Activity
@Override
public void onDataFocusChanged(final int dataID, final boolean focused) {
+ boolean isPreview = isCameraPreview(dataID);
+ boolean isFullScreen = mFilmStripView.inFullScreen();
+ if (isFullScreen && isPreview && CameraActivity.this.hasWindowFocus()){
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ updateStorageSpaceAndHint();
+ }
+ });
+ }
// Delay hiding action bar if there is any user interaction
if (mMainHandler.hasMessages(HIDE_ACTION_BAR)) {
mMainHandler.removeMessages(HIDE_ACTION_BAR);
@@ -1216,6 +1230,7 @@ public class CameraActivity extends Activity
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW) {
mResetToPreviewOnResume = false;
+ mIsEditActivityInProgress = false;
} else {
super.onActivityResult(requestCode, resultCode, data);
}
@@ -1263,6 +1278,14 @@ public class CameraActivity extends Activity
}
mLocalImagesObserver.setActivityPaused(false);
mLocalVideosObserver.setActivityPaused(false);
+
+ //This is a temporal solution to share LED resource
+ //as Android doesn’t have any default intent to share the state.
+ // if the led flash light is open, turn it off
+ Log.d(TAG, "send the turn off LED Flashlight the broadcast");
+ Intent intent = new Intent("qualcomm.android.LEDFlashlight.appWidgetUpdate");
+ intent.putExtra("camera_led", true);
+ sendBroadcast(intent);
}
@Override
@@ -1305,9 +1328,7 @@ public class CameraActivity extends Activity
// Prevent software keyboard or voice search from showing up.
if (keyCode == KeyEvent.KEYCODE_SEARCH
|| keyCode == KeyEvent.KEYCODE_MENU) {
- if (event.isLongPress()) {
- return true;
- }
+ return true;
}
}
@@ -1326,6 +1347,7 @@ public class CameraActivity extends Activity
public void onBackPressed() {
if (!mFilmStripView.inCameraFullscreen()) {
mFilmStripView.getController().goToFirstItem();
+ mCurrentModule.resizeForPreviewAspectRatio();
} else if (!mCurrentModule.onBackPressed()) {
super.onBackPressed();
}
@@ -1457,14 +1479,17 @@ public class CameraActivity extends Activity
* Launches an ACTION_EDIT intent for the given local data item.
*/
public void launchEditor(LocalData data) {
- Intent intent = new Intent(Intent.ACTION_EDIT)
- .setDataAndType(data.getContentUri(), data.getMimeType())
- .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- try {
- startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
- } catch (ActivityNotFoundException e) {
- startActivityForResult(Intent.createChooser(intent, null),
- REQ_CODE_DONT_SWITCH_TO_PREVIEW);
+ if (!mIsEditActivityInProgress) {
+ Intent intent = new Intent(Intent.ACTION_EDIT)
+ .setDataAndType(data.getContentUri(), data.getMimeType())
+ .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ try {
+ startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
+ } catch (ActivityNotFoundException e) {
+ startActivityForResult(Intent.createChooser(intent, null),
+ REQ_CODE_DONT_SWITCH_TO_PREVIEW);
+ }
+ mIsEditActivityInProgress = true;
}
}
@@ -1494,6 +1519,7 @@ public class CameraActivity extends Activity
module.onPauseBeforeSuper();
module.onPauseAfterSuper();
((ViewGroup) mCameraModuleRootView).removeAllViews();
+ ((ViewGroup) mCameraModuleRootView).clearDisappearingChildren();
}
private void performDeletion() {
diff --git a/src/com/android/camera/CameraErrorCallback.java b/src/com/android/camera/CameraErrorCallback.java
index 22f800ef9..7029ac427 100644
--- a/src/com/android/camera/CameraErrorCallback.java
+++ b/src/com/android/camera/CameraErrorCallback.java
@@ -25,7 +25,8 @@ public class CameraErrorCallback
@Override
public void onError(int error, android.hardware.Camera camera) {
Log.e(TAG, "Got camera error callback. error=" + error);
- if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
+ if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED
+ || error == android.hardware.Camera.CAMERA_ERROR_UNKNOWN) {
// We are not sure about the current state of the app (in preview or
// snapshot or recording). Closing the app is better than creating a
// new Camera object.
diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java
index e3f2c11e7..0797fad44 100644
--- a/src/com/android/camera/CameraHolder.java
+++ b/src/com/android/camera/CameraHolder.java
@@ -222,7 +222,7 @@ public class CameraHolder {
return null;
}
mCameraId = cameraId;
- mParameters = mCameraDevice.getParameters();
+ mParameters = mCameraDevice.getCamera().getParameters();
} else {
if (!mCameraDevice.reconnect(handler, cb)) {
Log.e(TAG, "fail to reconnect Camera:" + mCameraId + ", aborting.");
diff --git a/src/com/android/camera/CameraManager.java b/src/com/android/camera/CameraManager.java
index 909e1ca75..8ad0d52d6 100644
--- a/src/com/android/camera/CameraManager.java
+++ b/src/com/android/camera/CameraManager.java
@@ -25,6 +25,7 @@ import android.hardware.Camera.Parameters;
import android.os.Build;
import android.os.Handler;
import android.view.SurfaceHolder;
+import android.hardware.Camera.CameraDataCallback;
/**
* An interface which provides possible camera device operations.
@@ -349,5 +350,23 @@ public interface CameraManager {
* {@code false} to disable it.
*/
public void enableShutterSound(boolean enable);
+ /**
+ * Set histogram Mode
+ *
+ * @param cb cameraDataCallback to use
+ */
+ public void setHistogramMode(CameraDataCallback cb);
+ /**
+ * Send the Histogram Data.
+ *
+ */
+ public void sendHistogramData();
+ /**
+ * Enables/Disables longshot mode.
+ *
+ * @param enable {@code true} to enable longshot mode,
+ * {@code false} to disable it.
+ */
+ public void setLongshot(boolean enable);
}
}
diff --git a/src/com/android/camera/CameraModule.java b/src/com/android/camera/CameraModule.java
index 55cae9f0c..48d7eec4a 100644
--- a/src/com/android/camera/CameraModule.java
+++ b/src/com/android/camera/CameraModule.java
@@ -66,4 +66,6 @@ public interface CameraModule {
public void onMediaSaveServiceConnected(MediaSaveService s);
public boolean arePreviewControlsVisible();
+
+ public void resizeForPreviewAspectRatio();
}
diff --git a/src/com/android/camera/CameraPreference.java b/src/com/android/camera/CameraPreference.java
index 407c1408c..f2a78e9cc 100644
--- a/src/com/android/camera/CameraPreference.java
+++ b/src/com/android/camera/CameraPreference.java
@@ -34,6 +34,7 @@ public abstract class CameraPreference {
private final Context mContext;
static public interface OnPreferenceChangedListener {
+ public void onSharedPreferenceChanged(ListPreference pref);
public void onSharedPreferenceChanged();
public void onRestorePreferencesClicked();
public void onOverriddenPreferencesClicked();
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 55867a1e8..c70ee9909 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -16,12 +16,14 @@
package com.android.camera;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
@@ -36,6 +38,8 @@ import com.android.camera2.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import android.os.Build;
+import java.util.StringTokenizer;
/**
* Provides utilities and keys for Camera settings.
@@ -61,17 +65,95 @@ public class CameraSettings {
public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
public static final String KEY_CAMERA_ID = "pref_camera_id_key";
public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
+ public static final String KEY_CAMERA_HQ = "pref_camera_hq_key";
public static final String KEY_CAMERA_HDR_PLUS = "pref_camera_hdr_plus_key";
public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN = "pref_camera_first_use_hint_shown_key";
public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN = "pref_video_first_use_hint_shown_key";
public static final String KEY_PHOTOSPHERE_PICTURESIZE = "pref_photosphere_picturesize_key";
public static final String KEY_STARTUP_MODULE_INDEX = "camera.startup_module";
+ public static final String KEY_VIDEO_ENCODER = "pref_camera_videoencoder_key";
+ public static final String KEY_AUDIO_ENCODER = "pref_camera_audioencoder_key";
+ public static final String KEY_VIDEO_DURATION = "pref_camera_video_duration_key";
+ public static final String KEY_POWER_MODE = "pref_camera_powermode_key";
+ public static final String KEY_PICTURE_FORMAT = "pref_camera_pictureformat_key";
+ public static final String KEY_ZSL = "pref_camera_zsl_key";
+ public static final String KEY_CAMERA_SAVEPATH = "pref_camera_savepath_key";
+ public static final String KEY_COLOR_EFFECT = "pref_camera_coloreffect_key";
+ public static final String KEY_FACE_DETECTION = "pref_camera_facedetection_key";
+ public static final String KEY_TOUCH_AF_AEC = "pref_camera_touchafaec_key";
+ public static final String KEY_SELECTABLE_ZONE_AF = "pref_camera_selectablezoneaf_key";
+ public static final String KEY_SATURATION = "pref_camera_saturation_key";
+ public static final String KEY_CONTRAST = "pref_camera_contrast_key";
+ public static final String KEY_SHARPNESS = "pref_camera_sharpness_key";
+ public static final String KEY_AUTOEXPOSURE = "pref_camera_autoexposure_key";
+ public static final String KEY_ANTIBANDING = "pref_camera_antibanding_key";
+ public static final String KEY_ISO = "pref_camera_iso_key";
+ public static final String KEY_LENSSHADING = "pref_camera_lensshading_key";
+ public static final String KEY_HISTOGRAM = "pref_camera_histogram_key";
+ public static final String KEY_DENOISE = "pref_camera_denoise_key";
+ public static final String KEY_REDEYE_REDUCTION = "pref_camera_redeyereduction_key";
+ public static final String KEY_AE_BRACKET_HDR = "pref_camera_ae_bracket_hdr_key";
+ public static final String KEY_ADVANCED_FEATURES = "pref_camera_advanced_features_key";
+
+ public static final String KEY_VIDEO_SNAPSHOT_SIZE = "pref_camera_videosnapsize_key";
+ public static final String KEY_VIDEO_HIGH_FRAME_RATE = "pref_camera_hfr_key";
+ public static final String KEY_VIDEO_HDR = "pref_camera_video_hdr_key";
+ public static final String DEFAULT_VIDEO_QUALITY_VALUE = "custom";
+ public static final String KEY_SKIN_TONE_ENHANCEMENT = "pref_camera_skinToneEnhancement_key";
+ public static final String KEY_SKIN_TONE_ENHANCEMENT_FACTOR = "pref_camera_skinToneEnhancement_factor_key";
+
+ public static final String KEY_FACE_RECOGNITION = "pref_camera_facerc_key";
+ public static final String KEY_DIS = "pref_camera_dis_key";
+
+ public static final String KEY_LONGSHOT = "pref_camera_longshot_key";
+
+ private static final String KEY_QC_SUPPORTED_AE_BRACKETING_MODES = "ae-bracket-hdr-values";
+ private static final String KEY_QC_SUPPORTED_AF_BRACKETING_MODES = "af-bracket-values";
+ private static final String KEY_QC_SUPPORTED_CF_MODES = "chroma-flash-values";
+ private static final String KEY_QC_SUPPORTED_OZ_MODES = "opti-zoom-values";
+ private static final String KEY_QC_SUPPORTED_FACE_RECOGNITION_MODES = "face-recognition-values";
+ private static final String KEY_QC_SUPPORTED_DIS_MODES = "dis-values";
+ public static final String KEY_QC_AE_BRACKETING = "ae-bracket-hdr";
+ public static final String KEY_QC_AF_BRACKETING = "af-bracket";
+ public static final String KEY_QC_CHROMA_FLASH = "chroma-flash";
+ public static final String KEY_QC_OPTI_ZOOM = "opti-zoom";
+ public static final String KEY_QC_FACE_RECOGNITION = "face-recognition";
+ public static final String KEY_QC_DIS_MODE = "dis";
+
+ public static final String KEY_INTERNAL_PREVIEW_RESTART = "internal-restart";
+ public static final String KEY_QC_ZSL_HDR_SUPPORTED = "zsl-hdr-supported";
+ public static final String KEY_QC_LONGSHOT_SUPPORTED = "longshot-supported";
+ private static final String TRUE = "true";
+ private static final String FALSE = "false";
+
+ //for flip
+ public static final String KEY_QC_PREVIEW_FLIP = "preview-flip";
+ public static final String KEY_QC_VIDEO_FLIP = "video-flip";
+ public static final String KEY_QC_SNAPSHOT_PICTURE_FLIP = "snapshot-picture-flip";
+ public static final String KEY_QC_SUPPORTED_FLIP_MODES = "flip-mode-values";
+
+ public static final String FLIP_MODE_OFF = "off";
+ public static final String FLIP_MODE_V = "flip-v";
+ public static final String FLIP_MODE_H = "flip-h";
+ public static final String FLIP_MODE_VH = "flip-vh";
+
+ private static final String KEY_QC_PICTURE_FORMAT = "picture-format-values";
+ private static final String VIDEO_QUALITY_HIGH = "high";
+ private static final String VIDEO_QUALITY_MMS = "mms";
+ private static final String VIDEO_QUALITY_YOUTUBE = "youtube";
+
+
public static final String EXPOSURE_DEFAULT_VALUE = "0";
public static final int CURRENT_VERSION = 5;
public static final int CURRENT_LOCAL_VERSION = 2;
+ public static final int DEFAULT_VIDEO_DURATION = 0; // no limit
+ private static final int MMS_VIDEO_DURATION = (CamcorderProfile.get(CamcorderProfile.QUALITY_LOW) != null) ?
+ CamcorderProfile.get(CamcorderProfile.QUALITY_LOW).duration :30;
+ private static final int YOUTUBE_VIDEO_DURATION = 15 * 60; // 15 mins
+
private static final String TAG = "CameraSettings";
private final Context mContext;
@@ -96,10 +178,10 @@ public class CameraSettings {
}
public static String getSupportedHighestVideoQuality(int cameraId,
- String defaultQuality) {
+ String defaultQuality,Parameters parameters) {
// When launching the camera app first time, we will set the video quality
// to the first one (i.e. highest quality) in the supported list
- List<String> supported = getSupportedVideoQuality(cameraId);
+ List<String> supported = getSupportedVideoQuality(cameraId,parameters);
if (supported == null) {
Log.e(TAG, "No supported video quality is found");
return defaultQuality;
@@ -156,6 +238,210 @@ public class CameraSettings {
return duration;
}
+ public static List<String> getSupportedFaceRecognitionModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_FACE_RECOGNITION_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+ public static List<String> getSupportedDISModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_DIS_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+ public static List<String> getSupportedAEBracketingModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_AE_BRACKETING_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+ public List<String> getSupportedAdvancedFeatures(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_AF_BRACKETING_MODES);
+ str += ',' + params.get(KEY_QC_SUPPORTED_CF_MODES);
+ str += ',' + params.get(KEY_QC_SUPPORTED_OZ_MODES);
+ str += ',' + mContext.getString(R.string.pref_camera_advanced_feature_default);
+ return split(str);
+ }
+
+ public static List<String> getSupportedAFBracketingModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_AF_BRACKETING_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+ public static List<String> getSupportedChromaFlashModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_CF_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+ public static List<String> getSupportedOptiZoomModes(Parameters params) {
+ String str = params.get(KEY_QC_SUPPORTED_OZ_MODES);
+ if (str == null) {
+ return null;
+ }
+ return split(str);
+ }
+
+
+ // Splits a comma delimited string to an ArrayList of String.
+ // Return null if the passing string is null or the size is 0.
+ private static ArrayList<String> split(String str) {
+ if (str == null) return null;
+
+ // Use StringTokenizer because it is faster than split.
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ ArrayList<String> substrings = new ArrayList<String>();
+ while (tokenizer.hasMoreElements()) {
+ substrings.add(tokenizer.nextToken());
+ }
+ return substrings;
+ }
+ private List<String> getSupportedPictureFormatLists() {
+ String str = mParameters.get(KEY_QC_PICTURE_FORMAT);
+ if (str == null) {
+ str = "jpeg,raw"; // if not set, fall back to default behavior
+ }
+ return split(str);
+ }
+
+ public static List<String> getSupportedFlipMode(Parameters params){
+ String str = params.get(KEY_QC_SUPPORTED_FLIP_MODES);
+ if(str == null)
+ return null;
+
+ return split(str);
+ }
+
+ private void qcomInitPreferences(PreferenceGroup group){
+ //Qcom Preference add here
+ ListPreference powerMode = group.findPreference(KEY_POWER_MODE);
+ ListPreference zsl = group.findPreference(KEY_ZSL);
+ ListPreference colorEffect = group.findPreference(KEY_COLOR_EFFECT);
+ ListPreference faceDetection = group.findPreference(KEY_FACE_DETECTION);
+ ListPreference touchAfAec = group.findPreference(KEY_TOUCH_AF_AEC);
+ ListPreference selectableZoneAf = group.findPreference(KEY_SELECTABLE_ZONE_AF);
+ ListPreference saturation = group.findPreference(KEY_SATURATION);
+ ListPreference contrast = group.findPreference(KEY_CONTRAST);
+ ListPreference sharpness = group.findPreference(KEY_SHARPNESS);
+ ListPreference autoExposure = group.findPreference(KEY_AUTOEXPOSURE);
+ ListPreference antiBanding = group.findPreference(KEY_ANTIBANDING);
+ ListPreference mIso = group.findPreference(KEY_ISO);
+ ListPreference lensShade = group.findPreference(KEY_LENSSHADING);
+ ListPreference histogram = group.findPreference(KEY_HISTOGRAM);
+ ListPreference denoise = group.findPreference(KEY_DENOISE);
+ ListPreference redeyeReduction = group.findPreference(KEY_REDEYE_REDUCTION);
+ ListPreference aeBracketing = group.findPreference(KEY_AE_BRACKET_HDR);
+ ListPreference advancedFeatures = group.findPreference(KEY_ADVANCED_FEATURES);
+ ListPreference faceRC = group.findPreference(KEY_FACE_RECOGNITION);
+ ListPreference jpegQuality = group.findPreference(KEY_JPEG_QUALITY);
+ ListPreference videoSnapSize = group.findPreference(KEY_VIDEO_SNAPSHOT_SIZE);
+ ListPreference videoHdr = group.findPreference(KEY_VIDEO_HDR);
+ ListPreference pictureFormat = group.findPreference(KEY_PICTURE_FORMAT);
+ ListPreference hfr = group.findPreference(KEY_VIDEO_HIGH_FRAME_RATE);
+ ListPreference longShot = group.findPreference(KEY_LONGSHOT);
+
+ if (touchAfAec != null) {
+ filterUnsupportedOptions(group,
+ touchAfAec, mParameters.getSupportedTouchAfAec());
+ }
+
+ if (!mParameters.isPowerModeSupported() && powerMode != null) {
+ removePreference(group, powerMode.getKey());
+ }
+
+ if (selectableZoneAf != null) {
+ filterUnsupportedOptions(group,
+ selectableZoneAf, mParameters.getSupportedSelectableZoneAf());
+ }
+
+ if (mIso != null) {
+ filterUnsupportedOptions(group,
+ mIso, mParameters.getSupportedIsoValues());
+ }
+
+ if (redeyeReduction != null) {
+ filterUnsupportedOptions(group,
+ redeyeReduction, mParameters.getSupportedRedeyeReductionModes());
+ }
+
+ if (denoise != null) {
+ filterUnsupportedOptions(group,
+ denoise, mParameters.getSupportedDenoiseModes());
+ }
+
+ if (videoHdr != null) {
+ filterUnsupportedOptions(group,
+ videoHdr, mParameters.getSupportedVideoHDRModes());
+ }
+
+ if (colorEffect != null) {
+ filterUnsupportedOptions(group,
+ colorEffect, mParameters.getSupportedColorEffects());
+ }
+
+ if (aeBracketing != null) {
+ filterUnsupportedOptions(group,
+ aeBracketing, getSupportedAEBracketingModes(mParameters));
+ }
+
+ if (antiBanding != null) {
+ filterUnsupportedOptions(group,
+ antiBanding, mParameters.getSupportedAntibanding());
+ }
+
+ if (faceRC != null) {
+ filterUnsupportedOptions(group,
+ faceRC, getSupportedFaceRecognitionModes(mParameters));
+ }
+
+ if (autoExposure != null) {
+ filterUnsupportedOptions(group,
+ autoExposure, mParameters.getSupportedAutoexposure());
+ }
+
+ if (!mParameters.isPowerModeSupported()){
+ filterUnsupportedOptions(group,
+ videoSnapSize, null);
+ } else {
+ filterUnsupportedOptions(group, videoSnapSize, sizeListToStringList(
+ mParameters.getSupportedPictureSizes()));
+ }
+
+ if (histogram!= null) {
+ filterUnsupportedOptions(group,
+ histogram, mParameters.getSupportedHistogramModes());
+ }
+
+ if (pictureFormat!= null) {
+ filterUnsupportedOptions(group,
+ pictureFormat, getSupportedPictureFormatLists());
+ }
+
+ if (hfr != null) {
+ filterUnsupportedOptions(group,
+ hfr, mParameters.getSupportedVideoHighFrameRateModes());
+ }
+
+ if(advancedFeatures != null) {
+ filterUnsupportedOptions(group,
+ advancedFeatures, getSupportedAdvancedFeatures(mParameters));
+ }
+ if (longShot!= null && !isLongshotSupported(mParameters)) {
+ removePreference(group, longShot.getKey());
+ }
+ }
private void initPreference(PreferenceGroup group) {
ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY);
ListPreference timeLapseInterval = group.findPreference(KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL);
@@ -172,12 +458,21 @@ public class CameraSettings {
group.findPreference(KEY_VIDEOCAMERA_FLASH_MODE);
ListPreference videoEffect = group.findPreference(KEY_VIDEO_EFFECT);
ListPreference cameraHdr = group.findPreference(KEY_CAMERA_HDR);
+ ListPreference disMode = group.findPreference(KEY_DIS);
ListPreference cameraHdrPlus = group.findPreference(KEY_CAMERA_HDR_PLUS);
+ ListPreference videoHfrMode =
+ group.findPreference(KEY_VIDEO_HIGH_FRAME_RATE);
// Since the screen could be loaded from different resources, we need
// to check if the preference is available here
+ if ((videoHfrMode != null) &&
+ (mParameters.getSupportedHfrSizes() == null)) {
+ filterUnsupportedOptions(group, videoHfrMode, null);
+ }
+
if (videoQuality != null) {
- filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality(mCameraId));
+ filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality(
+ mCameraId,mParameters));
}
if (pictureSize != null) {
@@ -197,13 +492,14 @@ public class CameraSettings {
filterUnsupportedOptions(group,
flashMode, mParameters.getSupportedFlashModes());
}
+ if (disMode != null) {
+ filterUnsupportedOptions(group,
+ disMode, getSupportedDISModes(mParameters));
+ }
if (focusMode != null) {
if (!CameraUtil.isFocusAreaSupported(mParameters)) {
filterUnsupportedOptions(group,
focusMode, mParameters.getSupportedFocusModes());
- } else {
- // Remove the focus mode if we can use tap-to-focus.
- removePreference(group, focusMode.getKey());
}
}
if (videoFlashMode != null) {
@@ -223,13 +519,13 @@ public class CameraSettings {
|| !CameraUtil.isCameraHdrSupported(mParameters))) {
removePreference(group, cameraHdr.getKey());
}
-
int frontCameraId = CameraHolder.instance().getFrontCameraId();
boolean isFrontCamera = (frontCameraId == mCameraId);
if (cameraHdrPlus != null && (!ApiHelper.HAS_CAMERA_HDR_PLUS ||
!GcamHelper.hasGcamCapture() || isFrontCamera)) {
removePreference(group, cameraHdrPlus.getKey());
}
+ qcomInitPreferences(group);
}
private void buildExposureCompensation(
@@ -424,12 +720,15 @@ public class CameraSettings {
int n = CameraHolder.instance().getNumberOfCameras();
if (cameraId < 0 || cameraId >= n) {
- writePreferredCameraId(pref, 0);
+ cameraId = 0;
}
+ writePreferredCameraId(pref, cameraId);
}
public static int readPreferredCameraId(SharedPreferences pref) {
- return Integer.parseInt(pref.getString(KEY_CAMERA_ID, "0"));
+ String rearCameraId = Integer.toString(
+ CameraHolder.instance().getBackCameraId());
+ return Integer.parseInt(pref.getString(KEY_CAMERA_ID, rearCameraId));
}
public static void writePreferredCameraId(SharedPreferences pref,
@@ -484,19 +783,147 @@ public class CameraSettings {
initialCameraPictureSize(context, parameters);
writePreferredCameraId(preferences, currentCameraId);
}
+ private static boolean checkSupportedVideoQuality(Parameters parameters,int width, int height){
+ List <Size> supported = parameters.getSupportedVideoSizes();
+ int flag = 0;
+ for (Size size : supported){
+ //since we are having two profiles with same height, we are checking with height
+ if (size.height == 480) {
+ if (size.height == height && size.width == width) {
+ flag = 1;
+ break;
+ }
+ } else {
+ if (size.width == width) {
+ flag = 1;
+ break;
+ }
+ }
+ }
+ if (flag == 1)
+ return true;
- private static ArrayList<String> getSupportedVideoQuality(int cameraId) {
+ return false;
+ }
+ private static ArrayList<String> getSupportedVideoQuality(int cameraId,Parameters parameters) {
ArrayList<String> supported = new ArrayList<String>();
// Check for supported quality
+ if (ApiHelper.HAS_FINE_RESOLUTION_QUALITY_LEVELS) {
+ getFineResolutionQuality(supported,cameraId,parameters);
+ } else {
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_HIGH));
+ CamcorderProfile high = CamcorderProfile.get(
+ cameraId, CamcorderProfile.QUALITY_HIGH);
+ CamcorderProfile low = CamcorderProfile.get(
+ cameraId, CamcorderProfile.QUALITY_LOW);
+ if (high.videoFrameHeight * high.videoFrameWidth >
+ low.videoFrameHeight * low.videoFrameWidth) {
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_LOW));
+ }
+ }
+
+ return supported;
+ }
+
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
+ private static void getFineResolutionQuality(ArrayList<String> supported,
+ int cameraId,Parameters parameters) {
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_4kDCI)) {
+ if (checkSupportedVideoQuality(parameters,4096,2160)) {
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_4kDCI));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_4kUHD)) {
+ if (checkSupportedVideoQuality(parameters,3840,2160)) {
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_4kUHD));
+ }
+ }
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P));
+ if (checkSupportedVideoQuality(parameters,1920,1080)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P));
+ }
}
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_720P));
+ if (checkSupportedVideoQuality(parameters,1280,720)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_720P));
+ }
}
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_480P));
+ if (checkSupportedVideoQuality(parameters,720,480)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_480P));
+ }
}
- return supported;
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_FWVGA)) {
+ if (checkSupportedVideoQuality(parameters,864,480)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_FWVGA));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_WVGA)) {
+ if (checkSupportedVideoQuality(parameters,800,480)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_WVGA));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_VGA)) {
+ if (checkSupportedVideoQuality(parameters,640,480)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_VGA));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_CIF)) {
+ if (checkSupportedVideoQuality(parameters,352,288)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_CIF));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QVGA)) {
+ if (checkSupportedVideoQuality(parameters,320,240)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_QVGA));
+ }
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_QCIF)) {
+ if (checkSupportedVideoQuality(parameters,176,144)){
+ supported.add(Integer.toString(CamcorderProfile.QUALITY_QCIF));
+ }
+ }
+
+ }
+ public static int getVideoDurationInMillis(String quality) {
+ if (VIDEO_QUALITY_MMS.equals(quality)) {
+ return MMS_VIDEO_DURATION * 1000;
+ } else if (VIDEO_QUALITY_YOUTUBE.equals(quality)) {
+ return YOUTUBE_VIDEO_DURATION * 1000;
+ }
+ return DEFAULT_VIDEO_DURATION * 1000;
+ }
+
+ public static boolean isInternalPreviewSupported(Parameters params) {
+ boolean ret = false;
+ if (null != params) {
+ String val = params.get(KEY_INTERNAL_PREVIEW_RESTART);
+ if ((null != val) && (TRUE.equals(val))) {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+ public static boolean isLongshotSupported(Parameters params) {
+ boolean ret = false;
+ if (null != params) {
+ String val = params.get(KEY_QC_LONGSHOT_SUPPORTED);
+ if ((null != val) && (TRUE.equals(val))) {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+ public static boolean isZSLHDRSupported(Parameters params) {
+ boolean ret = false;
+ if (null != params) {
+ String val = params.get(KEY_QC_ZSL_HDR_SUPPORTED);
+ if ((null != val) && (TRUE.equals(val))) {
+ ret = true;
+ }
+ }
+ return ret;
}
}
diff --git a/src/com/android/camera/ComboPreferences.java b/src/com/android/camera/ComboPreferences.java
index 42cf62423..d0039ab9e 100644
--- a/src/com/android/camera/ComboPreferences.java
+++ b/src/com/android/camera/ComboPreferences.java
@@ -105,6 +105,7 @@ public class ComboPreferences implements
movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, src);
movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, src);
movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_EFFECT, src);
+ movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_SAVEPATH, src);
}
public static String[] getSharedPreferencesNames(Context context) {
@@ -143,15 +144,15 @@ public class ComboPreferences implements
}
private static boolean isGlobal(String key) {
- return key.equals(CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL)
- || key.equals(CameraSettings.KEY_CAMERA_ID)
+ return key.equals(CameraSettings.KEY_CAMERA_ID)
|| key.equals(CameraSettings.KEY_RECORD_LOCATION)
|| key.equals(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN)
|| key.equals(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN)
|| key.equals(CameraSettings.KEY_VIDEO_EFFECT)
|| key.equals(CameraSettings.KEY_TIMER)
|| key.equals(CameraSettings.KEY_TIMER_SOUND_EFFECTS)
- || key.equals(CameraSettings.KEY_PHOTOSPHERE_PICTURESIZE);
+ || key.equals(CameraSettings.KEY_PHOTOSPHERE_PICTURESIZE)
+ || key.equals(CameraSettings.KEY_CAMERA_SAVEPATH);
}
@Override
diff --git a/src/com/android/camera/CountDownTimerPreference.java b/src/com/android/camera/CountDownTimerPreference.java
index 9a7e44bfb..14819fa48 100644
--- a/src/com/android/camera/CountDownTimerPreference.java
+++ b/src/com/android/camera/CountDownTimerPreference.java
@@ -39,7 +39,8 @@ public class CountDownTimerPreference extends ListPreference {
entries[0] = context.getString(R.string.setting_off); // Off
} else {
entries[i] = context.getResources()
- .getQuantityString(R.plurals.pref_camera_timer_entry, i, i);
+ .getQuantityString(R.plurals.pref_camera_timer_entry, i,
+ DURATIONS[i]);
}
}
setEntries(entries);
diff --git a/src/com/android/camera/FocusOverlayManager.java b/src/com/android/camera/FocusOverlayManager.java
index 797316258..602c31767 100644
--- a/src/com/android/camera/FocusOverlayManager.java
+++ b/src/com/android/camera/FocusOverlayManager.java
@@ -63,12 +63,12 @@ public class FocusOverlayManager {
private static final int RESET_TOUCH_FOCUS_DELAY = 3000;
private int mState = STATE_IDLE;
- private static final int STATE_IDLE = 0; // Focus is not active.
- private static final int STATE_FOCUSING = 1; // Focus is in progress.
+ public static final int STATE_IDLE = 0; // Focus is not active.
+ public static final int STATE_FOCUSING = 1; // Focus is in progress.
// Focus is in progress and the camera should take a picture after focus finishes.
- private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
- private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
- private static final int STATE_FAIL = 4; // Focus finishes and fails.
+ public static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
+ public static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
+ public static final int STATE_FAIL = 4; // Focus finishes and fails.
private boolean mInitialized;
private boolean mFocusAreaSupported;
@@ -89,6 +89,9 @@ public class FocusOverlayManager {
private Handler mHandler;
Listener mListener;
private boolean mPreviousMoving;
+ private boolean mZslEnabled = false; //QCom Parameter to disable focus for ZSL
+ private boolean mTouchAFRunning = false;
+ private boolean mIsAFRunning = false;
private FocusUI mUI;
private final Rect mPreviewRect = new Rect(0, 0, 0, 0);
@@ -199,7 +202,7 @@ public class FocusOverlayManager {
}
private void lockAeAwbIfNeeded() {
- if (mLockAeAwbNeeded && !mAeAwbLock) {
+ if (mLockAeAwbNeeded && !mAeAwbLock && !mZslEnabled) {
mAeAwbLock = true;
mListener.setFocusParameters();
}
@@ -309,6 +312,10 @@ public class FocusOverlayManager {
// Ignore if the camera has detected some faces.
if (mUI.hasFaces()) {
mUI.clearFocus();
+ if (mIsAFRunning) {
+ mUI.onFocusSucceeded(true);
+ mIsAFRunning = false;
+ }
return;
}
@@ -319,8 +326,10 @@ public class FocusOverlayManager {
// animate on false->true trasition only b/8219520
if (moving && !mPreviousMoving) {
mUI.onFocusStarted();
+ mIsAFRunning = true;
} else if (!moving) {
mUI.onFocusSucceeded(true);
+ mIsAFRunning = false;
}
mPreviousMoving = moving;
}
@@ -378,6 +387,10 @@ public class FocusOverlayManager {
// Use margin to set the focus indicator to the touched area.
mUI.setFocusPosition(x, y);
+ if (mZslEnabled) {
+ mTouchAFRunning = true;
+ }
+
// Stop face detection because we want to specify focus and metering area.
mListener.stopFaceDetection();
@@ -405,6 +418,7 @@ public class FocusOverlayManager {
}
public void onCameraReleased() {
+ mTouchAFRunning = false;
onPreviewStopped();
}
@@ -519,7 +533,18 @@ public class FocusOverlayManager {
mUI.clearFocus();
// Initialize mFocusArea.
mFocusArea = null;
+ // Initialize mMeteringArea.
mMeteringArea = null;
+
+ // Reset metering area when no specific region is selected.
+ if (mMeteringAreaSupported) {
+ resetMeteringAreas();
+ }
+
+ if (mTouchAFRunning && mZslEnabled) {
+ mTouchAFRunning = false;
+ mListener.setFocusParameters();
+ }
}
private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) {
@@ -548,6 +573,10 @@ public class FocusOverlayManager {
return mState == STATE_SUCCESS || mState == STATE_FAIL;
}
+ public int getCurrentFocusState() {
+ return mState;
+ }
+
public boolean isFocusingSnapOnFinish() {
return mState == STATE_FOCUSING_SNAP_ON_FINISH;
}
@@ -574,4 +603,17 @@ public class FocusOverlayManager {
|| focusMode.equals(Parameters.FOCUS_MODE_FIXED)
|| focusMode.equals(Parameters.FOCUS_MODE_EDOF));
}
+
+ public void setZslEnable(boolean value) {
+ mZslEnabled = value;
+ }
+
+ public boolean isZslEnabled() {
+ return mZslEnabled;
+ }
+
+ public boolean isTouch() {
+ return mTouchAFRunning;
+ }
+
}
diff --git a/src/com/android/camera/ListPreference.java b/src/com/android/camera/ListPreference.java
index 909b32c55..2a33fb098 100644
--- a/src/com/android/camera/ListPreference.java
+++ b/src/com/android/camera/ListPreference.java
@@ -128,7 +128,9 @@ public class ListPreference extends CameraPreference {
}
public void setValue(String value) {
- if (findIndexOfValue(value) < 0) throw new IllegalArgumentException();
+ if (findIndexOfValue(value) < 0) {
+ value = findSupportedDefaultValue();
+ }
mValue = value;
persistStringValue(value);
}
diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java
index e8ec08d57..c19dcd498 100644
--- a/src/com/android/camera/MediaSaveService.java
+++ b/src/com/android/camera/MediaSaveService.java
@@ -28,7 +28,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.provider.MediaStore.Video;
import android.util.Log;
-
+import com.android.camera.PhotoModule;
import com.android.camera.exif.ExifInterface;
import java.io.File;
@@ -39,8 +39,8 @@ import java.io.File;
public class MediaSaveService extends Service {
public static final String VIDEO_BASE_URI = "content://media/external/video/media";
- // The memory limit for unsaved image is 20MB.
- private static final int SAVE_TASK_MEMORY_LIMIT = 20 * 1024 * 1024;
+ // The memory limit for unsaved image is 50MB.
+ private static final int SAVE_TASK_MEMORY_LIMIT = 50 * 1024 * 1024;
private static final String TAG = "CAM_" + MediaSaveService.class.getSimpleName();
private final IBinder mBinder = new LocalBinder();
@@ -87,14 +87,14 @@ public class MediaSaveService extends Service {
public void addImage(final byte[] data, String title, long date, Location loc,
int width, int height, int orientation, ExifInterface exif,
- OnMediaSavedListener l, ContentResolver resolver) {
+ OnMediaSavedListener l, ContentResolver resolver, String pictureFormat) {
if (isQueueFull()) {
Log.e(TAG, "Cannot add image when the queue is full");
return;
}
ImageSaveTask t = new ImageSaveTask(data, title, date,
(loc == null) ? null : new Location(loc),
- width, height, orientation, exif, resolver, l);
+ width, height, orientation, exif, resolver, l, pictureFormat);
mMemoryUse += data.length;
if (isQueueFull()) {
@@ -108,13 +108,14 @@ public class MediaSaveService extends Service {
OnMediaSavedListener l, ContentResolver resolver) {
// When dimensions are unknown, pass 0 as width and height,
// and decode image for width and height later in a background thread
- addImage(data, title, date, loc, 0, 0, orientation, exif, l, resolver);
+ addImage(data, title, date, loc, 0, 0, orientation, exif, l, resolver,
+ PhotoModule.PIXEL_FORMAT_JPEG);
}
public void addImage(final byte[] data, String title, Location loc,
int width, int height, int orientation, ExifInterface exif,
OnMediaSavedListener l, ContentResolver resolver) {
addImage(data, title, System.currentTimeMillis(), loc, width, height,
- orientation, exif, l, resolver);
+ orientation, exif, l, resolver,PhotoModule.PIXEL_FORMAT_JPEG);
}
public void addVideo(String path, long duration, ContentValues values,
@@ -148,10 +149,11 @@ public class MediaSaveService extends Service {
private ExifInterface exif;
private ContentResolver resolver;
private OnMediaSavedListener listener;
+ private String pictureFormat;
public ImageSaveTask(byte[] data, String title, long date, Location loc,
int width, int height, int orientation, ExifInterface exif,
- ContentResolver resolver, OnMediaSavedListener listener) {
+ ContentResolver resolver, OnMediaSavedListener listener, String pictureFormat) {
this.data = data;
this.title = title;
this.date = date;
@@ -162,6 +164,7 @@ public class MediaSaveService extends Service {
this.exif = exif;
this.resolver = resolver;
this.listener = listener;
+ this.pictureFormat = pictureFormat;
}
@Override
@@ -180,7 +183,7 @@ public class MediaSaveService extends Service {
height = options.outHeight;
}
return Storage.addImage(
- resolver, title, date, loc, orientation, exif, data, width, height);
+ resolver, title, date, loc, orientation, exif, data, width, height, pictureFormat);
}
@Override
diff --git a/src/com/android/camera/PauseButton.java b/src/com/android/camera/PauseButton.java
new file mode 100644
index 000000000..a785050fd
--- /dev/null
+++ b/src/com/android/camera/PauseButton.java
@@ -0,0 +1,82 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.camera;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+import android.view.MotionEvent;
+import android.view.View;
+import android.util.Log;
+
+/**
+ * A button designed to be used for the on-screen recording
+ * pausing-continue button.
+ */
+public class PauseButton extends ImageView {
+
+ public interface OnPauseButtonListener {
+ void onButtonPause();
+ void onButtonContinue();
+ }
+
+ public PauseButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setClickable(true);
+ setSelected(false);
+ }
+
+ public void setPaused(boolean paused) {
+ setSelected(paused);
+ }
+
+ @Override
+ public boolean performClick() {
+ boolean result = super.performClick();
+ if (isSelected()) {
+ setSelected(false);
+ if (mListener != null && getVisibility() == View.VISIBLE) {
+ mListener.onButtonContinue();
+ }
+ } else {
+ setSelected(true);
+ if (mListener != null && getVisibility() == View.VISIBLE) {
+ mListener.onButtonPause();
+ }
+ }
+ return result;
+ }
+
+ public void setOnPauseButtonListener(OnPauseButtonListener listener) {
+ mListener = listener;
+ }
+
+ private OnPauseButtonListener mListener;
+}
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
index 833c82574..c1c3a8562 100644
--- a/src/com/android/camera/PhotoController.java
+++ b/src/com/android/camera/PhotoController.java
@@ -31,6 +31,8 @@ public interface PhotoController extends OnShutterButtonListener {
public static final int SNAPSHOT_IN_PROGRESS = 3;
// Switching between cameras.
public static final int SWITCHING_CAMERA = 4;
+ // Longshot mode
+ public static final int LONGSHOT = 5;
// returns the actual set zoom value
public int onZoomChanged(int requestedZoom);
@@ -55,6 +57,8 @@ public interface PhotoController extends OnShutterButtonListener {
public void onCountDownFinished();
+ public void onScreenSizeChanged(int width, int height);
+
public void onPreviewRectChanged(Rect previewRect);
public void updateCameraOrientation();
diff --git a/src/com/android/camera/PhotoMenu.java b/src/com/android/camera/PhotoMenu.java
index 08ce3374e..a9526962b 100644
--- a/src/com/android/camera/PhotoMenu.java
+++ b/src/com/android/camera/PhotoMenu.java
@@ -24,21 +24,43 @@ import android.hardware.Camera.Parameters;
import com.android.camera.ui.AbstractSettingPopup;
import com.android.camera.ui.CountdownTimerPopup;
import com.android.camera.ui.ListPrefSettingPopup;
+import com.android.camera.ui.MoreSettingPopup;
import com.android.camera.ui.PieItem;
import com.android.camera.ui.PieItem.OnClickListener;
import com.android.camera.ui.PieRenderer;
import com.android.camera2.R;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.widget.Toast;
+import android.util.Log;
+
+import java.util.Locale;
public class PhotoMenu extends PieController
- implements CountdownTimerPopup.Listener,
+ implements MoreSettingPopup.Listener,
+ CountdownTimerPopup.Listener,
ListPrefSettingPopup.Listener {
private static String TAG = "PhotoMenu";
private final String mSettingOff;
+ private String[] mOtherKeys1;
+ private String[] mOtherKeys2;
+ private String[] mOtherKeys3;
+ private MoreSettingPopup mPopup1;
+ private MoreSettingPopup mPopup2;
+ private MoreSettingPopup mPopup3;
+ private static final int POPUP_NONE = 0;
+ private static final int POPUP_FIRST_LEVEL = 1;
+ private static final int POPUP_SECOND_LEVEL = 2;
private PhotoUI mUI;
+ private int mPopupStatus;
private AbstractSettingPopup mPopup;
private CameraActivity mActivity;
+ private int popupNum = 0;
+ private PieItem mHdrItem = null;
+ private PieItem mHdrPlusItem = null;
+ private boolean mHdrOn = false;
public PhotoMenu(CameraActivity activity, PhotoUI ui, PieRenderer pie) {
super(activity, pie);
@@ -50,39 +72,112 @@ public class PhotoMenu extends PieController
public void initialize(PreferenceGroup group) {
super.initialize(group);
mPopup = null;
+ mPopup1 = null;
+ mPopup2 = null;
+ mPopup3 = null;
+ mPopupStatus = POPUP_NONE;
PieItem item = null;
+ popupNum = 0;
final Resources res = mActivity.getResources();
Locale locale = res.getConfiguration().locale;
// The order is from left to right in the menu.
// HDR+ (GCam).
if (group.findPreference(CameraSettings.KEY_CAMERA_HDR_PLUS) != null) {
- item = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR_PLUS, true);
- mRenderer.addItem(item);
+ mHdrPlusItem = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR_PLUS, true);
+ mRenderer.addItem(mHdrPlusItem);
}
// HDR.
if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) {
- item = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR, true);
- mRenderer.addItem(item);
- }
- // Exposure compensation.
- if (group.findPreference(CameraSettings.KEY_EXPOSURE) != null) {
- item = makeItem(CameraSettings.KEY_EXPOSURE);
- item.setLabel(res.getString(R.string.pref_exposure_label));
- mRenderer.addItem(item);
- }
- // More settings.
- PieItem more = makeItem(R.drawable.ic_settings_holo_light);
- more.setLabel(res.getString(R.string.camera_menu_more_label));
- mRenderer.addItem(more);
-
- // Flash.
- if (group.findPreference(CameraSettings.KEY_FLASH_MODE) != null) {
- item = makeItem(CameraSettings.KEY_FLASH_MODE);
- item.setLabel(res.getString(R.string.pref_camera_flashmode_label));
- mRenderer.addItem(item);
+ mHdrItem = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR, true);
+ mRenderer.addItem(mHdrItem);
}
+
+ mOtherKeys1 = new String[] {
+ CameraSettings.KEY_SCENE_MODE,
+ CameraSettings.KEY_RECORD_LOCATION,
+ CameraSettings.KEY_PICTURE_SIZE,
+ CameraSettings.KEY_HISTOGRAM,
+ CameraSettings.KEY_JPEG_QUALITY,
+ CameraSettings.KEY_ZSL,
+ CameraSettings.KEY_TIMER,
+ CameraSettings.KEY_TIMER_SOUND_EFFECTS,
+ CameraSettings.KEY_CAMERA_SAVEPATH,
+ CameraSettings.KEY_LONGSHOT
+ };
+
+ mOtherKeys2 = new String[] {
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_FACE_DETECTION,
+ CameraSettings.KEY_FACE_RECOGNITION,
+ CameraSettings.KEY_TOUCH_AF_AEC,
+ CameraSettings.KEY_SELECTABLE_ZONE_AF,
+ CameraSettings.KEY_PICTURE_FORMAT,
+ CameraSettings.KEY_SATURATION,
+ CameraSettings.KEY_CONTRAST,
+ CameraSettings.KEY_SHARPNESS,
+ CameraSettings.KEY_AUTOEXPOSURE
+ };
+
+ mOtherKeys3 = new String[] {
+ CameraSettings.KEY_ANTIBANDING,
+ CameraSettings.KEY_ISO,
+ CameraSettings.KEY_DENOISE,
+ CameraSettings.KEY_ADVANCED_FEATURES,
+ CameraSettings.KEY_EXPOSURE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_FLASH_MODE,
+ CameraSettings.KEY_FOCUS_MODE,
+ CameraSettings.KEY_REDEYE_REDUCTION,
+ CameraSettings.KEY_AE_BRACKET_HDR
+ };
+
+ PieItem item1 = makeItem(R.drawable.ic_settings_holo_light);
+ item1.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label));
+ item1.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(PieItem item) {
+ if (mPopup1 == null || mPopupStatus != POPUP_FIRST_LEVEL){
+ initializePopup();
+ mPopupStatus = POPUP_FIRST_LEVEL;
+ }
+ mUI.showPopup(mPopup1);
+ popupNum = 1;
+ }
+ });
+ mRenderer.addItem(item1);
+
+ PieItem item2 = makeItem(R.drawable.ic_settings_holo_light);
+ item2.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label));
+ item2.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(PieItem item) {
+ if (mPopup2 == null || mPopupStatus != POPUP_FIRST_LEVEL) {
+ initializePopup();
+ mPopupStatus = POPUP_FIRST_LEVEL;
+ }
+ mUI.showPopup(mPopup2);
+ popupNum = 2;
+ }
+ });
+ mRenderer.addItem(item2);
+
+ PieItem item3= makeItem(R.drawable.ic_settings_holo_light);
+ item3.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label));
+ item3.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(PieItem item) {
+ if (mPopup3 == null || mPopupStatus != POPUP_FIRST_LEVEL) {
+ initializePopup();
+ mPopupStatus = POPUP_FIRST_LEVEL;
+ }
+ mUI.showPopup(mPopup3);
+ popupNum = 3;
+ }
+ });
+ mRenderer.addItem(item3);
+
// Camera switcher.
if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) {
item = makeSwitchItem(CameraSettings.KEY_CAMERA_ID, false);
@@ -105,79 +200,170 @@ public class PhotoMenu extends PieController
});
mRenderer.addItem(item);
}
- // Location.
- if (group.findPreference(CameraSettings.KEY_RECORD_LOCATION) != null) {
- item = makeSwitchItem(CameraSettings.KEY_RECORD_LOCATION, true);
- more.addItem(item);
- if (mActivity.isSecureCamera()) {
- // Prevent location preference from getting changed in secure camera mode
- item.setEnabled(false);
- }
- }
- // Countdown timer.
- final ListPreference ctpref = group.findPreference(CameraSettings.KEY_TIMER);
- final ListPreference beeppref = group.findPreference(CameraSettings.KEY_TIMER_SOUND_EFFECTS);
- item = makeItem(R.drawable.ic_timer);
- item.setLabel(res.getString(R.string.pref_camera_timer_title).toUpperCase(locale));
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- CountdownTimerPopup timerPopup = (CountdownTimerPopup) mActivity.getLayoutInflater().inflate(
- R.layout.countdown_setting_popup, null, false);
- timerPopup.initialize(ctpref, beeppref);
- timerPopup.setSettingChangedListener(PhotoMenu.this);
- mUI.dismissPopup();
- mPopup = timerPopup;
- mUI.showPopup(mPopup);
- }
- });
- more.addItem(item);
- // Image size.
- item = makeItem(R.drawable.ic_imagesize);
- final ListPreference sizePref = group.findPreference(CameraSettings.KEY_PICTURE_SIZE);
- item.setLabel(res.getString(R.string.pref_camera_picturesize_title).toUpperCase(locale));
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- ListPrefSettingPopup popup = (ListPrefSettingPopup) mActivity.getLayoutInflater().inflate(
- R.layout.list_pref_setting_popup, null, false);
- popup.initialize(sizePref);
- popup.setSettingChangedListener(PhotoMenu.this);
- mUI.dismissPopup();
- mPopup = popup;
- mUI.showPopup(mPopup);
- }
- });
- more.addItem(item);
- // White balance.
- if (group.findPreference(CameraSettings.KEY_WHITE_BALANCE) != null) {
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE);
- item.setLabel(res.getString(R.string.pref_camera_whitebalance_label));
- more.addItem(item);
- }
- // Scene mode.
- if (group.findPreference(CameraSettings.KEY_SCENE_MODE) != null) {
- IconListPreference pref = (IconListPreference) group.findPreference(
- CameraSettings.KEY_SCENE_MODE);
- pref.setUseSingleIcon(true);
- item = makeItem(CameraSettings.KEY_SCENE_MODE);
- more.addItem(item);
- }
}
@Override
// Hit when an item in a popup gets selected
public void onListPrefChanged(ListPreference pref) {
- if (mPopup != null) {
- mUI.dismissPopup();
+ if (mPopup != null && mPopup1 != null && mPopup2 != null && mPopup3 != null) {
+ mUI.dismissPopup();
}
onSettingChanged(pref);
}
- public void popupDismissed() {
- if (mPopup != null) {
- mPopup = null;
+ @Override
+ public void overrideSettings(final String ... keyvalues) {
+ super.overrideSettings(keyvalues);
+ if ((mPopup1 == null) && (mPopup2 == null) && (mPopup3 == null)) initializePopup();
+ mPopup1.overrideSettings(keyvalues);
+ mPopup2.overrideSettings(keyvalues);
+ mPopup3.overrideSettings(keyvalues);
+ }
+
+ protected void initializePopup() {
+ LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ MoreSettingPopup popup1 = (MoreSettingPopup) inflater.inflate(
+ R.layout.more_setting_popup, null, false);
+ popup1.setSettingChangedListener(this);
+ popup1.initialize(mPreferenceGroup, mOtherKeys1);
+ if (mActivity.isSecureCamera()) {
+ // Prevent location preference from getting changed in secure camera mode
+ popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION,false);
+ }
+ mPopup1 = popup1;
+
+ MoreSettingPopup popup2 = (MoreSettingPopup) inflater.inflate(
+ R.layout.more_setting_popup, null, false);
+ popup2.setSettingChangedListener(this);
+ popup2.initialize(mPreferenceGroup, mOtherKeys2);
+ mPopup2 = popup2;
+
+ MoreSettingPopup popup3 = (MoreSettingPopup) inflater.inflate(
+ R.layout.more_setting_popup, null, false);
+ popup3.setSettingChangedListener(this);
+ popup3.initialize(mPreferenceGroup, mOtherKeys3);
+ mPopup3 = popup3;
+
+ ListPreference pref = mPreferenceGroup.findPreference(
+ CameraSettings.KEY_SCENE_MODE);
+ String sceneMode = (pref != null) ? pref.getValue() : null;
+ pref = mPreferenceGroup.findPreference(CameraSettings.KEY_FACE_DETECTION);
+ String faceDetection = (pref != null) ? pref.getValue() : null;
+ pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ZSL);
+ String zsl = (pref != null) ? pref.getValue() : null;
+ if ((sceneMode != null) && !Parameters.SCENE_MODE_AUTO.equals(sceneMode)){
+ popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_AUTOEXPOSURE,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_SATURATION,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_CONTRAST,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_SHARPNESS,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE,false);
+ }
+ if ((zsl != null) && Parameters.ZSL_ON.equals(zsl)) {
+ popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false);
+ }
+ if ((faceDetection != null) && !Parameters.FACE_DETECTION_ON.equals(faceDetection)){
+ popup2.setPreferenceEnabled(CameraSettings.KEY_FACE_RECOGNITION,false);
+ }
+ popup1.setPreferenceEnabled(CameraSettings.KEY_ZSL, !mUI.isCountingDown());
+
+ pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ADVANCED_FEATURES);
+ String advancedFeatures = (pref != null) ? pref.getValue() : null;
+
+ String ubiFocusOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_ubifocus_on);
+ String chromaFlashOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_chromaflash_on);
+ String optiZoomOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_optizoom_on);
+
+ if ((zsl != null) && Parameters.ZSL_OFF.equals(zsl)) {
+ popup3.overrideSettings(CameraSettings.KEY_ADVANCED_FEATURES,
+ mActivity.getString(R.string.pref_camera_advanced_feature_default));
+
+ popup3.setPreferenceEnabled(CameraSettings.KEY_ADVANCED_FEATURES,false);
+ if (mHdrItem != null) {
+ mHdrItem.setEnabled(true);
+ }
+ if (mHdrPlusItem != null) {
+ mHdrPlusItem.setEnabled(true);
+ }
+ } else {
+ if ((advancedFeatures != null) && (advancedFeatures.equals(ubiFocusOn) ||
+ advancedFeatures.equals(chromaFlashOn) ||
+ advancedFeatures.equals(optiZoomOn))) {
+ popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_AE_BRACKET_HDR,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_REDEYE_REDUCTION,false);
+ popup3.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT,false);
+ popup2.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC,false);
+ popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE,false);
+
+ setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff);
+
+ if (mHdrItem != null) {
+ mHdrItem.setEnabled(false);
+ }
+ if (mHdrPlusItem != null) {
+ mHdrPlusItem.setEnabled(false);
+ }
+ } else {
+ if (mHdrItem != null) {
+ mHdrItem.setEnabled(true);
+ }
+ if (mHdrPlusItem != null) {
+ mHdrPlusItem.setEnabled(true);
+ }
+ }
+ }
+
+ if (mListener != null) {
+ mListener.onSharedPreferenceChanged();
+ }
+ }
+
+ public void popupDismissed(boolean dismissAll) {
+ if (!dismissAll && mPopupStatus == POPUP_SECOND_LEVEL) {
+ initializePopup();
+ mPopupStatus = POPUP_FIRST_LEVEL;
+ if (popupNum == 1)
+ mUI.showPopup(mPopup1);
+ else if (popupNum == 2)
+ mUI.showPopup(mPopup2);
+ else if (popupNum == 3)
+ mUI.showPopup(mPopup3);
+ if(mPopup1 != null) mPopup1 = null;
+ if(mPopup2 != null) mPopup2 = null;
+ if(mPopup3 != null) mPopup3 = null;
+ } else {
+ initializePopup();
}
+
+ }
+
+ @Override
+ // Hit when an item in the first-level popup gets selected, then bring up
+ // the second-level popup
+ public void onPreferenceClicked(ListPreference pref) {
+ if (mPopupStatus != POPUP_FIRST_LEVEL) return;
+
+ LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate(
+ R.layout.list_pref_setting_popup, null, false);
+ basic.initialize(pref);
+ basic.setSettingChangedListener(this);
+ mUI.dismissPopup();
+ mPopup = basic;
+ mUI.showPopup(mPopup);
+ mPopupStatus = POPUP_SECOND_LEVEL;
}
// Return true if the preference has the specified key but not the value.
@@ -185,7 +371,7 @@ public class PhotoMenu extends PieController
return (key.equals(pref.getKey()) && !value.equals(pref.getValue()));
}
- private void setPreference(String key, String value) {
+ public void setPreference(String key, String value) {
ListPreference pref = mPreferenceGroup.findPreference(key);
if (pref != null && !value.equals(pref.getValue())) {
pref.setValue(value);
@@ -199,9 +385,29 @@ public class PhotoMenu extends PieController
// set to non-auto.
if (notSame(pref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) {
setPreference(CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO);
+ Toast.makeText(mActivity, R.string.hdr_enable_message,
+ Toast.LENGTH_LONG).show();
+ mHdrOn = true;
} else if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) {
setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff);
+ if (mHdrOn) {
+ Toast.makeText(mActivity, R.string.scene_enable_message,
+ Toast.LENGTH_LONG).show();
+ }
+ mHdrOn = false;
+ } else if (notSame(pref,CameraSettings.KEY_AE_BRACKET_HDR,"Off")) {
+ Toast.makeText(mActivity,
+ R.string.flash_aebracket_message,Toast.LENGTH_SHORT).show();
+ setPreference(CameraSettings.KEY_FLASH_MODE,Parameters.FLASH_MODE_OFF);
+ } else if (notSame(pref,CameraSettings.KEY_FLASH_MODE,"Off")) {
+ ListPreference aePref =
+ mPreferenceGroup.findPreference(CameraSettings.KEY_AE_BRACKET_HDR);
+ if (notSame(aePref,CameraSettings.KEY_AE_BRACKET_HDR,"Off")) {
+ Toast.makeText(mActivity,
+ R.string.flash_aebracket_message,Toast.LENGTH_SHORT).show();
+ }
}
super.onSettingChanged(pref);
}
+
}
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 2afaf5bf5..3d6218281 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -30,6 +30,7 @@ import android.graphics.SurfaceTexture;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
+import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -50,6 +51,12 @@ import android.view.KeyEvent;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.WindowManager;
+import android.widget.Toast;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.LinearLayout;
+import android.widget.TextView;
import com.android.camera.CameraManager.CameraAFCallback;
import com.android.camera.CameraManager.CameraAFMoveCallback;
@@ -76,6 +83,14 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Vector;
+import java.util.HashMap;
+import android.util.AttributeSet;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.SystemProperties;
+import java.util.Collections;
+import java.util.Formatter;
public class PhotoModule
implements CameraModule,
@@ -89,6 +104,20 @@ public class PhotoModule
private static final String TAG = "CAM_PhotoModule";
+ //QCom data members
+ public static boolean mBrightnessVisible = true;
+ private static final int MAX_SHARPNESS_LEVEL = 6;
+ private boolean mRestartPreview = false;
+ private int mSnapshotMode;
+ private int mBurstSnapNum = 1;
+ private int mReceivedSnapNum = 0;
+ public boolean mFaceDetectionEnabled = false;
+
+ /*Histogram variables*/
+ private GraphView mGraphView;
+ private static final int STATS_DATA = 257;
+ public static int statsdata[] = new int[STATS_DATA];
+ public boolean mHiston = false;
// We number the request code from 1000 to avoid collision with Gallery.
private static final int REQUEST_CROP = 1000;
@@ -102,7 +131,10 @@ public class PhotoModule
private static final int CAMERA_OPEN_DONE = 8;
private static final int OPEN_CAMERA_FAIL = 9;
private static final int CAMERA_DISABLED = 10;
- private static final int SWITCH_TO_GCAM_MODULE = 11;
+ private static final int SET_SKIN_TONE_FACTOR = 11;
+ private static final int SET_PHOTO_UI_PARAMS = 12;
+ private static final int SWITCH_TO_GCAM_MODULE = 13;
+ private static final int CONFIGURE_SKIN_TONE_FACTOR = 14;
// The subset of parameters we need to update in setCameraParameters().
private static final int UPDATE_PARAM_INITIALIZE = 1;
@@ -122,6 +154,7 @@ public class PhotoModule
private int mCameraId;
private Parameters mParameters;
private boolean mPaused;
+ private View mRootView;
private PhotoUI mUI;
@@ -146,6 +179,8 @@ public class PhotoModule
private boolean mAeLockSupported;
private boolean mAwbLockSupported;
private boolean mContinuousFocusSupported;
+ private boolean mTouchAfAecFlag;
+ private boolean mLongshotSave = false;
// The degrees of the device rotated clockwise from its natural orientation.
private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
@@ -156,6 +191,33 @@ public class PhotoModule
private ContentProviderClient mMediaProviderClient;
private boolean mFaceDetectionStarted = false;
+ private static final String PERSIST_LONG_ENABLE = "persist.camera.longshot.enable";
+ private static final String PERSIST_LONG_SAVE = "persist.camera.longshot.save";
+ private static final String PERSIST_PREVIEW_RESTART = "persist.camera.feature.restart";
+
+ private static final int MINIMUM_BRIGHTNESS = 0;
+ private static final int MAXIMUM_BRIGHTNESS = 6;
+ private int mbrightness = 3;
+ private int mbrightness_step = 1;
+ private ProgressBar brightnessProgressBar;
+ // Constant from android.hardware.Camera.Parameters
+ private static final String KEY_PICTURE_FORMAT = "picture-format";
+ private static final String KEY_QC_RAW_PICUTRE_SIZE = "raw-size";
+ public static final String PIXEL_FORMAT_JPEG = "jpeg";
+
+ private static final int MIN_SCE_FACTOR = -10;
+ private static final int MAX_SCE_FACTOR = +10;
+ private int SCE_FACTOR_STEP = 10;
+ private int mskinToneValue = 0;
+ private boolean mSkinToneSeekBar= false;
+ private boolean mSeekBarInitialized = false;
+ private SeekBar skinToneSeekBar;
+ private TextView LeftValue;
+ private TextView RightValue;
+ private TextView Title;
+
+ private boolean mPreviewRestartSupport = false;
+
// mCropValue and mSaveUri are used only if isImageCaptureIntent() is true.
private String mCropValue;
private Uri mSaveUri;
@@ -215,6 +277,7 @@ public class PhotoModule
: null;
private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
+ private final StatsCallback mStatsCallback = new StatsCallback();
private long mFocusStartTime;
private long mShutterCallbackTime;
@@ -236,8 +299,10 @@ public class PhotoModule
private FocusOverlayManager mFocusManager;
private String mSceneMode;
+ private String mCurrTouchAfAec = Parameters.TOUCH_AF_AEC_ON;
private final Handler mHandler = new MainHandler();
+ private MessageQueue.IdleHandler mIdleHandler = null;
private PreferenceGroup mPreferenceGroup;
@@ -347,10 +412,47 @@ public class PhotoModule
R.string.camera_disabled);
break;
}
+ case SET_SKIN_TONE_FACTOR: {
+ Log.v(TAG, "set tone bar: mSceneMode = " + mSceneMode);
+ setSkinToneFactor();
+ mSeekBarInitialized = true;
+ // skin tone ie enabled only for party and portrait BSM
+ // when color effects are not enabled
+ String colorEffect = mPreferences.getString(
+ CameraSettings.KEY_COLOR_EFFECT,
+ mActivity.getString(R.string.pref_camera_coloreffect_default));
+ if((Parameters.SCENE_MODE_PARTY.equals(mSceneMode) ||
+ Parameters.SCENE_MODE_PORTRAIT.equals(mSceneMode))&&
+ (Parameters.EFFECT_NONE.equals(colorEffect))) {
+ ;
+ }
+ else{
+ Log.v(TAG, "Skin tone bar: disable");
+ disableSkinToneSeekBar();
+ }
+ break;
+ }
+ case SET_PHOTO_UI_PARAMS: {
+ setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
+ mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup,
+ mPreferences);
+ break;
+ }
case SWITCH_TO_GCAM_MODULE: {
mActivity.onModuleSelected(ModuleSwitcher.GCAM_MODULE_INDEX);
}
+
+ case CONFIGURE_SKIN_TONE_FACTOR: {
+ if ((mCameraDevice != null) && isCameraIdle()) {
+ synchronized (mCameraDevice) {
+ mParameters = mCameraDevice.getParameters();
+ mParameters.set("skinToneEnhancement", String.valueOf(msg.arg1));
+ mCameraDevice.setParameters(mParameters);
+ }
+ }
+ break;
+ }
}
}
}
@@ -359,6 +461,7 @@ public class PhotoModule
@Override
public void init(CameraActivity activity, View parent) {
mActivity = activity;
+ mRootView = parent;
mUI = new PhotoUI(activity, this, parent);
mPreferences = new ComboPreferences(mActivity);
CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal());
@@ -379,6 +482,23 @@ public class PhotoModule
mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
mLocationManager = new LocationManager(mActivity, mUI);
mSensorManager = (SensorManager)(mActivity.getSystemService(Context.SENSOR_SERVICE));
+
+ brightnessProgressBar = (ProgressBar)mRootView.findViewById(R.id.progress);
+ if (brightnessProgressBar instanceof SeekBar) {
+ SeekBar seeker = (SeekBar) brightnessProgressBar;
+ seeker.setOnSeekBarChangeListener(mSeekListener);
+ }
+ brightnessProgressBar.setMax(MAXIMUM_BRIGHTNESS);
+ brightnessProgressBar.setProgress(mbrightness);
+ skinToneSeekBar = (SeekBar) mRootView.findViewById(R.id.skintoneseek);
+ skinToneSeekBar.setOnSeekBarChangeListener(mskinToneSeekListener);
+ skinToneSeekBar.setVisibility(View.INVISIBLE);
+ Title = (TextView)mRootView.findViewById(R.id.skintonetitle);
+ RightValue = (TextView)mRootView.findViewById(R.id.skintoneright);
+ LeftValue = (TextView)mRootView.findViewById(R.id.skintoneleft);
+ Storage.setSaveSDCard(
+ mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
+
}
private void initializeControlByIntent() {
@@ -392,6 +512,7 @@ public class PhotoModule
setCameraState(IDLE);
startFaceDetection();
locationFirstRun();
+ mUI.enableShutter(true);
}
// Prompt the user to pick to record location for the very first run of
@@ -447,6 +568,7 @@ public class PhotoModule
int height = root.getHeight();
mFocusManager.setPreviewSize(width, height);
openCameraCommon();
+ resizeForPreviewAspectRatio();
}
private void switchCamera() {
@@ -461,6 +583,7 @@ public class PhotoModule
closeCamera();
mUI.collapseCameraControls();
mUI.clearFaces();
+ disableSkinToneSeekBar();
if (mFocusManager != null) mFocusManager.removeMessages();
// Restart the camera and initialize the UI. From onCreate.
@@ -484,6 +607,7 @@ public class PhotoModule
// reset zoom value index
mZoomValue = 0;
+ resizeForPreviewAspectRatio();
openCameraCommon();
// Start switch camera animation. Post a message because
@@ -505,13 +629,18 @@ public class PhotoModule
mUI.overrideSettings(CameraSettings.KEY_CAMERA_HDR_PLUS,
mActivity.getString(R.string.setting_off_value));
}
- updateSceneMode();
+ updateCameraSettings();
showTapToFocusToastIfNeeded();
}
@Override
+ public void onScreenSizeChanged(int width, int height) {
+ if (mFocusManager != null) mFocusManager.setPreviewSize(width, height);
+ }
+
+ @Override
public void onPreviewRectChanged(Rect previewRect) {
if (mFocusManager != null) mFocusManager.setPreviewRect(previewRect);
}
@@ -526,6 +655,29 @@ public class PhotoModule
}
}
+ void setPreviewFrameLayoutCameraOrientation(){
+ CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ //if camera mount angle is 0 or 180, we want to resize preview
+ if (info.orientation % 180 == 0){
+ mUI.cameraOrientationPreviewResize(true);
+ } else{
+ mUI.cameraOrientationPreviewResize(false);
+ }
+ }
+
+ @Override
+ public void resizeForPreviewAspectRatio() {
+ if ( mCameraDevice == null || mParameters == null) {
+ Log.e(TAG, "Camera not yet initialized");
+ return;
+ }
+ setPreviewFrameLayoutCameraOrientation();
+ Size size = mParameters.getPreviewSize();
+ Log.e(TAG,"Width = "+ size.width+ "Height = "+size.height);
+ mUI.setAspectRatio((float) size.width / size.height);
+ }
+
+
private void keepMediaProviderInstance() {
// We want to keep a reference to MediaProvider in camera's lifecycle.
// TODO: Utilize mMediaProviderClient instance to replace
@@ -560,8 +712,15 @@ public class PhotoModule
}
mNamedImages = new NamedImages();
+ mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view);
+ if(mGraphView == null){
+ Log.e(TAG, "mGraphView is null");
+ } else{
+ mGraphView.setPhotoModuleObject(this);
+ }
mFirstTimeInitialized = true;
+ Log.d(TAG, "addIdleHandler in first time initialization");
addIdleHandler();
mActivity.updateStorageSpaceAndHint();
@@ -579,6 +738,9 @@ public class PhotoModule
s.setListener(this);
}
mNamedImages = new NamedImages();
+ if (!mIsImageCaptureIntent) {
+ mUI.showSwitcher();
+ }
mUI.initializeSecondTime(mParameters);
keepMediaProviderInstance();
}
@@ -593,19 +755,32 @@ public class PhotoModule
}
private void addIdleHandler() {
- MessageQueue queue = Looper.myQueue();
- queue.addIdleHandler(new MessageQueue.IdleHandler() {
- @Override
- public boolean queueIdle() {
- Storage.ensureOSXCompatible();
- return false;
- }
- });
+ if (mIdleHandler == null) {
+ mIdleHandler = new MessageQueue.IdleHandler() {
+ @Override
+ public boolean queueIdle() {
+ Storage.ensureOSXCompatible();
+ return false;
+ }
+ };
+
+ MessageQueue queue = Looper.myQueue();
+ queue.addIdleHandler(mIdleHandler);
+ }
+ }
+
+ private void removeIdleHandler() {
+ if (mIdleHandler != null) {
+ MessageQueue queue = Looper.myQueue();
+ queue.removeIdleHandler(mIdleHandler);
+ mIdleHandler = null;
+ }
}
@Override
public void startFaceDetection() {
- if (mFaceDetectionStarted) return;
+ if (mFaceDetectionEnabled == false
+ || mFaceDetectionStarted || mCameraState != IDLE) return;
if (mParameters.getMaxNumDetectedFaces() > 0) {
mFaceDetectionStarted = true;
CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
@@ -618,7 +793,7 @@ public class PhotoModule
@Override
public void stopFaceDetection() {
- if (!mFaceDetectionStarted) return;
+ if (mFaceDetectionEnabled == false || !mFaceDetectionStarted) return;
if (mParameters.getMaxNumDetectedFaces() > 0) {
mFaceDetectionStarted = false;
mCameraDevice.setFaceDetectionCallback(null, null);
@@ -627,6 +802,34 @@ public class PhotoModule
}
}
+ private final class LongshotShutterCallback
+ implements CameraShutterCallback {
+
+ @Override
+ public void onShutter(CameraProxy camera) {
+ mShutterCallbackTime = System.currentTimeMillis();
+ mShutterLag = mShutterCallbackTime - mCaptureStartTime;
+ Log.e(TAG, "[KPI Perf] PROFILE_SHUTTER_LAG mShutterLag = " + mShutterLag + "ms");
+ synchronized(mCameraDevice) {
+
+ if (mCameraState != LONGSHOT) {
+ return;
+ }
+
+ if (mLongshotSave) {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new LongshotPictureCallback(null));
+ } else {
+ mCameraDevice.takePicture(mHandler,new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(null));
+ }
+ }
+ }
+ }
+
private final class ShutterCallback
implements CameraShutterCallback {
@@ -640,7 +843,7 @@ public class PhotoModule
public void onShutter(CameraProxy camera) {
mShutterCallbackTime = System.currentTimeMillis();
mShutterLag = mShutterCallbackTime - mCaptureStartTime;
- Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
+ Log.e(TAG, "[KPI Perf] PROFILE_SHUTTER_LAG mShutterLag = " + mShutterLag + "ms");
if (mNeedsAnimation) {
mActivity.runOnUiThread(new Runnable() {
@Override
@@ -651,7 +854,26 @@ public class PhotoModule
}
}
}
-
+ private final class StatsCallback
+ implements android.hardware.Camera.CameraDataCallback {
+ @Override
+ public void onCameraData(int [] data, android.hardware.Camera camera) {
+ //if(!mPreviewing || !mHiston || !mFirstTimeInitialized){
+ if(!mHiston || !mFirstTimeInitialized){
+ return;
+ }
+ /*The first element in the array stores max hist value . Stats data begin from second value*/
+ synchronized(statsdata) {
+ System.arraycopy(data,0,statsdata,0,STATS_DATA);
+ }
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if(mGraphView != null)
+ mGraphView.PreviewChanged();
+ }
+ });
+ }
+ }
private final class PostViewPictureCallback
implements CameraPictureCallback {
@Override
@@ -673,6 +895,64 @@ public class PhotoModule
}
}
+ private final class LongshotPictureCallback implements CameraPictureCallback {
+ Location mLocation;
+
+ public LongshotPictureCallback(Location loc) {
+ mLocation = loc;
+ }
+
+ @Override
+ public void onPictureTaken(final byte [] jpegData, CameraProxy camera) {
+ if (mPaused) {
+ return;
+ }
+
+ mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
+
+ String jpegFilePath = new String(jpegData);
+ mNamedImages.nameNewImage(mCaptureStartTime);
+ NamedEntity name = mNamedImages.getNextNameEntity();
+ String title = (name == null) ? null : name.title;
+ long date = (name == null) ? -1 : name.date;
+
+ if (title == null) {
+ Log.e(TAG, "Unbalanced name/data pair");
+ return;
+ }
+
+
+ if (date == -1 ) {
+ Log.e(TAG, "Invalid filename date");
+ return;
+ }
+
+ String dstPath = Storage.DIRECTORY;
+ File sdCard = android.os.Environment.getExternalStorageDirectory();
+ File dstFile = new File(dstPath);
+ if (dstFile == null) {
+ Log.e(TAG, "Destination file path invalid");
+ return;
+ }
+
+ File srcFile = new File(jpegFilePath);
+ if (srcFile == null) {
+ Log.e(TAG, "Source file path invalid");
+ return;
+ }
+
+ if ( srcFile.renameTo(dstFile) ) {
+ Size s = mParameters.getPictureSize();
+ String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT);
+ mActivity.getMediaSaveService().addImage(
+ null, title, date, mLocation, s.width, s.height,
+ 0, null, mOnMediaSavedListener, mContentResolver, pictureFormat);
+ } else {
+ Log.e(TAG, "Failed to move jpeg file");
+ }
+ }
+ }
+
private final class JpegPictureCallback
implements CameraPictureCallback {
Location mLocation;
@@ -695,7 +975,15 @@ public class PhotoModule
mUI.setSwipingEnabled(true);
}
+ mReceivedSnapNum = mReceivedSnapNum + 1;
mJpegPictureCallbackTime = System.currentTimeMillis();
+ if(mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
+ Log.v(TAG, "JpegPictureCallback : in zslmode");
+ mParameters = mCameraDevice.getParameters();
+ mBurstSnapNum = mParameters.getInt("num-snaps-per-shutter");
+ }
+ Log.v(TAG, "JpegPictureCallback: Received = " + mReceivedSnapNum +
+ "Burst count = " + mBurstSnapNum);
// If postview callback has arrived, the captured image is displayed
// in postview callback. If not, the captured image is displayed in
// raw picture callback.
@@ -714,14 +1002,37 @@ public class PhotoModule
+ mPictureDisplayedToJpegCallbackTime + "ms");
mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
- if (!mIsImageCaptureIntent) {
+
+ boolean needRestartPreview = !mIsImageCaptureIntent
+ && !mPreviewRestartSupport
+ && (mCameraState != LONGSHOT)
+ && (mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL)
+ && (mReceivedSnapNum == mBurstSnapNum);
+ if (needRestartPreview) {
setupPreview();
+ if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(
+ mFocusManager.getFocusMode())) {
+ mCameraDevice.cancelAutoFocus();
+ }
+ }else if ((mReceivedSnapNum == mBurstSnapNum)
+ && (mCameraState != LONGSHOT)){
+ mFocusManager.resetTouchFocus();
+ if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(
+ mFocusManager.getFocusMode())) {
+ mCameraDevice.cancelAutoFocus();
+ }
+ mUI.resumeFaceDetection();
+ setCameraState(IDLE);
}
ExifInterface exif = Exif.getExif(jpegData);
int orientation = Exif.getOrientation(exif);
if (!mIsImageCaptureIntent) {
+ // Burst snapshot. Generate new image name.
+ if (mReceivedSnapNum > 1)
+ mNamedImages.nameNewImage(mCaptureStartTime);
+
// Calculate the width and the height of the jpeg.
Size s = mParameters.getPictureSize();
int width, height;
@@ -732,6 +1043,19 @@ public class PhotoModule
width = s.height;
height = s.width;
}
+
+ String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT);
+ if (pictureFormat != null && !pictureFormat.equalsIgnoreCase(PIXEL_FORMAT_JPEG)) {
+ // overwrite width and height if raw picture
+ String pair = mParameters.get(KEY_QC_RAW_PICUTRE_SIZE);
+ if (pair != null) {
+ int pos = pair.indexOf('x');
+ if (pos != -1) {
+ width = Integer.parseInt(pair.substring(0, pos));
+ height = Integer.parseInt(pair.substring(pos + 1));
+ }
+ }
+ }
NamedEntity name = mNamedImages.getNextNameEntity();
String title = (name == null) ? null : name.title;
long date = (name == null) ? -1 : name.date;
@@ -762,12 +1086,22 @@ public class PhotoModule
exif.setTag(directionRefTag);
exif.setTag(directionTag);
}
+ String mPictureFormat = mParameters.get(KEY_PICTURE_FORMAT);
mActivity.getMediaSaveService().addImage(
jpegData, title, date, mLocation, width, height,
- orientation, exif, mOnMediaSavedListener, mContentResolver);
+ orientation, exif, mOnMediaSavedListener, mContentResolver, mPictureFormat);
}
// Animate capture with real jpeg data instead of a preview frame.
- mUI.animateCapture(jpegData, orientation, mMirror);
+ if (mCameraState != LONGSHOT) {
+ Size pic_size = mParameters.getPictureSize();
+ if ((pic_size.width <= 352) && (pic_size.height<= 288)) {
+ mUI.setDownFactor(2); //Downsample by 2 for CIF & below
+ }
+ else {
+ mUI.setDownFactor(4);
+ }
+ mUI.animateCapture(jpegData, orientation, mMirror);
+ }
} else {
mJpegImageData = jpegData;
if (!mQuickCapture) {
@@ -787,10 +1121,69 @@ public class PhotoModule
mJpegCallbackFinishTime = now - mJpegPictureCallbackTime;
Log.v(TAG, "mJpegCallbackFinishTime = "
+ mJpegCallbackFinishTime + "ms");
- mJpegPictureCallbackTime = 0;
+
+ if (mReceivedSnapNum == mBurstSnapNum)
+ mJpegPictureCallbackTime = 0;
+
+ if (mHiston && (mSnapshotMode ==CameraInfo.CAMERA_SUPPORT_MODE_ZSL)) {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if (mGraphView != null) {
+ mGraphView.setVisibility(View.VISIBLE);
+ mGraphView.PreviewChanged();
+ }
+ }
+ });
+ }
+ if (mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL &&
+ mCameraState != LONGSHOT &&
+ mReceivedSnapNum == mBurstSnapNum) {
+ cancelAutoFocus();
+ }
}
}
+ private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
+ public void onStartTrackingTouch(SeekBar bar) {
+ // no support
+ }
+ public void onProgressChanged(SeekBar bar, int progress, boolean fromtouch) {
+ }
+ public void onStopTrackingTouch(SeekBar bar) {
+ }
+ };
+
+ private OnSeekBarChangeListener mskinToneSeekListener = new OnSeekBarChangeListener() {
+ public void onStartTrackingTouch(SeekBar bar) {
+ // no support
+ }
+ public void onProgressChanged(SeekBar bar, int progress, boolean fromtouch) {
+ int value = (progress + MIN_SCE_FACTOR) * SCE_FACTOR_STEP;
+ if(progress > (MAX_SCE_FACTOR - MIN_SCE_FACTOR)/2){
+ RightValue.setText(String.valueOf(value));
+ LeftValue.setText("");
+ } else if (progress < (MAX_SCE_FACTOR - MIN_SCE_FACTOR)/2){
+ LeftValue.setText(String.valueOf(value));
+ RightValue.setText("");
+ } else {
+ LeftValue.setText("");
+ RightValue.setText("");
+ }
+ if (value != mskinToneValue && mCameraDevice != null) {
+ mskinToneValue = value;
+ Message msg = mHandler.obtainMessage(CONFIGURE_SKIN_TONE_FACTOR, mskinToneValue, 0);
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ public void onStopTrackingTouch(SeekBar bar) {
+ Log.v(TAG, "Set onStopTrackingTouch mskinToneValue = " + mskinToneValue);
+ Editor editor = mPreferences.edit();
+ editor.putString(CameraSettings.KEY_SKIN_TONE_ENHANCEMENT_FACTOR,
+ Integer.toString(mskinToneValue));
+ editor.apply();
+ }
+ };
private final class AutoFocusCallback implements CameraAFCallback {
@Override
public void onAutoFocus(
@@ -799,7 +1192,16 @@ public class PhotoModule
mAutoFocusTime = System.currentTimeMillis() - mFocusStartTime;
Log.v(TAG, "mAutoFocusTime = " + mAutoFocusTime + "ms");
- setCameraState(IDLE);
+ //don't reset the camera state while capture is in progress
+ //otherwise, it might result in another takepicture
+ switch (mCameraState) {
+ case PhotoController.LONGSHOT:
+ case SNAPSHOT_IN_PROGRESS:
+ break;
+ default:
+ setCameraState(IDLE);
+ break;
+ }
mFocusManager.onAutoFocus(focused, mUI.isShutterPressed());
}
}
@@ -851,6 +1253,7 @@ public class PhotoModule
switch (state) {
case PhotoController.PREVIEW_STOPPED:
case PhotoController.SNAPSHOT_IN_PROGRESS:
+ case PhotoController.LONGSHOT:
case PhotoController.SWITCHING_CAMERA:
mUI.enableGestures(false);
break;
@@ -884,6 +1287,18 @@ public class PhotoModule
mJpegImageData = null;
final boolean animateBefore = (mSceneMode == CameraUtil.SCENE_MODE_HDR);
+ if(mHiston) {
+ if (mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
+ mHiston = false;
+ mCameraDevice.setHistogramMode(null);
+ }
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if(mGraphView != null)
+ mGraphView.setVisibility(View.INVISIBLE);
+ }
+ });
+ }
if (animateBefore) {
animateAfterShutter();
@@ -900,22 +1315,55 @@ public class PhotoModule
}
mJpegRotation = CameraUtil.getJpegRotation(mCameraId, orientation);
mParameters.setRotation(mJpegRotation);
- Location loc = mLocationManager.getCurrentLocation();
+ String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT);
+ Location loc = null;
+ if (pictureFormat != null &&
+ PIXEL_FORMAT_JPEG.equalsIgnoreCase(pictureFormat)) {
+ loc = mLocationManager.getCurrentLocation();
+ }
CameraUtil.setGpsParameters(mParameters, loc);
mCameraDevice.setParameters(mParameters);
+ mParameters = mCameraDevice.getParameters();
+
+ mBurstSnapNum = mParameters.getInt("num-snaps-per-shutter");
+ mReceivedSnapNum = 0;
+ mPreviewRestartSupport = SystemProperties.getBoolean(
+ PERSIST_PREVIEW_RESTART, false);
+ mPreviewRestartSupport &= CameraSettings.isInternalPreviewSupported(
+ mParameters);
+ mPreviewRestartSupport &= (mBurstSnapNum == 1);
+ mPreviewRestartSupport &= PIXEL_FORMAT_JPEG.equalsIgnoreCase(
+ pictureFormat);
// We don't want user to press the button again while taking a
// multi-second HDR photo.
mUI.enableShutter(false);
- mCameraDevice.takePicture(mHandler,
- new ShutterCallback(!animateBefore),
- mRawPictureCallback, mPostViewPictureCallback,
- new JpegPictureCallback(loc));
+
+ if (mCameraState == LONGSHOT) {
+ if(mLongshotSave) {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new LongshotPictureCallback(loc));
+ } else {
+ mCameraDevice.takePicture(mHandler,
+ new LongshotShutterCallback(),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(loc));
+ }
+ } else {
+ mCameraDevice.takePicture(mHandler,
+ new ShutterCallback(!animateBefore),
+ mRawPictureCallback, mPostViewPictureCallback,
+ new JpegPictureCallback(loc));
+ setCameraState(SNAPSHOT_IN_PROGRESS);
+ }
mNamedImages.nameNewImage(mCaptureStartTime);
- mFaceDetectionStarted = false;
- setCameraState(SNAPSHOT_IN_PROGRESS);
+ if (mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
+ mFaceDetectionStarted = false;
+ }
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_CAPTURE_DONE, "Photo", 0,
UsageStatistics.hashFileName(mNamedImages.mQueue.lastElement().title + ".jpg"));
@@ -938,29 +1386,168 @@ public class PhotoModule
}
}
- private void updateSceneMode() {
- // If scene mode is set, we cannot set flash mode, white balance, and
- // focus mode, instead, we read it from driver
+ private void updateCameraSettings() {
+ String sceneMode = null;
+ String flashMode = null;
+ String redeyeReduction = null;
+ String aeBracketing = null;
+ String focusMode = null;
+ String colorEffect = null;
+ String exposureCompensation = null;
+ String touchAfAec = null;
+
+ String ubiFocusOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_ubifocus_on);
+ String continuousShotOn =
+ mActivity.getString(R.string.setting_on_value);
+ String chromaFlashOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_chromaflash_on);
+ String optiZoomOn = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_optizoom_on);
+ String optiZoom =
+ mParameters.get(CameraSettings.KEY_QC_OPTI_ZOOM);
+ String chromaFlash =
+ mParameters.get(CameraSettings.KEY_QC_CHROMA_FLASH);
+ String ubiFocus =
+ mParameters.get(CameraSettings.KEY_QC_AF_BRACKETING);
+ String continuousShot =
+ mParameters.get("long-shot");
+
+ if ((continuousShot != null) && continuousShot.equals(continuousShotOn)) {
+ String pictureFormat = mActivity.getString(R.string.
+ pref_camera_picture_format_value_jpeg);
+ mUI.overrideSettings(CameraSettings.KEY_PICTURE_FORMAT, pictureFormat);
+ } else {
+ mUI.overrideSettings(CameraSettings.KEY_PICTURE_FORMAT, null);
+ }
+ if ((ubiFocus != null && ubiFocus.equals(ubiFocusOn)) ||
+ (chromaFlash != null && chromaFlash.equals(chromaFlashOn)) ||
+ (optiZoom != null && optiZoom.equals(optiZoomOn))) {
+ mSceneMode = sceneMode = Parameters.SCENE_MODE_AUTO;
+ flashMode = Parameters.FLASH_MODE_OFF;
+ focusMode = Parameters.FOCUS_MODE_INFINITY;
+ redeyeReduction = mActivity.getString(R.string.
+ pref_camera_redeyereduction_entry_disable);
+ aeBracketing = mActivity.getString(R.string.
+ pref_camera_ae_bracket_hdr_entry_off);
+ colorEffect = mActivity.getString(R.string.
+ pref_camera_coloreffect_default);
+ exposureCompensation = CameraSettings.EXPOSURE_DEFAULT_VALUE;
+
+ overrideCameraSettings(flashMode, null, focusMode,
+ exposureCompensation, touchAfAec, null,
+ null, null, null, colorEffect,
+ sceneMode, redeyeReduction, aeBracketing);
+ }
+
+ // If scene mode is set, for flash mode, white balance and focus mode
+ // read settings from preferences so we retain user preferences.
if (!Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
- overrideCameraSettings(mParameters.getFlashMode(),
- mParameters.getWhiteBalance(), mParameters.getFocusMode());
+ flashMode = mPreferences.getString(
+ CameraSettings.KEY_FLASH_MODE,
+ mActivity.getString(R.string.pref_camera_flashmode_default));
+ String whiteBalance = mPreferences.getString(
+ CameraSettings.KEY_WHITE_BALANCE,
+ mActivity.getString(R.string.pref_camera_whitebalance_default));
+ focusMode = mFocusManager.getFocusMode();
+ colorEffect = mParameters.getColorEffect();
+ exposureCompensation =
+ Integer.toString(mParameters.getExposureCompensation());
+ touchAfAec = mCurrTouchAfAec;
+
+ overrideCameraSettings(flashMode, whiteBalance, focusMode,
+ exposureCompensation, touchAfAec,
+ mParameters.getAutoExposure(),
+ Integer.toString(mParameters.getSaturation()),
+ Integer.toString(mParameters.getContrast()),
+ Integer.toString(mParameters.getSharpness()),
+ colorEffect,
+ sceneMode, redeyeReduction, aeBracketing);
+ if (CameraUtil.SCENE_MODE_HDR.equals(mSceneMode)) {
+ mUI.overrideSettings(CameraSettings.KEY_LONGSHOT,
+ mActivity.getString(R.string.setting_off_value));
+ }
+ } else if (mFocusManager.isZslEnabled()) {
+ focusMode = mParameters.getFocusMode();
+ overrideCameraSettings(flashMode, null, focusMode,
+ exposureCompensation, touchAfAec, null,
+ null, null, null, colorEffect,
+ sceneMode, redeyeReduction, aeBracketing);
} else {
- overrideCameraSettings(null, null, null);
+ overrideCameraSettings(flashMode, null, focusMode,
+ exposureCompensation, touchAfAec, null,
+ null, null, null, colorEffect,
+ sceneMode, redeyeReduction, aeBracketing);
+ }
+ /* Disable focus if aebracket is ON */
+ String aeBracket = mParameters.get(CameraSettings.KEY_QC_AE_BRACKETING);
+ if (!aeBracket.equalsIgnoreCase("off")) {
+ String fMode = Parameters.FLASH_MODE_OFF;
+ mUI.overrideSettings(CameraSettings.KEY_FLASH_MODE, fMode);
+ mParameters.setFlashMode(fMode);
+ }
+ if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
+ mUI.overrideSettings(CameraSettings.KEY_LONGSHOT, null);
}
}
private void overrideCameraSettings(final String flashMode,
- final String whiteBalance, final String focusMode) {
+ final String whiteBalance, final String focusMode,
+ final String exposureMode, final String touchMode,
+ final String autoExposure, final String saturation,
+ final String contrast, final String sharpness,
+ final String coloreffect, final String sceneMode,
+ final String redeyeReduction, final String aeBracketing) {
mUI.overrideSettings(
CameraSettings.KEY_FLASH_MODE, flashMode,
CameraSettings.KEY_WHITE_BALANCE, whiteBalance,
- CameraSettings.KEY_FOCUS_MODE, focusMode);
+ CameraSettings.KEY_FOCUS_MODE, focusMode,
+ CameraSettings.KEY_EXPOSURE, exposureMode,
+ CameraSettings.KEY_TOUCH_AF_AEC, touchMode,
+ CameraSettings.KEY_AUTOEXPOSURE, autoExposure,
+ CameraSettings.KEY_SATURATION, saturation,
+ CameraSettings.KEY_CONTRAST, contrast,
+ CameraSettings.KEY_SHARPNESS, sharpness,
+ CameraSettings.KEY_COLOR_EFFECT, coloreffect,
+ CameraSettings.KEY_SCENE_MODE, sceneMode,
+ CameraSettings.KEY_REDEYE_REDUCTION, redeyeReduction,
+ CameraSettings.KEY_AE_BRACKET_HDR, aeBracketing);
}
private void loadCameraPreferences() {
CameraSettings settings = new CameraSettings(mActivity, mInitialParams,
mCameraId, CameraHolder.instance().getCameraInfo());
mPreferenceGroup = settings.getPreferenceGroup(R.xml.camera_preferences);
+
+ int numOfCams = Camera.getNumberOfCameras();
+ int backCamId = CameraHolder.instance().getBackCameraId();
+ int frontCamId = CameraHolder.instance().getFrontCameraId();
+ // We need to swap the list preference contents if back camera and front camera
+ // IDs are not 0 and 1 respectively
+ if ((numOfCams == 2) && ((backCamId != CameraInfo.CAMERA_FACING_BACK)
+ || (frontCamId != CameraInfo.CAMERA_FACING_FRONT))) {
+ Log.e(TAG,"loadCameraPreferences() updating camera_id pref");
+
+ IconListPreference switchIconPref =
+ (IconListPreference)mPreferenceGroup.findPreference(
+ CameraSettings.KEY_CAMERA_ID);
+
+ int[] iconIds = {R.drawable.ic_switch_front, R.drawable.ic_switch_back};
+ switchIconPref.setIconIds(iconIds);
+
+ String[] entries = {mActivity.getResources().getString(
+ R.string.pref_camera_id_entry_front), mActivity.getResources().
+ getString(R.string.pref_camera_id_entry_back)};
+ switchIconPref.setEntries(entries);
+
+ String[] labels = {mActivity.getResources().getString(
+ R.string.pref_camera_id_label_front), mActivity.getResources().
+ getString(R.string.pref_camera_id_label_back)};
+ switchIconPref.setLabels(labels);
+
+ int[] largeIconIds = {R.drawable.ic_switch_front, R.drawable.ic_switch_back};
+ switchIconPref.setLargeIconIds(largeIconIds);
+ }
}
@Override
@@ -969,13 +1556,27 @@ public class PhotoModule
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return;
+ int oldOrientation = mOrientation;
mOrientation = CameraUtil.roundOrientation(orientation, mOrientation);
+ if (oldOrientation != mOrientation) {
+ Log.v(TAG, "onOrientationChanged, update parameters");
+ if (mParameters != null && mCameraDevice != null) {
+ onSharedPreferenceChanged();
+ }
+ }
// Show the toast after getting the first orientation changed.
if (mHandler.hasMessages(SHOW_TAP_TO_FOCUS_TOAST)) {
mHandler.removeMessages(SHOW_TAP_TO_FOCUS_TOAST);
showTapToFocusToast();
}
+
+ // need to re-initialize mGraphView to show histogram on rotate
+ mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view);
+ if(mGraphView != null){
+ mGraphView.setPhotoModuleObject(this);
+ mGraphView.PreviewChanged();
+ }
}
@Override
@@ -1089,6 +1690,23 @@ public class PhotoModule
|| (mCameraState == SNAPSHOT_IN_PROGRESS)
|| (mCameraState == PREVIEW_STOPPED)) return;
+ synchronized(mCameraDevice) {
+ if (mCameraState == LONGSHOT) {
+ mCameraDevice.setLongshot(false);
+ if (!mFocusManager.isZslEnabled()) {
+ setupPreview();
+ } else {
+ setCameraState(IDLE);
+ mFocusManager.resetTouchFocus();
+ if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(
+ mFocusManager.getFocusMode())) {
+ mCameraDevice.cancelAutoFocus();
+ }
+ mUI.resumeFaceDetection();
+ }
+ }
+ }
+
// Do not do focus if there is not enough storage.
if (pressed && !canTakePicture()) return;
@@ -1121,6 +1739,14 @@ public class PhotoModule
mUI.hideSwitcher();
mUI.setSwipingEnabled(false);
}
+
+ //Need to disable focus for ZSL mode
+ if(mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL) {
+ mFocusManager.setZslEnable(true);
+ } else {
+ mFocusManager.setZslEnable(false);
+ }
+
// If the user wants to do a snapshot while the previous one is still
// in progress, remember the fact and do it after we finish the previous
// one and re-start the preview. Snapshot in progress also includes the
@@ -1146,6 +1772,9 @@ public class PhotoModule
mUI.cancelCountDown();
}
if (seconds > 0) {
+ String zsl = mPreferences.getString(CameraSettings.KEY_ZSL,
+ mActivity.getString(R.string.pref_camera_zsl_default));
+ mUI.overrideSettings(CameraSettings.KEY_ZSL, zsl);
mUI.startCountDown(seconds, playSound);
} else {
mSnapshotOnIdle = false;
@@ -1154,6 +1783,32 @@ public class PhotoModule
}
@Override
+ public void onShutterButtonLongClick() {
+ // Do not take the picture if there is not enough storage.
+ if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
+ Log.i(TAG, "Not enough space or storage not ready. remaining="
+ + mActivity.getStorageSpaceBytes());
+ return;
+ }
+
+ if ((null != mCameraDevice) && ((mCameraState == IDLE) || (mCameraState == FOCUSING))) {
+ //Add on/off Menu for longshot
+ String longshot_enable = mPreferences.getString(
+ CameraSettings.KEY_LONGSHOT,
+ mActivity.getString(R.string.pref_camera_longshot_default));
+
+ Log.d(TAG, "longshot_enable = " + longshot_enable);
+ if (longshot_enable.equals("on")) {
+ boolean enable = SystemProperties.getBoolean(PERSIST_LONG_SAVE, false);
+ mLongshotSave = enable;
+ mCameraDevice.setLongshot(true);
+ setCameraState(PhotoController.LONGSHOT);
+ mFocusManager.doSnap();
+ }
+ }
+ }
+
+ @Override
public void installIntentFilter() {
// Do nothing.
}
@@ -1212,6 +1867,12 @@ public class PhotoModule
Log.v(TAG, "On resume.");
onResumeTasks();
}
+ mHandler.post(new Runnable(){
+ @Override
+ public void run(){
+ mActivity.updateStorageSpaceAndHint();
+ }
+ });
}
private void onResumeTasks() {
@@ -1226,6 +1887,11 @@ public class PhotoModule
return;
}
+ if (mSkinToneSeekBar != true)
+ {
+ Log.v(TAG, "Send tone bar: mSkinToneSeekBar = " + mSkinToneSeekBar);
+ mHandler.sendEmptyMessage(SET_SKIN_TONE_FACTOR);
+ }
// If first time initialization is not finished, put it in the
// message queue.
if (!mFirstTimeInitialized) {
@@ -1262,6 +1928,9 @@ public class PhotoModule
if (msensor != null) {
mSensorManager.unregisterListener(this, msensor);
}
+
+ Log.d(TAG, "remove idle handleer in onPause");
+ removeIdleHandler();
}
@Override
@@ -1329,6 +1998,7 @@ public class PhotoModule
public void onConfigurationChanged(Configuration newConfig) {
Log.v(TAG, "onConfigurationChanged");
setDisplayOrientation();
+ resizeForPreviewAspectRatio();
}
@Override
@@ -1361,6 +2031,10 @@ public class PhotoModule
}
}
+ protected CameraManager.CameraProxy getCamera() {
+ return mCameraDevice;
+ }
+
private boolean canTakePicture() {
return isCameraIdle() && (mActivity.getStorageSpaceBytes() > Storage.LOW_STORAGE_THRESHOLD_BYTES);
}
@@ -1374,9 +2048,11 @@ public class PhotoModule
@Override
public void cancelAutoFocus() {
- mCameraDevice.cancelAutoFocus();
- setCameraState(IDLE);
- setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ if (null != mCameraDevice ) {
+ mCameraDevice.cancelAutoFocus();
+ setCameraState(IDLE);
+ setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ }
}
// Preview area is touched. Handle touch focus.
@@ -1388,7 +2064,10 @@ public class PhotoModule
|| mCameraState == PREVIEW_STOPPED) {
return;
}
-
+ //If Touch AF/AEC is disabled in UI, return
+ if(this.mTouchAfAecFlag == false) {
+ return;
+ }
// Check if metering area or focus area is supported.
if (!mFocusAreaSupported && !mMeteringAreaSupported) return;
mFocusManager.onSingleTapUp(x, y);
@@ -1417,6 +2096,40 @@ public class PhotoModule
onShutterButtonClick();
}
return true;
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if ( (mCameraState != PREVIEW_STOPPED) &&
+ (mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&
+ (mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {
+ if (mbrightness > MINIMUM_BRIGHTNESS) {
+ mbrightness-=mbrightness_step;
+ synchronized (mCameraDevice) {
+ /* Set the "luma-adaptation" parameter */
+ mParameters = mCameraDevice.getParameters();
+ mParameters.set("luma-adaptation", String.valueOf(mbrightness));
+ mCameraDevice.setParameters(mParameters);
+ }
+ }
+ brightnessProgressBar.setProgress(mbrightness);
+ brightnessProgressBar.setVisibility(View.VISIBLE);
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if ( (mCameraState != PREVIEW_STOPPED) &&
+ (mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING) &&
+ (mFocusManager.getCurrentFocusState() != mFocusManager.STATE_FOCUSING_SNAP_ON_FINISH) ) {
+ if (mbrightness < MAXIMUM_BRIGHTNESS) {
+ mbrightness+=mbrightness_step;
+ synchronized (mCameraDevice) {
+ /* Set the "luma-adaptation" parameter */
+ mParameters = mCameraDevice.getParameters();
+ mParameters.set("luma-adaptation", String.valueOf(mbrightness));
+ mCameraDevice.setParameters(mParameters);
+ }
+ }
+ brightnessProgressBar.setProgress(mbrightness);
+ brightnessProgressBar.setVisibility(View.VISIBLE);
+ }
+ break;
case KeyEvent.KEYCODE_DPAD_CENTER:
// If we get a dpad center event without any focused view, move
// the focus to the shutter button and press it.
@@ -1547,7 +2260,6 @@ public class PhotoModule
if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
Log.v(TAG, "stopPreview");
mCameraDevice.stopPreview();
- mFaceDetectionStarted = false;
}
setCameraState(PREVIEW_STOPPED);
if (mFocusManager != null) mFocusManager.onPreviewStopped();
@@ -1577,10 +2289,402 @@ public class PhotoModule
private void updateCameraParametersZoom() {
// Set zoom.
if (mParameters.isZoomSupported()) {
+ Parameters p = mCameraDevice.getParameters();
+ mZoomValue = p.getZoom();
mParameters.setZoom(mZoomValue);
}
}
+ private boolean needRestart() {
+ mRestartPreview = false;
+ String zsl = mPreferences.getString(CameraSettings.KEY_ZSL,
+ mActivity.getString(R.string.pref_camera_zsl_default));
+ if(zsl.equals("on") && mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL
+ && mCameraState != PREVIEW_STOPPED) {
+ //Switch on ZSL Camera mode
+ Log.v(TAG, "Switching to ZSL Camera Mode. Restart Preview");
+ mRestartPreview = true;
+ return mRestartPreview;
+ }
+ if(zsl.equals("off") && mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_NONZSL
+ && mCameraState != PREVIEW_STOPPED) {
+ //Switch on Normal Camera mode
+ Log.v(TAG, "Switching to Normal Camera Mode. Restart Preview");
+ mRestartPreview = true;
+ return mRestartPreview;
+ }
+ return mRestartPreview;
+ }
+
+ private void qcomUpdateAdvancedFeatures(String ubiFocus,
+ String chromaFlash,
+ String optiZoom) {
+ if (CameraUtil.isSupported(ubiFocus,
+ CameraSettings.getSupportedAFBracketingModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_AF_BRACKETING, ubiFocus);
+ }
+ if (CameraUtil.isSupported(chromaFlash,
+ CameraSettings.getSupportedChromaFlashModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_CHROMA_FLASH, chromaFlash);
+ }
+ if (CameraUtil.isSupported(optiZoom,
+ CameraSettings.getSupportedOptiZoomModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_OPTI_ZOOM, optiZoom);
+ }
+ }
+ private void qcomUpdateCameraParametersPreference() {
+ //qcom Related Parameter update
+ //Set Brightness.
+ mParameters.set("luma-adaptation", String.valueOf(mbrightness));
+
+ String longshot_enable = mPreferences.getString(
+ CameraSettings.KEY_LONGSHOT,
+ mActivity.getString(R.string.pref_camera_longshot_default));
+ mParameters.set("long-shot", longshot_enable);
+
+ if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode) ||
+ CameraUtil.SCENE_MODE_HDR.equals(mSceneMode)) {
+ // Set Touch AF/AEC parameter.
+ String touchAfAec = mPreferences.getString(
+ CameraSettings.KEY_TOUCH_AF_AEC,
+ mActivity.getString(R.string.pref_camera_touchafaec_default));
+ if (CameraUtil.isSupported(touchAfAec, mParameters.getSupportedTouchAfAec())) {
+ mCurrTouchAfAec = touchAfAec;
+ mParameters.setTouchAfAec(touchAfAec);
+ }
+ } else {
+ mParameters.setTouchAfAec(mParameters.TOUCH_AF_AEC_OFF);
+ mFocusManager.resetTouchFocus();
+ }
+ try {
+ if(mParameters.getTouchAfAec().equals(mParameters.TOUCH_AF_AEC_ON))
+ this.mTouchAfAecFlag = true;
+ else
+ this.mTouchAfAecFlag = false;
+ } catch(Exception e){
+ Log.e(TAG, "Handled NULL pointer Exception");
+ }
+
+ // Set Picture Format
+ // Picture Formats specified in UI should be consistent with
+ // PIXEL_FORMAT_JPEG and PIXEL_FORMAT_RAW constants
+ String pictureFormat = mPreferences.getString(
+ CameraSettings.KEY_PICTURE_FORMAT,
+ mActivity.getString(R.string.pref_camera_picture_format_default));
+
+ //Change picture format to JPEG if camera is start from other APK by intent.
+ if (mIsImageCaptureIntent && !pictureFormat.equals(PIXEL_FORMAT_JPEG)) {
+ pictureFormat = PIXEL_FORMAT_JPEG;
+ Editor editor = mPreferences.edit();
+ editor.putString(CameraSettings.KEY_PICTURE_FORMAT,
+ mActivity.getString(R.string.pref_camera_picture_format_value_jpeg));
+ editor.apply();
+ }
+ Log.v(TAG, "Picture format value =" + pictureFormat);
+ mParameters.set(KEY_PICTURE_FORMAT, pictureFormat);
+
+ // Set JPEG quality.
+ String jpegQuality = mPreferences.getString(
+ CameraSettings.KEY_JPEG_QUALITY,
+ mActivity.getString(R.string.pref_camera_jpegquality_default));
+ //mUnsupportedJpegQuality = false;
+ Size pic_size = mParameters.getPictureSize();
+ if (pic_size == null) {
+ Log.e(TAG, "error getPictureSize: size is null");
+ }
+ else{
+ if("100".equals(jpegQuality) && (pic_size.width >= 3200)){
+ //mUnsupportedJpegQuality = true;
+ }else {
+ mParameters.setJpegQuality(JpegEncodingQualityMappings.getQualityNumber(jpegQuality));
+ }
+ }
+
+ // Set Selectable Zone Af parameter.
+ String selectableZoneAf = mPreferences.getString(
+ CameraSettings.KEY_SELECTABLE_ZONE_AF,
+ mActivity.getString(R.string.pref_camera_selectablezoneaf_default));
+ List<String> str = mParameters.getSupportedSelectableZoneAf();
+ if (CameraUtil.isSupported(selectableZoneAf, mParameters.getSupportedSelectableZoneAf())) {
+ mParameters.setSelectableZoneAf(selectableZoneAf);
+ }
+
+ // Set wavelet denoise mode
+ if (mParameters.getSupportedDenoiseModes() != null) {
+ String Denoise = mPreferences.getString( CameraSettings.KEY_DENOISE,
+ mActivity.getString(R.string.pref_camera_denoise_default));
+ mParameters.setDenoise(Denoise);
+ }
+ // Set Redeye Reduction
+ String redeyeReduction = mPreferences.getString(
+ CameraSettings.KEY_REDEYE_REDUCTION,
+ mActivity.getString(R.string.pref_camera_redeyereduction_default));
+ if (CameraUtil.isSupported(redeyeReduction,
+ mParameters.getSupportedRedeyeReductionModes())) {
+ mParameters.setRedeyeReductionMode(redeyeReduction);
+ }
+ // Set ISO parameter
+ String iso = mPreferences.getString(
+ CameraSettings.KEY_ISO,
+ mActivity.getString(R.string.pref_camera_iso_default));
+ if (CameraUtil.isSupported(iso,
+ mParameters.getSupportedIsoValues())) {
+ mParameters.setISOValue(iso);
+ }
+ // Set color effect parameter.
+ String colorEffect = mPreferences.getString(
+ CameraSettings.KEY_COLOR_EFFECT,
+ mActivity.getString(R.string.pref_camera_coloreffect_default));
+ Log.v(TAG, "Color effect value =" + colorEffect);
+ if (CameraUtil.isSupported(colorEffect, mParameters.getSupportedColorEffects())) {
+ mParameters.setColorEffect(colorEffect);
+ }
+ //Set Saturation
+ String saturationStr = mPreferences.getString(
+ CameraSettings.KEY_SATURATION,
+ mActivity.getString(R.string.pref_camera_saturation_default));
+ int saturation = Integer.parseInt(saturationStr);
+ Log.v(TAG, "Saturation value =" + saturation);
+ if((0 <= saturation) && (saturation <= mParameters.getMaxSaturation())){
+ mParameters.setSaturation(saturation);
+ }
+ // Set contrast parameter.
+ String contrastStr = mPreferences.getString(
+ CameraSettings.KEY_CONTRAST,
+ mActivity.getString(R.string.pref_camera_contrast_default));
+ int contrast = Integer.parseInt(contrastStr);
+ Log.v(TAG, "Contrast value =" +contrast);
+ if((0 <= contrast) && (contrast <= mParameters.getMaxContrast())){
+ mParameters.setContrast(contrast);
+ }
+ // Set sharpness parameter
+ String sharpnessStr = mPreferences.getString(
+ CameraSettings.KEY_SHARPNESS,
+ mActivity.getString(R.string.pref_camera_sharpness_default));
+ int sharpness = Integer.parseInt(sharpnessStr) *
+ (mParameters.getMaxSharpness()/MAX_SHARPNESS_LEVEL);
+ Log.v(TAG, "Sharpness value =" + sharpness);
+ if((0 <= sharpness) && (sharpness <= mParameters.getMaxSharpness())){
+ mParameters.setSharpness(sharpness);
+ }
+ // Set Face Recognition
+ String faceRC = mPreferences.getString(
+ CameraSettings.KEY_FACE_RECOGNITION,
+ mActivity.getString(R.string.pref_camera_facerc_default));
+ Log.v(TAG, "Face Recognition value = " + faceRC);
+ if (CameraUtil.isSupported(faceRC,
+ CameraSettings.getSupportedFaceRecognitionModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_FACE_RECOGNITION, faceRC);
+ }
+ // Set AE Bracketing
+ String aeBracketing = mPreferences.getString(
+ CameraSettings.KEY_AE_BRACKET_HDR,
+ mActivity.getString(R.string.pref_camera_ae_bracket_hdr_default));
+ Log.v(TAG, "AE Bracketing value =" + aeBracketing);
+ if (CameraUtil.isSupported(aeBracketing,
+ CameraSettings.getSupportedAEBracketingModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_AE_BRACKETING, aeBracketing);
+ }
+ // Set Advanced features.
+ String advancedFeature = mPreferences.getString(
+ CameraSettings.KEY_ADVANCED_FEATURES,
+ mActivity.getString(R.string.pref_camera_advanced_feature_default));
+ Log.v(TAG, " advancedFeature value =" + advancedFeature);
+
+ if(advancedFeature != null) {
+ String ubiFocusOff = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_ubifocus_off);
+ String chromaFlashOff = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_chromaflash_off);
+ String optiZoomOff = mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_optizoom_off);
+
+ if (advancedFeature.equals(mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_ubifocus_on))) {
+ qcomUpdateAdvancedFeatures(advancedFeature,
+ chromaFlashOff,
+ optiZoomOff);
+ } else if (advancedFeature.equals(mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_chromaflash_on))) {
+ qcomUpdateAdvancedFeatures(ubiFocusOff,
+ advancedFeature,
+ optiZoomOff);
+ } else if (advancedFeature.equals(mActivity.getString(R.string.
+ pref_camera_advanced_feature_value_optizoom_on))) {
+ qcomUpdateAdvancedFeatures(ubiFocusOff,
+ chromaFlashOff,
+ advancedFeature);
+ } else {
+ qcomUpdateAdvancedFeatures(ubiFocusOff,
+ chromaFlashOff,
+ optiZoomOff);
+ }
+ }
+ // Set auto exposure parameter.
+ String autoExposure = mPreferences.getString(
+ CameraSettings.KEY_AUTOEXPOSURE,
+ mActivity.getString(R.string.pref_camera_autoexposure_default));
+ Log.v(TAG, "autoExposure value =" + autoExposure);
+ if (CameraUtil.isSupported(autoExposure, mParameters.getSupportedAutoexposure())) {
+ mParameters.setAutoExposure(autoExposure);
+ }
+
+ // Set anti banding parameter.
+ String antiBanding = mPreferences.getString(
+ CameraSettings.KEY_ANTIBANDING,
+ mActivity.getString(R.string.pref_camera_antibanding_default));
+ Log.v(TAG, "antiBanding value =" + antiBanding);
+ if (CameraUtil.isSupported(antiBanding, mParameters.getSupportedAntibanding())) {
+ mParameters.setAntibanding(antiBanding);
+ }
+
+ String zsl = mPreferences.getString(CameraSettings.KEY_ZSL,
+ mActivity.getString(R.string.pref_camera_zsl_default));
+ mParameters.setZSLMode(zsl);
+ if(zsl.equals("on")) {
+ //Switch on ZSL Camera mode
+ mSnapshotMode = CameraInfo.CAMERA_SUPPORT_MODE_ZSL;
+ mParameters.setCameraMode(1);
+ mFocusManager.setZslEnable(true);
+
+ //Raw picture format is not supported under ZSL mode
+ mParameters.set(KEY_PICTURE_FORMAT, PIXEL_FORMAT_JPEG);
+ Editor editor = mPreferences.edit();
+ editor.putString(CameraSettings.KEY_PICTURE_FORMAT, mActivity.getString(R.string.pref_camera_picture_format_value_jpeg));
+ editor.apply();
+ mUI.overrideSettings(CameraSettings.KEY_PICTURE_FORMAT, mActivity.getString(R.string.pref_camera_picture_format_entry_jpeg));
+
+ //Try to set CAF for ZSL
+ if(CameraUtil.isSupported(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
+ mParameters.getSupportedFocusModes()) && !mFocusManager.isTouch()) {
+ mFocusManager.overrideFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ mParameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ } else if (mFocusManager.isTouch()) {
+ mFocusManager.overrideFocusMode(null);
+ mParameters.setFocusMode(mFocusManager.getFocusMode());
+ } else {
+ // If not supported use the current mode
+ mFocusManager.overrideFocusMode(mFocusManager.getFocusMode());
+ }
+
+ if(!pictureFormat.equals(PIXEL_FORMAT_JPEG)) {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ Toast.makeText(mActivity, R.string.error_app_unsupported_raw,
+ Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+ } else if(zsl.equals("off")) {
+ mSnapshotMode = CameraInfo.CAMERA_SUPPORT_MODE_NONZSL;
+ mParameters.setCameraMode(0);
+ mFocusManager.setZslEnable(false);
+ mFocusManager.overrideFocusMode(null);
+ mParameters.setFocusMode(mFocusManager.getFocusMode());
+ }
+ // Set face detetction parameter.
+ String faceDetection = mPreferences.getString(
+ CameraSettings.KEY_FACE_DETECTION,
+ mActivity.getString(R.string.pref_camera_facedetection_default));
+ if (CameraUtil.isSupported(faceDetection, mParameters.getSupportedFaceDetectionModes())) {
+ mParameters.setFaceDetectionMode(faceDetection);
+ if(faceDetection.equals("on") && mFaceDetectionEnabled == false) {
+ mFaceDetectionEnabled = true;
+ startFaceDetection();
+ }
+ if(faceDetection.equals("off") && mFaceDetectionEnabled == true) {
+ stopFaceDetection();
+ mFaceDetectionEnabled = false;
+ }
+ }
+ // skin tone ie enabled only for auto,party and portrait BSM
+ // when color effects are not enabled
+ if((Parameters.SCENE_MODE_PARTY.equals(mSceneMode) ||
+ Parameters.SCENE_MODE_PORTRAIT.equals(mSceneMode)) &&
+ (Parameters.EFFECT_NONE.equals(colorEffect))) {
+ //Set Skin Tone Correction factor
+ Log.v(TAG, "set tone bar: mSceneMode = " + mSceneMode);
+ if(mSeekBarInitialized == true)
+ mHandler.sendEmptyMessage(SET_SKIN_TONE_FACTOR);
+ }
+
+ //Set Histogram
+ String histogram = mPreferences.getString(
+ CameraSettings.KEY_HISTOGRAM,
+ mActivity.getString(R.string.pref_camera_histogram_default));
+ if (CameraUtil.isSupported(histogram,
+ mParameters.getSupportedHistogramModes()) && mCameraDevice != null) {
+ // Call for histogram
+ if(histogram.equals("enable")) {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if(mGraphView != null) {
+ mGraphView.setVisibility(View.VISIBLE);
+ mGraphView.PreviewChanged();
+ }
+ }
+ });
+ mCameraDevice.setHistogramMode(mStatsCallback);
+ mHiston = true;
+ } else {
+ mHiston = false;
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ if (mGraphView != null)
+ mGraphView.setVisibility(View.INVISIBLE);
+ }
+ });
+ mCameraDevice.setHistogramMode(null);
+ }
+ }
+ // Read Flip mode from adb command
+ //value: 0(default) - FLIP_MODE_OFF
+ //value: 1 - FLIP_MODE_H
+ //value: 2 - FLIP_MODE_V
+ //value: 3 - FLIP_MODE_VH
+ int preview_flip_value = SystemProperties.getInt("debug.camera.preview.flip", 0);
+ int video_flip_value = SystemProperties.getInt("debug.camera.video.flip", 0);
+ int picture_flip_value = SystemProperties.getInt("debug.camera.picture.flip", 0);
+ int rotation = CameraUtil.getJpegRotation(mCameraId, mOrientation);
+ mParameters.setRotation(rotation);
+ if (rotation == 90 || rotation == 270) {
+ // in case of 90 or 270 degree, V/H flip should reverse
+ if (preview_flip_value == 1) {
+ preview_flip_value = 2;
+ } else if (preview_flip_value == 2) {
+ preview_flip_value = 1;
+ }
+ if (video_flip_value == 1) {
+ video_flip_value = 2;
+ } else if (video_flip_value == 2) {
+ video_flip_value = 1;
+ }
+ if (picture_flip_value == 1) {
+ picture_flip_value = 2;
+ } else if (picture_flip_value == 2) {
+ picture_flip_value = 1;
+ }
+ }
+ String preview_flip = CameraUtil.getFilpModeString(preview_flip_value);
+ String video_flip = CameraUtil.getFilpModeString(video_flip_value);
+ String picture_flip = CameraUtil.getFilpModeString(picture_flip_value);
+ if(CameraUtil.isSupported(preview_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_PREVIEW_FLIP, preview_flip);
+ }
+ if(CameraUtil.isSupported(video_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_VIDEO_FLIP, video_flip);
+ }
+ if(CameraUtil.isSupported(picture_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_SNAPSHOT_PICTURE_FLIP, picture_flip);
+ }
+ /* Disable focus if aebracket is ON */
+ String aeBracket = mParameters.get(CameraSettings.KEY_QC_AE_BRACKETING);
+ if (!aeBracket.equalsIgnoreCase("off")) {
+ String fMode = Parameters.FLASH_MODE_OFF;
+ mUI.overrideSettings(CameraSettings.KEY_FLASH_MODE, fMode);
+ mParameters.setFlashMode(fMode);
+ }
+ }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void setAutoExposureLockIfSupported() {
if (mAeLockSupported) {
@@ -1623,9 +2727,19 @@ public class PhotoModule
if (pictureSize == null) {
CameraSettings.initialCameraPictureSize(mActivity, mParameters);
} else {
+ Size old_size = mParameters.getPictureSize();
+ Log.v(TAG, "old picture_size = " + old_size.width + " x " + old_size.height);
List<Size> supported = mParameters.getSupportedPictureSizes();
CameraSettings.setCameraPictureSize(
pictureSize, supported, mParameters);
+ Size size = mParameters.getPictureSize();
+ Log.v(TAG, "new picture_size = " + size.width + " x " + size.height);
+ if (old_size != null && size != null) {
+ if(!size.equals(old_size) && mCameraState != PREVIEW_STOPPED) {
+ Log.v(TAG, "Picture Size changed. Restart Preview");
+ mRestartPreview = true;
+ }
+ }
}
Size size = mParameters.getPictureSize();
@@ -1647,12 +2761,10 @@ public class PhotoModule
mCameraDevice.setParameters(mParameters);
}
mParameters = mCameraDevice.getParameters();
+ Log.v(TAG, "Preview Size changed. Restart Preview");
+ mRestartPreview = true;
}
- if(optimalSize.width != 0 && optimalSize.height != 0) {
- mUI.updatePreviewAspectRatio((float) optimalSize.width
- / (float) optimalSize.height);
- }
Log.v(TAG, "Preview size is " + optimalSize.width + "x" + optimalSize.height);
// Since changing scene mode may change supported values, set scene mode
@@ -1673,6 +2785,11 @@ public class PhotoModule
} else {
if (hdrOn) {
mSceneMode = CameraUtil.SCENE_MODE_HDR;
+ if (!(Parameters.SCENE_MODE_AUTO).equals(mParameters.getSceneMode())) {
+ mParameters.setSceneMode(Parameters.SCENE_MODE_AUTO);
+ mCameraDevice.setParameters(mParameters);
+ mParameters = mCameraDevice.getParameters();
+ }
} else {
mSceneMode = mPreferences.getString(
CameraSettings.KEY_SCENE_MODE,
@@ -1749,12 +2866,15 @@ public class PhotoModule
mParameters.setFocusMode(mFocusManager.getFocusMode());
} else {
mFocusManager.overrideFocusMode(mParameters.getFocusMode());
+ if (hdrOn)
+ mParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
}
if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
updateAutoFocusMoveCallback();
}
-
+ //QCom related parameters updated here.
+ qcomUpdateCameraParametersPreference();
return doGcamModeSwitch;
}
@@ -1772,25 +2892,27 @@ public class PhotoModule
// the subsets actually need updating. The PREFERENCE set needs extra
// locking because the preference can be changed from GLThread as well.
private void setCameraParameters(int updateSet) {
- boolean doModeSwitch = false;
+ synchronized (mCameraDevice) {
+ boolean doModeSwitch = false;
- if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) {
- updateCameraParametersInitialize();
- }
+ if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) {
+ updateCameraParametersInitialize();
+ }
- if ((updateSet & UPDATE_PARAM_ZOOM) != 0) {
- updateCameraParametersZoom();
- }
+ if ((updateSet & UPDATE_PARAM_ZOOM) != 0) {
+ updateCameraParametersZoom();
+ }
- if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
- doModeSwitch = updateCameraParametersPreference();
- }
+ if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
+ doModeSwitch = updateCameraParametersPreference();
+ }
- mCameraDevice.setParameters(mParameters);
+ mCameraDevice.setParameters(mParameters);
- // Switch to gcam module if HDR+ was selected
- if (doModeSwitch && !mIsImageCaptureIntent) {
- mHandler.sendEmptyMessage(SWITCH_TO_GCAM_MODULE);
+ // Switch to gcam module if HDR+ was selected
+ if (doModeSwitch && !mIsImageCaptureIntent) {
+ mHandler.sendEmptyMessage(SWITCH_TO_GCAM_MODULE);
+ }
}
}
@@ -1805,7 +2927,15 @@ public class PhotoModule
return;
} else if (isCameraIdle()) {
setCameraParameters(mUpdateSet);
- updateSceneMode();
+ if(mRestartPreview && mCameraState != PREVIEW_STOPPED) {
+ Log.v(TAG, "Restarting Preview...");
+ stopPreview();
+ resizeForPreviewAspectRatio();
+ startPreview();
+ setCameraState(IDLE);
+ }
+ mRestartPreview = false;
+ updateCameraSettings();
mUpdateSet = 0;
} else {
if (!mHandler.hasMessages(SET_CAMERA_PARAMETERS_WHEN_IDLE)) {
@@ -1838,6 +2968,30 @@ public class PhotoModule
}
}
+ // Return true if the preference has the specified key but not the value.
+ private static boolean notSame(ListPreference pref, String key, String value) {
+ return (key.equals(pref.getKey()) && !value.equals(pref.getValue()));
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(ListPreference pref) {
+ // ignore the events after "onPause()"
+ if (mPaused) return;
+
+ //filter off unsupported settings
+ final String settingOff = mActivity.getString(R.string.setting_off_value);
+ if (!CameraSettings.isZSLHDRSupported(mParameters)) {
+ if (notSame(pref, CameraSettings.KEY_CAMERA_HDR, settingOff)) {
+ mUI.setPreference(CameraSettings.KEY_ZSL,settingOff);
+ } else if (notSame(pref,CameraSettings.KEY_ZSL,settingOff)) {
+ mUI.setPreference(CameraSettings.KEY_CAMERA_HDR, settingOff);
+ }
+ }
+
+ //call generic onSharedPreferenceChanged
+ onSharedPreferenceChanged();
+ }
+
@Override
public void onSharedPreferenceChanged() {
// ignore the events after "onPause()"
@@ -1846,9 +3000,44 @@ public class PhotoModule
boolean recordLocation = RecordLocationPreference.get(
mPreferences, mContentResolver);
mLocationManager.recordLocation(recordLocation);
-
- setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
- mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup, mPreferences);
+ if(needRestart()){
+ Log.v(TAG, "Restarting Preview... Camera Mode Changhed");
+ stopPreview();
+ startPreview();
+ setCameraState(IDLE);
+ mRestartPreview = false;
+ }
+ /* Check if the PhotoUI Menu is initialized or not. This
+ * should be initialized during onCameraOpen() which should
+ * have been called by now. But for some reason that is not
+ * executed till now, then schedule these functionality for
+ * later by posting a message to the handler */
+ if (mUI.mMenuInitialized) {
+ setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
+ mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup,
+ mPreferences);
+ } else {
+ mHandler.sendEmptyMessage(SET_PHOTO_UI_PARAMS);
+ }
+ resizeForPreviewAspectRatio();
+ if (mSeekBarInitialized == true){
+ Log.v(TAG, "onSharedPreferenceChanged Skin tone bar: change");
+ // skin tone is enabled only for party and portrait BSM
+ // when color effects are not enabled
+ String colorEffect = mPreferences.getString(
+ CameraSettings.KEY_COLOR_EFFECT,
+ mActivity.getString(R.string.pref_camera_coloreffect_default));
+ if((Parameters.SCENE_MODE_PARTY.equals(mSceneMode) ||
+ Parameters.SCENE_MODE_PORTRAIT.equals(mSceneMode)) &&
+ (Parameters.EFFECT_NONE.equals(colorEffect))) {
+ Log.v(TAG, "Party/Portrait + No effect, SkinToneBar enabled");
+ } else {
+ disableSkinToneSeekBar();
+ }
+ }
+ Storage.setSaveSDCard(
+ mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
+ mActivity.updateStorageSpaceAndHint();
}
@Override
@@ -1921,6 +3110,7 @@ public class PhotoModule
mSnapshotOnIdle = false;
mFocusManager.doSnap();
mFocusManager.onShutterUp();
+ mUI.overrideSettings(CameraSettings.KEY_ZSL, null);
}
@Override
@@ -1988,12 +3178,91 @@ public class PhotoModule
mHeading += 360;
}
}
-
@Override
public void onPreviewFocusChanged(boolean previewFocused) {
mUI.onPreviewFocusChanged(previewFocused);
}
+ // TODO: Delete this function after old camera code is removed
+ @Override
+ public void onRestorePreferencesClicked() {}
+ private void setSkinToneFactor() {
+ if(mCameraDevice == null || mParameters == null || skinToneSeekBar == null)
+ return;
+
+ String skinToneEnhancementPref = "enable";
+ if(CameraUtil.isSupported(skinToneEnhancementPref,
+ mParameters.getSupportedSkinToneEnhancementModes())) {
+ if(skinToneEnhancementPref.equals("enable")) {
+ int skinToneValue =0;
+ int progress;
+ //get the value for the first time!
+ if (mskinToneValue ==0) {
+ String factor = mPreferences.getString(
+ CameraSettings.KEY_SKIN_TONE_ENHANCEMENT_FACTOR, "0");
+ skinToneValue = Integer.parseInt(factor);
+ }
+
+ Log.v(TAG, "Skin tone bar: enable = " + mskinToneValue);
+ enableSkinToneSeekBar();
+ //As a wrokaround set progress again to show the actually progress on screen.
+ if (skinToneValue != 0) {
+ progress = (skinToneValue/SCE_FACTOR_STEP)-MIN_SCE_FACTOR;
+ skinToneSeekBar.setProgress(progress);
+ }
+ } else {
+ Log.v(TAG, "Skin tone bar: disable");
+ disableSkinToneSeekBar();
+ }
+ } else {
+ Log.v(TAG, "Skin tone bar: Not supported");
+ skinToneSeekBar.setVisibility(View.INVISIBLE);
+ }
+ }
+ private void enableSkinToneSeekBar() {
+ int progress;
+ if(brightnessProgressBar != null)
+ brightnessProgressBar.setVisibility(View.INVISIBLE);
+ skinToneSeekBar.setMax(MAX_SCE_FACTOR-MIN_SCE_FACTOR);
+ skinToneSeekBar.setVisibility(View.VISIBLE);
+ skinToneSeekBar.requestFocus();
+ if (mskinToneValue != 0) {
+ progress = (mskinToneValue/SCE_FACTOR_STEP)-MIN_SCE_FACTOR;
+ mskinToneSeekListener.onProgressChanged(skinToneSeekBar, progress, false);
+ } else {
+ progress = (MAX_SCE_FACTOR-MIN_SCE_FACTOR)/2;
+ RightValue.setText("");
+ LeftValue.setText("");
+ }
+ skinToneSeekBar.setProgress(progress);
+ mActivity.findViewById(R.id.linear).bringToFront();
+ skinToneSeekBar.bringToFront();
+ Title.setText("Skin Tone Enhancement");
+ Title.setVisibility(View.VISIBLE);
+ RightValue.setVisibility(View.VISIBLE);
+ LeftValue.setVisibility(View.VISIBLE);
+ mSkinToneSeekBar = true;
+ }
+
+ private void disableSkinToneSeekBar() {
+ skinToneSeekBar.setVisibility(View.INVISIBLE);
+ Title.setVisibility(View.INVISIBLE);
+ RightValue.setVisibility(View.INVISIBLE);
+ LeftValue.setVisibility(View.INVISIBLE);
+ mskinToneValue = 0;
+ mSkinToneSeekBar = false;
+ Editor editor = mPreferences.edit();
+ editor.putString(CameraSettings.KEY_SKIN_TONE_ENHANCEMENT_FACTOR,
+ Integer.toString(mskinToneValue - MIN_SCE_FACTOR));
+ editor.apply();
+ if(brightnessProgressBar != null)
+ brightnessProgressBar.setVisibility(View.VISIBLE);
+}
+
+/*
+ * Provide a mapping for Jpeg encoding quality levels
+ * from String representation to numeric representation.
+ */
@Override
public boolean arePreviewControlsVisible() {
return mUI.arePreviewControlsVisible();
@@ -2019,13 +3288,141 @@ public class PhotoModule
}
}
}
+}
/* Below is no longer needed, except to get rid of compile error
* TODO: Remove these
*/
+class JpegEncodingQualityMappings {
+ private static final String TAG = "JpegEncodingQualityMappings";
+ private static final int DEFAULT_QUALITY = 85;
+ private static HashMap<String, Integer> mHashMap =
+ new HashMap<String, Integer>();
+
+ static {
+ mHashMap.put("normal", CameraProfile.QUALITY_LOW);
+ mHashMap.put("fine", CameraProfile.QUALITY_MEDIUM);
+ mHashMap.put("superfine", CameraProfile.QUALITY_HIGH);
+ }
+
+ // Retrieve and return the Jpeg encoding quality number
+ // for the given quality level.
+ public static int getQualityNumber(String jpegQuality) {
+ try{
+ int qualityPercentile = Integer.parseInt(jpegQuality);
+ if(qualityPercentile >= 0 && qualityPercentile <=100)
+ return qualityPercentile;
+ else
+ return DEFAULT_QUALITY;
+ } catch(NumberFormatException nfe){
+ //chosen quality is not a number, continue
+ }
+ Integer quality = mHashMap.get(jpegQuality);
+ if (quality == null) {
+ Log.w(TAG, "Unknown Jpeg quality: " + jpegQuality);
+ return DEFAULT_QUALITY;
+ }
+ return CameraProfile.getJpegEncodingQualityParameter(quality.intValue());
+ }
+}
- // TODO: Delete this function after old camera code is removed
+class GraphView extends View {
+ private Bitmap mBitmap;
+ private Paint mPaint = new Paint();
+ private Paint mPaintRect = new Paint();
+ private Canvas mCanvas = new Canvas();
+ private float mScale = (float)3;
+ private float mWidth;
+ private float mHeight;
+ private PhotoModule mPhotoModule;
+ private CameraManager.CameraProxy mGraphCameraDevice;
+ private float scaled;
+ private static final int STATS_SIZE = 256;
+ private static final String TAG = "GraphView";
+
+
+ public GraphView(Context context, AttributeSet attrs) {
+ super(context,attrs);
+
+ mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+ mPaintRect.setColor(0xFFFFFFFF);
+ mPaintRect.setStyle(Paint.Style.FILL);
+ }
@Override
- public void onRestorePreferencesClicked() {}
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
+ mCanvas.setBitmap(mBitmap);
+ mWidth = w;
+ mHeight = h;
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+ @Override
+ protected void onDraw(Canvas canvas) {
+ Log.v(TAG, "in Camera.java ondraw");
+ if(mPhotoModule == null || !mPhotoModule.mHiston ) {
+ Log.e(TAG, "returning as histogram is off ");
+ return;
+ }
+ if (mBitmap != null) {
+ final Paint paint = mPaint;
+ final Canvas cavas = mCanvas;
+ final float border = 5;
+ float graphheight = mHeight - (2 * border);
+ float graphwidth = mWidth - (2 * border);
+ float left,top,right,bottom;
+ float bargap = 0.0f;
+ float barwidth = graphwidth/STATS_SIZE;
+
+ cavas.drawColor(0xFFAAAAAA);
+ paint.setColor(Color.BLACK);
+
+ for (int k = 0; k <= (graphheight /32) ; k++) {
+ float y = (float)(32 * k)+ border;
+ cavas.drawLine(border, y, graphwidth + border , y, paint);
+ }
+ for (int j = 0; j <= (graphwidth /32); j++) {
+ float x = (float)(32 * j)+ border;
+ cavas.drawLine(x, border, x, graphheight + border, paint);
+ }
+ synchronized(PhotoModule.statsdata) {
+ //Assumption: The first element contains
+ // the maximum value.
+ int maxValue = Integer.MIN_VALUE;
+ if ( 0 == PhotoModule.statsdata[0] ) {
+ for ( int i = 1 ; i <= STATS_SIZE ; i++ ) {
+ if ( maxValue < PhotoModule.statsdata[i] ) {
+ maxValue = PhotoModule.statsdata[i];
+ }
+ }
+ } else {
+ maxValue = PhotoModule.statsdata[0];
+ }
+ mScale = ( float ) maxValue;
+ for(int i=1 ; i<=STATS_SIZE ; i++) {
+ scaled = (PhotoModule.statsdata[i]/mScale)*STATS_SIZE;
+ if(scaled >= (float)STATS_SIZE)
+ scaled = (float)STATS_SIZE;
+ left = (bargap * (i+1)) + (barwidth * i) + border;
+ top = graphheight + border;
+ right = left + barwidth;
+ bottom = top - scaled;
+ cavas.drawRect(left, top, right, bottom, mPaintRect);
+ }
+ }
+ canvas.drawBitmap(mBitmap, 0, 0, null);
+ }
+ if (mPhotoModule.mHiston && mPhotoModule!= null) {
+ mGraphCameraDevice = mPhotoModule.getCamera();
+ if (mGraphCameraDevice != null){
+ mGraphCameraDevice.sendHistogramData();
+ }
+ }
+ }
+ public void PreviewChanged() {
+ invalidate();
+ }
+ public void setPhotoModuleObject(PhotoModule photoModule) {
+ mPhotoModule = photoModule;
+ }
}
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index 5018c16d6..b0c642a8b 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -19,6 +19,7 @@ package com.android.camera;
import android.app.AlertDialog;
import android.content.DialogInterface;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
@@ -67,7 +68,7 @@ public class PhotoUI implements PieListener,
CameraManager.CameraFaceDetectionCallback {
private static final String TAG = "CAM_UI";
- private static final int DOWN_SAMPLE_FACTOR = 4;
+ private int mDownSampleFactor = 4;
private final AnimationManager mAnimationManager;
private CameraActivity mActivity;
private PhotoController mController;
@@ -106,6 +107,7 @@ public class PhotoUI implements PieListener,
private int mPreviewWidth = 0;
private int mPreviewHeight = 0;
+ public boolean mMenuInitialized = false;
private float mSurfaceTextureUncroppedWidth;
private float mSurfaceTextureUncroppedHeight;
@@ -116,6 +118,10 @@ public class PhotoUI implements PieListener,
private TextureView mTextureView;
private Matrix mMatrix = null;
private float mAspectRatio = 4f / 3f;
+ private boolean mAspectRatioResize;
+
+ private boolean mOrientationResize;
+ private boolean mPrevOrientationResize;
private View mPreviewCover;
private final Object mSurfaceTextureLock = new Object();
@@ -129,10 +135,15 @@ public class PhotoUI implements PieListener,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
int width = right - left;
int height = bottom - top;
- if (mPreviewWidth != width || mPreviewHeight != height) {
+ if (mPreviewWidth != width || mPreviewHeight != height
+ || (mOrientationResize != mPrevOrientationResize)
+ || mAspectRatioResize) {
mPreviewWidth = width;
mPreviewHeight = height;
setTransformMatrix(width, height);
+ mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth,
+ (int) mSurfaceTextureUncroppedHeight);
+ mAspectRatioResize = false;
}
}
};
@@ -151,8 +162,8 @@ public class PhotoUI implements PieListener,
@Override
protected Bitmap doInBackground(Void... params) {
// Decode image in background.
- Bitmap bitmap = CameraUtil.downSample(mData, DOWN_SAMPLE_FACTOR);
- if (mOrientation != 0 || mMirror) {
+ Bitmap bitmap = CameraUtil.downSample(mData, mDownSampleFactor);
+ if ((mOrientation != 0 || mMirror) && (bitmap != null)) {
Matrix m = new Matrix();
if (mMirror) {
// Flip horizontally
@@ -218,44 +229,63 @@ public class PhotoUI implements PieListener,
}
mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
mAnimationManager = new AnimationManager();
+
+ mOrientationResize = false;
+ mPrevOrientationResize = false;
}
- public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {
- mSurfaceTextureSizeListener = listener;
+ public void setDownFactor(int factor) {
+ mDownSampleFactor = factor;
}
- public void updatePreviewAspectRatio(float aspectRatio) {
- if (aspectRatio <= 0) {
- Log.e(TAG, "Invalid aspect ratio: " + aspectRatio);
- return;
- }
- if (aspectRatio < 1f) {
- aspectRatio = 1f / aspectRatio;
- }
+ public void cameraOrientationPreviewResize(boolean orientation){
+ mPrevOrientationResize = mOrientationResize;
+ mOrientationResize = orientation;
+ }
- if (mAspectRatio != aspectRatio) {
- mAspectRatio = aspectRatio;
- // Update transform matrix with the new aspect ratio.
- if (mPreviewWidth != 0 && mPreviewHeight != 0) {
- setTransformMatrix(mPreviewWidth, mPreviewHeight);
- }
+ public void setAspectRatio(float ratio) {
+ if (ratio <= 0.0) throw new IllegalArgumentException();
+
+ if (mOrientationResize &&
+ mActivity.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_PORTRAIT) {
+ ratio = 1 / ratio;
}
+
+ Log.d(TAG,"setAspectRatio() ratio["+ratio+"] mAspectRatio["+mAspectRatio+"]");
+ mAspectRatio = ratio;
+ mAspectRatioResize = true;
+ mTextureView.requestLayout();
+ }
+
+ public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {
+ mSurfaceTextureSizeListener = listener;
}
private void setTransformMatrix(int width, int height) {
mMatrix = mTextureView.getTransform(mMatrix);
float scaleX = 1f, scaleY = 1f;
float scaledTextureWidth, scaledTextureHeight;
- if (width > height) {
- scaledTextureWidth = Math.max(width,
- (int) (height * mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int)(width / mAspectRatio));
+ if (mOrientationResize){
+ scaledTextureWidth = height * mAspectRatio;
+ if(scaledTextureWidth > width){
+ scaledTextureWidth = width;
+ scaledTextureHeight = scaledTextureWidth / mAspectRatio;
+ } else {
+ scaledTextureHeight = height;
+ }
} else {
- scaledTextureWidth = Math.max(width,
- (int) (height / mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int) (width * mAspectRatio));
+ if (width > height) {
+ scaledTextureWidth = Math.max(width,
+ (int) (height * mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int)(width / mAspectRatio));
+ } else {
+ scaledTextureWidth = Math.max(width,
+ (int) (height / mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int) (width * mAspectRatio));
+ }
}
if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
@@ -341,6 +371,7 @@ public class PhotoUI implements PieListener,
mMenu.setListener(listener);
}
mMenu.initialize(prefGroup);
+ mMenuInitialized = true;
if (mZoomRenderer == null) {
mZoomRenderer = new ZoomRenderer(mActivity);
@@ -516,12 +547,13 @@ public class PhotoUI implements PieListener,
public void hideGpsOnScreenIndicator() { }
public void overrideSettings(final String ... keyvalues) {
+ if (mMenu == null) return;
mMenu.overrideSettings(keyvalues);
}
public void updateOnScreenIndicators(Camera.Parameters params,
PreferenceGroup group, ComboPreferences prefs) {
- if (params == null) return;
+ if (params == null || group == null) return;
mOnScreenIndicators.updateSceneOnScreenIndicator(params.getSceneMode());
mOnScreenIndicators.updateExposureOnScreenIndicator(params,
CameraSettings.readExposure(prefs));
@@ -613,7 +645,8 @@ public class PhotoUI implements PieListener,
@Override
public void onDismiss() {
mPopup = null;
- mMenu.popupDismissed();
+ mMenu.popupDismissed(mDismissAll);
+ mDismissAll = false;
showUI();
// Switch back into fullscreen/lights-out mode after popup
@@ -633,6 +666,14 @@ public class PhotoUI implements PieListener,
}
}
+ private boolean mDismissAll = false;
+ public void dismissAllPopup() {
+ mDismissAll = true;
+ if (mPopup != null && mPopup.isShowing()) {
+ mPopup.dismiss();
+ }
+ }
+
public void onShowSwitcherPopup() {
if (mPieRenderer != null && mPieRenderer.showsItems()) {
mPieRenderer.hide();
@@ -655,7 +696,7 @@ public class PhotoUI implements PieListener,
// Remove all the popups/dialog boxes
boolean ret = false;
if (mPopup != null) {
- dismissPopup();
+ dismissAllPopup();
ret = true;
}
onShowSwitcherPopup();
@@ -728,6 +769,7 @@ public class PhotoUI implements PieListener,
@Override
public void onZoomStart() {
if (mPieRenderer != null) {
+ mPieRenderer.hide();
mPieRenderer.setBlockFocus(true);
}
}
@@ -773,6 +815,7 @@ public class PhotoUI implements PieListener,
(ViewGroup) mRootView, true);
mCountDownView = (CountDownView) (mRootView.findViewById(R.id.count_down_to_capture));
mCountDownView.setCountDownFinishedListener((OnCountDownFinishedListener) mController);
+ mCountDownView.bringToFront();
}
public boolean isCountingDown() {
@@ -893,4 +936,8 @@ public class PhotoUI implements PieListener,
mController.updateCameraOrientation();
}
+ public void setPreference(String key, String value) {
+ mMenu.setPreference(key, value);
+ }
+
}
diff --git a/src/com/android/camera/PieController.java b/src/com/android/camera/PieController.java
index 622440151..d2e5b72c1 100644
--- a/src/com/android/camera/PieController.java
+++ b/src/com/android/camera/PieController.java
@@ -19,12 +19,14 @@ package com.android.camera;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.util.Log;
+import android.widget.Toast;
import com.android.camera.CameraPreference.OnPreferenceChangedListener;
import com.android.camera.drawable.TextDrawable;
import com.android.camera.ui.PieItem;
import com.android.camera.ui.PieItem.OnClickListener;
import com.android.camera.ui.PieRenderer;
+import com.android.camera2.R;
import java.util.ArrayList;
import java.util.HashMap;
@@ -65,11 +67,13 @@ public class PieController {
mRenderer.clearItems();
mPreferenceMap.clear();
setPreferenceGroup(group);
+ mPreferences.clear();
+ mOverrides.clear();
}
public void onSettingChanged(ListPreference pref) {
if (mListener != null) {
- mListener.onSharedPreferenceChanged();
+ mListener.onSharedPreferenceChanged(pref);
}
}
@@ -165,6 +169,12 @@ public class PieController {
CharSequence[] values = pref.getEntryValues();
index = (index + 1) % values.length;
pref.setValueIndex(index);
+ // when enable HDR,inform to disable Continuous Shot
+ if (index == 1 && prefKey == CameraSettings.KEY_CAMERA_HDR)
+ {
+ Toast.makeText(mActivity, R.string.HDR_disable_continuous_shot,
+ Toast.LENGTH_LONG).show();
+ }
fitem.setLabel(pref.getLabels()[index]);
fitem.setImageResource(mActivity,
((IconListPreference) pref).getLargeIconIds()[index]);
diff --git a/src/com/android/camera/SDCard.java b/src/com/android/camera/SDCard.java
new file mode 100644
index 000000000..dad354007
--- /dev/null
+++ b/src/com/android/camera/SDCard.java
@@ -0,0 +1,107 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.camera;
+
+import android.content.Context;
+import android.os.StatFs;
+import android.os.Environment;
+import android.os.storage.StorageVolume;
+import android.os.storage.IMountService;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public class SDCard {
+ private static final String TAG = "SDCard";
+
+ private static final int VOLUME_SDCARD_INDEX = 1;
+ private IMountService mMountService = null;
+ private StorageVolume mVolume = null;
+ private String path = null;
+ private String rawpath = null;
+ private static SDCard sSDCard;
+
+ public boolean isWriteable() {
+ if (mVolume == null) return false;
+ final String state = getSDCardStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+ }
+
+ public String getDirectory() {
+ if (mVolume == null) {
+ return null;
+ }
+ if (path == null) {
+ path = mVolume.getPath() + "/DCIM/Camera";
+ }
+ return path;
+ }
+
+ public String getRawDirectory() {
+ if (mVolume == null) {
+ return null;
+ }
+ if (rawpath == null) {
+ rawpath = mVolume.getPath() + "/DCIM/Camera/raw";
+ }
+ return rawpath;
+ }
+
+ public static synchronized SDCard instance() {
+ if (sSDCard == null) {
+ sSDCard = new SDCard();
+ }
+ return sSDCard;
+ }
+
+ private String getSDCardStorageState() {
+ try {
+ return mMountService.getVolumeState(mVolume.getPath());
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to read SDCard storage state; assuming REMOVED: " + e);
+ return Environment.MEDIA_REMOVED;
+ }
+ }
+
+ private SDCard() {
+ try {
+ mMountService = IMountService.Stub.asInterface(ServiceManager
+ .getService("mount"));
+ final StorageVolume[] volumes = mMountService.getVolumeList();
+ if (volumes.length > VOLUME_SDCARD_INDEX) {
+ mVolume = volumes[VOLUME_SDCARD_INDEX];
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "couldn't talk to MountService", e);
+ }
+ }
+
+}
diff --git a/src/com/android/camera/ShutterButton.java b/src/com/android/camera/ShutterButton.java
index a1bbb1a0d..f1d969f9d 100755..100644
--- a/src/com/android/camera/ShutterButton.java
+++ b/src/com/android/camera/ShutterButton.java
@@ -29,7 +29,18 @@ import android.widget.ImageView;
*/
public class ShutterButton extends ImageView {
+ private class LongClickListener implements View.OnLongClickListener {
+ public boolean onLongClick(View v) {
+ if ( null != mListener ) {
+ mListener.onShutterButtonLongClick();
+ return true;
+ }
+ return false;
+ }
+ }
+
private boolean mTouchEnabled = true;
+ private LongClickListener mLongClick = new LongClickListener();
/**
* A callback to be invoked when a ShutterButton's pressed state changes.
@@ -42,6 +53,7 @@ public class ShutterButton extends ImageView {
*/
void onShutterButtonFocus(boolean pressed);
void onShutterButtonClick();
+ void onShutterButtonLongClick();
}
private OnShutterButtonListener mListener;
@@ -53,6 +65,7 @@ public class ShutterButton extends ImageView {
public void setOnShutterButtonListener(OnShutterButtonListener listener) {
mListener = listener;
+ setOnLongClickListener(mLongClick);
}
@Override
@@ -66,6 +79,7 @@ public class ShutterButton extends ImageView {
public void enableTouch(boolean enable) {
mTouchEnabled = enable;
+ setLongClickable(enable);
}
/**
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index b09eedafe..d27cf259f 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -43,6 +43,7 @@ public class Storage {
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
public static final String DIRECTORY = DCIM + "/Camera";
+ public static final String RAW_DIRECTORY = DCIM + "/Camera/raw";
public static final String JPEG_POSTFIX = ".jpg";
// Match the code in MediaProvider.computeBucketValues().
@@ -54,6 +55,16 @@ public class Storage {
public static final long UNKNOWN_SIZE = -3L;
public static final long LOW_STORAGE_THRESHOLD_BYTES = 50000000;
+ private static boolean sSaveSDCard = false;
+
+ public static boolean isSaveSDCard() {
+ return sSaveSDCard;
+ }
+
+ public static void setSaveSDCard(boolean saveSDCard) {
+ sSaveSDCard = saveSDCard;
+ }
+
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static void setImageSize(ContentValues values, int width, int height) {
// The two fields are available since ICS but got published in JB
@@ -63,14 +74,20 @@ public class Storage {
}
}
- public static void writeFile(String path, byte[] jpeg, ExifInterface exif) {
- if (exif != null) {
+ public static void writeFile(String path, byte[] jpeg, ExifInterface exif,
+ String mimeType) {
+ if (exif != null && (mimeType == null ||
+ mimeType.equalsIgnoreCase("jpeg"))) {
try {
exif.writeExif(jpeg, path);
} catch (Exception e) {
Log.e(TAG, "Failed to write data", e);
}
- } else {
+ } else if (jpeg != null) {
+ if (!(mimeType.equalsIgnoreCase("jpeg") || mimeType == null)) {
+ File dir = new File(RAW_DIRECTORY);
+ dir.mkdirs();
+ }
writeFile(path, jpeg);
}
}
@@ -91,22 +108,13 @@ public class Storage {
}
}
- // Save the image and add it to the MediaStore.
- public static Uri addImage(ContentResolver resolver, String title, long date,
- Location location, int orientation, ExifInterface exif, byte[] jpeg, int width,
- int height) {
-
- return addImage(resolver, title, date, location, orientation, exif, jpeg, width, height,
- LocalData.MIME_TYPE_JPEG);
- }
-
// Save the image with a given mimeType and add it the MediaStore.
public static Uri addImage(ContentResolver resolver, String title, long date,
Location location, int orientation, ExifInterface exif, byte[] jpeg, int width,
int height, String mimeType) {
- String path = generateFilepath(title);
- writeFile(path, jpeg, exif);
+ String path = generateFilepath(title, mimeType);
+ writeFile(path, jpeg, exif, mimeType);
return addImage(resolver, title, date, location, orientation,
jpeg.length, path, width, height, mimeType);
}
@@ -115,12 +123,18 @@ public class Storage {
public static ContentValues getContentValuesForData(String title,
long date, Location location, int orientation, int jpegLength,
String path, int width, int height, String mimeType) {
-
- ContentValues values = new ContentValues(11);
+ // Insert into MediaStore.
+ ContentValues values = new ContentValues(9);
values.put(ImageColumns.TITLE, title);
- values.put(ImageColumns.DISPLAY_NAME, title + JPEG_POSTFIX);
+ if (mimeType.equalsIgnoreCase("jpeg") ||
+ mimeType.equalsIgnoreCase("image/jpeg") ||
+ mimeType == null) {
+ values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
+ } else {
+ values.put(ImageColumns.DISPLAY_NAME, title + ".raw");
+ }
values.put(ImageColumns.DATE_TAKEN, date);
- values.put(ImageColumns.MIME_TYPE, mimeType);
+ values.put(ImageColumns.MIME_TYPE, "image/jpeg");
// Clockwise rotation in degrees. 0, 90, 180, or 270.
values.put(ImageColumns.ORIENTATION, orientation);
values.put(ImageColumns.DATA, path);
@@ -152,8 +166,8 @@ public class Storage {
public static void updateImage(Uri imageUri, ContentResolver resolver, String title, long date,
Location location, int orientation, ExifInterface exif, byte[] jpeg, int width,
int height, String mimeType) {
- String path = generateFilepath(title);
- writeFile(path, jpeg, exif);
+ String path = generateFilepath(title, mimeType);
+ writeFile(path, jpeg, exif, mimeType);
updateImage(imageUri, resolver, title, date, location, orientation, jpeg.length, path,
width, height, mimeType);
}
@@ -190,33 +204,55 @@ public class Storage {
}
}
- public static String generateFilepath(String title) {
- return DIRECTORY + '/' + title + ".jpg";
+ public static String generateFilepath(String title, String pictureFormat) {
+ if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg")) {
+ if (isSaveSDCard() && SDCard.instance().isWriteable()) {
+ return SDCard.instance().getDirectory() + '/' + title + ".jpg";
+ } else {
+ return DIRECTORY + '/' + title + ".jpg";
+ }
+ } else {
+ return RAW_DIRECTORY + '/' + title + ".raw";
+ }
}
public static long getAvailableSpace() {
- String state = Environment.getExternalStorageState();
- Log.d(TAG, "External storage state=" + state);
- if (Environment.MEDIA_CHECKING.equals(state)) {
- return PREPARING;
- }
- if (!Environment.MEDIA_MOUNTED.equals(state)) {
- return UNAVAILABLE;
- }
+ if (isSaveSDCard() && SDCard.instance().isWriteable()) {
+ File dir = new File(SDCard.instance().getDirectory());
+ dir.mkdirs();
+ try {
+ StatFs stat = new StatFs(SDCard.instance().getDirectory());
+ long ret = stat.getAvailableBlocks() * (long) stat.getBlockSize();
+ return ret;
+ } catch (Exception e) {
+ }
+ return UNKNOWN_SIZE;
+ } else if (isSaveSDCard() && !SDCard.instance().isWriteable()) {
+ return UNKNOWN_SIZE;
+ } else {
+ String state = Environment.getExternalStorageState();
+ Log.d(TAG, "External storage state=" + state);
+ if (Environment.MEDIA_CHECKING.equals(state)) {
+ return PREPARING;
+ }
+ if (!Environment.MEDIA_MOUNTED.equals(state)) {
+ return UNAVAILABLE;
+ }
- File dir = new File(DIRECTORY);
- dir.mkdirs();
- if (!dir.isDirectory() || !dir.canWrite()) {
- return UNAVAILABLE;
- }
+ File dir = new File(DIRECTORY);
+ dir.mkdirs();
+ if (!dir.isDirectory() || !dir.canWrite()) {
+ return UNAVAILABLE;
+ }
- try {
- StatFs stat = new StatFs(DIRECTORY);
- return stat.getAvailableBlocks() * (long) stat.getBlockSize();
- } catch (Exception e) {
- Log.i(TAG, "Fail to access external storage", e);
+ try {
+ StatFs stat = new StatFs(DIRECTORY);
+ return stat.getAvailableBlocks() * (long) stat.getBlockSize();
+ } catch (Exception e) {
+ Log.i(TAG, "Fail to access external storage", e);
+ }
+ return UNKNOWN_SIZE;
}
- return UNKNOWN_SIZE;
}
/**
diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java
index e84654821..cf694a391 100644
--- a/src/com/android/camera/VideoController.java
+++ b/src/com/android/camera/VideoController.java
@@ -19,8 +19,9 @@ package com.android.camera;
import android.view.View;
import com.android.camera.ShutterButton.OnShutterButtonListener;
+import com.android.camera.PauseButton.OnPauseButtonListener;
-public interface VideoController extends OnShutterButtonListener {
+public interface VideoController extends OnShutterButtonListener, OnPauseButtonListener {
public void onReviewDoneClicked(View view);
public void onReviewCancelClicked(View viwe);
diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java
index f0c7db272..440c70c46 100644
--- a/src/com/android/camera/VideoMenu.java
+++ b/src/com/android/camera/VideoMenu.java
@@ -36,13 +36,17 @@ public class VideoMenu extends PieController
private static String TAG = "CAM_VideoMenu";
private VideoUI mUI;
- private String[] mOtherKeys;
- private AbstractSettingPopup mPopup;
+ private String[] mOtherKeys1;
+ private String[] mOtherKeys2;
+
+ private AbstractSettingPopup mPopup1;
+ private AbstractSettingPopup mPopup2;
private static final int POPUP_NONE = 0;
private static final int POPUP_FIRST_LEVEL = 1;
private static final int POPUP_SECOND_LEVEL = 2;
private int mPopupStatus;
+ private int popupNum;
private CameraActivity mActivity;
public VideoMenu(CameraActivity activity, VideoUI ui, PieRenderer pie) {
@@ -51,37 +55,66 @@ public class VideoMenu extends PieController
mActivity = activity;
}
-
public void initialize(PreferenceGroup group) {
super.initialize(group);
- mPopup = null;
+ mPopup1 = null;
+ mPopup2 = null;
+ popupNum = 0;
mPopupStatus = POPUP_NONE;
PieItem item = null;
- // white balance
- if (group.findPreference(CameraSettings.KEY_WHITE_BALANCE) != null) {
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE);
- mRenderer.addItem(item);
- }
// settings popup
- mOtherKeys = new String[] {
+ mOtherKeys1 = new String[] {
+ CameraSettings.KEY_DIS,
CameraSettings.KEY_VIDEO_EFFECT,
CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
CameraSettings.KEY_VIDEO_QUALITY,
- CameraSettings.KEY_RECORD_LOCATION
+ CameraSettings.KEY_VIDEO_ENCODER,
+ CameraSettings.KEY_AUDIO_ENCODER,
+ CameraSettings.KEY_VIDEO_DURATION,
+ CameraSettings.KEY_RECORD_LOCATION,
+ CameraSettings.KEY_CAMERA_SAVEPATH
};
- item = makeItem(R.drawable.ic_settings_holo_light);
- item.setLabel(mActivity.getResources().getString(R.string.camera_menu_settings_label));
- item.setOnClickListener(new OnClickListener() {
+
+ //settings popup
+ mOtherKeys2 = new String[] {
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_VIDEO_HDR,
+ CameraSettings.KEY_POWER_MODE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,
+ CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
+ };
+
+ PieItem item1 = makeItem(R.drawable.ic_settings_holo_light);
+ item1.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label));
+ item1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(PieItem item) {
- if (mPopup == null || mPopupStatus != POPUP_FIRST_LEVEL) {
+ if (mPopup1 == null || mPopupStatus != POPUP_FIRST_LEVEL) {
initializePopup();
mPopupStatus = POPUP_FIRST_LEVEL;
}
- mUI.showPopup(mPopup);
+ mUI.showPopup(mPopup1);
+ popupNum = 1;
}
});
- mRenderer.addItem(item);
+ mRenderer.addItem(item1);
+
+ PieItem item2 = makeItem(R.drawable.ic_settings_holo_light);
+ item2.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label));
+ item2.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(PieItem item) {
+ if (mPopup2 == null || mPopupStatus != POPUP_FIRST_LEVEL) {
+ initializePopup();
+ mPopupStatus = POPUP_FIRST_LEVEL;
+ }
+ mUI.showPopup(mPopup2);
+ popupNum = 2;
+ }
+ });
+ mRenderer.addItem(item2);
+
// camera switcher
if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) {
item = makeItem(R.drawable.ic_switch_back);
@@ -114,37 +147,38 @@ public class VideoMenu extends PieController
});
mRenderer.addItem(item);
}
- // flash
- if (group.findPreference(CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE) != null) {
- item = makeItem(CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);
- mRenderer.addItem(item);
- }
}
@Override
public void reloadPreferences() {
super.reloadPreferences();
- if (mPopup != null) {
- mPopup.reloadPreference();
+ if (mPopup1 != null) {
+ mPopup1.reloadPreference();
+ }
+ if (mPopup2 != null) {
+ mPopup2.reloadPreference();
}
}
@Override
public void overrideSettings(final String ... keyvalues) {
super.overrideSettings(keyvalues);
- if (mPopup == null || mPopupStatus != POPUP_FIRST_LEVEL) {
+ if (((mPopup1 == null) && (mPopup2 == null)) || mPopupStatus != POPUP_FIRST_LEVEL) {
mPopupStatus = POPUP_FIRST_LEVEL;
initializePopup();
}
- ((MoreSettingPopup) mPopup).overrideSettings(keyvalues);
+ ((MoreSettingPopup) mPopup1).overrideSettings(keyvalues);
+ ((MoreSettingPopup) mPopup2).overrideSettings(keyvalues);
}
@Override
// Hit when an item in the second-level popup gets selected
public void onListPrefChanged(ListPreference pref) {
- if (mPopup != null) {
+ if (mPopup1 != null && mPopup2 != null) {
if (mPopupStatus == POPUP_SECOND_LEVEL) {
mUI.dismissPopup(true);
+ mPopup1.reloadPreference();
+ mPopup2.reloadPreference();
}
}
super.onSettingChanged(pref);
@@ -154,15 +188,21 @@ public class VideoMenu extends PieController
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- MoreSettingPopup popup = (MoreSettingPopup) inflater.inflate(
+ MoreSettingPopup popup1 = (MoreSettingPopup) inflater.inflate(
R.layout.more_setting_popup, null, false);
- popup.setSettingChangedListener(this);
- popup.initialize(mPreferenceGroup, mOtherKeys);
+ popup1.setSettingChangedListener(this);
+ popup1.initialize(mPreferenceGroup, mOtherKeys1);
if (mActivity.isSecureCamera()) {
// Prevent location preference from getting changed in secure camera mode
- popup.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false);
+ popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false);
}
- mPopup = popup;
+ mPopup1 = popup1;
+
+ MoreSettingPopup popup2 = (MoreSettingPopup) inflater.inflate(
+ R.layout.more_setting_popup, null, false);
+ popup2.setSettingChangedListener(this);
+ popup2.initialize(mPreferenceGroup, mOtherKeys2);
+ mPopup2 = popup2;
}
public void popupDismissed(boolean topPopupOnly) {
@@ -170,7 +210,12 @@ public class VideoMenu extends PieController
if (mPopupStatus == POPUP_SECOND_LEVEL) {
initializePopup();
mPopupStatus = POPUP_FIRST_LEVEL;
- if (topPopupOnly) mUI.showPopup(mPopup);
+ if (topPopupOnly) {
+ if(popupNum == 1) mUI.showPopup(mPopup1);
+ else if(popupNum == 2) mUI.showPopup(mPopup2);
+ }
+ } else {
+ initializePopup();
}
}
@@ -189,16 +234,17 @@ public class VideoMenu extends PieController
timeInterval.initialize((IconListPreference) pref);
timeInterval.setSettingChangedListener(this);
mUI.dismissPopup(true);
- mPopup = timeInterval;
+ mPopup1 = timeInterval;
} else {
ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate(
R.layout.list_pref_setting_popup, null, false);
basic.initialize(pref);
basic.setSettingChangedListener(this);
mUI.dismissPopup(true);
- mPopup = basic;
+ mPopup1 = basic;
}
- mUI.showPopup(mPopup);
+ mUI.showPopup(mPopup1);
mPopupStatus = POPUP_SECOND_LEVEL;
}
+
}
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 92a2a9493..20b11d61e 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -29,6 +29,8 @@ import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
@@ -41,6 +43,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemProperties;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.provider.MediaStore;
@@ -52,6 +55,8 @@ import android.view.OrientationEventListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
+import android.media.EncoderCapabilities;
+import android.media.EncoderCapabilities.VideoEncoderCap;
import com.android.camera.CameraManager.CameraPictureCallback;
import com.android.camera.CameraManager.CameraProxy;
@@ -63,13 +68,14 @@ import com.android.camera.util.ApiHelper;
import com.android.camera.util.CameraUtil;
import com.android.camera.util.UsageStatistics;
import com.android.camera2.R;
-
+import com.android.camera.PhotoModule;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.HashMap;
public class VideoModule implements CameraModule,
VideoController,
@@ -113,6 +119,8 @@ public class VideoModule implements CameraModule,
private ComboPreferences mPreferences;
private PreferenceGroup mPreferenceGroup;
+ private boolean mSaveToSDCard = false;
+
// Preference must be read before starting preview. We check this before starting
// preview.
private boolean mPreferenceRead;
@@ -124,7 +132,9 @@ public class VideoModule implements CameraModule,
private boolean mSwitchingCamera;
private boolean mMediaRecorderRecording = false;
+ private boolean mMediaRecorderPausing = false;
private long mRecordingStartTime;
+ private long mRecordingTotalTime;
private boolean mRecordingTimeCountsDown = false;
private long mOnResumeTime;
// The video file that the hardware camera is about to record into
@@ -161,7 +171,6 @@ public class VideoModule implements CameraModule,
private LocationManager mLocationManager;
private OrientationManager mOrientationManager;
-
private int mPendingSwitchCameraId;
private final Handler mHandler = new MainHandler();
private VideoUI mUI;
@@ -172,6 +181,14 @@ public class VideoModule implements CameraModule,
private int mZoomValue; // The current zoom value.
+ private boolean mStartRecPending = false;
+ private boolean mStopRecPending = false;
+ private boolean mStartPrevPending = false;
+ private boolean mStopPrevPending = false;
+
+ // The preview window is on focus
+ private boolean mPreviewFocused = false;
+
private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener =
new MediaSaveService.OnMediaSavedListener() {
@Override
@@ -214,8 +231,78 @@ public class VideoModule implements CameraModule,
return;
}
mParameters = mCameraDevice.getParameters();
+ mPreviewFocused = true;
+ }
+
+ //QCOM data Members Starts here
+ static class DefaultHashMap<K, V> extends HashMap<K, V> {
+ private V mDefaultValue;
+
+ public void putDefault(V defaultValue) {
+ mDefaultValue = defaultValue;
+ }
+
+ @Override
+ public V get(Object key) {
+ V value = super.get(key);
+ return (value == null) ? mDefaultValue : value;
+ }
+ public K getKey(V toCheck) {
+ Iterator<K> it = this.keySet().iterator();
+ V val;
+ K key;
+ while(it.hasNext()) {
+ key = it.next();
+ val = this.get(key);
+ if (val.equals(toCheck)) {
+ return key;
+ }
+ }
+ return null;
+ }
}
+
+ private static final DefaultHashMap<String, Integer>
+ OUTPUT_FORMAT_TABLE = new DefaultHashMap<String, Integer>();
+ private static final DefaultHashMap<String, Integer>
+ VIDEO_ENCODER_TABLE = new DefaultHashMap<String, Integer>();
+ private static final DefaultHashMap<String, Integer>
+ AUDIO_ENCODER_TABLE = new DefaultHashMap<String, Integer>();
+ private static final DefaultHashMap<String, Integer>
+ VIDEOQUALITY_BITRATE_TABLE = new DefaultHashMap<String, Integer>();
+
+ static {
+ OUTPUT_FORMAT_TABLE.put("3gp", MediaRecorder.OutputFormat.THREE_GPP);
+ OUTPUT_FORMAT_TABLE.put("mp4", MediaRecorder.OutputFormat.MPEG_4);
+ OUTPUT_FORMAT_TABLE.putDefault(MediaRecorder.OutputFormat.DEFAULT);
+
+ VIDEO_ENCODER_TABLE.put("h263", MediaRecorder.VideoEncoder.H263);
+ VIDEO_ENCODER_TABLE.put("h264", MediaRecorder.VideoEncoder.H264);
+ VIDEO_ENCODER_TABLE.put("m4v", MediaRecorder.VideoEncoder.MPEG_4_SP);
+ VIDEO_ENCODER_TABLE.putDefault(MediaRecorder.VideoEncoder.DEFAULT);
+
+ AUDIO_ENCODER_TABLE.put("amrnb", MediaRecorder.AudioEncoder.AMR_NB);
+ // Enabled once support is added in MediaRecorder.
+ // AUDIO_ENCODER_TABLE.put("qcelp", MediaRecorder.AudioEncoder.QCELP);
+ // AUDIO_ENCODER_TABLE.put("evrc", MediaRecorder.AudioEncoder.EVRC);
+ AUDIO_ENCODER_TABLE.put("amrwb", MediaRecorder.AudioEncoder.AMR_WB);
+ AUDIO_ENCODER_TABLE.put("aac", MediaRecorder.AudioEncoder.AAC);
+ AUDIO_ENCODER_TABLE.putDefault(MediaRecorder.AudioEncoder.DEFAULT);
+
+ }
+
+ private int mVideoEncoder;
+ private int mAudioEncoder;
+ private boolean mRestartPreview = false;
+ private int videoWidth;
+ private int videoHeight;
+ boolean mUnsupportedResolution = false;
+ private boolean mUnsupportedHFRVideoSize = false;
+ private boolean mUnsupportedHSRVideoSize = false;
+ private boolean mUnsupportedHFRVideoCodec = false;
+ private String mDefaultAntibanding = null;
+
// This Handler is used to post message back onto the main thread of the
// application
private class MainHandler extends Handler {
@@ -342,6 +429,9 @@ public class VideoModule implements CameraModule,
mContentResolver = mActivity.getContentResolver();
+ Storage.setSaveSDCard(
+ mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
+ mSaveToSDCard = Storage.isSaveSDCard();
// Surface texture is from camera screen nail and startPreview needs it.
// This must be done before startPreview.
mIsVideoCaptureIntent = isVideoCaptureIntent();
@@ -378,12 +468,14 @@ public class VideoModule implements CameraModule,
// Preview area is touched. Take a picture.
@Override
public void onSingleTapUp(View view, int x, int y) {
+ if (mMediaRecorderPausing) return;
takeASnapshot();
}
private void takeASnapshot() {
// Only take snapshots if video snapshot is supported by device
- if (CameraUtil.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
+ if (CameraUtil.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent
+ && !is4KEnabled()) {
if (!mMediaRecorderRecording || mPaused || mSnapshotInProgress) {
return;
}
@@ -418,6 +510,36 @@ public class VideoModule implements CameraModule,
// Remove the video quality preference setting when the quality is given in the intent.
mPreferenceGroup = filterPreferenceScreenByIntent(
settings.getPreferenceGroup(R.xml.video_preferences));
+
+ int numOfCams = Camera.getNumberOfCameras();
+ int backCamId = CameraHolder.instance().getBackCameraId();
+ int frontCamId = CameraHolder.instance().getFrontCameraId();
+ // We need to swap the list preference contents if back camera and front camera
+ // IDs are not 0 and 1 respectively
+ if( (numOfCams == 2) && ((backCamId != CameraInfo.CAMERA_FACING_BACK)
+ || (frontCamId != CameraInfo.CAMERA_FACING_FRONT))) {
+ Log.e(TAG,"loadCameraPreferences() updating camera_id pref");
+
+ IconListPreference switchIconPref =
+ (IconListPreference)mPreferenceGroup.findPreference(
+ CameraSettings.KEY_CAMERA_ID);
+
+ int[] iconIds = {R.drawable.ic_switch_front, R.drawable.ic_switch_back};
+ switchIconPref.setIconIds(iconIds);
+
+ String[] entries = {mActivity.getResources().getString(
+ R.string.pref_camera_id_entry_front), mActivity.getResources().
+ getString(R.string.pref_camera_id_entry_back)};
+ switchIconPref.setEntries(entries);
+
+ String[] labels = {mActivity.getResources().getString(
+ R.string.pref_camera_id_label_front), mActivity.getResources().
+ getString(R.string.pref_camera_id_label_back)};
+ switchIconPref.setLabels(labels);
+
+ int[] largeIconIds = {R.drawable.ic_switch_front, R.drawable.ic_switch_back};
+ switchIconPref.setLargeIconIds(largeIconIds);
+ }
}
private void initializeVideoControl() {
@@ -435,6 +557,10 @@ public class VideoModule implements CameraModule,
if (mOrientation != newOrientation) {
mOrientation = newOrientation;
+ Log.v(TAG, "onOrientationChanged, update parameters");
+ if ((mParameters != null) && (true == mPreviewing) && !mMediaRecorderRecording){
+ setCameraParameters();
+ }
}
// Show the toast after getting the first orientation changed.
@@ -520,12 +646,33 @@ public class VideoModule implements CameraModule,
// Consume clicks
}
+ public boolean isPreviewReady() {
+ if ((mStartPrevPending == true || mStopPrevPending == true))
+ return false;
+ else
+ return true;
+ }
+
+ public boolean isRecorderReady() {
+ if ((mStartRecPending == true || mStopRecPending == true))
+ return false;
+ else
+ return true;
+ }
+
@Override
public void onShutterButtonClick() {
- if (mUI.collapseCameraControls() || mSwitchingCamera) return;
+ if (mPaused || mUI.collapseCameraControls() ||
+ mSwitchingCamera) return;
boolean stop = mMediaRecorderRecording;
+ if (isPreviewReady() == false)
+ return;
+
+ if (isRecorderReady() == false)
+ return;
+
if (stop) {
onStopVideoRecording();
} else {
@@ -547,15 +694,81 @@ public class VideoModule implements CameraModule,
mUI.setShutterPressed(pressed);
}
+ @Override
+ public void onShutterButtonLongClick() {}
+
+ private void qcomReadVideoPreferences() {
+ String videoEncoder = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_ENCODER,
+ mActivity.getString(R.string.pref_camera_videoencoder_default));
+ mVideoEncoder = VIDEO_ENCODER_TABLE.get(videoEncoder);
+
+ Log.v(TAG, "Video Encoder selected = " +mVideoEncoder);
+
+ String audioEncoder = mPreferences.getString(
+ CameraSettings.KEY_AUDIO_ENCODER,
+ mActivity.getString(R.string.pref_camera_audioencoder_default));
+ mAudioEncoder = AUDIO_ENCODER_TABLE.get(audioEncoder);
+
+ Log.v(TAG, "Audio Encoder selected = " +mAudioEncoder);
+
+ String minutesStr = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_DURATION,
+ mActivity.getString(R.string.pref_camera_video_duration_default));
+ int minutes = -1;
+ try {
+ minutes = Integer.parseInt(minutesStr);
+ } catch(NumberFormatException npe) {
+ // use default value continue
+ minutes = Integer.parseInt(mActivity.getString(
+ R.string.pref_camera_video_duration_default));
+ }
+ if (minutes == -1) {
+ // User wants lowest, set 30s */
+ mMaxVideoDurationInMs = 30000;
+ } else {
+ // 1 minute = 60000ms
+ mMaxVideoDurationInMs = 60000 * minutes;
+ }
+
+ if(mParameters.isPowerModeSupported()) {
+ String powermode = mPreferences.getString(
+ CameraSettings.KEY_POWER_MODE,
+ mActivity.getString(R.string.pref_camera_powermode_default));
+ Log.v(TAG, "read videopreferences power mode =" +powermode);
+ String old_mode = mParameters.getPowerMode();
+ if(!old_mode.equals(powermode) && mPreviewing)
+ mRestartPreview = true;
+
+ mParameters.setPowerMode(powermode);
+ }
+
+ // Set wavelet denoise mode
+ if (mParameters.getSupportedDenoiseModes() != null) {
+ String denoise = mPreferences.getString(CameraSettings.KEY_DENOISE,
+ mActivity.getString(R.string.pref_camera_denoise_default));
+ mParameters.setDenoise(denoise);
+ }
+ }
+
private void readVideoPreferences() {
// The preference stores values from ListPreference and is thus string type for all values.
// We need to convert it to int manually.
String videoQuality = mPreferences.getString(CameraSettings.KEY_VIDEO_QUALITY,
null);
if (videoQuality == null) {
- // check for highest quality before setting default value
- videoQuality = CameraSettings.getSupportedHighestVideoQuality(mCameraId,
- mActivity.getResources().getString(R.string.pref_video_quality_default));
+ mParameters = mCameraDevice.getParameters();
+ String defaultQuality = mActivity.getResources().getString(
+ R.string.pref_video_quality_default);
+ boolean hasProfile = CamcorderProfile.hasProfile(
+ Integer.parseInt(defaultQuality));
+ if (hasProfile == true){
+ videoQuality = defaultQuality;
+ } else {
+ // check for highest quality if default quality is not supported
+ videoQuality = CameraSettings.getSupportedHighestVideoQuality(mCameraId,
+ defaultQuality, mParameters);
+ }
mPreferences.edit().putString(CameraSettings.KEY_VIDEO_QUALITY, videoQuality);
}
int quality = Integer.valueOf(videoQuality);
@@ -592,9 +805,19 @@ public class VideoModule implements CameraModule,
if (mCaptureTimeLapse) quality += 1000;
mProfile = CamcorderProfile.get(mCameraId, quality);
getDesiredPreviewSize();
+ qcomReadVideoPreferences();
mPreferenceRead = true;
}
+ private boolean is4KEnabled() {
+ if (mProfile.quality == CamcorderProfile.QUALITY_4kUHD ||
+ mProfile.quality == CamcorderProfile.QUALITY_4kDCI) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void getDesiredPreviewSize() {
if (mCameraDevice == null) {
@@ -626,7 +849,19 @@ public class VideoModule implements CameraModule,
". mDesiredPreviewHeight=" + mDesiredPreviewHeight);
}
- private void resizeForPreviewAspectRatio() {
+ void setPreviewFrameLayoutCameraOrientation(){
+ CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+
+ //if camera mount angle is 0 or 180, we want to resize preview
+ if (info.orientation % 180 == 0)
+ mUI.cameraOrientationPreviewResize(true);
+ else
+ mUI.cameraOrientationPreviewResize(false);
+ }
+
+ @Override
+ public void resizeForPreviewAspectRatio() {
+ setPreviewFrameLayoutCameraOrientation();
mUI.setAspectRatio(
(double) mProfile.videoFrameWidth / mProfile.videoFrameHeight);
}
@@ -686,6 +921,12 @@ public class VideoModule implements CameraModule,
UsageStatistics.onContentViewChanged(
UsageStatistics.COMPONENT_CAMERA, "VideoModule");
+ mHandler.post(new Runnable(){
+ @Override
+ public void run(){
+ mActivity.updateStorageSpaceAndHint();
+ }
+ });
}
private void setDisplayOrientation() {
@@ -721,10 +962,12 @@ public class VideoModule implements CameraModule,
private void startPreview() {
Log.v(TAG, "startPreview");
+ mStartPrevPending = true;
SurfaceTexture surfaceTexture = mUI.getSurfaceTexture();
if (!mPreferenceRead || surfaceTexture == null || mPaused == true ||
mCameraDevice == null) {
+ mStartPrevPending = false;
return;
}
@@ -746,6 +989,7 @@ public class VideoModule implements CameraModule,
closeCamera();
throw new RuntimeException("startPreview failed", ex);
}
+ mStartPrevPending = false;
}
private void onPreviewStarted() {
@@ -754,9 +998,16 @@ public class VideoModule implements CameraModule,
@Override
public void stopPreview() {
- if (!mPreviewing) return;
+ mStopPrevPending = true;
+
+ if (!mPreviewing) {
+ mStopPrevPending = false;
+ return;
+ }
mCameraDevice.stopPreview();
mPreviewing = false;
+ mStopPrevPending = false;
+ mUI.enableShutter(false);
}
private void closeCamera() {
@@ -771,6 +1022,7 @@ public class VideoModule implements CameraModule,
mCameraDevice = null;
mPreviewing = false;
mSnapshotInProgress = false;
+ mPreviewFocused = false;
}
private void releasePreviewResources() {
@@ -946,6 +1198,35 @@ public class VideoModule implements CameraModule,
Intent intent = mActivity.getIntent();
Bundle myExtras = intent.getExtras();
+ videoWidth = mProfile.videoFrameWidth;
+ videoHeight = mProfile.videoFrameHeight;
+ mUnsupportedResolution = false;
+
+ //check if codec supports the resolution, otherwise throw toast
+ List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
+ for (VideoEncoderCap videoEncoder: videoEncoders) {
+ if (videoEncoder.mCodec == mVideoEncoder){
+ if (videoWidth > videoEncoder.mMaxFrameWidth ||
+ videoWidth < videoEncoder.mMinFrameWidth ||
+ videoHeight > videoEncoder.mMaxFrameHeight ||
+ videoHeight < videoEncoder.mMinFrameHeight){
+ Log.e(TAG,"Selected codec "+mVideoEncoder+
+ " does not support "+ videoWidth + "x" + videoHeight
+ +" resolution");
+ Log.e(TAG, "Codec capabilities: " +
+ "mMinFrameWidth = " + videoEncoder.mMinFrameWidth + " , "+
+ "mMinFrameHeight = " + videoEncoder.mMinFrameHeight + " , "+
+ "mMaxFrameWidth = " + videoEncoder.mMaxFrameWidth + " , "+
+ "mMaxFrameHeight = " + videoEncoder.mMaxFrameHeight);
+ mUnsupportedResolution = true;
+ Toast.makeText(mActivity, R.string.error_app_unsupported,
+ Toast.LENGTH_LONG).show();
+ return;
+ }
+ break;
+ }
+ }
+
long requestedSizeLimit = 0;
closeVideoFileDescriptor();
mCurrentVideoUriFromMediaSaved = false;
@@ -968,10 +1249,19 @@ public class VideoModule implements CameraModule,
// Unlock the camera object before passing it to media recorder.
mCameraDevice.unlock();
mMediaRecorder.setCamera(mCameraDevice.getCamera());
- if (!mCaptureTimeLapse) {
+ String hfr = mParameters.getVideoHighFrameRate();
+ if (!mCaptureTimeLapse && ((hfr == null) || ("off".equals(hfr)))) {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ mProfile.audioCodec = mAudioEncoder;
+ } else {
+ mProfile.audioCodec = -1; //not set
}
+
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+ mProfile.videoCodec = mVideoEncoder;
+ mProfile.duration = mMaxVideoDurationInMs;
+
mMediaRecorder.setProfile(mProfile);
mMediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
@@ -1065,7 +1355,12 @@ public class VideoModule implements CameraModule,
// Used when emailing.
String filename = title + convertOutputFormatToFileExt(outputFileFormat);
String mime = convertOutputFormatToMimeType(outputFileFormat);
- String path = Storage.DIRECTORY + '/' + filename;
+ String path = null;
+ if (Storage.isSaveSDCard() && SDCard.instance().isWriteable()) {
+ path = SDCard.instance().getDirectory() + '/' + filename;
+ } else {
+ path = Storage.DIRECTORY + '/' + filename;
+ }
String tmpPath = path + ".tmp";
mCurrentVideoValues = new ContentValues(9);
mCurrentVideoValues.put(Video.Media.TITLE, title);
@@ -1088,7 +1383,7 @@ public class VideoModule implements CameraModule,
private void saveVideo() {
if (mVideoFileDescriptor == null) {
- long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
+ long duration = SystemClock.uptimeMillis() - mRecordingStartTime + mRecordingTotalTime;
if (duration > 0) {
if (mCaptureTimeLapse) {
duration = getTimeLapseVideoLength(duration);
@@ -1096,6 +1391,29 @@ public class VideoModule implements CameraModule,
} else {
Log.w(TAG, "Video duration <= 0 : " + duration);
}
+
+ File origFile = new File(mCurrentVideoFilename);
+ if (!origFile.exists() || origFile.length() <= 0) {
+ Log.e(TAG, "Invalid file");
+ mCurrentVideoValues = null;
+ return;
+ }
+
+ /* Change the duration as per HFR selection */
+ String hfr = mParameters.getVideoHighFrameRate();
+ int defaultFps = 30;
+ int hfrRatio = 1;
+ if (!("off".equals(hfr))) {
+ try {
+ int hfrFps = Integer.parseInt(hfr);
+ hfrRatio = hfrFps / defaultFps;
+ } catch(NumberFormatException ex) {
+ //Default value will be used
+ Log.e(TAG,"Invalid hfr values:"+hfr);
+ }
+ }
+ duration = duration * hfrRatio;
+
mActivity.getMediaSaveService().addVideo(mCurrentVideoFilename,
duration, mCurrentVideoValues,
mOnVideoSavedListener, mContentResolver);
@@ -1130,9 +1448,9 @@ public class VideoModule implements CameraModule,
@Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
+ stopVideoRecording();
if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
// We may have run out of space on the sdcard.
- stopVideoRecording();
mActivity.updateStorageSpaceAndHint();
}
}
@@ -1171,22 +1489,51 @@ public class VideoModule implements CameraModule,
private void startVideoRecording() {
Log.v(TAG, "startVideoRecording");
+ mStartRecPending = true;
mUI.cancelAnimations();
mUI.setSwipingEnabled(false);
mActivity.updateStorageSpaceAndHint();
if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
Log.v(TAG, "Storage issue, ignore the start request");
+ mStartRecPending = false;
+ return;
+ }
+
+ if( mUnsupportedHFRVideoSize == true) {
+ Log.e(TAG, "Unsupported HFR and video size combinations");
+ Toast.makeText(mActivity,R.string.error_app_unsupported_hfr, Toast.LENGTH_SHORT).show();
+ mStartRecPending = false;
return;
}
+ if (mUnsupportedHSRVideoSize == true) {
+ Log.e(TAG, "Unsupported HSR and video size combinations");
+ Toast.makeText(mActivity,R.string.error_app_unsupported_hsr, Toast.LENGTH_SHORT).show();
+ mStartRecPending = false;
+ return;
+ }
+
+ if( mUnsupportedHFRVideoCodec == true) {
+ Log.e(TAG, "Unsupported HFR and video codec combinations");
+ Toast.makeText(mActivity, R.string.error_app_unsupported_hfr_codec,
+ Toast.LENGTH_SHORT).show();
+ mStartRecPending = false;
+ return;
+ }
//??
//if (!mCameraDevice.waitDone()) return;
mCurrentVideoUri = null;
initializeRecorder();
+ if (mUnsupportedResolution == true) {
+ Log.v(TAG, "Unsupported Resolution according to target");
+ mStartRecPending = false;
+ return;
+ }
if (mMediaRecorder == null) {
Log.e(TAG, "Fail to initialize media recorder");
+ mStartRecPending = false;
return;
}
@@ -1199,6 +1546,7 @@ public class VideoModule implements CameraModule,
releaseMediaRecorder();
// If start fails, frameworks will not lock the camera for us.
mCameraDevice.lock();
+ mStartRecPending = false;
return;
}
@@ -1219,7 +1567,10 @@ public class VideoModule implements CameraModule,
mUI.enableCameraControls(false);
mMediaRecorderRecording = true;
+ mMediaRecorderPausing = false;
+ mUI.resetPauseButton();
mOrientationManager.lockOrientation();
+ mRecordingTotalTime = 0L;
mRecordingStartTime = SystemClock.uptimeMillis();
mUI.showRecordingUI(true);
@@ -1227,6 +1578,7 @@ public class VideoModule implements CameraModule,
keepScreenOn();
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_CAPTURE_START, "Video");
+ mStartRecPending = false;
}
private Bitmap getVideoThumbnail() {
@@ -1266,8 +1618,24 @@ public class VideoModule implements CameraModule,
mUI.showTimeLapseUI(false);
}
+ private void pauseVideoRecording() {
+ Log.v(TAG, "pauseVideoRecording");
+ mMediaRecorderPausing = true;
+ mRecordingTotalTime += SystemClock.uptimeMillis() - mRecordingStartTime;
+ mMediaRecorder.pause();
+ }
+
+ private void resumeVideoRecording() {
+ Log.v(TAG, "resumeVideoRecording");
+ mMediaRecorderPausing = false;
+ mRecordingStartTime = SystemClock.uptimeMillis();
+ updateRecordingTime();
+ mMediaRecorder.start();
+ }
+
private boolean stopVideoRecording() {
Log.v(TAG, "stopVideoRecording");
+ mStopRecPending = true;
mUI.setSwipingEnabled(true);
if (!isVideoCaptureIntent()) {
mUI.showSwitcher();
@@ -1293,6 +1661,12 @@ public class VideoModule implements CameraModule,
fail = true;
}
mMediaRecorderRecording = false;
+
+ //If recording stops while snapshot is in progress, we might not get jpeg callback
+ //because cameraservice will disable picture related messages. Hence reset the
+ //flag here so that we can take liveshots in the next recording session.
+ mSnapshotInProgress = false;
+
mOrientationManager.unlockOrientation();
// If the activity is paused, this means activity is interrupted
@@ -1336,7 +1710,8 @@ public class VideoModule implements CameraModule,
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
fail ? UsageStatistics.ACTION_CAPTURE_FAIL :
UsageStatistics.ACTION_CAPTURE_DONE, "Video",
- SystemClock.uptimeMillis() - mRecordingStartTime);
+ SystemClock.uptimeMillis() - mRecordingStartTime + mRecordingTotalTime);
+ mStopRecPending = false;
return fail;
}
@@ -1412,8 +1787,12 @@ public class VideoModule implements CameraModule,
if (!mMediaRecorderRecording) {
return;
}
+ if (mMediaRecorderPausing) {
+ return;
+ }
+
long now = SystemClock.uptimeMillis();
- long delta = now - mRecordingStartTime;
+ long delta = now - mRecordingStartTime + mRecordingTotalTime;
// Starting a minute before reaching the max duration
// limit, we'll countdown the remaining time instead.
@@ -1461,8 +1840,245 @@ public class VideoModule implements CameraModule,
return supported == null ? false : supported.indexOf(value) >= 0;
}
+ private void qcomSetCameraParameters(){
+ // add QCOM Parameters here
+ // Set color effect parameter.
+ String colorEffect = mPreferences.getString(
+ CameraSettings.KEY_COLOR_EFFECT,
+ mActivity.getString(R.string.pref_camera_coloreffect_default));
+ Log.v(TAG, "Color effect value =" + colorEffect);
+ if (isSupported(colorEffect, mParameters.getSupportedColorEffects())) {
+ mParameters.setColorEffect(colorEffect);
+ }
+
+ String disMode = mPreferences.getString(
+ CameraSettings.KEY_DIS,
+ mActivity.getString(R.string.pref_camera_dis_default));
+ Log.v(TAG, "DIS value =" + disMode);
+ if (isSupported(disMode,
+ CameraSettings.getSupportedDISModes(mParameters))) {
+ mParameters.set(CameraSettings.KEY_QC_DIS_MODE, disMode);
+ }
+
+ if (mDefaultAntibanding == null) {
+ mDefaultAntibanding = mParameters.getAntibanding();
+ Log.d(TAG, "default antibanding value = " + mDefaultAntibanding);
+ }
+
+ if (disMode.equals("enable")) {
+ Log.d(TAG, "dis is enabled, set antibanding to auto.");
+ if (isSupported(Parameters.ANTIBANDING_AUTO, mParameters.getSupportedAntibanding())) {
+ mParameters.setAntibanding(Parameters.ANTIBANDING_AUTO);
+ }
+ } else {
+ if (isSupported(mDefaultAntibanding, mParameters.getSupportedAntibanding())) {
+ mParameters.setAntibanding(mDefaultAntibanding);
+ }
+ }
+ Log.d(TAG, "antiBanding value = " + mParameters.getAntibanding());
+
+ mUnsupportedHFRVideoSize = false;
+ mUnsupportedHFRVideoCodec = false;
+ // To set preview format as YV12 , run command
+ // "adb shell setprop "debug.camera.yv12" true"
+ String yv12formatset = SystemProperties.get("debug.camera.yv12");
+ if(yv12formatset.equals("true")) {
+ Log.v(TAG, "preview format set to YV12");
+ mParameters.setPreviewFormat (ImageFormat.YV12);
+ }
+
+ // Set High Frame Rate.
+ String HighFrameRate = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,
+ mActivity. getString(R.string.pref_camera_hfr_default));
+
+ if(!("off".equals(HighFrameRate)) && !("hsr".equals(HighFrameRate))){
+ mUnsupportedHFRVideoSize = true;
+ String hfrsize = videoWidth+"x"+videoHeight;
+ Log.v(TAG, "current set resolution is : "+hfrsize);
+ try {
+ Size size = null;
+ if (isSupported(HighFrameRate,mParameters.getSupportedVideoHighFrameRateModes())) {
+ int index = mParameters.getSupportedVideoHighFrameRateModes().indexOf(
+ HighFrameRate);
+ size = mParameters.getSupportedHfrSizes().get(index);
+ }
+ if (size != null) {
+ Log.v(TAG, "supported hfr size : "+ size.width+ " "+size.height);
+ if (videoWidth <= size.width && videoHeight <= size.height) {
+ mUnsupportedHFRVideoSize = false;
+ Log.v(TAG,"Current hfr resolution is supported");
+ }
+ }
+ } catch (NullPointerException e){
+ Log.e(TAG, "supported hfr sizes is null");
+ }
+
+ int hfrFps = Integer.parseInt(HighFrameRate);
+ int inputBitrate = videoWidth*videoHeight*hfrFps;
+
+ //check if codec supports the resolution, otherwise throw toast
+ List<VideoEncoderCap> videoEncoders = EncoderCapabilities.getVideoEncoders();
+ for (VideoEncoderCap videoEncoder: videoEncoders) {
+ if (videoEncoder.mCodec == mVideoEncoder){
+ int maxBitrate = (videoEncoder.mMaxHFRFrameWidth *
+ videoEncoder.mMaxHFRFrameHeight *
+ videoEncoder.mMaxHFRMode);
+ if (inputBitrate > maxBitrate ){
+ Log.e(TAG,"Selected codec "+mVideoEncoder+
+ " does not support HFR " + HighFrameRate + " with "+ videoWidth
+ + "x" + videoHeight +" resolution");
+ Log.e(TAG, "Codec capabilities: " +
+ "mMaxHFRFrameWidth = " + videoEncoder.mMaxHFRFrameWidth + " , "+
+ "mMaxHFRFrameHeight = " + videoEncoder.mMaxHFRFrameHeight + " , "+
+ "mMaxHFRMode = " + videoEncoder.mMaxHFRMode);
+ mUnsupportedHFRVideoSize = true;
+ }
+ break;
+ }
+ }
+
+ if(mUnsupportedHFRVideoSize)
+ Log.v(TAG,"Unsupported hfr resolution");
+
+ if(mVideoEncoder != MediaRecorder.VideoEncoder.H264)
+ mUnsupportedHFRVideoCodec = true;
+ }
+ if (isSupported(HighFrameRate,
+ mParameters.getSupportedVideoHighFrameRateModes()) &&
+ !mUnsupportedHFRVideoSize &&
+ !("hsr".equals(HighFrameRate))) {
+ mParameters.setVideoHighFrameRate(HighFrameRate);
+ mParameters.set("video-hsr", "off");
+ }
+ else {
+ mParameters.setVideoHighFrameRate("off");
+ }
+ mUnsupportedHSRVideoSize = false;
+
+ if (("hsr".equals(HighFrameRate))) {
+ mUnsupportedHSRVideoSize = true;
+ String hsrsize = videoWidth+"x"+videoHeight;
+ Log.v(TAG, "current set resolution is : "+hsrsize);
+ try {
+ Size size = null;
+ if (isSupported("120",mParameters.getSupportedVideoHighFrameRateModes())) {
+ int index = mParameters.getSupportedVideoHighFrameRateModes().indexOf(
+ "120");
+ size = mParameters.getSupportedHfrSizes().get(index);
+ }
+ if (size != null) {
+ Log.v(TAG, "supported hsr size : "+ size.width+ " "+size.height);
+ if (videoWidth <= size.width && videoHeight <= size.height) {
+ mUnsupportedHSRVideoSize = false;
+ Log.v(TAG,"Current hsr resolution is supported");
+ }
+ }
+ } catch (NullPointerException e) {
+ Log.e(TAG, "supported hfr sizes is null");
+ }
+
+ if (mUnsupportedHSRVideoSize) Log.v(TAG,"Unsupported hsr resolution");
+ }
+
+ if (("hsr".equals(HighFrameRate)) && !mUnsupportedHSRVideoSize) {
+ mParameters.set("video-hsr", "on");
+ }
+ else {
+ mParameters.set("video-hsr", "off");
+ }
+
+ // Read Flip mode from adb command
+ //value: 0(default) - FLIP_MODE_OFF
+ //value: 1 - FLIP_MODE_H
+ //value: 2 - FLIP_MODE_V
+ //value: 3 - FLIP_MODE_VH
+ int preview_flip_value = SystemProperties.getInt("debug.camera.preview.flip", 0);
+ int video_flip_value = SystemProperties.getInt("debug.camera.video.flip", 0);
+ int picture_flip_value = SystemProperties.getInt("debug.camera.picture.flip", 0);
+ int rotation = CameraUtil.getJpegRotation(mCameraId, mOrientation);
+ mParameters.setRotation(rotation);
+ if (rotation == 90 || rotation == 270) {
+ // in case of 90 or 270 degree, V/H flip should reverse
+ if (preview_flip_value == 1) {
+ preview_flip_value = 2;
+ } else if (preview_flip_value == 2) {
+ preview_flip_value = 1;
+ }
+ if (video_flip_value == 1) {
+ video_flip_value = 2;
+ } else if (video_flip_value == 2) {
+ video_flip_value = 1;
+ }
+ if (picture_flip_value == 1) {
+ picture_flip_value = 2;
+ } else if (picture_flip_value == 2) {
+ picture_flip_value = 1;
+ }
+ }
+ String preview_flip = CameraUtil.getFilpModeString(preview_flip_value);
+ String video_flip = CameraUtil.getFilpModeString(video_flip_value);
+ String picture_flip = CameraUtil.getFilpModeString(picture_flip_value);
+
+ if(CameraUtil.isSupported(preview_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_PREVIEW_FLIP, preview_flip);
+ }
+ if(CameraUtil.isSupported(video_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_VIDEO_FLIP, video_flip);
+ }
+ if(CameraUtil.isSupported(picture_flip, CameraSettings.getSupportedFlipMode(mParameters))){
+ mParameters.set(CameraSettings.KEY_QC_SNAPSHOT_PICTURE_FLIP, picture_flip);
+ }
+
+ // Set Video HDR.
+ String videoHDR = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_HDR,
+ mActivity.getString(R.string.pref_camera_video_hdr_default));
+ Log.v(TAG, "Video HDR Setting =" + videoHDR);
+ if (isSupported(videoHDR, mParameters.getSupportedVideoHDRModes())) {
+ mParameters.setVideoHDRMode(videoHDR);
+ } else
+ mParameters.setVideoHDRMode("off");
+
+ //HFR/HSR recording not supported with DIS,TimeLapse,HDR option
+ String hfr = mParameters.getVideoHighFrameRate();
+ String hsr = mParameters.get("video-hsr");
+ String hdr = mParameters.getVideoHDRMode();
+ if ( ((hfr != null) && (!hfr.equals("off"))) ||
+ ((hsr != null) && (!hsr.equals("off"))) ) {
+ // Read time lapse recording interval.
+ String frameIntervalStr = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
+ mActivity.getString(R.string.pref_video_time_lapse_frame_interval_default));
+ int timeLapseInterval = Integer.parseInt(frameIntervalStr);
+ if ( (timeLapseInterval != 0) ||
+ (disMode.equals("enable")) ||
+ ((hdr != null) && (!hdr.equals("off"))) ) {
+ Log.v(TAG,"HDR/DIS/Time Lapse ON for HFR/HSR selection, turning HFR/HSR off");
+ Toast.makeText(mActivity, R.string.error_app_unsupported_hfr_selection,
+ Toast.LENGTH_LONG).show();
+ mParameters.setVideoHighFrameRate("off");
+ mParameters.set("video-hsr", "off");
+ mUI.overrideSettings(CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE,"off");
+ }
+ }
+
+ //getSupportedPictureSizes will always send a sorted a list in descending order
+ Size biggestSize = mParameters.getSupportedPictureSizes().get(0);
+
+ if (biggestSize.width <= videoWidth || biggestSize.height <= videoHeight) {
+ if (disMode.equals("enable")) {
+ Log.v(TAG,"DIS is not supported for this video quality");
+ Toast.makeText(mActivity, R.string.error_app_unsupported_dis,
+ Toast.LENGTH_LONG).show();
+ mParameters.set(CameraSettings.KEY_QC_DIS_MODE, "disable");
+ mUI.overrideSettings(CameraSettings.KEY_DIS,"disable");
+ }
+ }
+ }
@SuppressWarnings("deprecation")
private void setCameraParameters() {
+ Log.d(TAG,"Preview dimension in App->"+mDesiredPreviewWidth+"X"+mDesiredPreviewHeight);
mParameters.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
mParameters.set("video-size", mProfile.videoFrameWidth+"x"+mProfile.videoFrameHeight);
int[] fpsRange = CameraUtil.getMaxPreviewFpsRange(mParameters);
@@ -1474,8 +2090,12 @@ public class VideoModule implements CameraModule,
mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
}
- forceFlashOffIfSupported(!mUI.isVisible());
-
+ forceFlashOffIfSupported(!mPreviewFocused);
+ videoWidth = mProfile.videoFrameWidth;
+ videoHeight = mProfile.videoFrameHeight;
+ String recordSize = videoWidth + "x" + videoHeight;
+ Log.e(TAG,"Video dimension in App->"+recordSize);
+ mParameters.set("video-size", recordSize);
// Set white balance parameter.
String whiteBalance = mPreferences.getString(
CameraSettings.KEY_WHITE_BALANCE,
@@ -1492,6 +2112,8 @@ public class VideoModule implements CameraModule,
// Set zoom.
if (mParameters.isZoomSupported()) {
+ Parameters p = mCameraDevice.getParameters();
+ mZoomValue = p.getZoom();
mParameters.setZoom(mZoomValue);
}
@@ -1528,6 +2150,8 @@ public class VideoModule implements CameraModule,
int jpegQuality = CameraProfile.getJpegEncodingQualityParameter(mCameraId,
CameraProfile.QUALITY_HIGH);
mParameters.setJpegQuality(jpegQuality);
+ //Call Qcom related Camera Parameters
+ qcomSetCameraParameters();
boolean flag = false;
if (mPreviewing) {
@@ -1554,6 +2178,7 @@ public class VideoModule implements CameraModule,
public void onConfigurationChanged(Configuration newConfig) {
Log.v(TAG, "onConfigurationChanged");
setDisplayOrientation();
+ resizeForPreviewAspectRatio();
}
@Override
@@ -1566,6 +2191,11 @@ public class VideoModule implements CameraModule,
}
@Override
+ public void onSharedPreferenceChanged(ListPreference pref) {
+ onSharedPreferenceChanged();
+ }
+
+ @Override
public void onSharedPreferenceChanged() {
// ignore the events after "onPause()" or preview has not started yet
if (mPaused) {
@@ -1585,7 +2215,7 @@ public class VideoModule implements CameraModule,
// We need to restart the preview if preview size is changed.
Size size = mParameters.getPreviewSize();
if (size.width != mDesiredPreviewWidth
- || size.height != mDesiredPreviewHeight) {
+ || size.height != mDesiredPreviewHeight || mRestartPreview) {
stopPreview();
resizeForPreviewAspectRatio();
@@ -1593,7 +2223,11 @@ public class VideoModule implements CameraModule,
} else {
setCameraParameters();
}
+ mRestartPreview = false;
mUI.updateOnScreenIndicators(mParameters, mPreferences);
+ Storage.setSaveSDCard(
+ mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
+ mActivity.updateStorageSpaceAndHint();
}
}
@@ -1633,6 +2267,9 @@ public class VideoModule implements CameraModule,
// onFrameAvailable from the old camera may already exist.
mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION);
mUI.updateOnScreenIndicators(mParameters, mPreferences);
+
+ //Display timelapse msg depending upon selection in front/back camera.
+ mUI.showTimeLapseUI(mCaptureTimeLapse);
}
// Preview texture has been copied. Now camera can be released and the
@@ -1712,6 +2349,7 @@ public class VideoModule implements CameraModule,
public void onPreviewFocusChanged(boolean previewFocused) {
mUI.onPreviewFocusChanged(previewFocused);
forceFlashOff(!previewFocused);
+ mPreviewFocused = previewFocused;
}
@Override
@@ -1729,6 +2367,7 @@ public class VideoModule implements CameraModule,
@Override
public void onPictureTaken(byte [] jpegData, CameraProxy camera) {
Log.v(TAG, "onPictureTaken");
+ if(!mSnapshotInProgress || mPaused || mCameraDevice == null) return;
mSnapshotInProgress = false;
showVideoSnapshotUI(false);
storeImage(jpegData, mLocation);
@@ -1740,10 +2379,11 @@ public class VideoModule implements CameraModule,
String title = CameraUtil.createJpegName(dateTaken);
ExifInterface exif = Exif.getExif(data);
int orientation = Exif.getOrientation(exif);
-
+ Size s = mParameters.getPictureSize();
mActivity.getMediaSaveService().addImage(
- data, title, dateTaken, loc, orientation,
- exif, mOnPhotoSavedListener, mContentResolver);
+ data, title, dateTaken, loc, s.width, s.height, orientation,
+ exif, mOnPhotoSavedListener, mContentResolver,
+ PhotoModule.PIXEL_FORMAT_JPEG);
}
private String convertOutputFormatToMimeType(int outputFileFormat) {
@@ -1820,4 +2460,15 @@ public class VideoModule implements CameraModule,
public void onPreviewUIDestroyed() {
stopPreview();
}
+
+ @Override
+ public void onButtonPause() {
+ pauseVideoRecording();
+ }
+
+ @Override
+ public void onButtonContinue() {
+ resumeVideoRecording();
+ }
+
}
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index a8819e054..9ffd1a113 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -16,6 +16,7 @@
package com.android.camera;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
@@ -48,6 +49,7 @@ import com.android.camera.ui.ModuleSwitcher;
import com.android.camera.ui.PieRenderer;
import com.android.camera.ui.RenderOverlay;
import com.android.camera.ui.RotateLayout;
+import com.android.camera.PauseButton.OnPauseButtonListener;
import com.android.camera.ui.ZoomRenderer;
import com.android.camera.util.CameraUtil;
import com.android.camera2.R;
@@ -57,7 +59,8 @@ import java.util.List;
public class VideoUI implements PieRenderer.PieListener,
PreviewGestures.SingleTapListener,
CameraRootView.MyDisplayListener,
- SurfaceTextureListener, SurfaceHolder.Callback {
+ SurfaceTextureListener, SurfaceHolder.Callback,
+ PauseButton.OnPauseButtonListener {
private static final String TAG = "CAM_VideoUI";
private static final int UPDATE_TRANSFORM_MATRIX = 1;
// module fields
@@ -71,6 +74,7 @@ public class VideoUI implements PieRenderer.PieListener,
private View mReviewDoneButton;
private View mReviewPlayButton;
private ShutterButton mShutterButton;
+ private PauseButton mPauseButton;
private ModuleSwitcher mSwitcher;
private TextView mRecordingTimeView;
private LinearLayout mLabelsLinearLayout;
@@ -92,6 +96,9 @@ public class VideoUI implements PieRenderer.PieListener,
private List<Integer> mZoomRatios;
private View mPreviewThumb;
private View mFlashOverlay;
+ private boolean mOrientationResize;
+ private boolean mPrevOrientationResize;
+ private boolean mIsTimeLapse = false;
private View mPreviewCover;
private SurfaceView mSurfaceView = null;
@@ -100,6 +107,7 @@ public class VideoUI implements PieRenderer.PieListener,
private float mSurfaceTextureUncroppedWidth;
private float mSurfaceTextureUncroppedHeight;
private float mAspectRatio = 4f / 3f;
+ private boolean mAspectRatioResize;
private Matrix mMatrix = null;
private final AnimationManager mAnimationManager;
private final Handler mHandler = new Handler() {
@@ -127,10 +135,13 @@ public class VideoUI implements PieRenderer.PieListener,
w = height;
h = width;
}
- if (mPreviewWidth != width || mPreviewHeight != height) {
+ if (mPreviewWidth != width || mPreviewHeight != height
+ || (mOrientationResize != mPrevOrientationResize)
+ || (mAspectRatioResize)) {
mPreviewWidth = width;
mPreviewHeight = height;
onScreenSizeChanged(width, height, w, h);
+ mAspectRatioResize = false;
}
}
};
@@ -185,9 +196,16 @@ public class VideoUI implements PieRenderer.PieListener,
initializeMiscControls();
initializeControlByIntent();
initializeOverlay();
+ initializePauseButton();
mAnimationManager = new AnimationManager();
+ mOrientationResize = false;
+ mPrevOrientationResize = false;
}
+ public void cameraOrientationPreviewResize(boolean orientation){
+ mPrevOrientationResize = mOrientationResize;
+ mOrientationResize = orientation;
+ }
public void initializeSurfaceView() {
mSurfaceView = new SurfaceView(mActivity);
@@ -247,10 +265,21 @@ public class VideoUI implements PieRenderer.PieListener,
Log.w(TAG, "Preview size should not be 0.");
return;
}
+ float ratio;
if (width > height) {
- mAspectRatio = (float) width / height;
+ ratio = (float) width / height;
} else {
- mAspectRatio = (float) height / width;
+ ratio = (float) height / width;
+ }
+ if (mOrientationResize &&
+ mActivity.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_PORTRAIT) {
+ ratio = 1 / ratio;
+ }
+
+ if (ratio != mAspectRatio){
+ mAspectRatioResize = true;
+ mAspectRatio = ratio;
}
mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
}
@@ -272,16 +301,26 @@ public class VideoUI implements PieRenderer.PieListener,
int orientation = CameraUtil.getDisplayRotation(mActivity);
float scaleX = 1f, scaleY = 1f;
float scaledTextureWidth, scaledTextureHeight;
- if (width > height) {
- scaledTextureWidth = Math.max(width,
- (int) (height * mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int)(width / mAspectRatio));
+ if (mOrientationResize){
+ if (width/mAspectRatio > height){
+ scaledTextureHeight = height;
+ scaledTextureWidth = (int)(height * mAspectRatio + 0.5f);
+ } else {
+ scaledTextureWidth = width;
+ scaledTextureHeight = (int)(width / mAspectRatio + 0.5f);
+ }
} else {
- scaledTextureWidth = Math.max(width,
- (int) (height / mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int) (width * mAspectRatio));
+ if (width > height) {
+ scaledTextureWidth = Math.max(width,
+ (int) (height * mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int)(width / mAspectRatio));
+ } else {
+ scaledTextureWidth = Math.max(width,
+ (int) (height / mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int) (width * mAspectRatio));
+ }
}
if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
@@ -480,6 +519,11 @@ public class VideoUI implements PieRenderer.PieListener,
mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels);
}
+ private void initializePauseButton() {
+ mPauseButton = (PauseButton) mRootView.findViewById(R.id.video_pause);
+ mPauseButton.setOnPauseButtonListener(this);
+ }
+
public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) {
mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode());
boolean location = RecordLocationPreference.get(
@@ -489,13 +533,25 @@ public class VideoUI implements PieRenderer.PieListener,
}
public void setAspectRatio(double ratio) {
- // mPreviewFrameLayout.setAspectRatio(ratio);
+ if (mOrientationResize &&
+ mActivity.getResources().getConfiguration().orientation
+ != Configuration.ORIENTATION_PORTRAIT) {
+ ratio = 1 / ratio;
+ }
+
+ if (ratio != mAspectRatio){
+ mAspectRatioResize = true;
+ mAspectRatio = (float)ratio;
+ }
+ mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
+
}
public void showTimeLapseUI(boolean enable) {
if (mTimeLapseLabel != null) {
mTimeLapseLabel.setVisibility(enable ? View.VISIBLE : View.GONE);
}
+ mIsTimeLapse = enable;
}
private void openMenu() {
@@ -586,12 +642,14 @@ public class VideoUI implements PieRenderer.PieListener,
hideSwitcher();
mRecordingTimeView.setText("");
mRecordingTimeView.setVisibility(View.VISIBLE);
+ mPauseButton.setVisibility(mIsTimeLapse ? View.GONE : View.VISIBLE);
} else {
mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
if (!mController.isVideoCaptureIntent()) {
showSwitcher();
}
mRecordingTimeView.setVisibility(View.GONE);
+ mPauseButton.setVisibility(View.GONE);
}
}
@@ -620,6 +678,8 @@ public class VideoUI implements PieRenderer.PieListener,
}
private void setShowMenu(boolean show) {
+ if (mController.isVideoCaptureIntent())
+ return;
if (mOnScreenIndicators != null) {
mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
}
@@ -705,10 +765,17 @@ public class VideoUI implements PieRenderer.PieListener,
@Override
public void onZoomStart() {
+ if (mPieRenderer != null) {
+ if (!mRecordingStarted) mPieRenderer.hide();
+ mPieRenderer.setBlockFocus(true);
+ }
}
@Override
public void onZoomEnd() {
+ if (mPieRenderer != null) {
+ mPieRenderer.setBlockFocus(false);
+ }
}
}
@@ -759,4 +826,24 @@ public class VideoUI implements PieRenderer.PieListener,
Log.v(TAG, "Surface destroyed");
mController.stopPreview();
}
+
+ @Override
+ public void onButtonPause() {
+ mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.ic_pausing_indicator, 0, 0, 0);
+ mController.onButtonPause();
+ }
+
+ @Override
+ public void onButtonContinue() {
+ mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.ic_recording_indicator, 0, 0, 0);
+ mController.onButtonContinue();
+ }
+
+ public void resetPauseButton() {
+ mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.ic_recording_indicator, 0, 0, 0);
+ mPauseButton.setPaused(false);
+ }
}
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index 34b3071a4..f6daa6019 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -43,7 +43,7 @@ import android.view.OrientationEventListener;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-
+import com.android.camera.PhotoModule;
import com.android.camera.CameraManager.CameraProxy;
import com.android.camera.app.OrientationManager;
import com.android.camera.data.LocalData;
@@ -482,9 +482,24 @@ public class WideAnglePanoramaModule
@Override
public void onPreviewUILayoutChange(int l, int t, int r, int b) {
Log.d(TAG, "layout change: " + (r - l) + "/" + (b - t));
+ boolean capturePending = false;
+ if (mCaptureState == CAPTURE_STATE_MOSAIC){
+ capturePending = true;
+ }
mPreviewUIWidth = r - l;
mPreviewUIHeight = b - t;
configMosaicPreview();
+ if (capturePending == true){
+ mMainHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (!mPaused){
+ mMainHandler.removeMessages(MSG_RESET_TO_PREVIEW);
+ startCapture();
+ }
+ }
+ });
+ }
}
@Override
@@ -509,9 +524,11 @@ public class WideAnglePanoramaModule
float progressX, float progressY) {
float accumulatedHorizontalAngle = progressX * mHorizontalViewAngle;
float accumulatedVerticalAngle = progressY * mVerticalViewAngle;
+ boolean isRotated = !(mDeviceOrientationAtCapture == mDeviceOrientation);
if (isFinished
|| (Math.abs(accumulatedHorizontalAngle) >= DEFAULT_SWEEP_ANGLE)
- || (Math.abs(accumulatedVerticalAngle) >= DEFAULT_SWEEP_ANGLE)) {
+ || (Math.abs(accumulatedVerticalAngle) >= DEFAULT_SWEEP_ANGLE)
+ || isRotated) {
stopCapture(false);
} else {
float panningRateXInDegree = panningRateX * mHorizontalViewAngle;
@@ -641,7 +658,7 @@ public class WideAnglePanoramaModule
if (mUsingFrontCamera) {
// mCameraOrientation is negative with respect to the front facing camera.
// See document of android.hardware.Camera.Parameters.setRotation.
- orientation = (mDeviceOrientationAtCapture - mCameraOrientation + 360) % 360;
+ orientation = (mDeviceOrientationAtCapture - mCameraOrientation - 360) % 360;
} else {
orientation = (mDeviceOrientationAtCapture + mCameraOrientation) % 360;
}
@@ -742,7 +759,8 @@ public class WideAnglePanoramaModule
if (jpegData != null) {
String filename = PanoUtil.createName(
mActivity.getResources().getString(R.string.pano_file_name_format), mTimeTaken);
- String filepath = Storage.generateFilepath(filename);
+ String filepath = Storage.generateFilepath(filename,
+ PhotoModule.PIXEL_FORMAT_JPEG);
UsageStatistics.onEvent(UsageStatistics.COMPONENT_PANORAMA,
UsageStatistics.ACTION_CAPTURE_DONE, null, 0,
@@ -854,6 +872,10 @@ public class WideAnglePanoramaModule
}
@Override
+ public void resizeForPreviewAspectRatio() {
+ }
+
+ @Override
public void onResumeBeforeSuper() {
mPaused = false;
}
@@ -874,7 +896,7 @@ public class WideAnglePanoramaModule
// Check if another panorama instance is using the mosaic frame processor.
mUI.dismissAllDialogs();
- if (!mThreadRunning && mMosaicFrameProcessor.isMosaicMemoryAllocated()) {
+ if (mThreadRunning && mMosaicFrameProcessor.isMosaicMemoryAllocated()) {
mUI.showWaitingDialog(mDialogWaitingPreviousString);
// If stitching is still going on, make sure switcher and shutter button
// are not showing
@@ -888,7 +910,12 @@ public class WideAnglePanoramaModule
mPreviewUIWidth = size.x;
mPreviewUIHeight = size.y;
configMosaicPreview();
- mActivity.updateStorageSpaceAndHint();
+ mMainHandler.post(new Runnable(){
+ @Override
+ public void run(){
+ mActivity.updateStorageSpaceAndHint();
+ }
+ });
}
keepScreenOnAwhile();
@@ -976,8 +1003,12 @@ public class WideAnglePanoramaModule
// Set the display orientation to 0, so that the underlying mosaic
// library can always get undistorted mCameraPreviewWidth x mCameraPreviewHeight
// image data from SurfaceTexture.
+ // as Panoroma will add 90 degree rotation compensation during
+ // postprocessing, we need to consider both camera mount angle and
+ // this compensation angle
mCameraDevice.setDisplayOrientation(0);
+ if (mCameraTexture != null)
mCameraTexture.setOnFrameAvailableListener(this);
mCameraDevice.setPreviewTexture(mCameraTexture);
}
diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java
index 268c82b2b..f41653982 100644
--- a/src/com/android/camera/WideAnglePanoramaUI.java
+++ b/src/com/android/camera/WideAnglePanoramaUI.java
@@ -290,6 +290,7 @@ public class WideAnglePanoramaUI implements
mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mReviewControl.removeAllViews();
+ ((ViewGroup) mReviewControl).clearDisappearingChildren();
inflater.inflate(R.layout.pano_review_control, mReviewControl, true);
mRootView.bringChildToFront(mCameraControls);
@@ -321,6 +322,9 @@ public class WideAnglePanoramaUI implements
}
@Override
+ public void onShutterButtonLongClick() {}
+
+ @Override
public void onLayoutChange(
View v, int l, int t, int r, int b,
int oldl, int oldt, int oldr, int oldb) {
diff --git a/src/com/android/camera/app/AppManagerFactory.java b/src/com/android/camera/app/AppManagerFactory.java
index 43d2a00cd..5cd70a796 100644
--- a/src/com/android/camera/app/AppManagerFactory.java
+++ b/src/com/android/camera/app/AppManagerFactory.java
@@ -29,7 +29,7 @@ public class AppManagerFactory {
public static synchronized AppManagerFactory getInstance(Context ctx) {
if (sFactory == null) {
- sFactory = new AppManagerFactory(ctx);
+ sFactory = new AppManagerFactory(ctx.getApplicationContext());
}
return sFactory;
}
diff --git a/src/com/android/camera/crop/ImageLoader.java b/src/com/android/camera/crop/ImageLoader.java
index 9eae63e8a..2fa54a19d 100644
--- a/src/com/android/camera/crop/ImageLoader.java
+++ b/src/com/android/camera/crop/ImageLoader.java
@@ -79,7 +79,9 @@ public final class ImageLoader {
}
int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
- return cursor.getString(index);
+ String path = cursor.getString(index);
+ Utils.closeSilently(cursor);
+ return path;
}
/**
diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
index 99bde4181..4643d03bf 100644
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ b/src/com/android/camera/data/CameraDataAdapter.java
@@ -27,6 +27,7 @@ import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
+import com.android.camera.SDCard;
import com.android.camera.Storage;
import com.android.camera.app.PlaceholderManager;
import com.android.camera.ui.FilmStripView.ImageData;
@@ -41,7 +42,7 @@ public class CameraDataAdapter implements LocalDataAdapter {
private static final String TAG = "CAM_CameraDataAdapter";
private static final int DEFAULT_DECODE_SIZE = 1600;
- private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" };
+ private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "/%" ,SDCard.instance().getDirectory() + "/%"};
private LocalDataList mImages;
@@ -135,20 +136,26 @@ public class CameraDataAdapter implements LocalDataAdapter {
public void addNewVideo(ContentResolver cr, Uri uri) {
Cursor c = cr.query(uri,
LocalMediaData.VideoData.QUERY_PROJECTION,
- MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
+ MediaStore.Video.Media.DATA + " like ? or " +
+ MediaStore.Video.Media.DATA + " like ? ", CAMERA_PATH,
LocalMediaData.VideoData.QUERY_ORDER);
if (c == null || !c.moveToFirst()) {
return;
}
int pos = findDataByContentUri(uri);
LocalMediaData.VideoData newData = LocalMediaData.VideoData.buildFromCursor(c);
- if (pos != -1) {
- // A duplicate one, just do a substitute.
- updateData(pos, newData);
+ if (newData != null) {
+ if (pos != -1) {
+ // A duplicate one, just do a substitute.
+ updateData(pos, newData);
+ } else {
+ // A new data.
+ insertData(newData);
+ }
} else {
- // A new data.
- insertData(newData);
+ Log.e(TAG, "video data not found");
}
+ c.close();
}
// TODO: put the database query on background thread
@@ -156,6 +163,7 @@ public class CameraDataAdapter implements LocalDataAdapter {
public void addNewPhoto(ContentResolver cr, Uri uri) {
Cursor c = cr.query(uri,
LocalMediaData.PhotoData.QUERY_PROJECTION,
+ MediaStore.Images.Media.DATA + " like ? or " +
MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
LocalMediaData.PhotoData.QUERY_ORDER);
if (c == null || !c.moveToFirst()) {
@@ -171,6 +179,7 @@ public class CameraDataAdapter implements LocalDataAdapter {
// a new data.
insertData(newData);
}
+ c.close();
}
@Override
@@ -279,6 +288,7 @@ public class CameraDataAdapter implements LocalDataAdapter {
Cursor c = resolver[0].query(
LocalMediaData.PhotoData.CONTENT_URI,
LocalMediaData.PhotoData.QUERY_PROJECTION,
+ MediaStore.Images.Media.DATA + " like ? or " +
MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
LocalMediaData.PhotoData.QUERY_ORDER);
if (c != null && c.moveToFirst()) {
@@ -308,6 +318,7 @@ public class CameraDataAdapter implements LocalDataAdapter {
c = resolver[0].query(
LocalMediaData.VideoData.CONTENT_URI,
LocalMediaData.VideoData.QUERY_PROJECTION,
+ MediaStore.Video.Media.DATA + " like ? or " +
MediaStore.Video.Media.DATA + " like ? ", CAMERA_PATH,
LocalMediaData.VideoData.QUERY_ORDER);
if (c != null && c.moveToFirst()) {
diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java
index 1f9c725d0..fe5610863 100644
--- a/src/com/android/camera/data/LocalMediaData.java
+++ b/src/com/android/camera/data/LocalMediaData.java
@@ -457,6 +457,7 @@ public abstract class LocalMediaData implements LocalData {
return null;
}
PhotoData newData = buildFromCursor(c);
+ c.close();
return newData;
}
@@ -636,6 +637,14 @@ public abstract class LocalMediaData implements LocalData {
int height = c.getInt(COL_HEIGHT);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
String rotation = null;
+
+ File origFile = new File(path);
+ if (!origFile.exists() || origFile.length() <= 0) {
+ Log.e(TAG, "Invalid video file");
+ retriever.release();
+ return null;
+ }
+
try {
retriever.setDataSource(path);
} catch (RuntimeException ex) {
@@ -736,6 +745,7 @@ public abstract class LocalMediaData implements LocalData {
return null;
}
VideoData newData = buildFromCursor(c);
+ c.close();
return newData;
}
diff --git a/src/com/android/camera/tinyplanet/TinyPlanetFragment.java b/src/com/android/camera/tinyplanet/TinyPlanetFragment.java
index 9cde87b16..d1d5af91c 100644
--- a/src/com/android/camera/tinyplanet/TinyPlanetFragment.java
+++ b/src/com/android/camera/tinyplanet/TinyPlanetFragment.java
@@ -43,6 +43,7 @@ import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPMeta;
import com.android.camera.CameraActivity;
import com.android.camera.MediaSaveService;
+import com.android.camera.PhotoModule;
import com.android.camera.MediaSaveService.OnMediaSavedListener;
import com.android.camera.exif.ExifInterface;
import com.android.camera.tinyplanet.TinyPlanetPreview.PreviewSizeListener;
@@ -321,7 +322,7 @@ public class TinyPlanetFragment extends DialogFragment implements PreviewSizeLis
mediaSaveService.addImage(image.mJpegData, tinyPlanetTitle, (new Date()).getTime(),
null,
image.mSize, image.mSize, 0, null, doneListener, getActivity()
- .getContentResolver());
+ .getContentResolver(),PhotoModule.PIXEL_FORMAT_JPEG);
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java
index 1b3a9c72e..1868e0a38 100644
--- a/src/com/android/camera/ui/FaceView.java
+++ b/src/com/android/camera/ui/FaceView.java
@@ -21,6 +21,7 @@ import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Color;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.hardware.Camera.Face;
@@ -33,6 +34,7 @@ import android.view.View;
import com.android.camera.PhotoUI;
import com.android.camera.util.CameraUtil;
import com.android.camera2.R;
+import org.codeaurora.camera.ExtendedFace;
public class FaceView extends View
implements FocusIndicator, Rotatable,
@@ -63,6 +65,11 @@ public class FaceView extends View
private int mUncroppedWidth;
private int mUncroppedHeight;
+
+ private final int smile_threashold_no_smile = 30;
+ private final int smile_threashold_small_smile = 60;
+ private final int blink_threshold = 60;
+
private static final int MSG_SWITCH_FACES = 1;
private static final int SWITCH_DELAY = 70;
private boolean mStateSwitchPending = false;
@@ -90,6 +97,9 @@ public class FaceView extends View
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(res.getDimension(R.dimen.face_circle_stroke));
+ mPaint.setDither(true);
+ mPaint.setColor(Color.WHITE);//setColor(0xFFFFFF00);
+ mPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
@@ -215,6 +225,161 @@ public class FaceView extends View
mPaint.setColor(mColor);
mRect.offset(dx, dy);
canvas.drawOval(mRect, mPaint);
+ if (mFaces[i] instanceof ExtendedFace) {
+ ExtendedFace face = (ExtendedFace)mFaces[i];
+ float[] point = new float[4];
+ int delta_x = mFaces[i].rect.width() / 12;
+ int delta_y = mFaces[i].rect.height() / 12;
+ Log.e(TAG, "blink: (" + face.getLeftEyeBlinkDegree()+ ", " +
+ face.getRightEyeBlinkDegree() + ")");
+ if (face.leftEye != null) {
+ if ((mDisplayOrientation == 90) ||
+ (mDisplayOrientation == 270)) {
+ point[0] = face.leftEye.x;
+ point[1] = face.leftEye.y - delta_y / 2;
+ point[2] = face.leftEye.x;
+ point[3] = face.leftEye.y + delta_y / 2;
+ } else {
+ point[0] = face.leftEye.x - delta_x / 2;
+ point[1] = face.leftEye.y;
+ point[2] = face.leftEye.x + delta_x / 2;
+ point[3] = face.leftEye.y;
+
+ }
+ mMatrix.mapPoints (point);
+ if (face.getLeftEyeBlinkDegree() >= blink_threshold) {
+ canvas.drawLine(point[0]+ dx, point[1]+ dy,
+ point[2]+ dx, point[3]+ dy, mPaint);
+ }
+ }
+ if (face.rightEye != null) {
+ if ((mDisplayOrientation == 90) ||
+ (mDisplayOrientation == 270)) {
+ point[0] = face.rightEye.x;
+ point[1] = face.rightEye.y - delta_y / 2;
+ point[2] = face.rightEye.x;
+ point[3] = face.rightEye.y + delta_y / 2;
+ } else {
+ point[0] = face.rightEye.x - delta_x / 2;
+ point[1] = face.rightEye.y;
+ point[2] = face.rightEye.x + delta_x / 2;
+ point[3] = face.rightEye.y;
+ }
+ mMatrix.mapPoints (point);
+ if (face.getRightEyeBlinkDegree() >= blink_threshold) {
+ //Add offset to the points if the rect has an offset
+ canvas.drawLine(point[0] + dx, point[1] + dy,
+ point[2] +dx, point[3] +dy, mPaint);
+ }
+ }
+
+ if (face.getLeftRightGazeDegree() != 0
+ || face.getTopBottomGazeDegree() != 0 ) {
+
+ double length =
+ Math.sqrt((face.leftEye.x - face.rightEye.x) *
+ (face.leftEye.x - face.rightEye.x) +
+ (face.leftEye.y - face.rightEye.y) *
+ (face.leftEye.y - face.rightEye.y)) / 2.0;
+ double nGazeYaw = -face.getLeftRightGazeDegree();
+ double nGazePitch = -face.getTopBottomGazeDegree();
+ float gazeRollX =
+ (float)((-Math.sin(nGazeYaw/180.0*Math.PI) *
+ Math.cos(-face.getRollDirection()/
+ 180.0*Math.PI) +
+ Math.sin(nGazePitch/180.0*Math.PI) *
+ Math.cos(nGazeYaw/180.0*Math.PI) *
+ Math.sin(-face.getRollDirection()/
+ 180.0*Math.PI)) *
+ (-length) + 0.5);
+ float gazeRollY =
+ (float)((Math.sin(-nGazeYaw/180.0*Math.PI) *
+ Math.sin(-face.getRollDirection()/
+ 180.0*Math.PI)-
+ Math.sin(nGazePitch/180.0*Math.PI) *
+ Math.cos(nGazeYaw/180.0*Math.PI) *
+ Math.cos(-face.getRollDirection()/
+ 180.0*Math.PI)) *
+ (-length) + 0.5);
+
+ if (face.getLeftEyeBlinkDegree() < blink_threshold) {
+ if ((mDisplayOrientation == 90) ||
+ (mDisplayOrientation == 270)) {
+ point[0] = face.leftEye.x;
+ point[1] = face.leftEye.y;
+ point[2] = face.leftEye.x + gazeRollX;
+ point[3] = face.leftEye.y + gazeRollY;
+ } else {
+ point[0] = face.leftEye.x;
+ point[1] = face.leftEye.y;
+ point[2] = face.leftEye.x + gazeRollY;
+ point[3] = face.leftEye.y + gazeRollX;
+ }
+ mMatrix.mapPoints (point);
+ canvas.drawLine(point[0] +dx, point[1] + dy,
+ point[2] + dx, point[3] +dy, mPaint);
+ }
+
+ if (face.getRightEyeBlinkDegree() < blink_threshold) {
+ if ((mDisplayOrientation == 90) ||
+ (mDisplayOrientation == 270)) {
+ point[0] = face.rightEye.x;
+ point[1] = face.rightEye.y;
+ point[2] = face.rightEye.x + gazeRollX;
+ point[3] = face.rightEye.y + gazeRollY;
+ } else {
+ point[0] = face.rightEye.x;
+ point[1] = face.rightEye.y;
+ point[2] = face.rightEye.x + gazeRollY;
+ point[3] = face.rightEye.y + gazeRollX;
+
+ }
+ mMatrix.mapPoints (point);
+ canvas.drawLine(point[0] + dx, point[1] + dy,
+ point[2] + dx, point[3] + dy, mPaint);
+ }
+ }
+
+ if (face.mouth != null) {
+ Log.e(TAG, "smile: " + face.getSmileDegree() + "," +
+ face.getSmileScore());
+ if (face.getSmileDegree() < smile_threashold_no_smile) {
+
+ if ((mDisplayOrientation == 90) ||
+ (mDisplayOrientation == 270)) {
+ point[0] = face.mouth.x;
+ point[1] = face.mouth.y - delta_y;
+ point[2] = face.mouth.x;
+ point[3] = face.mouth.y + delta_y;
+ } else {
+ point[0] = face.mouth.x - delta_x;
+ point[1] = face.mouth.y;
+ point[2] = face.mouth.x + delta_x ;
+ point[3] = face.mouth.y;
+ }
+ mMatrix.mapPoints (point);
+ canvas.drawLine(point[0] + dx, point[1] + dy,
+ point[2] + dx, point[3] + dy, mPaint);
+
+ } else if (face.getSmileDegree() <
+ smile_threashold_small_smile) {
+
+ mRect.set(face.mouth.x-delta_x,
+ face.mouth.y-delta_y, face.mouth.x+delta_x,
+ face.mouth.y+delta_y);
+ mMatrix.mapRect(mRect);
+ mRect.offset(dx, dy);
+ canvas.drawArc(mRect, 0, 180, true, mPaint);
+ } else {
+ mRect.set(face.mouth.x-delta_x,
+ face.mouth.y-delta_y, face.mouth.x+delta_x,
+ face.mouth.y+delta_y);
+ mMatrix.mapRect(mRect);
+ mRect.offset(dx, dy);
+ canvas.drawOval(mRect, mPaint);
+ }
+ }
+ }
}
canvas.restore();
}
diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java
index 6b2b7f5e0..d0bcdfcc2 100644
--- a/src/com/android/camera/ui/FilmStripView.java
+++ b/src/com/android/camera/ui/FilmStripView.java
@@ -409,6 +409,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
public void goToFilmStrip();
public void goToFullScreen();
+
}
/**
@@ -1852,7 +1853,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
// Check the current one.
ViewItem curr = mViewItem[mCurrentItem];
int dataId = curr.getId();
- if (reporter.isDataRemoved(dataId)) {
+ if (reporter.isDataRemoved(dataId) || mDataAdapter.getTotalNumber() == 1) {
reload();
return;
}
diff --git a/src/com/android/camera/ui/MoreSettingPopup.java b/src/com/android/camera/ui/MoreSettingPopup.java
index 8da26c946..ad8ed7721 100644
--- a/src/com/android/camera/ui/MoreSettingPopup.java
+++ b/src/com/android/camera/ui/MoreSettingPopup.java
@@ -82,12 +82,11 @@ public class MoreSettingPopup extends AbstractSettingPopup
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView != null) return convertView;
-
ListPreference pref = mListItem.get(position);
-
int viewLayoutId = getSettingLayoutId(pref);
- InLineSettingItem view = (InLineSettingItem)
+ InLineSettingItem view = (InLineSettingItem)convertView;
+
+ view = (InLineSettingItem)
mInflater.inflate(viewLayoutId, parent, false);
view.initialize(pref); // no init for restore one
diff --git a/src/com/android/camera/ui/PieRenderer.java b/src/com/android/camera/ui/PieRenderer.java
index f1a5a9a4b..0039aa22c 100644
--- a/src/com/android/camera/ui/PieRenderer.java
+++ b/src/com/android/camera/ui/PieRenderer.java
@@ -118,7 +118,7 @@ public class PieRenderer extends OverlayRenderer
private int mPieCenterX;
private int mPieCenterY;
private int mSliceRadius;
- private int mArcRadius;
+ private int mArcRadius, mMaxArcRadius;
private int mArcOffset;
private int mDialAngle;
@@ -225,6 +225,7 @@ public class PieRenderer extends OverlayRenderer
mMenuArcPaint.setStyle(Paint.Style.STROKE);
mSliceRadius = res.getDimensionPixelSize(R.dimen.pie_item_radius);
mArcRadius = res.getDimensionPixelSize(R.dimen.pie_arc_radius);
+ mMaxArcRadius = mArcRadius;
mArcOffset = res.getDimensionPixelSize(R.dimen.pie_arc_offset);
mLabel = new TextDrawable(res);
mLabel.setDropShadow(true);
@@ -357,6 +358,12 @@ public class PieRenderer extends OverlayRenderer
mCenterX = (r - l) / 2;
mCenterY = (b - t) / 2;
+ int layoutWidth = r - l;
+ if( (layoutWidth > 0) && ((mMaxArcRadius + mCenterX) > layoutWidth) ){
+ mArcRadius = layoutWidth - mCenterX;
+ } else {
+ mArcRadius = mMaxArcRadius;
+ }
mFocusX = mCenterX;
mFocusY = mCenterY;
resetPieCenter();
diff --git a/src/com/android/camera/util/ApiHelper.java b/src/com/android/camera/util/ApiHelper.java
index dd5208cc8..4a917799e 100644
--- a/src/com/android/camera/util/ApiHelper.java
+++ b/src/com/android/camera/util/ApiHelper.java
@@ -49,7 +49,8 @@ public class ApiHelper {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
public static final boolean HAS_ROTATION_ANIMATION =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
-
+ public static final boolean HAS_FINE_RESOLUTION_QUALITY_LEVELS =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
public static final boolean HAS_HIDEYBARS = isKitKatOrHigher();
public static int getIntFieldIfExists(Class<?> klass, String fieldName,
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 708308b63..68211d648 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -56,6 +56,7 @@ import com.android.camera.CameraActivity;
import com.android.camera.CameraDisabledException;
import com.android.camera.CameraHolder;
import com.android.camera.CameraManager;
+import com.android.camera.CameraSettings;
import com.android.camera.util.IntentHelper;
import com.android.camera2.R;
@@ -820,7 +821,20 @@ public class CameraUtil {
}
}
}
-
+ public static String getFilpModeString(int value){
+ switch(value){
+ case 0:
+ return CameraSettings.FLIP_MODE_OFF;
+ case 1:
+ return CameraSettings.FLIP_MODE_H;
+ case 2:
+ return CameraSettings.FLIP_MODE_V;
+ case 3:
+ return CameraSettings.FLIP_MODE_VH;
+ default:
+ return null;
+ }
+ }
/**
* For still image capture, we need to get the right fps range such that the
* camera can slow down the framerate to allow for less-noisy/dark