From d150e03d827e65d4e3faa0c4dc119d7b74571682 Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Mon, 14 Mar 2016 15:52:45 -0700 Subject: SnapdragonCamera: create base files for camera2 API All the new files are copied from the commit : f3448373ef3c92b492ac65a9b4008d45a51f88ee res/layout/capture_module.xml copied from res/layout/photo_module.xml src/com/android/camera/CaptureMenu.java copied from src/com/android/camera/PhotoMenu.java src/com/android/camera/CaptureModule.java copied from src/com/android/camera/PhotoModule.java src/com/android/camera/CaptureUI.java copied from src/com/android/camera/PhotoUI.java CRs-Fixed: 989750 Change-Id: I4a97975ed5847d9025f9ff8e8fcbcbeaedd49e16 --- src/com/android/camera/CaptureMenu.java | 1482 +++++++++ src/com/android/camera/CaptureModule.java | 4934 +++++++++++++++++++++++++++++ src/com/android/camera/CaptureUI.java | 1463 +++++++++ 3 files changed, 7879 insertions(+) create mode 100644 src/com/android/camera/CaptureMenu.java create mode 100644 src/com/android/camera/CaptureModule.java create mode 100644 src/com/android/camera/CaptureUI.java (limited to 'src') diff --git a/src/com/android/camera/CaptureMenu.java b/src/com/android/camera/CaptureMenu.java new file mode 100644 index 000000000..2e90e825b --- /dev/null +++ b/src/com/android/camera/CaptureMenu.java @@ -0,0 +1,1482 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import java.util.Locale; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.hardware.Camera.Parameters; +import android.graphics.Rect; +import android.os.Handler; +import android.os.Message; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewPropertyAnimator; +import android.widget.ListView; +import android.widget.Toast; +import android.widget.TextView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.TsMakeupManager.MakeupLevelListener; +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.CountdownTimerPopup; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.ListMenu; +import com.android.camera.ui.RotateLayout; +import com.android.camera.ui.RotateImageView; +import com.android.camera.ui.RotateTextToast; +import org.codeaurora.snapcam.R; +import android.widget.HorizontalScrollView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.Display; +import com.android.camera.util.CameraUtil; +import java.util.Locale; + +public class PhotoMenu extends MenuController + implements ListMenu.Listener, + CountdownTimerPopup.Listener, + ListSubMenu.Listener { + private static String TAG = "PhotoMenu"; + + private final String mSettingOff; + private final String mSettingOn; + + private String[] mOtherKeys1; + private String[] mOtherKeys2; + private ListMenu mListMenu; + private View mPreviewMenu; + private static final int POPUP_NONE = 0; + private static final int POPUP_FIRST_LEVEL = 1; + private static final int POPUP_SECOND_LEVEL = 2; + private static final int POPUP_IN_ANIMATION_SLIDE = 3; + private static final int POPUP_IN_ANIMATION_FADE = 4; + private static final int POPUP_IN_MAKEUP = 5; + private static final int PREVIEW_MENU_NONE = 0; + private static final int PREVIEW_MENU_IN_ANIMATION = 1; + private static final int PREVIEW_MENU_ON = 2; + private static final int MODE_SCENE = 0; + private static final int MODE_FILTER = 1; + private static final int MODE_MAKEUP = 2; + private static final int DEVELOPER_MENU_TOUCH_COUNT = 10; + private int mSceneStatus; + private View mHdrSwitcher; + private View mTsMakeupSwitcher; + private View mFrontBackSwitcher; + private View mSceneModeSwitcher; + private View mFilterModeSwitcher; + private View mCameraSwitcher; + private View mSettingMenu; + private View mPreviewThumbnail; + private PhotoUI mUI; + private int mPopupStatus; + private int mPreviewMenuStatus; + private ListSubMenu mListSubMenu; + private CameraActivity mActivity; + private String mPrevSavedCDS; + private boolean mIsTNREnabled = false; + private boolean mIsCDSUpdated = false; + private int privateCounter = 0; + private static final int ANIMATION_DURATION = 300; + private static final int CLICK_THRESHOLD = 200; + private int previewMenuSize; + private TsMakeupManager mTsMakeupManager; + private MakeupLevelListener mMakeupListener; + private MakeupHandler mHandler = new MakeupHandler(); + private static final int MAKEUP_MESSAGE_ID = 0; + + public PhotoMenu(CameraActivity activity, PhotoUI ui, MakeupLevelListener makeupListener) { + super(activity); + mUI = ui; + mSettingOff = activity.getString(R.string.setting_off_value); + mSettingOn = activity.getString(R.string.setting_on_value); + mActivity = activity; + mFrontBackSwitcher = ui.getRootView().findViewById(R.id.front_back_switcher); + mHdrSwitcher = ui.getRootView().findViewById(R.id.hdr_switcher); + mTsMakeupSwitcher = ui.getRootView().findViewById(R.id.ts_makeup_switcher); + mSceneModeSwitcher = ui.getRootView().findViewById(R.id.scene_mode_switcher); + mFilterModeSwitcher = ui.getRootView().findViewById(R.id.filter_mode_switcher); + mMakeupListener = makeupListener; + mSettingMenu = ui.getRootView().findViewById(R.id.menu); + mCameraSwitcher = ui.getRootView().findViewById(R.id.camera_switcher); + mPreviewThumbnail = ui.getRootView().findViewById(R.id.preview_thumb); + } + + public void initialize(PreferenceGroup group) { + super.initialize(group); + mListSubMenu = null; + mListMenu = null; + mPopupStatus = POPUP_NONE; + mPreviewMenuStatus = POPUP_NONE; + final Resources res = mActivity.getResources(); + Locale locale = res.getConfiguration().locale; + // The order is from left to right in the menu. + + if(TsMakeupManager.HAS_TS_MAKEUP) { + if(mTsMakeupManager != null) { + mTsMakeupManager.removeAllViews(); + mTsMakeupManager = null; + } + if(mTsMakeupManager == null) { + mTsMakeupManager = new TsMakeupManager(mActivity, this, mUI, mPreferenceGroup, mTsMakeupSwitcher); + mTsMakeupManager.setMakeupLevelListener(mMakeupListener); + } + } + + initSceneModeButton(mSceneModeSwitcher); + initFilterModeButton(mFilterModeSwitcher); + if(TsMakeupManager.HAS_TS_MAKEUP) { + initMakeupModeButton(mTsMakeupSwitcher); + } else { + mHdrSwitcher.setVisibility(View.INVISIBLE); + } + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + if(!TsMakeupManager.HAS_TS_MAKEUP) { + // HDR. + if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) { + mHdrSwitcher.setVisibility(View.VISIBLE); + initSwitchItem(CameraSettings.KEY_CAMERA_HDR, mHdrSwitcher); + } else { + mHdrSwitcher.setVisibility(View.INVISIBLE); + } + } + + mOtherKeys1 = new String[] { + CameraSettings.KEY_SELFIE_FLASH, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_PICTURE_SIZE, + CameraSettings.KEY_JPEG_QUALITY, + CameraSettings.KEY_TIMER, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_LONGSHOT, + CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_QC_CHROMA_FLASH, + CameraSettings.KEY_REDEYE_REDUCTION + }; + + mOtherKeys2 = new String[] { + CameraSettings.KEY_SELFIE_FLASH, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_PICTURE_SIZE, + CameraSettings.KEY_JPEG_QUALITY, + CameraSettings.KEY_TIMER, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_LONGSHOT, + CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_QC_CHROMA_FLASH, + CameraSettings.KEY_FOCUS_MODE, + CameraSettings.KEY_REDEYE_REDUCTION, + CameraSettings.KEY_AUTO_HDR, + CameraSettings.KEY_HDR_MODE, + CameraSettings.KEY_HDR_NEED_1X, + CameraSettings.KEY_CDS_MODE, + CameraSettings.KEY_TNR_MODE, + CameraSettings.KEY_HISTOGRAM, + CameraSettings.KEY_ZSL, + CameraSettings.KEY_TIMER_SOUND_EFFECTS, + 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, + CameraSettings.KEY_ANTIBANDING, + CameraSettings.KEY_DENOISE, + CameraSettings.KEY_ADVANCED_FEATURES, + CameraSettings.KEY_AE_BRACKET_HDR, + CameraSettings.KEY_MANUAL_EXPOSURE, + CameraSettings.KEY_MANUAL_WB, + CameraSettings.KEY_MANUAL_FOCUS + }; + + initSwitchItem(CameraSettings.KEY_CAMERA_ID, mFrontBackSwitcher); + } + + protected class MakeupHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MAKEUP_MESSAGE_ID: + mTsMakeupManager.showMakeupView(); + mUI.adjustOrientation(); + break; + } + } + } + + @Override + // Hit when an item in a popup gets selected + public void onListPrefChanged(ListPreference pref) { + onSettingChanged(pref); + closeView(); + } + + public boolean handleBackKey() { + if(TsMakeupManager.HAS_TS_MAKEUP && mTsMakeupManager.isShowMakeup()) { + mTsMakeupManager.dismissMakeupUI(); + closeMakeupMode(true); + mTsMakeupManager.resetMakeupUIStatus(); + mPopupStatus = POPUP_NONE; + mPreviewMenuStatus = PREVIEW_MENU_NONE; + return true; + } + if (mPreviewMenuStatus == PREVIEW_MENU_ON) { + animateSlideOut(mPreviewMenu); + return true; + } + if (mPopupStatus == POPUP_NONE) + return false; + if (mPopupStatus == POPUP_FIRST_LEVEL) { + animateSlideOut(mListMenu, 1); + } else if (mPopupStatus == POPUP_SECOND_LEVEL) { + animateFadeOut(mListSubMenu, 2); + ((ListMenu) mListMenu).resetHighlight(); + } + return true; + } + + public void closeSceneMode() { + mUI.removeSceneModeMenu(); + } + + public void closeMakeupMode(boolean isMakeup) { + mUI.removeSceneModeMenu(); + } + + public void tryToCloseSubList() { + if (mListMenu != null) + ((ListMenu) mListMenu).resetHighlight(); + + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + private void animateFadeOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION_FADE) + return; + mPopupStatus = POPUP_IN_ANIMATION_FADE; + + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0f).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + private void animateSlideOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION_SLIDE) + return; + mPopupStatus = POPUP_IN_ANIMATION_SLIDE; + + ViewPropertyAnimator vp = v.animate(); + if (View.LAYOUT_DIRECTION_RTL == TextUtils + .getLayoutDirectionFromLocale(Locale.getDefault())) { + switch (mUI.getOrientation()) { + case 0: + vp.translationXBy(v.getWidth()); + break; + case 90: + vp.translationYBy(-2 * v.getHeight()); + break; + case 180: + vp.translationXBy(-2 * v.getWidth()); + break; + case 270: + vp.translationYBy(v.getHeight()); + break; + } + } else { + switch (mUI.getOrientation()) { + case 0: + vp.translationXBy(-v.getWidth()); + break; + case 90: + vp.translationYBy(2 * v.getHeight()); + break; + case 180: + vp.translationXBy(2 * v.getWidth()); + break; + case 270: + vp.translationYBy(-v.getHeight()); + break; + } + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.setDuration(ANIMATION_DURATION).start(); + } + + public void animateFadeIn(final ListView v) { + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0.85f).setDuration(ANIMATION_DURATION); + vp.start(); + } + + public void animateSlideIn(final View v, int delta, boolean forcePortrait) { + int orientation = mUI.getOrientation(); + if (!forcePortrait) + orientation = 0; + + ViewPropertyAnimator vp = v.animate(); + float dest; + if (View.LAYOUT_DIRECTION_RTL == TextUtils + .getLayoutDirectionFromLocale(Locale.getDefault())) { + switch (orientation) { + case 0: + dest = v.getX(); + v.setX(-(dest - delta)); + vp.translationX(dest); + break; + case 90: + dest = v.getY(); + v.setY(-(dest + delta)); + vp.translationY(dest); + break; + case 180: + dest = v.getX(); + v.setX(-(dest + delta)); + vp.translationX(dest); + break; + case 270: + dest = v.getY(); + v.setY(-(dest - delta)); + vp.translationY(dest); + break; + } + } else { + switch (orientation) { + case 0: + dest = v.getX(); + v.setX(dest - delta); + vp.translationX(dest); + break; + case 90: + dest = v.getY(); + v.setY(dest + delta); + vp.translationY(dest); + break; + case 180: + dest = v.getX(); + v.setX(dest + delta); + vp.translationX(dest); + break; + case 270: + dest = v.getY(); + v.setY(dest - delta); + vp.translationY(dest); + break; + } + } + vp.setDuration(ANIMATION_DURATION).start(); + } + + public void animateSlideOutPreviewMenu() { + if(TsMakeupManager.HAS_TS_MAKEUP && mTsMakeupManager.isShowMakeup()) { + mPreviewMenuStatus = PREVIEW_MENU_NONE; + mTsMakeupManager.dismissMakeupUI(); + closeMakeupMode(true); + mTsMakeupManager.resetMakeupUIStatus(); + } + + if (mPreviewMenu == null) + return; + animateSlideOut(mPreviewMenu); + } + + private void animateSlideOut(final View v) { + if (v == null || mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION) + return; + mPreviewMenuStatus = PREVIEW_MENU_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + if (View.LAYOUT_DIRECTION_RTL == TextUtils + .getLayoutDirectionFromLocale(Locale.getDefault())) { + vp.translationXBy(v.getWidth()).setDuration(ANIMATION_DURATION); + } else { + vp.translationXBy(-v.getWidth()).setDuration(ANIMATION_DURATION); + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + + @Override + public void onAnimationCancel(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + + } + }); + vp.start(); + } + + private void buttonSetEnabled(View v, boolean enable) { + v.setEnabled(enable); + if (v instanceof ViewGroup) { + View v2 = ((ViewGroup) v).getChildAt(0); + if (v2 != null) + v2.setEnabled(enable); + + } + + } + + public boolean isOverMenu(MotionEvent ev) { + if (mPopupStatus == POPUP_NONE + || mPopupStatus == POPUP_IN_ANIMATION_SLIDE + || mPopupStatus == POPUP_IN_ANIMATION_FADE) + return false; + if (mUI.getMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getMenuLayout().getChildAt(0).getHitRect(rec); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isOverPreviewMenu(MotionEvent ev) { + if (mPreviewMenuStatus != PREVIEW_MENU_ON) + return false; + if (mUI.getPreviewMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getPreviewMenuLayout().getChildAt(0).getHitRect(rec); + if (View.LAYOUT_DIRECTION_RTL == TextUtils + .getLayoutDirectionFromLocale(Locale.getDefault())) { + rec.left = mUI.getRootView().getWidth() - (rec.right-rec.left); + rec.right = mUI.getRootView().getWidth(); + } + rec.top += (int) mUI.getPreviewMenuLayout().getY(); + rec.bottom += (int) mUI.getPreviewMenuLayout().getY(); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isMenuBeingShown() { + return mPopupStatus != POPUP_NONE; + } + + public boolean isMenuBeingAnimated() { + return mPopupStatus == POPUP_IN_ANIMATION_SLIDE || mPopupStatus == POPUP_IN_ANIMATION_FADE; + } + + public boolean isPreviewMenuBeingShown() { + return mPreviewMenuStatus == PREVIEW_MENU_ON; + } + + public boolean isPreviewMenuBeingAnimated() { + return mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION; + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mUI.sendTouchToPreviewMenu(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + return mUI.sendTouchToMenu(ev); + } + + @Override + public void overrideSettings(final String... keyvalues) { + if (mListMenu != null) { + ListPreference pref_tnr = mPreferenceGroup.findPreference(CameraSettings.KEY_TNR_MODE); + ListPreference pref_cds = mPreferenceGroup.findPreference(CameraSettings.KEY_CDS_MODE); + + String tnr = (pref_tnr != null) ? pref_tnr.getValue() : null; + String cds = (pref_cds != null) ? pref_cds.getValue() : null; + + if (mPrevSavedCDS == null && cds != null) { + mPrevSavedCDS = cds; + } + + if ((tnr != null) && !mActivity.getString(R.string. + pref_camera_tnr_default).equals(tnr)) { + mListMenu.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, false); + mListMenu.overrideSettings(CameraSettings.KEY_CDS_MODE, + mActivity.getString(R.string.pref_camera_cds_value_off)); + mIsTNREnabled = true; + if (!mIsCDSUpdated) { + if (cds != null) { + mPrevSavedCDS = cds; + } + mIsCDSUpdated = true; + } + } else if (tnr != null) { + mListMenu.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, true); + if (mIsTNREnabled && mPrevSavedCDS != cds) { + mListMenu.overrideSettings(CameraSettings.KEY_CDS_MODE, mPrevSavedCDS); + mIsTNREnabled = false; + mIsCDSUpdated = false; + } + } + } + for (int i = 0; i < keyvalues.length; i += 2) { + if (keyvalues[i].equals(CameraSettings.KEY_SCENE_MODE)) { + buttonSetEnabled(mSceneModeSwitcher, keyvalues[i + 1] == null); + } + } + super.overrideSettings(keyvalues); + if ((mListMenu == null)) + initializePopup(); + mListMenu.overrideSettings(keyvalues); + } + + protected void initializePopup() { + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ListMenu popup1 = (ListMenu) inflater.inflate( + R.layout.list_menu, null, false); + + popup1.setSettingChangedListener(this); + + String[] keys = mOtherKeys1; + if (mActivity.isDeveloperMenuEnabled()) + keys = mOtherKeys2; + popup1.initialize(mPreferenceGroup, keys); + if (mActivity.isSecureCamera()) { + // Prevent location preference from getting changed in secure camera + // mode + popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false); + } + mListMenu = popup1; + + ListPreference pref = mPreferenceGroup.findPreference( + CameraSettings.KEY_SCENE_MODE); + updateFilterModeIcon(pref, mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_HDR)); + 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; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_AUTO_HDR); + String autohdr = (pref != null) ? pref.getValue() : null; + if (((sceneMode != null) && !Parameters.SCENE_MODE_AUTO.equals(sceneMode)) + || ((autohdr != null) && autohdr.equals("enable"))) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AUTOEXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SATURATION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_CONTRAST, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SHARPNESS, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + } + if ((autohdr != null) && autohdr.equals("enable")) { + popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false); + } + if ((zsl != null) && Parameters.ZSL_ON.equals(zsl)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_EXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_WB, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_FOCUS, false); + } + if ((faceDetection != null) && !Parameters.FACE_DETECTION_ON.equals(faceDetection)) { + popup1.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 reFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_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); + String fssrOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_on); + String truePortraitOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_on); + String multiTouchFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_on); + + if ((zsl != null) && Parameters.ZSL_OFF.equals(zsl)) { + popup1.overrideSettings(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + + popup1.setPreferenceEnabled(CameraSettings.KEY_ADVANCED_FEATURES, false); + if(!TsMakeupManager.HAS_TS_MAKEUP) { + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } + } else { + if ((advancedFeatures != null) && (advancedFeatures.equals(ubiFocusOn) || + advancedFeatures.equals(chromaFlashOn) || + advancedFeatures.equals(reFocusOn) || + advancedFeatures.equals(optiZoomOn) || + advancedFeatures.equals(fssrOn) || + advancedFeatures.equals(truePortraitOn) || + advancedFeatures.equals(multiTouchFocusOn))) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AE_BRACKET_HDR, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_REDEYE_REDUCTION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false); + + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + if(!TsMakeupManager.HAS_TS_MAKEUP) { + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, false); + } + } + } else { + if(!TsMakeupManager.HAS_TS_MAKEUP) { + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } + } + } + + if ((autohdr != null) && autohdr.equals("enable")) { + mHdrSwitcher.setVisibility(View.GONE); + mUI.getCameraControls().removeFromViewList(mHdrSwitcher); + } else { + mHdrSwitcher.setVisibility(View.VISIBLE); + } + + if (mListener != null) { + mListener.onSharedPreferenceChanged(); + } + } + + private void updateFilterModeIcon(ListPreference scenePref, ListPreference hdrPref) { + if (scenePref == null || hdrPref == null) return; + if ((notSame(scenePref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) + || (notSame(hdrPref, CameraSettings.KEY_CAMERA_HDR, mSettingOff))) { + buttonSetEnabled(mFilterModeSwitcher, false); + } else { + buttonSetEnabled(mFilterModeSwitcher, true); + } + } + + public void initSwitchItem(final String prefKey, View switcher) { + final IconListPreference pref = + (IconListPreference) mPreferenceGroup.findPreference(prefKey); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ((ImageView) switcher).setImageResource(resid); + switcher.setVisibility(View.VISIBLE); + mPreferences.add(pref); + mPreferenceMap.put(pref, switcher); + switcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(prefKey); + if (pref == null) + return; + int index = pref.findIndexOfValue(pref.getValue()); + CharSequence[] values = pref.getEntryValues(); + index = (index + 1) % values.length; + pref.setValueIndex(index); + ((ImageView) v).setImageResource( + ((IconListPreference) pref).getLargeIconIds()[index]); + if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) + mListener.onCameraPickerClicked(index); + reloadPreference(pref); + onSettingChanged(pref); + } + }); + } + + public void initMakeupModeButton(View button) { + if(!TsMakeupManager.HAS_TS_MAKEUP) { + return; + } + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_TS_MAKEUP_UILABLE); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ImageView iv = (ImageView) mTsMakeupSwitcher; + iv.setImageResource(resid); + + button.setVisibility(View.VISIBLE); + + String makeupOn = pref.getValue(); + Log.d(TAG, "PhotoMenu.initMakeupModeButton():current init makeupOn is " + makeupOn); + + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + ListPreference faceDetectPref = mPreferenceGroup.findPreference(CameraSettings.KEY_FACE_DETECTION); + String faceDetection = (faceDetectPref != null) ? faceDetectPref.getValue() : null; + Log.d(TAG, "initMakeupModeButton().onClick(): faceDetection is " + faceDetection); + if ((faceDetection != null) && Parameters.FACE_DETECTION_OFF.equals(faceDetection)) { + showAlertDialog(faceDetectPref); + } else { + toggleMakeupSettings(); + } + } + }); + } + + private void initMakeupMenu() { + if(!TsMakeupManager.HAS_TS_MAKEUP) { + return; + } + mPopupStatus = POPUP_NONE; + mHandler.removeMessages(MAKEUP_MESSAGE_ID); + mSceneStatus = MODE_MAKEUP; + mPreviewMenuStatus = PREVIEW_MENU_ON; + mHandler.sendEmptyMessageDelayed(MAKEUP_MESSAGE_ID, ANIMATION_DURATION); + } + + private void showAlertDialog(final ListPreference faceDetectPref) { + if(mActivity.isFinishing()) { + return; + } + new AlertDialog.Builder(mActivity) + .setIcon(android.R.drawable.ic_dialog_alert) + .setMessage(R.string.text_tsmakeup_alert_msg) + .setPositiveButton(R.string.text_tsmakeup_alert_continue, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + toggleMakeupSettings(); + + faceDetectPref.setValue(Parameters.FACE_DETECTION_ON); + onSettingChanged(faceDetectPref); + } + }) + .setNegativeButton(R.string.text_tsmakeup_alert_quit, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }) + .show(); + } + + private void toggleMakeupSettings() { + mUI.hideUI(); + initMakeupMenu(); + } + + private void closeMakeup() { + if(TsMakeupManager.HAS_TS_MAKEUP) { + if(mTsMakeupManager.isShowMakeup()) { + mTsMakeupManager.hideMakeupUI(); + closeMakeupMode(false); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } else { + mTsMakeupManager.hideMakeupUI(); + } + } + } + + public void initSceneModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + updateSceneModeIcon(pref); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addSceneMode(); + ViewGroup menuLayout = mUI.getPreviewMenuLayout(); + if (menuLayout != null) { + View view = menuLayout.getChildAt(0); + mUI.adjustOrientation(); + animateSlideIn(view, previewMenuSize, false); + } + } + }); + } + + public void addModeBack() { + if (mSceneStatus == MODE_SCENE) { + addSceneMode(); + } + if (mSceneStatus == MODE_FILTER) { + addFilterMode(); + } + } + + public void addSceneMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + + CharSequence[] entries = pref.getEntries(); + CharSequence[] entryValues = pref.getEntryValues(); + + int[] thumbnails = pref.getThumbnailIds(); + + Resources r = mActivity.getResources(); + int height = (int) (r.getDimension(R.dimen.scene_mode_height) + 2 + * r.getDimension(R.dimen.scene_mode_padding) + 1); + int width = (int) (r.getDimension(R.dimen.scene_mode_width) + 2 + * r.getDimension(R.dimen.scene_mode_padding) + 1); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = height; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = width; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_SCENE; + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + + RotateLayout layout2 = (RotateLayout) inflater.inflate( + R.layout.scene_mode_view, null, false); + + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + TextView label = (TextView) layout2.findViewById(R.id.label); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + onSettingChanged(pref); + updateSceneModeIcon(pref); + for (View v1 : views) { + v1.setBackgroundResource(R.drawable.scene_mode_view_border); + } + View border = v.findViewById(R.id.border); + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + animateSlideOutPreviewMenu(); + } + + } + return true; + } + }); + + View border = layout2.findViewById(R.id.border); + views[j] = border; + if (i == init) + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + + // ASD only available when developer options are enabled. + if(entryValues[i].equals("asd")) { + layout2.setVisibility(mActivity.isDeveloperMenuEnabled()?View.VISIBLE:View.GONE); + } + + if(entryValues[i].equals("hdr")) { + ListPreference autoHdrPref = mPreferenceGroup.findPreference(CameraSettings.KEY_AUTO_HDR); + if (autoHdrPref != null && autoHdrPref.getValue().equalsIgnoreCase("enable")) { + layout2.setVisibility(View.GONE); + } + } + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void updateSceneModeIcon(IconListPreference pref) { + int[] thumbnails = pref.getThumbnailIds(); + int ind = pref.getCurrentIndex(); + if (ind == -1) + ind = 0; + ((ImageView) mSceneModeSwitcher).setImageResource(thumbnails[ind]); + } + + public void initFilterModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null || pref.getValue() == null) + return; + changeFilterModeControlIcon(pref.getValue()); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + closeMakeup(); + + addFilterMode(); + ViewGroup menuLayout = mUI.getPreviewMenuLayout(); + if (menuLayout != null) { + View view = mUI.getPreviewMenuLayout().getChildAt(0); + mUI.adjustOrientation(); + animateSlideIn(view, previewMenuSize, false); + } + } + }); + } + + public void addFilterMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + CharSequence[] entries = pref.getEntries(); + + Resources r = mActivity.getResources(); + int height = (int) (r.getDimension(R.dimen.filter_mode_height) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + int width = (int) (r.getDimension(R.dimen.filter_mode_width) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = height; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = width; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_FILTER; + + int[] thumbnails = pref.getThumbnailIds(); + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + RotateLayout layout2 = (RotateLayout) inflater.inflate( + R.layout.filter_mode_view, null, false); + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + changeFilterModeControlIcon(pref.getValue()); + onSettingChanged(pref); + for (View v1 : views) { + v1.setBackground(null); + } + ImageView image = (ImageView) v.findViewById(R.id.image); + image.setBackgroundColor(0xff33b5e5); + } + } + return true; + } + }); + + views[j] = imageView; + if (i == init) + imageView.setBackgroundColor(0xff33b5e5); + TextView label = (TextView) layout2.findViewById(R.id.label); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + private void changeFilterModeControlIcon(String value) { + if(!value.equals("")) { + if(value.equalsIgnoreCase(mActivity.getString(R.string.pref_camera_coloreffect_entry_none))) { + value = mActivity.getString(R.string.pref_camera_filter_mode_entry_off); + } else { + value = mActivity.getString(R.string.pref_camera_filter_mode_entry_on); + } + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_FILTER_MODE); + pref.setValue(value); + int index = pref.getCurrentIndex(); + ImageView iv = (ImageView) mFilterModeSwitcher; + iv.setImageResource(((IconListPreference) pref).getLargeIconIds()[index]); + } + } + + public void openFirstLevel() { + if (isMenuBeingShown() || CameraControls.isAnimating()) { + return; + } + if(TsMakeupManager.HAS_TS_MAKEUP) { + if(mTsMakeupManager.isShowMakeup()) { + mTsMakeupManager.dismissMakeupUI(); + closeMakeupMode(false); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } else { + mTsMakeupManager.dismissMakeupUI(); + } + mTsMakeupManager.resetMakeupUIStatus(); + } + if (mListMenu == null || mPopupStatus != POPUP_FIRST_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + mUI.showPopup(mListMenu, 1, true); + } + + public void popupDismissed(boolean dismissAll) { + if (!dismissAll && mPopupStatus == POPUP_SECOND_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + mUI.showPopup(mListMenu, 1, false); + if (mListMenu != null) + mListMenu = 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) { + onPreferenceClicked(pref, 0); + } + + public void onPreferenceClicked(ListPreference pref, int y) { + if (!mActivity.isDeveloperMenuEnabled()) { + if (pref.getKey().equals(CameraSettings.KEY_REDEYE_REDUCTION)) { + privateCounter++; + if (privateCounter >= DEVELOPER_MENU_TOUCH_COUNT) { + mActivity.enableDeveloperMenu(); + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(mActivity); + prefs.edit().putBoolean(CameraSettings.KEY_DEVELOPER_MENU, true).apply(); + RotateTextToast.makeText(mActivity, + "Camera developer option is enabled now", Toast.LENGTH_SHORT).show(); + } + } else { + privateCounter = 0; + } + } + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ListSubMenu basic = (ListSubMenu) inflater.inflate( + R.layout.list_sub_menu, null, false); + basic.initialize(pref, y); + basic.setSettingChangedListener(this); + basic.setAlpha(0f); + mListSubMenu = basic; + mUI.removeLevel2(); + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.showPopup(mListSubMenu, 2, false); + } else { + mUI.showPopup(mListSubMenu, 2, true); + } + mPopupStatus = POPUP_SECOND_LEVEL; + } + + public void onListMenuTouched() { + mUI.removeLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + public void closeAllView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) { + animateSlideOut(mListMenu, 1); + } + animateSlideOutPreviewMenu(); + } + + public void closeView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null && mPopupStatus != POPUP_NONE) + animateSlideOut(mListMenu, 1); + } + + // 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())); + } + + // Return true if the preference has the specified key and the value. + private static boolean same(ListPreference pref, String key, String value) { + return (key.equals(pref.getKey()) && value.equals(pref.getValue())); + } + + public void setPreference(String key, String value) { + ListPreference pref = mPreferenceGroup.findPreference(key); + if (pref != null && !value.equals(pref.getValue())) { + pref.setValue(value); + reloadPreferences(); + } + } + + @Override + public void onSettingChanged(ListPreference pref) { + // Reset the scene mode if HDR is set to on. Reset HDR if scene mode is + // set to non-auto. + if (same(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_HDR)) { + ListPreference hdrPref = + mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_HDR); + if (hdrPref != null && same(hdrPref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) { + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOn); + } + } else if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_HDR)) { + ListPreference hdrPref = + mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_HDR); + if (hdrPref != null && notSame(hdrPref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) { + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + } + } else if (same(pref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) { + ListPreference scenePref = + mPreferenceGroup.findPreference(CameraSettings.KEY_SCENE_MODE); + if (scenePref != null && notSame(scenePref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + setPreference(CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO); + } + updateSceneModeIcon((IconListPreference) scenePref); + } else if (same(pref, CameraSettings.KEY_CAMERA_HDR, mSettingOn)) { + ListPreference scenePref = + mPreferenceGroup.findPreference(CameraSettings.KEY_SCENE_MODE); + if (scenePref != null && notSame(scenePref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_HDR)) { + setPreference(CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_HDR); + } + updateSceneModeIcon((IconListPreference) scenePref); + } else if (notSame(pref,CameraSettings.KEY_AE_BRACKET_HDR,"Off")) { + RotateTextToast.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")) { + RotateTextToast.makeText(mActivity, + R.string.flash_aebracket_message,Toast.LENGTH_SHORT).show(); + } + } else if (notSame(pref, CameraSettings.KEY_LONGSHOT, mSettingOff)) { + ListPreference advancefeaturePref = + mPreferenceGroup.findPreference(CameraSettings.KEY_ADVANCED_FEATURES); + if (advancefeaturePref != null) { + if (notSame(advancefeaturePref, CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default))) { + RotateTextToast.makeText(mActivity, R.string.longshot_enable_message, + Toast.LENGTH_LONG).show(); + } + setPreference(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + } + } else if (notSame(pref, CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default))) { + ListPreference longshotPref = + mPreferenceGroup.findPreference(CameraSettings.KEY_LONGSHOT); + if (longshotPref != null ) { + if (notSame(longshotPref, CameraSettings.KEY_LONGSHOT, mSettingOff)) { + RotateTextToast.makeText(mActivity, R.string.advance_feature_enable_msg, + Toast.LENGTH_LONG).show(); + } + setPreference(CameraSettings.KEY_LONGSHOT, mSettingOff); + } + } + + String refocusOn = mActivity.getString(R.string + .pref_camera_advanced_feature_value_refocus_on); + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, refocusOn)) { + ListPreference lp = mPreferenceGroup + .findPreference(CameraSettings.KEY_ADVANCED_FEATURES); + if (lp != null && refocusOn.equals(lp.getValue())) { + setPreference(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + } + } + + String optizoomOn = mActivity.getString(R.string + .pref_camera_advanced_feature_value_optizoom_on); + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, optizoomOn)) { + ListPreference lp = mPreferenceGroup + .findPreference(CameraSettings.KEY_ADVANCED_FEATURES); + if (lp != null && optizoomOn.equals(lp.getValue())) { + setPreference(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + } + } + + String scene_auto = mActivity.getString(R.string + .pref_camera_scenemode_entry_auto); + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, scene_auto)) { + setPreference(CameraSettings.KEY_COLOR_EFFECT, + mActivity.getString(R.string.pref_camera_coloreffect_default)); + } + + ListPreference autoHdrPref = mPreferenceGroup.findPreference(CameraSettings.KEY_AUTO_HDR); + if (autoHdrPref != null && autoHdrPref.getValue().equalsIgnoreCase("enable")) { + mHdrSwitcher.setVisibility(View.GONE); + mUI.getCameraControls().removeFromViewList(mHdrSwitcher); + } else { + mHdrSwitcher.setVisibility(View.VISIBLE); + } + updateFilterModeIcon(pref, pref); + + super.onSettingChanged(pref); + } + + public int getOrientation() { + return mUI == null ? 0 : mUI.getOrientation(); + } + + public void hideTopMenu(boolean hide) { + if (hide) { + mSceneModeSwitcher.setVisibility(View.GONE); + mFilterModeSwitcher.setVisibility(View.GONE); + mFrontBackSwitcher.setVisibility(View.GONE); + mTsMakeupSwitcher.setVisibility(View.GONE); + } else { + mSceneModeSwitcher.setVisibility(View.VISIBLE); + mFilterModeSwitcher.setVisibility(View.VISIBLE); + mFrontBackSwitcher.setVisibility(View.VISIBLE); + mTsMakeupSwitcher.setVisibility(View.VISIBLE); + } + } + + public void hideCameraControls(boolean hide) { + final int status = (hide) ? View.INVISIBLE : View.VISIBLE; + mSettingMenu.setVisibility(status); + mFrontBackSwitcher.setVisibility(status); + if (TsMakeupManager.HAS_TS_MAKEUP) { + mTsMakeupSwitcher.setVisibility(status); + } else { + mHdrSwitcher.setVisibility(status); + } + mSceneModeSwitcher.setVisibility(status); + mFilterModeSwitcher.setVisibility(status); + mCameraSwitcher.setVisibility(status); + mPreviewThumbnail.setVisibility(status); + } +} diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java new file mode 100644 index 000000000..b4b8d33d1 --- /dev/null +++ b/src/com/android/camera/CaptureModule.java @@ -0,0 +1,4934 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences.Editor; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.Rect; +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; +import android.hardware.SensorManager; +import android.location.Location; +import android.media.AudioManager; +import android.media.CameraProfile; +import android.media.SoundPool; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Debug; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.MessageQueue; +import android.os.SystemClock; +import android.provider.MediaStore; +import android.util.Log; +import android.view.KeyEvent; +import android.view.OrientationEventListener; +import android.view.SurfaceHolder; +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; +import com.android.camera.CameraManager.CameraPictureCallback; +import com.android.camera.CameraManager.CameraProxy; +import com.android.camera.CameraManager.CameraShutterCallback; +import com.android.camera.PhotoModule.NamedImages.NamedEntity; +import com.android.camera.TsMakeupManager.MakeupLevelListener; +import com.android.camera.exif.ExifInterface; +import com.android.camera.exif.ExifTag; +import com.android.camera.exif.Rational; +import com.android.camera.ui.CountDownView.OnCountDownFinishedListener; +import com.android.camera.ui.ModuleSwitcher; +import com.android.camera.ui.RotateTextToast; +import com.android.camera.util.ApiHelper; +import com.android.camera.util.CameraUtil; +import com.android.camera.util.GcamHelper; +import com.android.camera.util.UsageStatistics; +import org.codeaurora.snapcam.R; + +import android.widget.EditText; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.text.InputType; +import android.text.TextUtils; + +import com.android.internal.util.MemInfoReader; +import android.app.ActivityManager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +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, + PhotoController, + FocusOverlayManager.Listener, + CameraPreference.OnPreferenceChangedListener, + ShutterButton.OnShutterButtonListener, + MediaSaveService.Listener, + OnCountDownFinishedListener, + SensorEventListener, MakeupLevelListener { + + private static final String TAG = "CAM_PhotoModule"; + + //QCom data members + public static boolean mBrightnessVisible = false; + 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; + private DrawAutoHDR mDrawAutoHDR; + /*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; + + private static final int SETUP_PREVIEW = 1; + private static final int FIRST_TIME_INIT = 2; + private static final int CLEAR_SCREEN_DELAY = 3; + private static final int SET_CAMERA_PARAMETERS_WHEN_IDLE = 4; + private static final int SHOW_TAP_TO_FOCUS_TOAST = 5; + private static final int SWITCH_CAMERA = 6; + private static final int SWITCH_CAMERA_START_ANIMATION = 7; + 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 SET_PHOTO_UI_PARAMS = 11; + private static final int SWITCH_TO_GCAM_MODULE = 12; + private static final int ON_PREVIEW_STARTED = 13; + + // The subset of parameters we need to update in setCameraParameters(). + private static final int UPDATE_PARAM_INITIALIZE = 1; + private static final int UPDATE_PARAM_ZOOM = 2; + private static final int UPDATE_PARAM_PREFERENCE = 4; + private static final int UPDATE_PARAM_ALL = -1; + + // This is the delay before we execute onResume tasks when coming + // from the lock screen, to allow time for onPause to execute. + private static final int ON_RESUME_TASKS_DELAY_MSEC = 20; + + private static final String DEBUG_IMAGE_PREFIX = "DEBUG_"; + + // copied from Camera hierarchy + private CameraActivity mActivity; + private CameraProxy mCameraDevice; + private int mCameraId; + private Parameters mParameters; + private boolean mPaused; + private View mRootView; + + private PhotoUI mUI; + + public boolean mAutoHdrEnable; + // The activity is going to switch to the specified camera id. This is + // needed because texture copy is done in GL thread. -1 means camera is not + // switching. + protected int mPendingSwitchCameraId = -1; + private boolean mOpenCameraFail; + private boolean mCameraDisabled; + + // When setCameraParametersWhenIdle() is called, we accumulate the subsets + // needed to be updated in mUpdateSet. + private int mUpdateSet; + + private static final int SCREEN_DELAY = 2 * 60 * 1000; + + private int mZoomValue; // The current zoom value. + + private Parameters mInitialParams; + private boolean mFocusAreaSupported; + private boolean mMeteringAreaSupported; + private boolean mAeLockSupported; + private boolean mAwbLockSupported; + private boolean mContinuousFocusSupported; + private boolean mTouchAfAecFlag; + private boolean mLongshotSave = false; + private boolean mRefocus = false; + private boolean mLastPhotoTakenWithRefocus = false; + + private int mLongShotCaptureCount; + private int mLongShotCaptureCountLimit; + + // The degrees of the device rotated clockwise from its natural orientation. + private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN; + private ComboPreferences mPreferences; + private String mPrevSavedCDS; + private boolean isTNREnabled; + + private static final String sTempCropFilename = "crop-temp"; + + 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 String PERSIST_CAPTURE_ANIMATION = "persist.camera.capture.animate"; + + private static final int MINIMUM_BRIGHTNESS = 0; + private static final int MAXIMUM_BRIGHTNESS = 6; + private static final int DEFAULT_BRIGHTNESS = 3; + 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 boolean mPreviewRestartSupport = false; + + // mCropValue and mSaveUri are used only if isImageCaptureIntent() is true. + private String mCropValue; + private Uri mSaveUri; + + private Uri mDebugUri; + + // Used for check memory status for longshot mode + // Currently, this cancel threshold selection is based on test experiments, + // we can change it based on memory status or other requirements. + private static final int CHECKING_INTERVAL = 10; + private static final int LONGSHOT_CANCEL_THRESHOLD = CHECKING_INTERVAL * 40 * 1024 * 1024; + private int mRemainedMemCheckingCount; + private long mSecondaryServerMem; + private boolean mLongshotActive = false; + + // We use a queue to generated names of the images to be used later + // when the image is ready to be saved. + private NamedImages mNamedImages; + + private SoundPool mSoundPool; + private int mRefocusSound; + + private byte[] mLastJpegData; + private int mLastJpegOrientation = 0; + + private Runnable mDoSnapRunnable = new Runnable() { + @Override + public void run() { + onShutterButtonClick(); + } + }; + + private class OpenCameraThread extends Thread { + @Override + public void run() { + openCamera(); + startPreview(); + } + } + + private OpenCameraThread mOpenCameraThread = null; + /** + * An unpublished intent flag requesting to return as soon as capturing + * is completed. + * + * TODO: consider publishing by moving into MediaStore. + */ + private static final String EXTRA_QUICK_CAPTURE = + "android.intent.extra.quickCapture"; + + // The display rotation in degrees. This is only valid when mCameraState is + // not PREVIEW_STOPPED. + private int mDisplayRotation; + // The value for android.hardware.Camera.setDisplayOrientation. + private int mCameraDisplayOrientation; + // The value for UI components like indicators. + private int mDisplayOrientation; + // The value for android.hardware.Camera.Parameters.setRotation. + private int mJpegRotation; + // Indicates whether we are using front camera + private boolean mMirror; + private boolean mFirstTimeInitialized; + private boolean mIsImageCaptureIntent; + + private int mCameraState = INIT; + private boolean mSnapshotOnIdle = false; + + private ContentResolver mContentResolver; + + private LocationManager mLocationManager; + private boolean mLocationPromptTriggered = false; + + private final PostViewPictureCallback mPostViewPictureCallback = + new PostViewPictureCallback(); + private final RawPictureCallback mRawPictureCallback = + new RawPictureCallback(); + private final AutoFocusCallback mAutoFocusCallback = + new AutoFocusCallback(); + private final Object mAutoFocusMoveCallback = + ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK + ? new AutoFocusMoveCallback() + : null; + + private final CameraErrorCallback mErrorCallback = new CameraErrorCallback(); + private final StatsCallback mStatsCallback = new StatsCallback(); + private final MetaDataCallback mMetaDataCallback = new MetaDataCallback(); + private long mFocusStartTime; + private long mShutterCallbackTime; + private long mPostViewPictureCallbackTime; + private long mRawPictureCallbackTime; + private long mJpegPictureCallbackTime; + private long mOnResumeTime; + private byte[] mJpegImageData; + + // These latency time are for the CameraLatency test. + public long mAutoFocusTime; + public long mShutterLag; + public long mShutterToPictureDisplayedTime; + public long mPictureDisplayedToJpegCallbackTime; + public long mJpegCallbackFinishTime; + public long mCaptureStartTime; + + // This handles everything about focus. + private FocusOverlayManager mFocusManager; + + private String mSceneMode; + private String mCurrTouchAfAec = Parameters.TOUCH_AF_AEC_ON; + private String mSavedFlashMode = null; + + private final Handler mHandler = new MainHandler(); + private MessageQueue.IdleHandler mIdleHandler = null; + + private PreferenceGroup mPreferenceGroup; + + private boolean mQuickCapture; + private SensorManager mSensorManager; + private float[] mGData = new float[3]; + private float[] mMData = new float[3]; + private float[] mR = new float[16]; + private int mHeading = -1; + + // True if all the parameters needed to start preview is ready. + private boolean mCameraPreviewParamsReady = false; + + private int mManual3AEnabled = 0; + private static final int MANUAL_FOCUS = 1; + private static final int MANUAL_WB = 2; + private static final int MANUAL_EXPOSURE = 4; + private boolean mAnimateCapture = true; + + private int mJpegFileSizeEstimation = 0; + private int mRemainingPhotos = -1; + private static final int SELFIE_FLASH_DURATION = 680; + + private class SelfieThread extends Thread { + public void run() { + try { + Thread.sleep(SELFIE_FLASH_DURATION); + mActivity.runOnUiThread(new Runnable() { + public void run() { + mFocusManager.doSnap(); + } + }); + } catch(InterruptedException e) { + } + selfieThread = null; + } + } + private SelfieThread selfieThread; + + private class MediaSaveNotifyThread extends Thread + { + private Uri uri; + public MediaSaveNotifyThread(Uri uri) + { + this.uri = uri; + } + public void setUri(Uri uri) + { + this.uri = uri; + } + public void run() + { + while(mLongshotActive) { + try { + Thread.sleep(10); + } catch(InterruptedException e) { + } + } + mActivity.runOnUiThread(new Runnable() { + public void run() { + if (uri != null) + mActivity.notifyNewMedia(uri); + mActivity.updateStorageSpaceAndHint(); + updateRemainingPhotos(); + } + }); + mediaSaveNotifyThread = null; + } + } + + private MediaSaveNotifyThread mediaSaveNotifyThread; + private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener = + new MediaSaveService.OnMediaSavedListener() { + @Override + public void onMediaSaved(Uri uri) { + if(mLongshotActive) { + if(mediaSaveNotifyThread == null) { + mediaSaveNotifyThread = new MediaSaveNotifyThread(uri); + mediaSaveNotifyThread.start(); + } + else + mediaSaveNotifyThread.setUri(uri); + } else { + if (uri != null) { + mActivity.notifyNewMedia(uri); + } + } + } + }; + + private void checkDisplayRotation() { + // Set the display orientation if display rotation has changed. + // Sometimes this happens when the device is held upside + // down and camera app is opened. Rotation animation will + // take some time and the rotation value we have got may be + // wrong. Framework does not have a callback for this now. + if (CameraUtil.getDisplayRotation(mActivity) != mDisplayRotation) { + setDisplayOrientation(); + } + if (SystemClock.uptimeMillis() - mOnResumeTime < 5000) { + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + checkDisplayRotation(); + } + }, 100); + } + } + + public Parameters getParameters() + { + return mParameters; + } + + /** + * This Handler is used to post message back onto the main thread of the + * application + */ + private class MainHandler extends Handler { + public MainHandler() { + super(Looper.getMainLooper()); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case SETUP_PREVIEW: { + setupPreview(); + break; + } + + case CLEAR_SCREEN_DELAY: { + mActivity.getWindow().clearFlags( + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + break; + } + + case FIRST_TIME_INIT: { + initializeFirstTime(); + break; + } + + case SET_CAMERA_PARAMETERS_WHEN_IDLE: { + setCameraParametersWhenIdle(0); + break; + } + + case SHOW_TAP_TO_FOCUS_TOAST: { + showTapToFocusToast(); + break; + } + + case SWITCH_CAMERA: { + switchCamera(); + break; + } + + case SWITCH_CAMERA_START_ANIMATION: { + // TODO: Need to revisit + // ((CameraScreenNail) mActivity.mCameraScreenNail).animateSwitchCamera(); + break; + } + + case CAMERA_OPEN_DONE: { + onCameraOpened(); + break; + } + + case OPEN_CAMERA_FAIL: { + mOpenCameraFail = true; + CameraUtil.showErrorAndFinish(mActivity, + R.string.cannot_connect_camera); + break; + } + + case CAMERA_DISABLED: { + mCameraDisabled = true; + CameraUtil.showErrorAndFinish(mActivity, + R.string.camera_disabled); + 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); + break; + } + + case ON_PREVIEW_STARTED: { + onPreviewStarted(); + break; + } + } + } + } + + + @Override + public void init(CameraActivity activity, View parent) { + mActivity = activity; + mRootView = parent; + mPreferences = new ComboPreferences(mActivity); + CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal(), activity); + mCameraId = getPreferredCameraId(mPreferences); + + mContentResolver = mActivity.getContentResolver(); + + // Surface texture is from camera screen nail and startPreview needs it. + // This must be done before startPreview. + mIsImageCaptureIntent = isImageCaptureIntent(); + + mPreferences.setLocalId(mActivity, mCameraId); + CameraSettings.upgradeLocalPreferences(mPreferences.getLocal()); + + mUI = new PhotoUI(activity, this, parent); + if (mOpenCameraThread == null) { + mOpenCameraThread = new OpenCameraThread(); + mOpenCameraThread.start(); + } + initializeControlByIntent(); + 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); + mbrightness = mPreferences.getInt( + CameraSettings.KEY_BRIGHTNESS, + DEFAULT_BRIGHTNESS); + brightnessProgressBar.setProgress(mbrightness); + brightnessProgressBar.setVisibility(View.INVISIBLE); + Storage.setSaveSDCard( + mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1")); + } + + private void initializeControlByIntent() { + mUI.initializeControlByIntent(); + if (mIsImageCaptureIntent) { + setupCaptureParams(); + } + } + + private void onPreviewStarted() { + if (mCameraState == SNAPSHOT_IN_PROGRESS) { + return; + } + setCameraState(IDLE); + mFocusManager.onPreviewStarted(); + startFaceDetection(); + locationFirstRun(); + mUI.enableShutter(true); + } + + // Prompt the user to pick to record location for the very first run of + // camera only + private void locationFirstRun() { + /* Do not prompt if the preference is already set, this is a secure + * camera session, or the prompt has already been triggered. */ + if (RecordLocationPreference.isSet(mPreferences) || + mActivity.isSecureCamera() || mLocationPromptTriggered) { + return; + } + // Check if the back camera exists + int backCameraId = CameraHolder.instance().getBackCameraId(); + if (backCameraId == -1) { + // If there is no back camera, do not show the prompt. + return; + } + + mLocationPromptTriggered = true; + mUI.showLocationDialog(); + } + + @Override + public void enableRecordingLocation(boolean enable) { + setLocationPreference(enable ? RecordLocationPreference.VALUE_ON + : RecordLocationPreference.VALUE_OFF); + } + + @Override + public void onPreviewUIReady() { + if (mPaused || mCameraDevice == null) { + return; + } + Log.v(TAG, "onPreviewUIReady"); + if (mCameraState == PREVIEW_STOPPED) { + startPreview(); + } else { + synchronized (mCameraDevice) { + SurfaceHolder sh = mUI.getSurfaceHolder(); + if (sh == null) { + Log.w(TAG, "startPreview: holder for preview are not ready."); + return; + } + mCameraDevice.setPreviewDisplay(sh); + } + } + } + + @Override + public void onPreviewUIDestroyed() { + if (mCameraDevice == null) { + return; + } + try { + if (mOpenCameraThread != null) { + mOpenCameraThread.join(); + mOpenCameraThread = null; + } + } catch (InterruptedException ex) { + // ignore + } + mCameraDevice.setPreviewDisplay(null); + stopPreview(); + } + + private void setLocationPreference(String value) { + mPreferences.edit() + .putString(CameraSettings.KEY_RECORD_LOCATION, value) + .apply(); + // TODO: Fix this to use the actual onSharedPreferencesChanged listener + // instead of invoking manually + onSharedPreferenceChanged(); + } + + private void onCameraOpened() { + if (mPaused) { + return; + } + Log.v(TAG, "onCameraOpened"); + openCameraCommon(); + resizeForPreviewAspectRatio(); + updateFocusManager(mUI); + } + + private void switchCamera() { + if (mPaused) return; + + Log.v(TAG, "Start to switch camera. id=" + mPendingSwitchCameraId); + mCameraId = mPendingSwitchCameraId; + mPendingSwitchCameraId = -1; + setCameraId(mCameraId); + + // from onPause + try { + if (mOpenCameraThread != null) { + mOpenCameraThread.join(); + mOpenCameraThread = null; + } + } catch (InterruptedException ex) { + // ignore + } + closeCamera(); + mUI.collapseCameraControls(); + mUI.clearFaces(); + if (mFocusManager != null) mFocusManager.removeMessages(); + + // Restart the camera and initialize the UI. From onCreate. + mPreferences.setLocalId(mActivity, mCameraId); + CameraSettings.upgradeLocalPreferences(mPreferences.getLocal()); + mCameraDevice = CameraUtil.openCamera( + mActivity, mCameraId, mHandler, + mActivity.getCameraOpenErrorCallback()); + + if (mCameraDevice == null) { + Log.e(TAG, "Failed to open camera:" + mCameraId + ", aborting."); + return; + } + mParameters = mCameraDevice.getParameters(); + mInitialParams = mParameters; + initializeCapabilities(); + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + mMirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT); + mFocusManager.setMirror(mMirror); + mFocusManager.setParameters(mInitialParams); + setupPreview(); + + // reset zoom value index + mZoomValue = 0; + resizeForPreviewAspectRatio(); + openCameraCommon(); + + // Start switch camera animation. Post a message because + // onFrameAvailable from the old camera may already exist. + mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION); + } + + protected void setCameraId(int cameraId) { + ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID); + pref.setValue("" + cameraId); + } + + // either open a new camera or switch cameras + private void openCameraCommon() { + loadCameraPreferences(); + + mUI.onCameraOpened(mPreferenceGroup, mPreferences, mParameters, this, this); + if (mIsImageCaptureIntent) { + mUI.overrideSettings(CameraSettings.KEY_CAMERA_HDR_PLUS, + mActivity.getString(R.string.setting_off_value)); + } + updateCameraSettings(); + showTapToFocusToastIfNeeded(); + resetManual3ASettings(); + resetMiscSettings(); + } + + @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); + } + + private void resetExposureCompensation() { + String value = mPreferences.getString(CameraSettings.KEY_EXPOSURE, + CameraSettings.EXPOSURE_DEFAULT_VALUE); + if (!CameraSettings.EXPOSURE_DEFAULT_VALUE.equals(value)) { + Editor editor = mPreferences.edit(); + editor.putString(CameraSettings.KEY_EXPOSURE, "0"); + editor.apply(); + } + } + + private void resetManual3ASettings() { + String manualExposureDefault = mActivity.getString( + R.string.pref_camera_manual_exp_default); + String manualExposureMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_EXPOSURE, manualExposureDefault); + if (!manualExposureMode.equals(manualExposureDefault)) { + mUI.setPreference( + CameraSettings.KEY_MANUAL_EXPOSURE, manualExposureDefault); + UpdateManualExposureSettings(); + } + String manualFocusDefault = mActivity.getString( + R.string.pref_camera_manual_focus_default); + String manualFocusMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_FOCUS, manualFocusDefault); + if (!manualFocusMode.equals(manualFocusDefault)) { + mUI.setPreference( + CameraSettings.KEY_MANUAL_FOCUS, manualFocusDefault); + UpdateManualFocusSettings(); + } + String manualWBDefault = mActivity.getString( + R.string.pref_camera_manual_wb_default); + String manualWBMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_WB, manualWBDefault); + if (!manualWBMode.equals(manualWBDefault)) { + mUI.setPreference( + CameraSettings.KEY_MANUAL_WB, manualWBDefault); + UpdateManualWBSettings(); + } + mManual3AEnabled = 0; + } + + private void resetMiscSettings() { + boolean disableQcomMiscSetting = + SystemProperties.getBoolean("camera.qcom.misc.disable", false); + if (disableQcomMiscSetting) { + mUI.setPreference(CameraSettings.KEY_ZSL, Parameters.ZSL_OFF); + mUI.setPreference(CameraSettings.KEY_FACE_DETECTION, + Parameters.FACE_DETECTION_OFF); + mUI.setPreference(CameraSettings.KEY_TOUCH_AF_AEC, + Parameters.TOUCH_AF_AEC_OFF); + mUI.setPreference(CameraSettings.KEY_FOCUS_MODE, + Parameters.FOCUS_MODE_AUTO); + mUI.setPreference(CameraSettings.KEY_FLASH_MODE, + Parameters.FLASH_MODE_OFF); + mUI.setPreference(CameraSettings.KEY_DENOISE, + Parameters.DENOISE_OFF); + onSharedPreferenceChanged(); + } + } + + 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.i(TAG, "Using preview width = " + size.width + "& height = " + size.height); + mUI.setAspectRatio((float) size.width / size.height); + } + + @Override + public void onSwitchSavePath() { + if (mUI.mMenuInitialized) { + mUI.setPreference(CameraSettings.KEY_CAMERA_SAVEPATH, "1"); + } else { + mPreferences.edit() + .putString(CameraSettings.KEY_CAMERA_SAVEPATH, "1") + .apply(); + } + RotateTextToast.makeText(mActivity, R.string.on_switch_save_path_to_sdcard, + Toast.LENGTH_SHORT).show(); + } + + // Snapshots can only be taken after this is called. It should be called + // once only. We could have done these things in onCreate() but we want to + // make preview screen appear as soon as possible. + private void initializeFirstTime() { + if (mFirstTimeInitialized || mPaused) { + return; + } + + // Initialize location service. + boolean recordLocation = RecordLocationPreference.get( + mPreferences, mContentResolver); + mLocationManager.recordLocation(recordLocation); + + mUI.initializeFirstTime(); + MediaSaveService s = mActivity.getMediaSaveService(); + // We set the listener only when both service and shutterbutton + // are initialized. + if (s != null) { + s.setListener(this); + } + + mNamedImages = new NamedImages(); + mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view); + mDrawAutoHDR = (DrawAutoHDR )mRootView.findViewById(R.id.autohdr_view); + if (mGraphView == null || mDrawAutoHDR == null){ + Log.e(TAG, "mGraphView or mDrawAutoHDR is null"); + } else{ + mGraphView.setPhotoModuleObject(this); + mDrawAutoHDR.setPhotoModuleObject(this); + } + + mFirstTimeInitialized = true; + Log.d(TAG, "addIdleHandler in first time initialization"); + addIdleHandler(); + + } + + // If the activity is paused and resumed, this method will be called in + // onResume. + private void initializeSecondTime() { + // Start location update if needed. + boolean recordLocation = RecordLocationPreference.get( + mPreferences, mContentResolver); + mLocationManager.recordLocation(recordLocation); + MediaSaveService s = mActivity.getMediaSaveService(); + if (s != null) { + s.setListener(this); + } + mNamedImages = new NamedImages(); + if (!mIsImageCaptureIntent) { + mUI.showSwitcher(); + } + mUI.initializeSecondTime(mParameters); + } + + private void showTapToFocusToastIfNeeded() { + // Show the tap to focus toast if this is the first start. + if (mFocusAreaSupported && + mPreferences.getBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, true)) { + // Delay the toast for one second to wait for orientation. + mHandler.sendEmptyMessageDelayed(SHOW_TAP_TO_FOCUS_TOAST, 1000); + } + } + + private void addIdleHandler() { + 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 (mCameraDevice == null) return; + + if (mFaceDetectionEnabled == false + || mFaceDetectionStarted || mCameraState != IDLE) return; + if (mParameters.getMaxNumDetectedFaces() > 0) { + mFaceDetectionStarted = true; + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + mUI.onStartFaceDetection(mDisplayOrientation, + (info.facing == CameraInfo.CAMERA_FACING_FRONT)); + mCameraDevice.setFaceDetectionCallback(mHandler, mUI); + mCameraDevice.startFaceDetection(); + } + } + + @Override + public void stopFaceDetection() { + if (mFaceDetectionEnabled == false || !mFaceDetectionStarted) return; + if (mParameters.getMaxNumDetectedFaces() > 0) { + mFaceDetectionStarted = false; + mCameraDevice.setFaceDetectionCallback(null, null); + mUI.pauseFaceDetection(); + mCameraDevice.stopFaceDetection(); + mUI.onStopFaceDetection(); + } + } + + // TODO: need to check cached background apps memory and longshot ION memory + private boolean isLongshotNeedCancel() { + if(mRemainedMemCheckingCount < CHECKING_INTERVAL) { + mRemainedMemCheckingCount++; + return false; + } + mRemainedMemCheckingCount = 0; + if (Storage.getAvailableSpace() <= Storage.LOW_STORAGE_THRESHOLD_BYTES * CHECKING_INTERVAL) { + Log.w(TAG, "current storage is full"); + return true; + } + if (mSecondaryServerMem == 0) { + ActivityManager am = (ActivityManager) mActivity.getSystemService( + Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo(); + am.getMemoryInfo(memInfo); + mSecondaryServerMem = memInfo.secondaryServerThreshold; + } + + long totalMemory = Runtime.getRuntime().totalMemory(); + long maxMemory = Runtime.getRuntime().maxMemory(); + long remainMemory = maxMemory - totalMemory; + + MemInfoReader reader = new MemInfoReader(); + reader.readMemInfo(); + long[] info = reader.getRawInfo(); + long availMem = (info[Debug.MEMINFO_FREE] + info[Debug.MEMINFO_CACHED]) * 1024; + + if (availMem <= mSecondaryServerMem || remainMemory <= LONGSHOT_CANCEL_THRESHOLD) { + Log.e(TAG, "cancel longshot: free=" + info[Debug.MEMINFO_FREE] * 1024 + + " cached=" + info[Debug.MEMINFO_CACHED] * 1024 + + " threshold=" + mSecondaryServerMem); + mLongshotActive = false; + RotateTextToast.makeText(mActivity,R.string.msg_cancel_longshot_for_limited_memory, + Toast.LENGTH_SHORT).show(); + return true; + } + + return false; + } + + 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 || + !mLongshotActive) { + return; + } + + if(isLongshotNeedCancel()) { + return; + } + + if(mLongShotCaptureCount == mLongShotCaptureCountLimit) { + mLongshotActive = false; + return; + } + + mUI.doShutterAnimation(); + + Location loc = getLocationAccordPictureFormat(mParameters.get(KEY_PICTURE_FORMAT)); + + mLongShotCaptureCount++; + if (mLongshotSave) { + mCameraDevice.takePicture(mHandler, + new LongshotShutterCallback(), + mRawPictureCallback, mPostViewPictureCallback, + new LongshotPictureCallback(loc)); + } else { + mCameraDevice.takePicture(mHandler,new LongshotShutterCallback(), + mRawPictureCallback, mPostViewPictureCallback, + new JpegPictureCallback(loc)); + } + } + } + } + + private final class ShutterCallback + implements CameraShutterCallback { + + private boolean mNeedsAnimation; + + public ShutterCallback(boolean needsAnimation) { + mNeedsAnimation = needsAnimation; + } + + @Override + public void onShutter(CameraProxy camera) { + mShutterCallbackTime = System.currentTimeMillis(); + mShutterLag = mShutterCallbackTime - mCaptureStartTime; + Log.e(TAG, "[KPI Perf] PROFILE_SHUTTER_LAG mShutterLag = " + mShutterLag + "ms"); + if (mNeedsAnimation) { + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + animateAfterShutter(); + } + }); + } + if (mRefocus) { + mSoundPool.play(mRefocusSound, 1.0f, 1.0f, 0, 0, 1.0f); + } + } + } + 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 MetaDataCallback + implements android.hardware.Camera.CameraMetaDataCallback{ + @Override + public void onCameraMetaData (byte[] data, android.hardware.Camera camera) { + int metadata[] = new int[3]; + if (data.length >= 12) { + for (int i =0;i<3;i++) { + metadata[i] = byteToInt( (byte []) data, i*4); + } + if (metadata[2] == 1) { + mAutoHdrEnable = true; + mActivity.runOnUiThread(new Runnable() { + public void run() { + if (mDrawAutoHDR != null) + mDrawAutoHDR.AutoHDR(); + } + }); + } + else { + mAutoHdrEnable = false; + mActivity.runOnUiThread(new Runnable() { + public void run() { + if (mDrawAutoHDR != null) + mDrawAutoHDR.AutoHDR(); + } + }); + } + } + } + + private int byteToInt (byte[] b, int offset) { + int value = 0; + for (int i = 0; i < 4; i++) { + int shift = (4 - 1 - i) * 8; + value += (b[(3-i) + offset] & 0x000000FF) << shift; + } + return value; + } + } + + private final class PostViewPictureCallback + implements CameraPictureCallback { + @Override + public void onPictureTaken(byte [] data, CameraProxy camera) { + mPostViewPictureCallbackTime = System.currentTimeMillis(); + Log.v(TAG, "mShutterToPostViewCallbackTime = " + + (mPostViewPictureCallbackTime - mShutterCallbackTime) + + "ms"); + } + } + + private final class RawPictureCallback + implements CameraPictureCallback { + @Override + public void onPictureTaken(byte [] rawData, CameraProxy camera) { + mRawPictureCallbackTime = System.currentTimeMillis(); + Log.v(TAG, "mShutterToRawCallbackTime = " + + (mRawPictureCallbackTime - mShutterCallbackTime) + "ms"); + } + } + + 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; + + public JpegPictureCallback(Location loc) { + mLocation = loc; + } + + @Override + public void onPictureTaken(final byte [] jpegData, CameraProxy camera) { + mUI.stopSelfieFlash(); + mUI.enableShutter(true); + if (mPaused) { + return; + } + if (mIsImageCaptureIntent) { + if (!mRefocus) { + stopPreview(); + } + } else if (mSceneMode == CameraUtil.SCENE_MODE_HDR) { + mUI.showSwitcher(); + 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. + if (mPostViewPictureCallbackTime != 0) { + mShutterToPictureDisplayedTime = + mPostViewPictureCallbackTime - mShutterCallbackTime; + mPictureDisplayedToJpegCallbackTime = + mJpegPictureCallbackTime - mPostViewPictureCallbackTime; + } else { + mShutterToPictureDisplayedTime = + mRawPictureCallbackTime - mShutterCallbackTime; + mPictureDisplayedToJpegCallbackTime = + mJpegPictureCallbackTime - mRawPictureCallbackTime; + } + Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = " + + mPictureDisplayedToJpegCallbackTime + "ms"); + + mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden. + + 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(); + if (!mIsImageCaptureIntent) { + setCameraState(IDLE); + } + startFaceDetection(); + } + + mLastPhotoTakenWithRefocus = mRefocus; + if (mRefocus) { + final String[] NAMES = { "00.jpg", "01.jpg", "02.jpg", "03.jpg", + "04.jpg", "DepthMapImage.y", "AllFocusImage.jpg" }; + try { + FileOutputStream out = mActivity.openFileOutput(NAMES[mReceivedSnapNum - 1], + Context.MODE_PRIVATE); + out.write(jpegData, 0, jpegData.length); + out.close(); + } catch (Exception e) { + } + } + if (!mRefocus || (mRefocus && mReceivedSnapNum == 7)) { + ExifInterface exif = Exif.getExif(jpegData); + int orientation = Exif.getOrientation(exif); + if (!mIsImageCaptureIntent) { + // Burst snapshot. Generate new image name. + if (mReceivedSnapNum > 1) { + mNamedImages.nameNewImage(mCaptureStartTime, mRefocus); + } + // Calculate the width and the height of the jpeg. + Size s = mParameters.getPictureSize(); + int width, height; + if ((mJpegRotation + orientation) % 180 == 0) { + width = s.width; + height = s.height; + } else { + 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; + // Handle debug mode outputs + if (mDebugUri != null) { + // If using a debug uri, save jpeg there. + saveToDebugUri(jpegData); + // Adjust the title of the debug image shown in mediastore. + if (title != null) { + title = DEBUG_IMAGE_PREFIX + title; + } + } + if (title == null) { + Log.e(TAG, "Unbalanced name/data pair"); + } else { + if (date == -1) { + date = mCaptureStartTime; + } + if (mHeading >= 0) { + // heading direction has been updated by the sensor. + ExifTag directionRefTag = exif.buildTag( + ExifInterface.TAG_GPS_IMG_DIRECTION_REF, + ExifInterface.GpsTrackRef.MAGNETIC_DIRECTION); + ExifTag directionTag = exif.buildTag( + ExifInterface.TAG_GPS_IMG_DIRECTION, + new Rational(mHeading, 1)); + 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, mPictureFormat); + if (mRefocus && mReceivedSnapNum == 7) { + mUI.showRefocusToast(mRefocus); + } + } + // Animate capture with real jpeg data instead of a preview frame. + 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); + } + if (mAnimateCapture) { + mUI.animateCapture(jpegData, orientation, mMirror); + } + } else { + // In long shot mode, we do not want to update the preview thumbnail + // for each snapshot, instead, keep the last jpeg data and orientation, + // use it to show the final one at the end of long shot. + mLastJpegData = jpegData; + mLastJpegOrientation = orientation; + } + + } else { + stopPreview(); + mJpegImageData = jpegData; + if (!mQuickCapture) { + mUI.showCapturedImageForReview(jpegData, orientation, mMirror); + } else { + onCaptureDone(); + } + } + if(!mLongshotActive) + mActivity.updateStorageSpaceAndHint(); + mUI.updateRemainingPhotos(--mRemainingPhotos); + long now = System.currentTimeMillis(); + mJpegCallbackFinishTime = now - mJpegPictureCallbackTime; + Log.v(TAG, "mJpegCallbackFinishTime = " + + mJpegCallbackFinishTime + "ms"); + + 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 && + !mIsImageCaptureIntent) { + 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 final class AutoFocusCallback implements CameraAFCallback { + @Override + public void onAutoFocus( + boolean focused, CameraProxy camera) { + if (mPaused) return; + + mAutoFocusTime = System.currentTimeMillis() - mFocusStartTime; + Log.v(TAG, "mAutoFocusTime = " + mAutoFocusTime + "ms"); + //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()); + } + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private final class AutoFocusMoveCallback + implements CameraAFMoveCallback { + @Override + public void onAutoFocusMoving( + boolean moving, CameraProxy camera) { + mFocusManager.onAutoFocusMoving(moving); + } + } + + /** + * This class is just a thread-safe queue for name,date holder objects. + */ + public static class NamedImages { + private Vector mQueue; + + public NamedImages() { + mQueue = new Vector(); + } + + public void nameNewImage(long date) { + NamedEntity r = new NamedEntity(); + r.title = CameraUtil.createJpegName(date); + r.date = date; + mQueue.add(r); + } + + public void nameNewImage(long date, boolean refocus) { + NamedEntity r = new NamedEntity(); + r.title = CameraUtil.createJpegName(date, refocus); + r.date = date; + mQueue.add(r); + } + + public NamedEntity getNextNameEntity() { + synchronized(mQueue) { + if (!mQueue.isEmpty()) { + return mQueue.remove(0); + } + } + return null; + } + + public static class NamedEntity { + public String title; + public long date; + } + } + + private void setCameraState(int state) { + mCameraState = state; + switch (state) { + case PhotoController.PREVIEW_STOPPED: + case PhotoController.SNAPSHOT_IN_PROGRESS: + case PhotoController.LONGSHOT: + case PhotoController.SWITCHING_CAMERA: + mUI.enableGestures(false); + break; + case PhotoController.IDLE: + mUI.enableGestures(true); + break; + } + } + + private void animateAfterShutter() { + // Only animate when in full screen capture mode + // i.e. If monkey/a user swipes to the gallery during picture taking, + // don't show animation + if (!mIsImageCaptureIntent) { + mUI.animateFlash(); + } + } + + @Override + public boolean capture() { + // If we are already in the middle of taking a snapshot or the image save request + // is full then ignore. + if (mCameraDevice == null || mCameraState == SNAPSHOT_IN_PROGRESS + || mCameraState == SWITCHING_CAMERA + || mActivity.getMediaSaveService() == null + || mActivity.getMediaSaveService().isQueueFull()) { + return false; + } + mCaptureStartTime = System.currentTimeMillis(); + mPostViewPictureCallbackTime = 0; + 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(); + } + + if (mCameraState == LONGSHOT) { + mCameraDevice.setLongshot(true); + } + + // Set rotation and gps data. + int orientation = mOrientation; + mJpegRotation = CameraUtil.getJpegRotation(mCameraId, orientation); + String pictureFormat = mParameters.get(KEY_PICTURE_FORMAT); + Location loc = getLocationAccordPictureFormat(pictureFormat); + + synchronized (mCameraDevice) { + mParameters.setRotation(mJpegRotation); + CameraUtil.setGpsParameters(mParameters, loc); + + if (mRefocus) { + mParameters.set(CameraSettings.KEY_QC_LEGACY_BURST, + CameraSettings.KEY_QC_RE_FOCUS_COUNT); + } else { + mParameters.remove(CameraSettings.KEY_QC_LEGACY_BURST); + } + + // Unlock AE&AWB, if they continue + // to be locked during snapshot, then + // side effects could be triggered w.r.t. + // flash. + mFocusManager.setAeAwbLock(false); + setAutoExposureLockIfSupported(); + setAutoWhiteBalanceLockIfSupported(); + + 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); + // Restart is needed if HDR is enabled + mPreviewRestartSupport &= !CameraUtil.SCENE_MODE_HDR.equals(mSceneMode); + mPreviewRestartSupport &= PIXEL_FORMAT_JPEG.equalsIgnoreCase( + pictureFormat); + + // We don't want user to press the button again while taking a + // multi-second HDR photo. For longshot, no need to disable. + if (mCameraState != LONGSHOT) { + mUI.enableShutter(false); + } + + if (mCameraState == LONGSHOT) { + mLongShotCaptureCountLimit = SystemProperties.getInt( + "persist.camera.longshot.shotnum", 0); + mLongShotCaptureCount = 1; + 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.enableShutterSound(!mRefocus); + mCameraDevice.takePicture(mHandler, + new ShutterCallback(!animateBefore), + mRawPictureCallback, mPostViewPictureCallback, + new JpegPictureCallback(loc)); + setCameraState(SNAPSHOT_IN_PROGRESS); + } + + mNamedImages.nameNewImage(mCaptureStartTime, mRefocus); + + 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")); + return true; + } + + @Override + public void setFocusParameters() { + setCameraParameters(UPDATE_PARAM_PREFERENCE); + } + + private Location getLocationAccordPictureFormat(String pictureFormat) { + if (pictureFormat != null && + PIXEL_FORMAT_JPEG.equalsIgnoreCase(pictureFormat)) { + return mLocationManager.getCurrentLocation(); + } + return null; + } + + private int getPreferredCameraId(ComboPreferences preferences) { + int intentCameraId = CameraUtil.getCameraFacingIntentExtras(mActivity); + if (intentCameraId != -1) { + // Testing purpose. Launch a specific camera through the intent + // extras. + return intentCameraId; + } else { + return CameraSettings.readPreferredCameraId(preferences); + } + } + + private void updateCommonManual3ASettings() { + String touchAfAec = mParameters.TOUCH_AF_AEC_OFF; + mSceneMode = Parameters.SCENE_MODE_AUTO; + String flashMode = Parameters.FLASH_MODE_OFF; + String redeyeReduction = mActivity.getString(R.string. + pref_camera_redeyereduction_entry_disable); + String aeBracketing = mActivity.getString(R.string. + pref_camera_ae_bracket_hdr_entry_off); + String colorEffect = mActivity.getString(R.string. + pref_camera_coloreffect_default); + String exposureCompensation = CameraSettings.EXPOSURE_DEFAULT_VALUE; + + if (mManual3AEnabled > 0) { + overrideCameraSettings(flashMode, null, null, + exposureCompensation, touchAfAec, + mParameters.getAutoExposure(), + Integer.toString(mParameters.getSaturation()), + Integer.toString(mParameters.getContrast()), + Integer.toString(mParameters.getSharpness()), + colorEffect, + mSceneMode, redeyeReduction, aeBracketing); + mUI.overrideSettings(CameraSettings.KEY_LONGSHOT, + mActivity.getString(R.string.setting_off_value)); + } else { + //enable all + touchAfAec = mActivity.getString( + R.string.pref_camera_touchafaec_default); + overrideCameraSettings(null, null, null, + null, touchAfAec, null, + null, null, null, null, + null, null, null); + mUI.overrideSettings(CameraSettings.KEY_LONGSHOT, null); + } + + String isoMode = mParameters.getISOValue(); + final String isoManual = CameraSettings.KEY_MANUAL_ISO; + if (isoMode.equals(isoManual)) { + final String isoPref = mPreferences.getString( + CameraSettings.KEY_ISO, + mActivity.getString(R.string.pref_camera_iso_default)); + mUI.overrideSettings(CameraSettings.KEY_ISO, isoPref); + } + if ((mManual3AEnabled & MANUAL_WB) != 0) { + String whiteBalance = mPreferences.getString( + CameraSettings.KEY_WHITE_BALANCE, + mActivity.getString(R.string.pref_camera_whitebalance_default)); + mUI.overrideSettings(CameraSettings.KEY_WHITE_BALANCE, whiteBalance); + } + if ((mManual3AEnabled & MANUAL_FOCUS) != 0) { + mUI.overrideSettings(CameraSettings.KEY_FOCUS_MODE, + mFocusManager.getFocusMode()); + } + } + + 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; + boolean disableLongShot = false; + + String ubiFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_ubifocus_on); + String continuousShotOn = + mActivity.getString(R.string.setting_on_value); + String reFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_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); + String fssrOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_on); + String truPortraitOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_on); + String multiTouchFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_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 fssr = + mParameters.get(CameraSettings.KEY_QC_FSSR); + String truePortrait = + mParameters.get(CameraSettings.KEY_QC_TP); + String multiTouchFocus = + mParameters.get(CameraSettings.KEY_QC_MULTI_TOUCH_FOCUS); + String stillMoreOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_stillmore_on); + String stillMore = + mParameters.get(CameraSettings.KEY_QC_STILL_MORE); + String continuousShot = + mParameters.get("long-shot"); + + if (mManual3AEnabled > 0) { + disableLongShot = true; + } + + 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); + } + String reFocus = + mParameters.get(CameraSettings.KEY_QC_RE_FOCUS); + + if (mFocusManager.isZslEnabled()) { + 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 ((multiTouchFocus != null && multiTouchFocus.equals(multiTouchFocusOn)) || + (chromaFlash != null && chromaFlash.equals(chromaFlashOn)) || + (optiZoom != null && optiZoom.equals(optiZoomOn)) || + (fssr != null && fssr.equals(fssrOn)) || + (truePortrait != null && truePortrait.equals(truPortraitOn)) || + (stillMore != null && stillMore.equals(stillMoreOn))) { + if (optiZoom != null && optiZoom.equals(optiZoomOn)) { + sceneMode = null; + } else { + 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(null, null, focusMode, + exposureCompensation, touchAfAec, null, + null, null, null, colorEffect, + sceneMode, redeyeReduction, aeBracketing); + disableLongShot = true; + } + + // If scene mode is set, for white balance and focus mode + // read settings from preferences so we retain user preferences. + if (!Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) { + flashMode = mParameters.FLASH_MODE_OFF; + String whiteBalance = Parameters.WHITE_BALANCE_AUTO; + focusMode = mFocusManager.getFocusMode(); + colorEffect = mParameters.getColorEffect(); + String defaultEffect = mActivity.getString(R.string.pref_camera_coloreffect_default); + if (CameraUtil.SCENE_MODE_HDR.equals(mSceneMode) + && colorEffect != null & !colorEffect.equals(defaultEffect)) { + disableLongShot = true; + // Change the colorEffect to default(None effect) when HDR ON. + colorEffect = defaultEffect; + mUI.setPreference(CameraSettings.KEY_COLOR_EFFECT, colorEffect); + mParameters.setColorEffect(colorEffect); + mCameraDevice.setParameters(mParameters); + mParameters = mCameraDevice.getParameters(); + } + exposureCompensation = + Integer.toString(mParameters.getExposureCompensation()); + touchAfAec = mCurrTouchAfAec; + + overrideCameraSettings(null, whiteBalance, focusMode, + exposureCompensation, touchAfAec, + mParameters.getAutoExposure(), + Integer.toString(mParameters.getSaturation()), + Integer.toString(mParameters.getContrast()), + Integer.toString(mParameters.getSharpness()), + colorEffect, + sceneMode, redeyeReduction, aeBracketing); + } else if (mFocusManager.isZslEnabled()) { + focusMode = mParameters.getFocusMode(); + overrideCameraSettings(null, null, focusMode, + exposureCompensation, touchAfAec, null, + null, null, null, colorEffect, + sceneMode, redeyeReduction, aeBracketing); + } else { + if (mManual3AEnabled > 0) { + updateCommonManual3ASettings(); + } else { + overrideCameraSettings(null, 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")) { + flashMode = Parameters.FLASH_MODE_OFF; + mParameters.setFlashMode(flashMode); + } + if (disableLongShot) { + mUI.overrideSettings(CameraSettings.KEY_LONGSHOT, + mActivity.getString(R.string.setting_off_value)); + } else { + mUI.overrideSettings(CameraSettings.KEY_LONGSHOT, null); + } + + if (flashMode == null) { + // Restore saved flash mode or default mode + if (mSavedFlashMode == null) { + mSavedFlashMode = mPreferences.getString( + CameraSettings.KEY_FLASH_MODE, + mActivity.getString(R.string.pref_camera_flashmode_default)); + } + mUI.setPreference(CameraSettings.KEY_FLASH_MODE, mSavedFlashMode); + mSavedFlashMode = null; + } else { + // Save the current flash mode + if (mSavedFlashMode == null) { + mSavedFlashMode = mPreferences.getString( + CameraSettings.KEY_FLASH_MODE, + mActivity.getString(R.string.pref_camera_flashmode_default)); + } + mUI.overrideSettings(CameraSettings.KEY_FLASH_MODE, flashMode); + } + + if(mCameraId != CameraHolder.instance().getFrontCameraId()) + CameraSettings.removePreferenceFromScreen(mPreferenceGroup, CameraSettings.KEY_SELFIE_FLASH); + } + + private void overrideCameraSettings(final String flashMode, + 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_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(); + + Log.e(TAG,"loadCameraPreferences() updating camera_id pref"); + + IconListPreference switchIconPref = + (IconListPreference)mPreferenceGroup.findPreference( + CameraSettings.KEY_CAMERA_ID); + + //if numOfCams < 2 then switchIconPref will be null as there is no switch icon in this case + if (switchIconPref == null) + return; + + int[] iconIds = new int[numOfCams]; + String[] entries = new String[numOfCams]; + String[] labels = new String[numOfCams]; + int[] largeIconIds = new int[numOfCams]; + + for(int i=0;i onPause --> onResume cycle from lock screen. + // Don't do always because letting go of thread can cause delay. + String action = mActivity.getIntent().getAction(); + if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(action) + || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) { + Log.v(TAG, "On resume, from lock screen."); + // Note: onPauseAfterSuper() will delete this runnable, so we will + // at most have 1 copy queued up. + mHandler.postDelayed(new Runnable() { + public void run() { + onResumeTasks(); + } + }, ON_RESUME_TASKS_DELAY_MSEC); + } else { + Log.v(TAG, "On resume."); + onResumeTasks(); + } + + mUI.setSwitcherIndex(); + if (mSoundPool == null) { + mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); + mRefocusSound = mSoundPool.load(mActivity, R.raw.camera_click_x5, 1); + } + + mHandler.post(new Runnable(){ + @Override + public void run(){ + mActivity.updateStorageSpaceAndHint(); + updateRemainingPhotos(); + } + }); + } + + private void updateRemainingPhotos() { + if (mJpegFileSizeEstimation != 0) { + mRemainingPhotos = (int) + ((mActivity.getStorageSpaceBytes() - Storage.LOW_STORAGE_THRESHOLD_BYTES) + / mJpegFileSizeEstimation); + } else { + mRemainingPhotos = -1; + } + mUI.updateRemainingPhotos(mRemainingPhotos); + } + + private void onResumeTasks() { + Log.v(TAG, "Executing onResumeTasks."); + if (mOpenCameraFail || mCameraDisabled) return; + + if (mOpenCameraThread == null) { + mOpenCameraThread = new OpenCameraThread(); + mOpenCameraThread.start(); + } + + mJpegPictureCallbackTime = 0; + mZoomValue = 0; + + // If first time initialization is not finished, put it in the + // message queue. + if (!mFirstTimeInitialized) { + mHandler.sendEmptyMessage(FIRST_TIME_INIT); + } else { + initializeSecondTime(); + } + mUI.initDisplayChangeListener(); + keepScreenOnAwhile(); + mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup, + mPreferences); + + UsageStatistics.onContentViewChanged( + UsageStatistics.COMPONENT_CAMERA, "PhotoModule"); + + Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (gsensor != null) { + mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_NORMAL); + } + + Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); + if (msensor != null) { + mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_NORMAL); + } + + mOnResumeTime = SystemClock.uptimeMillis(); + checkDisplayRotation(); + + mAnimateCapture = SystemProperties.getBoolean( + PERSIST_CAPTURE_ANIMATION, true); + } + + @Override + public void onPauseBeforeSuper() { + mPaused = true; + Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (gsensor != null) { + mSensorManager.unregisterListener(this, gsensor); + } + + Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); + if (msensor != null) { + mSensorManager.unregisterListener(this, msensor); + } + + if (mSoundPool != null) { + mSoundPool.release(); + mSoundPool = null; + } + + if(selfieThread != null) { + selfieThread.interrupt(); + } + mUI.stopSelfieFlash(); + + Log.d(TAG, "remove idle handleer in onPause"); + removeIdleHandler(); + } + + @Override + public void onPauseAfterSuper() { + Log.v(TAG, "On pause."); + mUI.showPreviewCover(); + + try { + if (mOpenCameraThread != null) { + mOpenCameraThread.join(); + } + } catch (InterruptedException ex) { + // ignore + } + mOpenCameraThread = null; + // Reset the focus first. Camera CTS does not guarantee that + // cancelAutoFocus is allowed after preview stops. + if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) { + mCameraDevice.cancelAutoFocus(); + } + resetManual3ASettings(); + // If the camera has not been opened asynchronously yet, + // and startPreview hasn't been called, then this is a no-op. + // (e.g. onResume -> onPause -> onResume). + stopPreview(); + + mNamedImages = null; + + if (mLocationManager != null) mLocationManager.recordLocation(false); + + // If we are in an image capture intent and has taken + // a picture, we just clear it in onPause. + mJpegImageData = null; + + // Remove the messages and runnables in the queue. + mHandler.removeCallbacksAndMessages(null); + + closeCamera(); + + resetScreenOn(); + mUI.onPause(); + + mPendingSwitchCameraId = -1; + if (mFocusManager != null) mFocusManager.removeMessages(); + MediaSaveService s = mActivity.getMediaSaveService(); + if (s != null) { + s.setListener(null); + } + mUI.removeDisplayChangeListener(); + } + + /** + * The focus manager is the first UI related element to get initialized, + * and it requires the RenderOverlay, so initialize it here + */ + private void initializeFocusManager() { + // Create FocusManager object. startPreview needs it. + // if mFocusManager not null, reuse it + // otherwise create a new instance + if (mFocusManager != null) { + mFocusManager.removeMessages(); + } else { + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + mMirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT); + String[] defaultFocusModes = mActivity.getResources().getStringArray( + R.array.pref_camera_focusmode_default_array); + mFocusManager = new FocusOverlayManager(mPreferences, defaultFocusModes, + mInitialParams, this, mMirror, + mActivity.getMainLooper(), mUI); + } + } + + private void updateFocusManager(PhotoUI mUI) { + // Idea here is to let focus manager create in camera open thread + // (in initializeFocusManager) even if photoUI is null by that time so + // as to not block start preview process. Once UI creation is done, + // we will update focus manager with proper UI. + if (mFocusManager != null && mUI != null) { + mFocusManager.setPhotoUI(mUI); + + View root = mUI.getRootView(); + // These depend on camera parameters. + int width = root.getWidth(); + int height = root.getHeight(); + mFocusManager.setPreviewSize(width, height); + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + Log.v(TAG, "onConfigurationChanged"); + setDisplayOrientation(); + resizeForPreviewAspectRatio(); + } + + @Override + public void updateCameraOrientation() { + if (mDisplayRotation != CameraUtil.getDisplayRotation(mActivity)) { + setDisplayOrientation(); + } + } + + @Override + public void onActivityResult( + int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case REQUEST_CROP: { + Intent intent = new Intent(); + if (data != null) { + Bundle extras = data.getExtras(); + if (extras != null) { + intent.putExtras(extras); + } + } + mActivity.setResultEx(resultCode, intent); + mActivity.finish(); + + File path = mActivity.getFileStreamPath(sTempCropFilename); + path.delete(); + + break; + } + } + } + + protected CameraManager.CameraProxy getCamera() { + return mCameraDevice; + } + + private boolean canTakePicture() { + return isCameraIdle() && (mActivity.getStorageSpaceBytes() > Storage.LOW_STORAGE_THRESHOLD_BYTES); + } + + @Override + public void autoFocus() { + mFocusStartTime = System.currentTimeMillis(); + mCameraDevice.autoFocus(mHandler, mAutoFocusCallback); + setCameraState(FOCUSING); + } + + @Override + public void cancelAutoFocus() { + if (null != mCameraDevice ) { + mCameraDevice.cancelAutoFocus(); + setCameraState(IDLE); + setCameraParameters(UPDATE_PARAM_PREFERENCE); + } + } + + // Preview area is touched. Handle touch focus. + @Override + public void onSingleTapUp(View view, int x, int y) { + if (mPaused || mCameraDevice == null || !mFirstTimeInitialized + || mCameraState == SNAPSHOT_IN_PROGRESS + || mCameraState == SWITCHING_CAMERA + || 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; + if (! mFocusManager.getPreviewRect().contains(x, y)) return; + mFocusManager.onSingleTapUp(x, y); + } + + @Override + public boolean onBackPressed() { + return mUI.onBackPressed(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + if (CameraUtil.volumeKeyShutterDisable(mActivity)) { + return false; + } + case KeyEvent.KEYCODE_FOCUS: + if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized) { + if (event.getRepeatCount() == 0) { + onShutterButtonFocus(true); + } + return true; + } + return false; + case KeyEvent.KEYCODE_CAMERA: + if (mFirstTimeInitialized && event.getRepeatCount() == 0) { + onShutterButtonClick(); + } + return true; + case KeyEvent.KEYCODE_DPAD_LEFT: + if ( (mCameraState != PREVIEW_STOPPED) && (mFocusManager != null) && + (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); + Editor editor = mPreferences.edit(); + editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness); + editor.apply(); + brightnessProgressBar.setVisibility(View.INVISIBLE); + mBrightnessVisible = true; + } + break; + case KeyEvent.KEYCODE_DPAD_RIGHT: + if ( (mCameraState != PREVIEW_STOPPED) && (mFocusManager != null) && + (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); + Editor editor = mPreferences.edit(); + editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness); + editor.apply(); + brightnessProgressBar.setVisibility(View.INVISIBLE); + mBrightnessVisible = true; + } + 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. + if (mFirstTimeInitialized && event.getRepeatCount() == 0) { + // Start auto-focus immediately to reduce shutter lag. After + // the shutter button gets the focus, onShutterButtonFocus() + // will be called again but it is fine. + onShutterButtonFocus(true); + mUI.pressShutterButton(); + } + return true; + } + return false; + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + if (/*mActivity.isInCameraApp() && */ mFirstTimeInitialized + && !CameraUtil.volumeKeyShutterDisable(mActivity)) { + onShutterButtonClick(); + return true; + } + return false; + case KeyEvent.KEYCODE_FOCUS: + if (mFirstTimeInitialized) { + onShutterButtonFocus(false); + } + return true; + } + return false; + } + + private void closeCamera() { + Log.v(TAG, "Close camera device."); + if (mCameraDevice != null) { + mCameraDevice.setZoomChangeListener(null); + mCameraDevice.setFaceDetectionCallback(null, null); + mCameraDevice.setErrorCallback(null); + + if (mActivity.isSecureCamera()) { + // Blocks until camera is actually released. + CameraHolder.instance().strongRelease(); + } else { + CameraHolder.instance().release(); + } + + mFaceDetectionStarted = false; + mCameraDevice = null; + setCameraState(PREVIEW_STOPPED); + if (mFocusManager != null) { + mFocusManager.onCameraReleased(); + } + } + } + + private void setDisplayOrientation() { + mDisplayRotation = CameraUtil.getDisplayRotation(mActivity); + mDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, mCameraId); + mCameraDisplayOrientation = mDisplayOrientation; + // This will be called again in checkDisplayRotation(), so there + // should not be any problem even if mUI is null. + if (mUI != null) { + mUI.setDisplayOrientation(mDisplayOrientation); + } + if (mFocusManager != null) { + mFocusManager.setDisplayOrientation(mDisplayOrientation); + } + // Change the camera display orientation + if (mCameraDevice != null) { + mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation); + } + } + + /** Only called by UI thread. */ + private void setupPreview() { + mFocusManager.resetTouchFocus(); + startPreview(); + } + + /** This can run on a background thread, so don't do UI updates here. Post any + view updates to MainHandler or do it on onPreviewStarted() . */ + private void startPreview() { + if (mPaused || mCameraDevice == null || mParameters == null) { + return; + } + + synchronized (mCameraDevice) { + SurfaceHolder sh = null; + Log.v(TAG, "startPreview: SurfaceHolder (MDP path)"); + if (mUI != null) { + sh = mUI.getSurfaceHolder(); + } + + // Let UI set its expected aspect ratio + mCameraDevice.setPreviewDisplay(sh); + } + + if (!mCameraPreviewParamsReady) { + Log.w(TAG, "startPreview: parameters for preview are not ready."); + return; + } + mErrorCallback.setActivity(mActivity); + mCameraDevice.setErrorCallback(mErrorCallback); + // ICS camera frameworks has a bug. Face detection state is not cleared 1589 + // after taking a picture. Stop the preview to work around it. The bug + // was fixed in JB. + if (mCameraState != PREVIEW_STOPPED && mCameraState != INIT) { + stopPreview(); + } + + if (!mSnapshotOnIdle) { + mFocusManager.setAeAwbLock(false); // Unlock AE and AWB. + } + + setCameraParameters(UPDATE_PARAM_ALL); + mCameraDevice.setOneShotPreviewCallback(mHandler, + new CameraManager.CameraPreviewDataCallback() { + @Override + public void onPreviewFrame(byte[] data, CameraProxy camera) { + mUI.hidePreviewCover(); + } + }); + mCameraDevice.startPreview(); + + mHandler.sendEmptyMessage(ON_PREVIEW_STARTED); + + setDisplayOrientation(); + + if (!mSnapshotOnIdle) { + // If the focus mode is continuous autofocus, call cancelAutoFocus to + // resume it because it may have been paused by autoFocus call. + if (CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) { + mCameraDevice.cancelAutoFocus(); + } + } else { + mHandler.post(mDoSnapRunnable); + } + } + + @Override + public void stopPreview() { + if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) { + Log.v(TAG, "stopPreview"); + mCameraDevice.stopPreview(); + } + setCameraState(PREVIEW_STOPPED); + if (mFocusManager != null) mFocusManager.onPreviewStopped(); + stopFaceDetection(); + } + + @SuppressWarnings("deprecation") + private void updateCameraParametersInitialize() { + // Reset preview frame rate to the maximum because it may be lowered by + // video camera application. + int[] fpsRange = CameraUtil.getPhotoPreviewFpsRange(mParameters); + if (fpsRange != null && fpsRange.length > 0) { + mParameters.setPreviewFpsRange( + fpsRange[Parameters.PREVIEW_FPS_MIN_INDEX], + fpsRange[Parameters.PREVIEW_FPS_MAX_INDEX]); + } + + mParameters.set(CameraUtil.RECORDING_HINT, CameraUtil.FALSE); + + // Disable video stabilization. Convenience methods not available in API + // level <= 14 + String vstabSupported = mParameters.get("video-stabilization-supported"); + if ("true".equals(vstabSupported)) { + mParameters.set("video-stabilization", "false"); + } + } + + 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 reFocus, + String optiZoom, + String fssr, + String truePortrait, + String multiTouchFocus, + String stillMore) { + 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); + } + if (CameraUtil.isSupported(reFocus, + CameraSettings.getSupportedRefocusModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_RE_FOCUS, reFocus); + } + if (CameraUtil.isSupported(fssr, + CameraSettings.getSupportedFSSRModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_FSSR, fssr); + } + if (CameraUtil.isSupported(truePortrait, + CameraSettings.getSupportedTruePortraitModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_TP, truePortrait); + } + if(CameraUtil.isSupported(multiTouchFocus, + CameraSettings.getSupportedMultiTouchFocusModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_MULTI_TOUCH_FOCUS, multiTouchFocus); + } + if (CameraUtil.isSupported(stillMore, + CameraSettings.getSupportedStillMoreModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_STILL_MORE, stillMore); + } + } + + /** This can run on a background thread, so don't do UI updates here.*/ + 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); + String optizoomOn = mActivity.getString(R.string + .pref_camera_advanced_feature_value_optizoom_on); + + if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode) || + CameraUtil.SCENE_MODE_HDR.equals(mSceneMode) || + optizoomOn.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)); + int jpegFileSize = estimateJpegFileSize(pic_size, jpegQuality); + if (jpegFileSize != mJpegFileSizeEstimation) { + mJpegFileSizeEstimation = jpegFileSize; + mHandler.post(new Runnable() { + @Override + public void run() { + updateRemainingPhotos(); + } + }); + } + } + } + + // Set Selectable Zone Af parameter. + String selectableZoneAf = mPreferences.getString( + CameraSettings.KEY_SELECTABLE_ZONE_AF, + mActivity.getString(R.string.pref_camera_selectablezoneaf_default)); + List 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 + if ((mManual3AEnabled & MANUAL_EXPOSURE) == 0) { + 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 CDS + String cds = mPreferences.getString( + CameraSettings.KEY_CDS_MODE, + mActivity.getString(R.string.pref_camera_cds_default)); + if ((mPrevSavedCDS == null) && (cds != null)) { + mPrevSavedCDS = cds; + } + if (CameraUtil.isSupported(cds, + CameraSettings.getSupportedCDSModes(mParameters))) { + mParameters.set(CameraSettings.KEY_QC_CDS_MODE, cds); + } + + // Set TNR + String tnr = mPreferences.getString( + CameraSettings.KEY_TNR_MODE, + mActivity.getString(R.string.pref_camera_tnr_default)); + if (CameraUtil.isSupported(tnr, + CameraSettings.getSupportedTNRModes(mParameters))) { + if (!tnr.equals(mActivity.getString(R.string. + pref_camera_tnr_value_off))) { + mParameters.set(CameraSettings.KEY_QC_CDS_MODE, + mActivity.getString(R.string.pref_camera_cds_value_off)); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.overrideSettings(CameraSettings.KEY_QC_CDS_MODE, + mActivity.getString(R.string.pref_camera_cds_value_off)); + } + }); + if (cds != null) { + mPrevSavedCDS = cds; + } + isTNREnabled = true; + } else if (isTNREnabled) { + mParameters.set(CameraSettings.KEY_QC_CDS_MODE, mPrevSavedCDS); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.overrideSettings(CameraSettings.KEY_QC_CDS_MODE, + mPrevSavedCDS); + } + }); + isTNREnabled = false; + } + mParameters.set(CameraSettings.KEY_QC_TNR_MODE, tnr); + } + + // Set hdr mode + String hdrMode = mPreferences.getString( + CameraSettings.KEY_HDR_MODE, + mActivity.getString(R.string.pref_camera_hdr_mode_default)); + Log.v(TAG, "HDR Mode value =" + hdrMode); + if (CameraUtil.isSupported(hdrMode, + CameraSettings.getSupportedHDRModes(mParameters))) { + mParameters.set(CameraSettings.KEY_SNAPCAM_HDR_MODE, hdrMode); + } + + // Set hdr need 1x + String hdrNeed1x = mPreferences.getString( + CameraSettings.KEY_HDR_NEED_1X, + mActivity.getString(R.string.pref_camera_hdr_need_1x_default)); + Log.v(TAG, "HDR need 1x value =" + hdrNeed1x); + if (CameraUtil.isSupported(hdrNeed1x, + CameraSettings.getSupportedHDRNeed1x(mParameters))) { + mParameters.set(CameraSettings.KEY_SNAPCAM_HDR_NEED_1X, hdrNeed1x); + } + + // Set Advanced features. + String advancedFeature = mPreferences.getString( + CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + Log.e(TAG, " advancedFeature value =" + advancedFeature); + + mRefocus = false; + 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); + String reFocusOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_off); + String fssrOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_off); + String truePortraitOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_off); + String multiTouchFocusOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_off); + String stillMoreOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_stillmore_off); + + if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_ubifocus_on))) { + qcomUpdateAdvancedFeatures(advancedFeature, + chromaFlashOff, + reFocusOff, + optiZoomOff, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_chromaflash_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + advancedFeature, + reFocusOff, + optiZoomOff, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + advancedFeature, + optiZoomOff, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + mRefocus = true; + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_optizoom_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + advancedFeature, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + optiZoomOff, + advancedFeature, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + optiZoomOff, + fssrOff, + advancedFeature, + multiTouchFocusOff, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + optiZoomOff, + fssrOff, + truePortraitOff, + advancedFeature, + stillMoreOff); + } else if (advancedFeature.equals(mActivity.getString(R.string. + pref_camera_advanced_feature_value_stillmore_on))) { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + optiZoomOff, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + advancedFeature); + } else { + qcomUpdateAdvancedFeatures(ubiFocusOff, + chromaFlashOff, + reFocusOff, + optiZoomOff, + fssrOff, + truePortraitOff, + multiTouchFocusOff, + stillMoreOff); + } + } + + if (mActivity.getString(R.string.pref_camera_advanced_feature_value_trueportrait_on) + .equals(advancedFeature)) { + // face detection must always be on for truePortrait + if (CameraUtil.isSupported(Parameters.FACE_DETECTION_ON, mParameters.getSupportedFaceDetectionModes())) { + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.overrideSettings(CameraSettings.KEY_FACE_DETECTION, Parameters.FACE_DETECTION_ON); + } + }); + + mParameters.setFaceDetectionMode(Parameters.FACE_DETECTION_ON); + if(mFaceDetectionEnabled == false) { + mFaceDetectionEnabled = true; + startFaceDetection(); + } + } + } else { + // Set face detetction parameter. + // clear override to re-enable setting if true portrait is off. + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.overrideSettings(CameraSettings.KEY_FACE_DETECTION, null); + } + }); + + 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; + } + } + } + + // 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)); + String auto_hdr = mPreferences.getString(CameraSettings.KEY_AUTO_HDR, + mActivity.getString(R.string.pref_camera_hdr_default)); + if (CameraUtil.isAutoHDRSupported(mParameters)) { + mParameters.set("auto-hdr-enable",auto_hdr); + if (auto_hdr.equals("enable")) { + mActivity.runOnUiThread(new Runnable() { + public void run() { + if (mDrawAutoHDR != null) { + mDrawAutoHDR.setVisibility(View.VISIBLE); + } + } + }); + mParameters.setSceneMode("asd"); + mCameraDevice.setMetadataCb(mMetaDataCallback); + } + else { + mAutoHdrEnable = false; + mActivity.runOnUiThread( new Runnable() { + public void run () { + if (mDrawAutoHDR != null) { + mDrawAutoHDR.setVisibility (View.INVISIBLE); + } + } + }); + } + } + 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); + + //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() { + RotateTextToast.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); + if ((mManual3AEnabled & MANUAL_FOCUS) == 0) { + mFocusManager.overrideFocusMode(null); + mParameters.setFocusMode(mFocusManager.getFocusMode()); + } + } + + //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); + } + } + + setFlipValue(); + + /* 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; + mParameters.setFlashMode(fMode); + } + + if(!mFocusManager.getFocusMode().equals(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) && + !mFocusManager.isFocusCompleted()) { + mUI.clearFocus(); + } + } + + private int estimateJpegFileSize(final Size size, final String quality) { + int[] ratios = mActivity.getResources().getIntArray(R.array.jpegquality_compression_ratio); + String[] qualities = mActivity.getResources().getStringArray( + R.array.pref_camera_jpegquality_entryvalues); + int ratio = 0; + for (int i = ratios.length - 1; i >= 0; --i) { + if (qualities[i].equals(quality)) { + ratio = ratios[i]; + break; + } + } + + if (ratio == 0) { + return 0; + } else { + return size.width * size.height * 3 / ratio; + } + } + + private void setFlipValue() { + // 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); + } + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private void setAutoExposureLockIfSupported() { + if (mAeLockSupported) { + mParameters.setAutoExposureLock(mFocusManager.getAeAwbLock()); + } + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private void setAutoWhiteBalanceLockIfSupported() { + if (mAwbLockSupported) { + mParameters.setAutoWhiteBalanceLock(mFocusManager.getAeAwbLock()); + } + } + + private void setFocusAreasIfSupported() { + if (mFocusAreaSupported) { + mParameters.setFocusAreas(mFocusManager.getFocusAreas()); + } + } + + private void setMeteringAreasIfSupported() { + if (mMeteringAreaSupported) { + mParameters.setMeteringAreas(mFocusManager.getMeteringAreas()); + } + } + + /** This can run on a background thread, so don't do UI updates here.*/ + private boolean updateCameraParametersPreference() { + setAutoExposureLockIfSupported(); + setAutoWhiteBalanceLockIfSupported(); + setFocusAreasIfSupported(); + setMeteringAreasIfSupported(); + + // initialize focus mode + if ((mManual3AEnabled & MANUAL_FOCUS) == 0) { + mFocusManager.overrideFocusMode(null); + mParameters.setFocusMode(mFocusManager.getFocusMode()); + } + + // Set picture size. + String pictureSize = mPreferences.getString( + CameraSettings.KEY_PICTURE_SIZE, null); + 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 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(); + + // Set a preview size that is closest to the viewfinder height and has + // the right aspect ratio. + List sizes = mParameters.getSupportedPreviewSizes(); + Size optimalSize = CameraUtil.getOptimalPreviewSize(mActivity, sizes, + (double) size.width / size.height); + + //Read Preview Resolution from adb command + //value: 0(default) - Default value as per snapshot aspect ratio + //value: 1 - 640x480 + //value: 2 - 720x480 + //value: 3 - 1280x720 + //value: 4 - 1920x1080 + int preview_resolution = SystemProperties.getInt("persist.camera.preview.size", 0); + switch (preview_resolution) { + case 1: { + optimalSize.width = 640; + optimalSize.height = 480; + Log.v(TAG, "Preview resolution hardcoded to 640x480"); + break; + } + case 2: { + optimalSize.width = 720; + optimalSize.height = 480; + Log.v(TAG, "Preview resolution hardcoded to 720x480"); + break; + } + case 3: { + optimalSize.width = 1280; + optimalSize.height = 720; + Log.v(TAG, "Preview resolution hardcoded to 1280x720"); + break; + } + case 4: { + optimalSize.width = 1920; + optimalSize.height = 1080; + Log.v(TAG, "Preview resolution hardcoded to 1920x1080"); + break; + } + default: { + Log.v(TAG, "Preview resolution as per Snapshot aspect ratio"); + break; + } + } + + Size original = mParameters.getPreviewSize(); + if (!original.equals(optimalSize)) { + mParameters.setPreviewSize(optimalSize.width, optimalSize.height); + + // Zoom related settings will be changed for different preview + // sizes, so set and read the parameters to get latest values + if (mHandler.getLooper() == Looper.myLooper()) { + // On UI thread only, not when camera starts up + setupPreview(); + } else { + mCameraDevice.setParameters(mParameters); + } + mParameters = mCameraDevice.getParameters(); + Log.v(TAG, "Preview Size changed. Restart Preview"); + mRestartPreview = true; + } + + Log.v(TAG, "Preview size is " + optimalSize.width + "x" + optimalSize.height); + size = mParameters.getPictureSize(); + + // Set jpegthumbnail size + // Set a jpegthumbnail size that is closest to the Picture height and has + // the right aspect ratio. + List supported = mParameters.getSupportedJpegThumbnailSizes(); + optimalSize = CameraUtil.getOptimalJpegThumbnailSize(supported, + (double) size.width / size.height); + original = mParameters.getJpegThumbnailSize(); + if (!original.equals(optimalSize)) { + mParameters.setJpegThumbnailSize(optimalSize.width, optimalSize.height); + } + + Log.v(TAG, "Thumbnail size is " + optimalSize.width + "x" + optimalSize.height); + + // Since changing scene mode may change supported values, set scene mode + // first. HDR is a scene mode. To promote it in UI, it is stored in a + // separate preference. + String onValue = mActivity.getString(R.string.setting_on_value); + String hdr = mPreferences.getString(CameraSettings.KEY_CAMERA_HDR, + mActivity.getString(R.string.pref_camera_hdr_default)); + String hdrPlus = mPreferences.getString(CameraSettings.KEY_CAMERA_HDR_PLUS, + mActivity.getString(R.string.pref_camera_hdr_plus_default)); + boolean hdrOn = onValue.equals(hdr); + boolean hdrPlusOn = onValue.equals(hdrPlus); + + boolean doGcamModeSwitch = false; + if (hdrPlusOn && GcamHelper.hasGcamCapture()) { + // Kick off mode switch to gcam. + doGcamModeSwitch = true; + } else { + if (hdrOn) { + mSceneMode = CameraUtil.SCENE_MODE_HDR; + if (!(Parameters.SCENE_MODE_AUTO).equals(mParameters.getSceneMode()) + && !(Parameters.SCENE_MODE_HDR).equals(mParameters.getSceneMode())) { + mParameters.setSceneMode(Parameters.SCENE_MODE_AUTO); + mCameraDevice.setParameters(mParameters); + mParameters = mCameraDevice.getParameters(); + } + } else { + mSceneMode = mPreferences.getString( + CameraSettings.KEY_SCENE_MODE, + mActivity.getString(R.string.pref_camera_scenemode_default)); + } + } + + String refocusOn = mActivity.getString(R.string + .pref_camera_advanced_feature_value_refocus_on); + String optizoomOn = mActivity.getString(R.string + .pref_camera_advanced_feature_value_optizoom_on); + if (refocusOn.equals(mSceneMode)) { + try { + mSceneMode = Parameters.SCENE_MODE_AUTO; + mUI.setPreference(CameraSettings.KEY_ADVANCED_FEATURES, refocusOn); + mUI.showRefocusDialog(); + } catch (NullPointerException e) { + } + } else if (optizoomOn.equals(mSceneMode)) { + try { + mSceneMode = Parameters.SCENE_MODE_AUTO; + mUI.setPreference(CameraSettings.KEY_ADVANCED_FEATURES, optizoomOn); + } catch (NullPointerException e) { + } + } else if (mSceneMode == null) { + mSceneMode = Parameters.SCENE_MODE_AUTO; + } + + if (CameraUtil.isSupported(mSceneMode, mParameters.getSupportedSceneModes())) { + if (!mParameters.getSceneMode().equals(mSceneMode)) { + mParameters.setSceneMode(mSceneMode); + + // Setting scene mode will change the settings of flash mode, + // white balance, and focus mode. Here we read back the + // parameters, so we can know those settings. + mCameraDevice.setParameters(mParameters); + mParameters = mCameraDevice.getParameters(); + } + } + + // Set JPEG quality. + int jpegQuality; + if(mCameraId>1) { + jpegQuality=95; //Temproray Solution for camera ids greater than 1. Proper fix TBD. + } else { + jpegQuality = CameraProfile.getJpegEncodingQualityParameter(mCameraId, + CameraProfile.QUALITY_HIGH); + } + + mParameters.setJpegQuality(jpegQuality); + + // For the following settings, we need to check if the settings are + // still supported by latest driver, if not, ignore the settings. + + // Set exposure compensation + int value = CameraSettings.readExposure(mPreferences); + int max = mParameters.getMaxExposureCompensation(); + int min = mParameters.getMinExposureCompensation(); + if (value >= min && value <= max) { + mParameters.setExposureCompensation(value); + } else { + Log.w(TAG, "invalid exposure range: " + value); + } + + if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) { + // Set flash mode. + String flashMode; + if (mSavedFlashMode == null) { + flashMode = mPreferences.getString( + CameraSettings.KEY_FLASH_MODE, + mActivity.getString(R.string.pref_camera_flashmode_default)); + } else { + flashMode = mSavedFlashMode; + } + + List supportedFlash = mParameters.getSupportedFlashModes(); + if (CameraUtil.isSupported(flashMode, supportedFlash)) { + mParameters.setFlashMode(flashMode); + } else { + flashMode = mParameters.getFlashMode(); + if (flashMode == null) { + flashMode = mActivity.getString( + R.string.pref_camera_flashmode_no_flash); + } + } + + // Set white balance parameter. + if ((mManual3AEnabled & MANUAL_WB) == 0) { + String whiteBalance = mPreferences.getString( + CameraSettings.KEY_WHITE_BALANCE, + mActivity.getString(R.string.pref_camera_whitebalance_default)); + if (CameraUtil.isSupported(whiteBalance, + mParameters.getSupportedWhiteBalance())) { + mParameters.setWhiteBalance(whiteBalance); + } else { + whiteBalance = mParameters.getWhiteBalance(); + if (whiteBalance == null) { + whiteBalance = Parameters.WHITE_BALANCE_AUTO; + } + } + } + + // Set focus mode. + if ((mManual3AEnabled & MANUAL_FOCUS) == 0) { + mFocusManager.overrideFocusMode(null); + mParameters.setFocusMode(mFocusManager.getFocusMode()); + } + } else { + mFocusManager.overrideFocusMode(mParameters.getFocusMode()); + if (CameraUtil.isSupported(Parameters.FLASH_MODE_OFF, + mParameters.getSupportedFlashModes())) { + mParameters.setFlashMode(Parameters.FLASH_MODE_OFF); + } + if (CameraUtil.isSupported(Parameters.WHITE_BALANCE_AUTO, + mParameters.getSupportedWhiteBalance())) { + mParameters.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO); + } + } + + if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) { + updateAutoFocusMoveCallback(); + } + + String makeupParamValue = mPreferences.getString(CameraSettings.KEY_TS_MAKEUP_UILABLE, + mActivity.getString(R.string.pref_camera_tsmakeup_default)); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM, makeupParamValue); + Log.v(TAG,"updateCameraParametersPreference(): TSMakeup " + CameraSettings.KEY_TS_MAKEUP_PARAM +" value = " + makeupParamValue); + + if(TsMakeupManager.MAKEUP_ON.equals(makeupParamValue)) { + String makeupWhitenValue = mPreferences.getString(CameraSettings.KEY_TS_MAKEUP_LEVEL_WHITEN, + mActivity.getString(R.string.pref_camera_tsmakeup_level_default)); + String makeupCleanValue = mPreferences.getString(CameraSettings.KEY_TS_MAKEUP_LEVEL_CLEAN, + mActivity.getString(R.string.pref_camera_tsmakeup_level_default)); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_WHITEN, makeupWhitenValue); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_CLEAN, makeupCleanValue); + } + + //QCom related parameters updated here. + qcomUpdateCameraParametersPreference(); + return doGcamModeSwitch; + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private void updateAutoFocusMoveCallback() { + if (mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE)) { + mCameraDevice.setAutoFocusMoveCallback(mHandler, + (CameraAFMoveCallback) mAutoFocusMoveCallback); + } else { + mCameraDevice.setAutoFocusMoveCallback(null, null); + } + } + + // We separate the parameters into several subsets, so we can update only + // 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) { + if (mCameraDevice == null) { + return; + } + synchronized (mCameraDevice) { + boolean doModeSwitch = false; + + if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) { + updateCameraParametersInitialize(); + } + + if ((updateSet & UPDATE_PARAM_ZOOM) != 0) { + updateCameraParametersZoom(); + } + + if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) { + doModeSwitch = updateCameraParametersPreference(); + } + + mCameraDevice.setParameters(mParameters); + + // Switch to gcam module if HDR+ was selected + if (doModeSwitch && !mIsImageCaptureIntent) { + mHandler.sendEmptyMessage(SWITCH_TO_GCAM_MODULE); + } + } + } + + // If the Camera is idle, update the parameters immediately, otherwise + // accumulate them in mUpdateSet and update later. + private void setCameraParametersWhenIdle(int additionalUpdateSet) { + mUpdateSet |= additionalUpdateSet; + if (mCameraDevice == null) { + // We will update all the parameters when we open the device, so + // we don't need to do anything now. + mUpdateSet = 0; + return; + } else if (isCameraIdle()) { + setCameraParameters(mUpdateSet); + 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)) { + mHandler.sendEmptyMessageDelayed( + SET_CAMERA_PARAMETERS_WHEN_IDLE, 1000); + } + } + } + + @Override + public boolean isCameraIdle() { + return (mCameraState == IDLE) || + (mCameraState == PREVIEW_STOPPED) || + ((mFocusManager != null) && mFocusManager.isFocusCompleted() + && (mCameraState != SWITCHING_CAMERA)); + } + + @Override + public boolean isImageCaptureIntent() { + String action = mActivity.getIntent().getAction(); + return (MediaStore.ACTION_IMAGE_CAPTURE.equals(action) + || CameraActivity.ACTION_IMAGE_CAPTURE_SECURE.equals(action)); + } + + private void setupCaptureParams() { + Bundle myExtras = mActivity.getIntent().getExtras(); + if (myExtras != null) { + mSaveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); + mCropValue = myExtras.getString("crop"); + } + } + + private void UpdateManualFocusSettings() { + //dismiss all popups first, because we need to show edit dialog + mUI.collapseCameraControls(); + final AlertDialog.Builder alert = new AlertDialog.Builder(mActivity); + LinearLayout linear = new LinearLayout(mActivity); + linear.setOrientation(1); + alert.setTitle("Manual Focus Settings"); + alert.setNegativeButton("Cancel",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + dialog.cancel(); + } + }); + final TextView focusPositionText = new TextView(mActivity); + String scaleMode = mActivity.getString( + R.string.pref_camera_manual_focus_value_scale_mode); + String diopterMode = mActivity.getString( + R.string.pref_camera_manual_focus_value_diopter_mode); + String manualFocusMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_FOCUS, + mActivity.getString(R.string.pref_camera_manual_focus_default)); + + Log.v(TAG, "manualFocusMode selected = " + manualFocusMode); + if (manualFocusMode.equals(scaleMode)) { + final SeekBar focusbar = new SeekBar(mActivity); + final int minFocusPos = mParameters.getInt(CameraSettings.KEY_MIN_FOCUS_SCALE); + final int maxFocusPos = mParameters.getInt(CameraSettings.KEY_MAX_FOCUS_SCALE); + //update mparameters to fetch latest focus position + mParameters = mCameraDevice.getParameters(); + final int CurFocusPos = mParameters.getInt(CameraSettings.KEY_MANUAL_FOCUS_SCALE); + focusbar.setProgress(CurFocusPos); + focusPositionText.setText("Current focus position is " + CurFocusPos); + + alert.setMessage("Enter focus position in the range of " + minFocusPos + + " to " + maxFocusPos); + + focusbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) { + focusPositionText.setText("Current focus position is " + progress); + } + }); + linear.addView(focusbar); + linear.addView(focusPositionText); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + int focusPos = focusbar.getProgress(); + Log.v(TAG, "Setting focus position : " + focusPos); + mManual3AEnabled |= MANUAL_FOCUS; + mParameters.setFocusMode(Parameters.FOCUS_MODE_MANUAL_POSITION); + mParameters.set(CameraSettings.KEY_MANUAL_FOCUS_TYPE, 2); // 2 for scale mode + mParameters.set(CameraSettings.KEY_MANUAL_FOCUS_POSITION, focusPos); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } + }); + alert.show(); + } else if (manualFocusMode.equals(diopterMode)) { + String minFocusStr = mParameters.get(CameraSettings.KEY_MIN_FOCUS_DIOPTER); + String maxFocusStr = mParameters.get(CameraSettings.KEY_MAX_FOCUS_DIOPTER); + final double minFocusPos = Double.parseDouble(minFocusStr); + final double maxFocusPos = Double.parseDouble(maxFocusStr); + final EditText input = new EditText(mActivity); + int floatType = InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_CLASS_NUMBER; + input.setInputType(floatType); + alert.setMessage("Enter focus position in the range of " + minFocusPos + + " to " + maxFocusPos); + //update mparameters to fetch latest focus position + mParameters = mCameraDevice.getParameters(); + final String CurFocusPos = mParameters.get(CameraSettings.KEY_MANUAL_FOCUS_DIOPTER); + focusPositionText.setText("Current focus position is " + CurFocusPos); + linear.addView(input); + linear.addView(focusPositionText); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + double focuspos = 0; + String focusStr = input.getText().toString(); + if (focusStr.length() > 0) { + try { + focuspos = Double.parseDouble(focusStr); + } catch (NumberFormatException e) { + Log.w(TAG, "Input foucspos " + focuspos + " is invalid"); + focuspos = maxFocusPos + 1f; + } + + } else { + RotateTextToast.makeText(mActivity, "Invalid focus position", + Toast.LENGTH_SHORT).show(); + return; + } + if (focuspos >= minFocusPos && focuspos <= maxFocusPos) { + Log.v(TAG, "Setting focus position : " + focusStr); + mManual3AEnabled |= MANUAL_FOCUS; + mParameters.setFocusMode(Parameters.FOCUS_MODE_MANUAL_POSITION); + //focus type 3 is diopter mode + mParameters.set(CameraSettings.KEY_MANUAL_FOCUS_TYPE, 3); + mParameters.set(CameraSettings.KEY_MANUAL_FOCUS_POSITION, focusStr); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid focus position", + Toast.LENGTH_SHORT).show(); + } + } + }); + alert.show(); + } else { + mManual3AEnabled &= ~MANUAL_FOCUS; + mParameters.setFocusMode(mFocusManager.getFocusMode()); + mUI.overrideSettings(CameraSettings.KEY_FOCUS_MODE, null); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } + } + + private void UpdateManualWBSettings() { + //dismiss all popups first, because we need to show edit dialog + mUI.collapseCameraControls(); + final AlertDialog.Builder alert = new AlertDialog.Builder(mActivity); + LinearLayout linear = new LinearLayout(mActivity); + linear.setOrientation(1); + alert.setTitle("Manual White Balance Settings"); + alert.setNegativeButton("Cancel",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + dialog.cancel(); + } + }); + + String cctMode = mActivity.getString( + R.string.pref_camera_manual_wb_value_color_temperature); + String rgbGainMode = mActivity.getString( + R.string.pref_camera_manual_wb_value_rbgb_gains); + String manualWBMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_WB, + mActivity.getString(R.string.pref_camera_manual_wb_default)); + final String wbPref = mPreferences.getString( + CameraSettings.KEY_WHITE_BALANCE, + mActivity.getString(R.string.pref_camera_whitebalance_default)); + Log.v(TAG, "manualWBMode selected = " + manualWBMode); + if (manualWBMode.equals(cctMode)) { + final TextView CCTtext = new TextView(mActivity); + final EditText CCTinput = new EditText(mActivity); + CCTinput.setInputType(InputType.TYPE_CLASS_NUMBER); + final int minCCT = mParameters.getInt(CameraSettings.KEY_MIN_WB_CCT); + final int maxCCT = mParameters.getInt(CameraSettings.KEY_MAX_WB_CCT); + + //refresh camera parameters to get latest CCT value + mParameters = mCameraDevice.getParameters(); + String currentCCT = mParameters.get(CameraSettings.KEY_MANUAL_WB_CCT); + if (currentCCT != null) { + CCTtext.setText("Current CCT is " + currentCCT); + } + alert.setMessage("Enter CCT value in the range of " + minCCT+ " to " + maxCCT); + linear.addView(CCTinput); + linear.addView(CCTtext); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + int newCCT = -1; + String cct = CCTinput.getText().toString(); + if (cct.length() > 0) { + newCCT = Integer.parseInt(cct); + } + if (newCCT <= maxCCT && newCCT >= minCCT) { + mManual3AEnabled |= MANUAL_WB; + Log.v(TAG, "Setting CCT value : " + newCCT); + mParameters.setWhiteBalance(CameraSettings.KEY_MANUAL_WHITE_BALANCE); + //0 corresponds to manual CCT mode + mParameters.set(CameraSettings.KEY_MANUAL_WB_TYPE, 0); + mParameters.set(CameraSettings.KEY_MANUAL_WB_VALUE, newCCT); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid CCT", Toast.LENGTH_SHORT) + .show(); + } + } + }); + alert.show(); + } else if (manualWBMode.equals(rgbGainMode)) { + final TextView RGBtext = new TextView(mActivity); + final EditText Rinput = new EditText(mActivity); + Rinput.setHint("Enter R gain here"); + final EditText Ginput = new EditText(mActivity); + Ginput.setHint("Enter G gain here"); + final EditText Binput = new EditText(mActivity); + Binput.setHint("Enter B gain here"); + + int floatType = InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_CLASS_NUMBER; + Rinput.setInputType(floatType); + Ginput.setInputType(floatType); + Binput.setInputType(floatType); + + String minGainStr = mParameters.get(CameraSettings.KEY_MIN_WB_GAIN); + final double minGain = Double.parseDouble(minGainStr); + String maxGainStr = mParameters.get(CameraSettings.KEY_MAX_WB_GAIN); + final double maxGain = Double.parseDouble(maxGainStr); + + //refresh camera parameters to get latest WB gains + mParameters = mCameraDevice.getParameters(); + String currentGains = mParameters.get(CameraSettings.KEY_MANUAL_WB_GAINS); + if (currentGains != null) { + RGBtext.setText("Current RGB gains are " + currentGains); + } + + alert.setMessage("Enter RGB gains in the range of " + minGain + + " to " + maxGain); + linear.addView(Rinput); + linear.addView(Ginput); + linear.addView(Binput); + linear.addView(RGBtext); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + String Rgain = Rinput.getText().toString(); + String Ggain = Ginput.getText().toString(); + String Bgain = Binput.getText().toString(); + double Rgainf = -1; + double Ggainf = -1; + double Bgainf = -1; + if (Rgain.length() > 0 && Ggain.length() > 0 && Bgain.length() > 0) { + try { + Rgainf = Double.parseDouble(Rgain); + Ggainf = Double.parseDouble(Ggain); + Bgainf = Double.parseDouble(Bgain); + } catch (NumberFormatException e) { + Log.w(TAG, "Input RGB gain is invalid"); + Rgainf = maxGain + 1f; + Ggainf = maxGain + 1f; + Bgainf = maxGain + 1f; + } + String RGBGain = Rgain + "," + Ggain + "," + Bgain; + if (Rgainf <= maxGain && Rgainf >= minGain && + Ggainf <= maxGain && Ggainf >= minGain && + Bgainf <= maxGain && Bgainf >= minGain) { + Log.v(TAG, "Setting RGB gains : " + RGBGain); + mManual3AEnabled |= MANUAL_WB; + mParameters.setWhiteBalance(CameraSettings.KEY_MANUAL_WHITE_BALANCE); + // 1 corresponds to manual WB gain mode + mParameters.set(CameraSettings.KEY_MANUAL_WB_TYPE, 1); + mParameters.set(CameraSettings.KEY_MANUAL_WB_VALUE, RGBGain); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid RGB gains", + Toast.LENGTH_SHORT).show(); + } + } else { + RotateTextToast.makeText(mActivity, "Invalid RGB gains", + Toast.LENGTH_SHORT).show(); + } + } + }); + alert.show(); + } else { + //reset white balance + mManual3AEnabled &= ~MANUAL_WB; + mUI.overrideSettings(CameraSettings.KEY_WHITE_BALANCE, null); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } + } + + private void UpdateManualExposureSettings() { + //dismiss all popups first, because we need to show edit dialog + mUI.collapseCameraControls(); + final AlertDialog.Builder alert = new AlertDialog.Builder(mActivity); + LinearLayout linear = new LinearLayout(mActivity); + linear.setOrientation(1); + final TextView ISOtext = new TextView(mActivity); + final EditText ISOinput = new EditText(mActivity); + final TextView ExpTimeText = new TextView(mActivity); + final EditText ExpTimeInput = new EditText(mActivity); + ISOinput.setInputType(InputType.TYPE_CLASS_NUMBER); + int floatType = InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_CLASS_NUMBER; + ExpTimeInput.setInputType(floatType); + alert.setTitle("Manual Exposure Settings"); + alert.setNegativeButton("Cancel",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + dialog.cancel(); + } + }); + + mParameters = mCameraDevice.getParameters(); + final int minISO = mParameters.getInt(CameraSettings.KEY_MIN_ISO); + final int maxISO = mParameters.getInt(CameraSettings.KEY_MAX_ISO); + String isoMode = mParameters.getISOValue(); + final String isoManual = CameraSettings.KEY_MANUAL_ISO; + String currentISO = mParameters.get(CameraSettings.KEY_CURRENT_ISO); + if (currentISO != null) { + ISOtext.setText("Current ISO is " + currentISO); + } + + final String minExpTime = mParameters.get(CameraSettings.KEY_MIN_EXPOSURE_TIME); + final String maxExpTime = mParameters.get(CameraSettings.KEY_MAX_EXPOSURE_TIME); + String currentExpTime = mParameters.get(CameraSettings.KEY_CURRENT_EXPOSURE_TIME); + if (currentExpTime != null) { + ExpTimeText.setText("Current exposure time is " + currentExpTime); + } + + String isoPriority = mActivity.getString( + R.string.pref_camera_manual_exp_value_ISO_priority); + String expTimePriority = mActivity.getString( + R.string.pref_camera_manual_exp_value_exptime_priority); + String userSetting = mActivity.getString( + R.string.pref_camera_manual_exp_value_user_setting); + String manualExposureMode = mPreferences.getString( + CameraSettings.KEY_MANUAL_EXPOSURE, + mActivity.getString(R.string.pref_camera_manual_exp_default)); + Log.v(TAG, "manual Exposure Mode selected = " + manualExposureMode); + if (manualExposureMode.equals(isoPriority)) { + alert.setMessage("Enter ISO in the range of " + minISO + " to " + maxISO); + linear.addView(ISOinput); + linear.addView(ISOtext); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + int newISO = -1; + String iso = ISOinput.getText().toString(); + Log.v(TAG, "string iso length " + iso.length()); + if (iso.length() > 0) { + newISO = Integer.parseInt(iso); + } + if (newISO <= maxISO && newISO >= minISO) { + Log.v(TAG, "Setting ISO : " + newISO); + mManual3AEnabled |= MANUAL_EXPOSURE; + mParameters.setISOValue(isoManual); + mParameters.set(CameraSettings.KEY_CONTINUOUS_ISO, newISO); + mParameters.set(CameraSettings.KEY_EXPOSURE_TIME, "0"); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid ISO", Toast.LENGTH_SHORT).show(); + } + } + }); + alert.show(); + } else if (manualExposureMode.equals(expTimePriority)) { + alert.setMessage("Enter exposure time in the range of " + minExpTime + + "ms to " + maxExpTime + "ms"); + linear.addView(ExpTimeInput); + linear.addView(ExpTimeText); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + double newExpTime = -1; + String expTime = ExpTimeInput.getText().toString(); + if (expTime.length() > 0) { + try { + newExpTime = Double.parseDouble(expTime); + } catch (NumberFormatException e) { + Log.w(TAG, "Input expTime " + expTime + " is invalid"); + newExpTime = Double.parseDouble(maxExpTime) + 1f; + } + } + if (newExpTime <= Double.parseDouble(maxExpTime) && + newExpTime >= Double.parseDouble(minExpTime)) { + Log.v(TAG, "Setting Exposure time : " + newExpTime); + mManual3AEnabled |= MANUAL_EXPOSURE; + mParameters.set(CameraSettings.KEY_EXPOSURE_TIME, expTime); + mParameters.setISOValue(Parameters.ISO_AUTO); + mUI.setPreference(CameraSettings.KEY_ISO, Parameters.ISO_AUTO); + mUI.overrideSettings(CameraSettings.KEY_ISO, null); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid exposure time", + Toast.LENGTH_SHORT).show(); + } + } + }); + alert.show(); + } else if (manualExposureMode.equals(userSetting)) { + alert.setMessage("Full manual mode - Enter both ISO and Exposure Time"); + final TextView ISORangeText = new TextView(mActivity); + final TextView ExpTimeRangeText = new TextView(mActivity); + ISORangeText.setText("Enter ISO in the range of " + minISO + " to " + maxISO); + ExpTimeRangeText.setText("Enter exposure time in the range of " + minExpTime + + "ms to " + maxExpTime + "ms"); + linear.addView(ISORangeText); + linear.addView(ISOinput); + linear.addView(ISOtext); + linear.addView(ExpTimeRangeText); + linear.addView(ExpTimeInput); + linear.addView(ExpTimeText); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog,int id) + { + int newISO = -1; + String iso = ISOinput.getText().toString(); + Log.v(TAG, "string iso length " + iso.length()); + if (iso.length() > 0) { + newISO = Integer.parseInt(iso); + } + double newExpTime = -1; + String expTime = ExpTimeInput.getText().toString(); + if (expTime.length() > 0) { + try { + newExpTime = Double.parseDouble(expTime); + } catch (NumberFormatException e) { + Log.w(TAG, "input newExpTime " + newExpTime + " is invalid"); + newExpTime = Double.parseDouble(maxExpTime) + 1f; + } + + } + if (newISO <= maxISO && newISO >= minISO && + newExpTime <= Double.parseDouble(maxExpTime) && + newExpTime >= Double.parseDouble(minExpTime)) { + mManual3AEnabled |= MANUAL_EXPOSURE; + Log.v(TAG, "Setting ISO : " + newISO); + mParameters.setISOValue(isoManual); + mParameters.set(CameraSettings.KEY_CONTINUOUS_ISO, newISO); + Log.v(TAG, "Setting Exposure time : " + newExpTime); + mParameters.set(CameraSettings.KEY_EXPOSURE_TIME, expTime); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } else { + RotateTextToast.makeText(mActivity, "Invalid input", Toast.LENGTH_SHORT) + .show(); + } + } + }); + alert.show(); + } else { + mManual3AEnabled &= ~MANUAL_EXPOSURE; + //auto exposure mode - reset both exposure time and ISO + mParameters.set(CameraSettings.KEY_EXPOSURE_TIME, "0"); + mUI.overrideSettings(CameraSettings.KEY_ISO, null); + updateCommonManual3ASettings(); + onSharedPreferenceChanged(); + } + } + + // 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)) { + //HDR internally uses AE-bracketing. Disable both if not supported. + if (notSame(pref, CameraSettings.KEY_CAMERA_HDR, settingOff) || + notSame(pref, CameraSettings.KEY_AE_BRACKET_HDR, settingOff)) { + mUI.setPreference(CameraSettings.KEY_ZSL,settingOff); + } else if (notSame(pref,CameraSettings.KEY_ZSL,settingOff)) { + mUI.setPreference(CameraSettings.KEY_CAMERA_HDR, settingOff); + mUI.setPreference(CameraSettings.KEY_AE_BRACKET_HDR, settingOff); + } + } + + if(CameraSettings.KEY_MANUAL_EXPOSURE.equals(pref.getKey())) { + UpdateManualExposureSettings(); + return; + } + if (CameraSettings.KEY_MANUAL_WB.equals(pref.getKey())) { + UpdateManualWBSettings(); + return; + } + if (CameraSettings.KEY_MANUAL_FOCUS.equals(pref.getKey())) { + UpdateManualFocusSettings(); + return; + } + + if (CameraSettings.KEY_CAMERA_SAVEPATH.equals(pref.getKey())) { + Storage.setSaveSDCard( + mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1")); + mActivity.updateStorageSpaceAndHint(); + updateRemainingPhotos(); + } + + if (CameraSettings.KEY_QC_CHROMA_FLASH.equals(pref.getKey())) { + mUI.setPreference(CameraSettings.KEY_ADVANCED_FEATURES, pref.getValue()); + } + + 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); + String reFocusOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_off); + String fssrOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_off); + String truePortraitOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_off); + String multiTouchFocusOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_off); + String stillMoreOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_stillmore_off); + String advancedFeatureOff = mActivity.getString(R.string. + pref_camera_advanced_feature_value_none); + if (notSame(pref, CameraSettings.KEY_QC_OPTI_ZOOM, optiZoomOff) || + notSame(pref, CameraSettings.KEY_QC_AF_BRACKETING, ubiFocusOff) || + notSame(pref, CameraSettings.KEY_QC_FSSR, fssrOff) || + notSame(pref, CameraSettings.KEY_QC_TP, truePortraitOff) || + notSame(pref, CameraSettings.KEY_QC_MULTI_TOUCH_FOCUS, multiTouchFocusOff) || + notSame(pref, CameraSettings.KEY_QC_STILL_MORE, stillMoreOff) || + notSame(pref, CameraSettings.KEY_QC_RE_FOCUS, reFocusOff) || + notSame(pref, CameraSettings.KEY_ADVANCED_FEATURES, advancedFeatureOff)) { + RotateTextToast.makeText(mActivity, R.string.advanced_capture_disable_continuous_shot, + Toast.LENGTH_LONG).show(); + } + //call generic onSharedPreferenceChanged + onSharedPreferenceChanged(); + } + + @Override + public void onSharedPreferenceChanged() { + // ignore the events after "onPause()" + if (mPaused) return; + + boolean recordLocation = RecordLocationPreference.get( + mPreferences, mContentResolver); + mLocationManager.recordLocation(recordLocation); + if(needRestart()){ + Log.v(TAG, "Restarting Preview... Camera Mode Changed"); + 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(); + } + + @Override + public void onCameraPickerClicked(int cameraId) { + if (mPaused || mPendingSwitchCameraId != -1) return; + + mPendingSwitchCameraId = cameraId; + + Log.v(TAG, "Start to switch camera. cameraId=" + cameraId); + // We need to keep a preview frame for the animation before + // releasing the camera. This will trigger onPreviewTextureCopied. + //TODO: Need to animate the camera switch + switchCamera(); + } + + // Preview texture has been copied. Now camera can be released and the + // animation can be started. + @Override + public void onPreviewTextureCopied() { + mHandler.sendEmptyMessage(SWITCH_CAMERA); + } + + @Override + public void onCaptureTextureCopied() { + } + + @Override + public void onUserInteraction() { + if (!mActivity.isFinishing()) keepScreenOnAwhile(); + } + + private void resetScreenOn() { + mHandler.removeMessages(CLEAR_SCREEN_DELAY); + mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + private void keepScreenOnAwhile() { + mHandler.removeMessages(CLEAR_SCREEN_DELAY); + mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); + } + + @Override + public void onOverriddenPreferencesClicked() { + if (mPaused) return; + mUI.showPreferencesToast(); + } + + private void showTapToFocusToast() { + // TODO: Use a toast? + new RotateTextToast(mActivity, R.string.tap_to_focus, 0).show(); + // Clear the preference. + Editor editor = mPreferences.edit(); + editor.putBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, false); + editor.apply(); + } + + private void initializeCapabilities() { + mFocusAreaSupported = CameraUtil.isFocusAreaSupported(mInitialParams); + mMeteringAreaSupported = CameraUtil.isMeteringAreaSupported(mInitialParams); + mAeLockSupported = CameraUtil.isAutoExposureLockSupported(mInitialParams); + mAwbLockSupported = CameraUtil.isAutoWhiteBalanceLockSupported(mInitialParams); + mContinuousFocusSupported = mInitialParams.getSupportedFocusModes().contains( + CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE); + } + + @Override + public void onCountDownFinished() { + mSnapshotOnIdle = false; + initiateSnap(); + mFocusManager.onShutterUp(); + mUI.overrideSettings(CameraSettings.KEY_ZSL, null); + mUI.showUIAfterCountDown(); + } + + @Override + public void onShowSwitcherPopup() { + mUI.onShowSwitcherPopup(); + } + + @Override + public int onZoomChanged(int index) { + // Not useful to change zoom value when the activity is paused. + if (mPaused) return index; + mZoomValue = index; + if (mParameters == null || mCameraDevice == null) return index; + // Set zoom parameters asynchronously + synchronized (mCameraDevice) { + mParameters.setZoom(mZoomValue); + mCameraDevice.setParameters(mParameters); + Parameters p = mCameraDevice.getParameters(); + if (p != null) return p.getZoom(); + } + return index; + } + + @Override + public int getCameraState() { + return mCameraState; + } + + @Override + public void onQueueStatus(boolean full) { + mUI.enableShutter(!full); + } + + @Override + public void onMediaSaveServiceConnected(MediaSaveService s) { + // We set the listener only when both service and shutterbutton + // are initialized. + if (mFirstTimeInitialized) { + s.setListener(this); + } + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + @Override + public void onSensorChanged(SensorEvent event) { + int type = event.sensor.getType(); + float[] data; + if (type == Sensor.TYPE_ACCELEROMETER) { + data = mGData; + } else if (type == Sensor.TYPE_MAGNETIC_FIELD) { + data = mMData; + } else { + // we should not be here. + return; + } + for (int i = 0; i < 3 ; i++) { + data[i] = event.values[i]; + } + float[] orientation = new float[3]; + SensorManager.getRotationMatrix(mR, null, mGData, mMData); + SensorManager.getOrientation(mR, orientation); + mHeading = (int) (orientation[0] * 180f / Math.PI) % 360; + if (mHeading < 0) { + 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() {} + +/* + * Provide a mapping for Jpeg encoding quality levels + * from String representation to numeric representation. + */ + @Override + public boolean arePreviewControlsVisible() { + return mUI.arePreviewControlsVisible(); + } + + // For debugging only. + public void setDebugUri(Uri uri) { + mDebugUri = uri; + } + + // For debugging only. + private void saveToDebugUri(byte[] data) { + if (mDebugUri != null) { + OutputStream outputStream = null; + try { + outputStream = mContentResolver.openOutputStream(mDebugUri); + outputStream.write(data); + outputStream.close(); + } catch (IOException e) { + Log.e(TAG, "Exception while writing debug jpeg file", e); + } finally { + CameraUtil.closeSilently(outputStream); + } + } + } + + public boolean isRefocus() { + return mLastPhotoTakenWithRefocus; + } + + @Override + public void onMakeupLevel(String key, String value) { + synchronized (mCameraDevice) { + onMakeupLevelSync(key, value); + } + } + + public void onMakeupLevelSync(String key, String value) { + Log.d(TAG, "PhotoModule.onMakeupLevel(): key is " + key + ", value is " + value); + + if(TextUtils.isEmpty(value)) { + return; + } + + String prefValue = TsMakeupManager.MAKEUP_ON; + if(TsMakeupManager.MAKEUP_OFF.equals(value)) { + prefValue = TsMakeupManager.MAKEUP_OFF; + } + + Log.d(TAG, "onMakeupLevel(): prefValue is " + prefValue); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM, prefValue); + + if(!TextUtils.isDigitsOnly(value)) { + if(TsMakeupManager.MAKEUP_NONE.equals(value)) { + ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_TS_MAKEUP_LEVEL_WHITEN); + if(pref != null) { + String whitenValue = pref.getValue(); + if(TextUtils.isEmpty(whitenValue)) { + whitenValue = mActivity.getString(R.string.pref_camera_tsmakeup_level_default); + } + pref.setMakeupSeekBarValue(whitenValue); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_WHITEN, Integer.parseInt(whitenValue)); + } + + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_TS_MAKEUP_LEVEL_CLEAN); + if(pref != null) { + String cleanValue = pref.getValue(); + if(TextUtils.isEmpty(cleanValue)) { + cleanValue = mActivity.getString(R.string.pref_camera_tsmakeup_level_default); + } + pref.setMakeupSeekBarValue(cleanValue); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_CLEAN, Integer.parseInt(cleanValue)); + } + } + } else { + if(CameraSettings.KEY_TS_MAKEUP_LEVEL.equals(key)) { + if(mParameters != null) { + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_WHITEN, Integer.parseInt(value)); + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_CLEAN, Integer.parseInt(value)); + } + ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_TS_MAKEUP_LEVEL_WHITEN); + if(pref != null) { + pref.setMakeupSeekBarValue(value); + } + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_TS_MAKEUP_LEVEL_CLEAN); + if(pref != null) { + pref.setMakeupSeekBarValue(value); + } + } else if(CameraSettings.KEY_TS_MAKEUP_LEVEL_WHITEN.equals(key)) { + if(mParameters != null) { + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_WHITEN, Integer.parseInt(value)); + } + } else if(CameraSettings.KEY_TS_MAKEUP_LEVEL_CLEAN.equals(key)) { + if(mParameters != null) { + mParameters.set(CameraSettings.KEY_TS_MAKEUP_PARAM_CLEAN, Integer.parseInt(value)); + } + } + } + + mCameraDevice.setParameters(mParameters); + mParameters = mCameraDevice.getParameters(); + } +} + +/* 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 mHashMap = + new HashMap(); + + 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()); + } +} + +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 + 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; + } +} + +class DrawAutoHDR extends View{ + + private static final String TAG = "AutoHdrView"; + private PhotoModule mPhotoModule; + + public DrawAutoHDR (Context context, AttributeSet attrs) { + super(context,attrs); + } + + @Override + protected void onDraw (Canvas canvas) { + if (mPhotoModule == null) + return; + if (mPhotoModule.mAutoHdrEnable) { + Paint AutoHDRPaint = new Paint(); + AutoHDRPaint.setColor(Color.WHITE); + AutoHDRPaint.setAlpha (0); + canvas.drawPaint(AutoHDRPaint); + AutoHDRPaint.setStyle(Paint.Style.STROKE); + AutoHDRPaint.setColor(Color.MAGENTA); + AutoHDRPaint.setStrokeWidth(1); + AutoHDRPaint.setTextSize(16); + AutoHDRPaint.setAlpha (255); + canvas.drawText("HDR On",200,100,AutoHDRPaint); + } + else { + super.onDraw(canvas); + return; + } + } + + public void AutoHDR () { + invalidate(); + } + + public void setPhotoModuleObject (PhotoModule photoModule) { + mPhotoModule = photoModule; + } +} diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java new file mode 100644 index 000000000..334868e8d --- /dev/null +++ b/src/com/android/camera/CaptureUI.java @@ -0,0 +1,1463 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.camera; + +import java.util.List; + +import org.codeaurora.snapcam.R; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Point; +import android.graphics.RectF; +import android.graphics.drawable.AnimationDrawable; +import android.graphics.drawable.ColorDrawable; +import android.hardware.Camera; +import android.hardware.Camera.Face; +import android.os.AsyncTask; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnLayoutChangeListener; +import android.view.ViewGroup; +import android.view.ViewStub; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.Toast; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.FocusOverlayManager.FocusUI; +import com.android.camera.TsMakeupManager.MakeupLevelListener; +import com.android.camera.ui.AbstractSettingPopup; +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.CameraRootView; +import com.android.camera.ui.CountDownView; +import com.android.camera.ui.CountDownView.OnCountDownFinishedListener; +import com.android.camera.ui.FaceView; +import com.android.camera.ui.FocusIndicator; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.ModuleSwitcher; +import com.android.camera.ui.MenuHelp; +import com.android.camera.ui.PieRenderer; +import com.android.camera.ui.PieRenderer.PieListener; +import com.android.camera.ui.RenderOverlay; +import com.android.camera.ui.RotateImageView; +import com.android.camera.ui.RotateLayout; +import com.android.camera.ui.RotateTextToast; +import com.android.camera.ui.SelfieFlashView; +import com.android.camera.ui.ZoomRenderer; +import com.android.camera.util.CameraUtil; + +public class PhotoUI implements PieListener, + PreviewGestures.SingleTapListener, + FocusUI, + SurfaceHolder.Callback, + LocationManager.Listener, + CameraRootView.MyDisplayListener, + CameraManager.CameraFaceDetectionCallback { + + private static final String TAG = "CAM_UI"; + private int mDownSampleFactor = 4; + private final AnimationManager mAnimationManager; + private CameraActivity mActivity; + private PhotoController mController; + private PreviewGestures mGestures; + + private View mRootView; + private SurfaceHolder mSurfaceHolder; + + private PopupWindow mPopup; + private ShutterButton mShutterButton; + private CountDownView mCountDownView; + private SelfieFlashView mSelfieView; + + private FaceView mFaceView; + private RenderOverlay mRenderOverlay; + private View mReviewCancelButton; + private View mReviewDoneButton; + private View mReviewRetakeButton; + private ImageView mReviewImage; + private DecodeImageForReview mDecodeTaskForReview = null; + + private View mMenuButton; + private PhotoMenu mMenu; + private ModuleSwitcher mSwitcher; + private CameraControls mCameraControls; + private MenuHelp mMenuHelp; + private AlertDialog mLocationDialog; + + // Small indicators which show the camera settings in the viewfinder. + private OnScreenIndicators mOnScreenIndicators; + + private PieRenderer mPieRenderer; + private ZoomRenderer mZoomRenderer; + private RotateTextToast mNotSelectableToast; + + private int mZoomMax; + private List mZoomRatios; + + private int mMaxPreviewWidth = 0; + private int mMaxPreviewHeight = 0; + + public boolean mMenuInitialized = false; + private float mSurfaceTextureUncroppedWidth; + private float mSurfaceTextureUncroppedHeight; + + private ImageView mThumbnail; + private View mFlashOverlay; + + private SurfaceTextureSizeChangedListener mSurfaceTextureSizeListener; + private SurfaceView mSurfaceView = null; + private float mAspectRatio = 4f / 3f; + private boolean mAspectRatioResize; + + private boolean mOrientationResize; + private boolean mPrevOrientationResize; + private View mPreviewCover; + private RotateLayout mMenuLayout; + private RotateLayout mSubMenuLayout; + private LinearLayout mPreviewMenuLayout; + private LinearLayout mMakeupMenuLayout; + private boolean mUIhidden = false; + private int mPreviewOrientation = -1; + + private int mScreenRatio = CameraUtil.RATIO_UNKNOWN; + private int mTopMargin = 0; + private int mBottomMargin = 0; + + private int mOrientation; + private float mScreenBrightness = 0.0f; + + public interface SurfaceTextureSizeChangedListener { + public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight); + } + + private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, + int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (mMenu != null) + mMenu.tryToCloseSubList(); + + Camera.Parameters parameters = ((PhotoModule)mController).getParameters(); + if(parameters != null) { + Camera.Size size = parameters.getPreviewSize(); + if (size != null) { + setAspectRatio((float) size.width / size.height); + } + } + } + }; + + public CameraControls getCameraControls() { + return mCameraControls; + } + + private class DecodeTask extends AsyncTask { + private final byte [] mData; + private int mOrientation; + private boolean mMirror; + + public DecodeTask(byte[] data, int orientation, boolean mirror) { + mData = data; + mOrientation = orientation; + mMirror = mirror; + } + + @Override + protected Bitmap doInBackground(Void... params) { + // Decode image in background. + Bitmap bitmap = CameraUtil.downSample(mData, mDownSampleFactor); + if ((mOrientation != 0 || mMirror) && (bitmap != null)) { + Matrix m = new Matrix(); + if (mMirror) { + // Flip horizontally + m.setScale(-1f, 1f); + } + m.preRotate(mOrientation); + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, + false); + } + return bitmap; + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + } + } + + private class DecodeImageForReview extends DecodeTask { + public DecodeImageForReview(byte[] data, int orientation, boolean mirror) { + super(data, orientation, mirror); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (isCancelled()) { + return; + } + mReviewImage.setImageBitmap(bitmap); + mReviewImage.setVisibility(View.VISIBLE); + mDecodeTaskForReview = null; + } + } + + public PhotoUI(CameraActivity activity, PhotoController controller, View parent) { + mActivity = activity; + mController = controller; + mRootView = parent; + mActivity.getLayoutInflater().inflate(R.layout.photo_module, + (ViewGroup) mRootView, true); + mPreviewCover = mRootView.findViewById(R.id.preview_cover); + // display the view + mSurfaceView = (SurfaceView) mRootView.findViewById(R.id.mdp_preview_content); + mSurfaceView.setVisibility(View.VISIBLE); + mSurfaceHolder = mSurfaceView.getHolder(); + mSurfaceHolder.addCallback(this); + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + mSurfaceView.addOnLayoutChangeListener(mLayoutListener); + Log.v(TAG, "Using mdp_preview_content (MDP path)"); + + View surfaceContainer = mRootView.findViewById(R.id.preview_container); + surfaceContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, + int bottom, int oldLeft, int oldTop, int oldRight, + int oldBottom) { + int width = right - left; + int height = bottom - top; + + if (mMaxPreviewWidth == 0 && mMaxPreviewHeight == 0) { + mMaxPreviewWidth = width; + mMaxPreviewHeight = height; + } + + int orientation = mActivity.getResources().getConfiguration().orientation; + if ((orientation == Configuration.ORIENTATION_PORTRAIT && width > height) + || (orientation == Configuration.ORIENTATION_LANDSCAPE && width < height)) { + // The screen has rotated; swap SurfaceView width & height + // to ensure correct preview + int oldWidth = width; + width = height; + height = oldWidth; + Log.d(TAG, "Swapping SurfaceView width & height dimensions"); + if (mMaxPreviewWidth != 0 && mMaxPreviewHeight != 0) { + int temp = mMaxPreviewWidth; + mMaxPreviewWidth = mMaxPreviewHeight; + mMaxPreviewHeight = temp; + } + } + if (mOrientationResize != mPrevOrientationResize + || mAspectRatioResize) { + layoutPreview(mAspectRatio); + mAspectRatioResize = false; + } + } + }); + + mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay); + mFlashOverlay = mRootView.findViewById(R.id.flash_overlay); + mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button); + mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher); + mSwitcher.setCurrentIndex(ModuleSwitcher.PHOTO_MODULE_INDEX); + mSwitcher.setSwitchListener(mActivity); + mSwitcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mController.getCameraState() == PhotoController.LONGSHOT) { + return; + } + mSwitcher.showPopup(); + mSwitcher.setOrientation(mOrientation, false); + } + }); + mMenuButton = mRootView.findViewById(R.id.menu); + + RotateImageView muteButton = (RotateImageView)mRootView.findViewById(R.id.mute_button); + muteButton.setVisibility(View.GONE); + + mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls); + ViewStub faceViewStub = (ViewStub) mRootView + .findViewById(R.id.face_view_stub); + if (faceViewStub != null) { + faceViewStub.inflate(); + mFaceView = (FaceView) mRootView.findViewById(R.id.face_view); + setSurfaceTextureSizeChangedListener(mFaceView); + } + initIndicators(); + mAnimationManager = new AnimationManager(); + mOrientationResize = false; + mPrevOrientationResize = false; + + Point size = new Point(); + mActivity.getWindowManager().getDefaultDisplay().getSize(size); + mScreenRatio = CameraUtil.determineRatio(size.x, size.y); + calculateMargins(size); + mCameraControls.setMargins(mTopMargin, mBottomMargin); + showFirstTimeHelp(); + } + + private void calculateMargins(Point size) { + int l = size.x > size.y ? size.x : size.y; + int tm = mActivity.getResources().getDimensionPixelSize(R.dimen.preview_top_margin); + int bm = mActivity.getResources().getDimensionPixelSize(R.dimen.preview_bottom_margin); + mTopMargin = l / 4 * tm / (tm + bm); + mBottomMargin = l / 4 - mTopMargin; + } + + public void setDownFactor(int factor) { + mDownSampleFactor = factor; + } + + public void cameraOrientationPreviewResize(boolean orientation){ + mPrevOrientationResize = mOrientationResize; + mOrientationResize = orientation; + } + + private void showFirstTimeHelp(int topMargin, int bottomMargin) { + mMenuHelp = (MenuHelp) mRootView.findViewById(R.id.menu_help); + mMenuHelp.setVisibility(View.VISIBLE); + mMenuHelp.setMargins(topMargin, bottomMargin); + mMenuHelp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mMenuHelp.setVisibility(View.GONE); + mMenuHelp = null; + } + }); + } + + 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 + "]"); + if (ratio != mAspectRatio) { + mAspectRatioResize = true; + mAspectRatio = ratio; + } + mCameraControls.setPreviewRatio(mAspectRatio, false); + layoutPreview(ratio); + } + + public void layoutPreview(float ratio) { + FrameLayout.LayoutParams lp; + float scaledTextureWidth, scaledTextureHeight; + int rotation = CameraUtil.getDisplayRotation(mActivity); + mScreenRatio = CameraUtil.determineRatio(ratio); + if (mScreenRatio == CameraUtil.RATIO_16_9 + && CameraUtil.determinCloseRatio(ratio) == CameraUtil.RATIO_4_3) { + int l = (mTopMargin + mBottomMargin) * 4; + int s = l * 9 / 16; + switch (rotation) { + case 90: + lp = new FrameLayout.LayoutParams(l * 3 / 4, s); + lp.setMargins(mTopMargin, 0, mBottomMargin, 0); + scaledTextureWidth = l * 3 / 4; + scaledTextureHeight = s; + break; + case 180: + lp = new FrameLayout.LayoutParams(s, l * 3 / 4); + lp.setMargins(0, mBottomMargin, 0, mTopMargin); + scaledTextureWidth = s; + scaledTextureHeight = l * 3 / 4; + break; + case 270: + lp = new FrameLayout.LayoutParams(l * 3 / 4, s); + lp.setMargins(mBottomMargin, 0, mTopMargin, 0); + scaledTextureWidth = l * 3 / 4; + scaledTextureHeight = s; + break; + default: + lp = new FrameLayout.LayoutParams(s, l * 3 / 4); + lp.setMargins(0, mTopMargin, 0, mBottomMargin); + scaledTextureWidth = s; + scaledTextureHeight = l * 3 / 4; + break; + } + } else { + float width = mMaxPreviewWidth, height = mMaxPreviewHeight; + if (width == 0 || height == 0) return; + if(mScreenRatio == CameraUtil.RATIO_4_3) + height -= (mTopMargin + mBottomMargin); + if (mOrientationResize) { + scaledTextureWidth = height * mAspectRatio; + if (scaledTextureWidth > width) { + scaledTextureWidth = width; + scaledTextureHeight = scaledTextureWidth / mAspectRatio; + } else { + scaledTextureHeight = height; + } + } else { + if (width > height) { + if(Math.max(width, height * mAspectRatio) > width) { + scaledTextureWidth = width; + scaledTextureHeight = width / mAspectRatio; + } else { + scaledTextureWidth = height * mAspectRatio; + scaledTextureHeight = height; + } + } else { + if(Math.max(height, width * mAspectRatio) > height) { + scaledTextureWidth = height / mAspectRatio; + scaledTextureHeight = height; + } else { + scaledTextureWidth = width; + scaledTextureHeight = width * mAspectRatio; + } + } + } + + Log.v(TAG, "setTransformMatrix: scaledTextureWidth = " + scaledTextureWidth + + ", scaledTextureHeight = " + scaledTextureHeight); + if (((rotation == 0 || rotation == 180) && scaledTextureWidth > scaledTextureHeight) + || ((rotation == 90 || rotation == 270) + && scaledTextureWidth < scaledTextureHeight)) { + lp = new FrameLayout.LayoutParams((int) scaledTextureHeight, + (int) scaledTextureWidth, Gravity.CENTER); + } else { + lp = new FrameLayout.LayoutParams((int) scaledTextureWidth, + (int) scaledTextureHeight, Gravity.CENTER); + } + if(mScreenRatio == CameraUtil.RATIO_4_3) { + lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + lp.setMargins(0, mTopMargin, 0, mBottomMargin); + } + } + + if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || + mSurfaceTextureUncroppedHeight != scaledTextureHeight) { + mSurfaceTextureUncroppedWidth = scaledTextureWidth; + mSurfaceTextureUncroppedHeight = scaledTextureHeight; + if (mSurfaceTextureSizeListener != null) { + mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged( + (int) mSurfaceTextureUncroppedWidth, + (int) mSurfaceTextureUncroppedHeight); + Log.d(TAG, "mSurfaceTextureUncroppedWidth=" + mSurfaceTextureUncroppedWidth + + "mSurfaceTextureUncroppedHeight=" + mSurfaceTextureUncroppedHeight); + } + } + + mSurfaceView.setLayoutParams(lp); + if (mFaceView != null) { + mFaceView.setLayoutParams(lp); + } + + mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth, + (int) mSurfaceTextureUncroppedHeight); + } + + public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) { + mSurfaceTextureSizeListener = listener; + } + + // SurfaceHolder callbacks + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + Log.v(TAG, "surfaceChanged: width =" + width + ", height = " + height); + RectF r = new RectF(mSurfaceView.getLeft(), mSurfaceView.getTop(), + mSurfaceView.getRight(), mSurfaceView.getBottom()); + mController.onPreviewRectChanged(CameraUtil.rectFToRect(r)); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + Log.v(TAG, "surfaceCreated"); + mSurfaceHolder = holder; + mController.onPreviewUIReady(); + mActivity.updateThumbnail(mThumbnail); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + Log.v(TAG, "surfaceDestroyed"); + mSurfaceHolder = null; + mController.onPreviewUIDestroyed(); + } + + public View getRootView() { + return mRootView; + } + + private void initIndicators() { + mOnScreenIndicators = new OnScreenIndicators(mActivity, + mRootView.findViewById(R.id.on_screen_indicators)); + } + + public void onCameraOpened(PreferenceGroup prefGroup, ComboPreferences prefs, + Camera.Parameters params, OnPreferenceChangedListener listener, MakeupLevelListener makeupListener) { + if (mPieRenderer == null) { + mPieRenderer = new PieRenderer(mActivity); + mPieRenderer.setPieListener(this); + mRenderOverlay.addRenderer(mPieRenderer); + } + + if (mMenu == null) { + mMenu = new PhotoMenu(mActivity, this, makeupListener); + mMenu.setListener(listener); + } + mMenu.initialize(prefGroup); + mMenuInitialized = true; + + if (mZoomRenderer == null) { + mZoomRenderer = new ZoomRenderer(mActivity); + mRenderOverlay.addRenderer(mZoomRenderer); + } + + if (mGestures == null) { + // this will handle gesture disambiguation and dispatching + mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); + mRenderOverlay.setGestures(mGestures); + } + mGestures.setPhotoMenu(mMenu); + + mGestures.setZoomEnabled(params.isZoomSupported()); + mGestures.setRenderOverlay(mRenderOverlay); + mRenderOverlay.requestLayout(); + + initializeZoom(params); + updateOnScreenIndicators(params, prefGroup, prefs); + mActivity.setPreviewGestures(mGestures); + } + + public void animateCapture(final byte[] jpegData, int orientation, boolean mirror) { + // Decode jpeg byte array and then animate the jpeg + mActivity.updateThumbnail(jpegData); + } + + public void showRefocusToast(boolean show) { + mCameraControls.showRefocusToast(show); + } + + private void openMenu() { + if (mPieRenderer != null) { + // If autofocus is not finished, cancel autofocus so that the + // subsequent touch can be handled by PreviewGestures + if (mController.getCameraState() == PhotoController.FOCUSING) { + mController.cancelAutoFocus(); + } + mPieRenderer.showInCenter(); + } + } + + public void initializeControlByIntent() { + mThumbnail = (ImageView) mRootView.findViewById(R.id.preview_thumb); + mThumbnail.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (!CameraControls.isAnimating() + && mController.getCameraState() != PhotoController.SNAPSHOT_IN_PROGRESS) + mActivity.gotoGallery(); + } + }); + mMenuButton = mRootView.findViewById(R.id.menu); + mMenuButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mMenu != null) { + mMenu.openFirstLevel(); + } + } + }); + if (mController.isImageCaptureIntent()) { + hideSwitcher(); + mSwitcher.setSwitcherVisibility(false); + ViewGroup cameraControls = (ViewGroup) mRootView.findViewById(R.id.camera_controls); + mActivity.getLayoutInflater().inflate(R.layout.review_module_control, cameraControls); + + mReviewDoneButton = mRootView.findViewById(R.id.btn_done); + mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel); + mReviewRetakeButton = mRootView.findViewById(R.id.btn_retake); + mReviewImage = (ImageView) mRootView.findViewById(R.id.review_image); + mReviewCancelButton.setVisibility(View.VISIBLE); + + mReviewDoneButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mController.onCaptureDone(); + } + }); + mReviewCancelButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mController.onCaptureCancelled(); + } + }); + + mReviewRetakeButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mController.onCaptureRetake(); + if (mController.isImageCaptureIntent()) { + mCameraControls.setTitleBarVisibility(View.VISIBLE); + } + } + }); + } + } + + public void hideUI() { + mSwitcher.closePopup(); + if (mUIhidden) + return; + mUIhidden = true; + mCameraControls.hideUI(); + } + + public void showUI() { + if (!mUIhidden || (mMenu != null && mMenu.isMenuBeingShown())) + return; + mUIhidden = false; + mCameraControls.showUI(); + } + + public boolean arePreviewControlsVisible() { + return !mUIhidden; + } + + public void hideSwitcher() { + mSwitcher.closePopup(); + mSwitcher.setVisibility(View.INVISIBLE); + } + + public void showSwitcher() { + mSwitcher.setVisibility(View.VISIBLE); + } + + public void setSwitcherIndex() { + mSwitcher.setCurrentIndex(ModuleSwitcher.PHOTO_MODULE_INDEX); + } + + // called from onResume but only the first time + public void initializeFirstTime() { + // Initialize shutter button. + mShutterButton.setImageResource(R.drawable.shutter_button_anim); + mShutterButton.setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) { + if (!CameraControls.isAnimating()) + doShutterAnimation(); + if (mController.isImageCaptureIntent()) { + mCameraControls.setTitleBarVisibility(View.VISIBLE); + } + } + }); + + mShutterButton.setOnShutterButtonListener(mController); + mShutterButton.setVisibility(View.VISIBLE); + } + + public void doShutterAnimation() { + AnimationDrawable frameAnimation = (AnimationDrawable) mShutterButton.getDrawable(); + frameAnimation.stop(); + frameAnimation.start(); + } + + // called from onResume every other time + public void initializeSecondTime(Camera.Parameters params) { + initializeZoom(params); + if (mController.isImageCaptureIntent()) { + hidePostCaptureAlert(); + } + if (mMenu != null) { + mMenu.reloadPreferences(); + } + RotateImageView muteButton = (RotateImageView)mRootView.findViewById(R.id.mute_button); + muteButton.setVisibility(View.GONE); + } + + public void showLocationDialog() { + mLocationDialog = new AlertDialog.Builder(mActivity) + .setTitle(R.string.remember_location_title) + .setMessage(R.string.remember_location_prompt) + .setPositiveButton(R.string.remember_location_yes, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int arg1) { + mController.enableRecordingLocation(true); + mLocationDialog = null; + } + }) + .setNegativeButton(R.string.remember_location_no, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int arg1) { + dialog.cancel(); + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + mController.enableRecordingLocation(false); + mLocationDialog = null; + } + }) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + mActivity.setSystemBarsVisibility(false); + } + }) + .show(); + } + + public void initializeZoom(Camera.Parameters params) { + if ((params == null) || !params.isZoomSupported() + || (mZoomRenderer == null)) return; + mZoomMax = params.getMaxZoom(); + mZoomRatios = params.getZoomRatios(); + // Currently we use immediate zoom for fast zooming to get better UX and + // there is no plan to take advantage of the smooth zoom. + if (mZoomRenderer != null) { + mZoomRenderer.setZoomMax(mZoomMax); + mZoomRenderer.setZoom(params.getZoom()); + mZoomRenderer.setZoomValue(mZoomRatios.get(params.getZoom())); + mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener()); + } + } + + @Override + public void showGpsOnScreenIndicator(boolean hasSignal) { } + + @Override + 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 || group == null) return; + mOnScreenIndicators.updateSceneOnScreenIndicator(params.getSceneMode()); + mOnScreenIndicators.updateExposureOnScreenIndicator(params, + CameraSettings.readExposure(prefs)); + mOnScreenIndicators.updateFlashOnScreenIndicator(params.getFlashMode()); + int wbIndex = -1; + String wb = Camera.Parameters.WHITE_BALANCE_AUTO; + if (Camera.Parameters.SCENE_MODE_AUTO.equals(params.getSceneMode())) { + wb = params.getWhiteBalance(); + } + ListPreference pref = group.findPreference(CameraSettings.KEY_WHITE_BALANCE); + if (pref != null) { + wbIndex = pref.findIndexOfValue(wb); + } + // make sure the correct value was found + // otherwise use auto index + mOnScreenIndicators.updateWBIndicator(wbIndex < 0 ? 2 : wbIndex); + boolean location = RecordLocationPreference.get( + prefs, mActivity.getContentResolver()); + mOnScreenIndicators.updateLocationIndicator(location); + } + + public void setCameraState(int state) { + } + + public void animateFlash() { + mAnimationManager.startFlashAnimation(mFlashOverlay); + } + + public void enableGestures(boolean enable) { + if (mGestures != null) { + mGestures.setEnabled(enable); + } + } + + // forward from preview gestures to controller + @Override + public void onSingleTapUp(View view, int x, int y) { + mController.onSingleTapUp(view, x, y); + } + + public boolean onBackPressed() { + if (mMenu != null && mMenu.handleBackKey()) { + return true; + } + + if (mPieRenderer != null && mPieRenderer.showsItems()) { + mPieRenderer.hide(); + return true; + } + // In image capture mode, back button should: + // 1) if there is any popup, dismiss them, 2) otherwise, get out of + // image capture + if (mController.isImageCaptureIntent()) { + mController.onCaptureCancelled(); + return true; + } else if (!mController.isCameraIdle()) { + // ignore backs while we're taking a picture + return true; + } if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; + } else { + return false; + } + } + + public void onPreviewFocusChanged(boolean previewFocused) { + if (previewFocused) { + showUI(); + } else { + hideUI(); + } + if (mFaceView != null) { + mFaceView.setBlockDraw(!previewFocused); + } + if (mGestures != null) { + mGestures.setEnabled(previewFocused); + } + if (mRenderOverlay != null) { + // this can not happen in capture mode + mRenderOverlay.setVisibility(previewFocused ? View.VISIBLE : View.GONE); + } + if (mPieRenderer != null) { + mPieRenderer.setBlockFocus(!previewFocused); + } + setShowMenu(previewFocused); + if (!previewFocused && mCountDownView != null) mCountDownView.cancelCountDown(); + } + + public ViewGroup getMenuLayout() { + return mMenuLayout; + } + + public void setPreviewMenuLayout(LinearLayout layout) { + mPreviewMenuLayout = layout; + } + + public ViewGroup getPreviewMenuLayout() { + return mPreviewMenuLayout; + } + + public void setMakeupMenuLayout(LinearLayout layout) { + mMakeupMenuLayout = layout; + } + + public void showPopup(ListView popup, int level, boolean animate) { + FrameLayout.LayoutParams params; + hideUI(); + + popup.setVisibility(View.VISIBLE); + if (level == 1) { + if (mMenuLayout == null) { + mMenuLayout = new RotateLayout(mActivity, null); + if (mRootView.getLayoutDirection() != View.LAYOUT_DIRECTION_RTL) { + params = new FrameLayout.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT, + Gravity.LEFT | Gravity.TOP); + } else { + params = new FrameLayout.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT, + Gravity.RIGHT | Gravity.TOP); + } + mMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mMenuLayout); + } + mMenuLayout.setOrientation(mOrientation, true); + mMenuLayout.addView(popup); + } + if (level == 2) { + if (mSubMenuLayout == null) { + mSubMenuLayout = new RotateLayout(mActivity, null); + ((ViewGroup) mRootView).addView(mSubMenuLayout); + } + if (mRootView.getLayoutDirection() != View.LAYOUT_DIRECTION_RTL) { + params = new FrameLayout.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT, + Gravity.LEFT | Gravity.TOP); + } else { + params = new FrameLayout.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT, + Gravity.RIGHT | Gravity.TOP); + } + int screenHeight = (mOrientation == 0 || mOrientation == 180) + ? mRootView.getHeight() : mRootView.getWidth(); + int height = ((ListSubMenu) popup).getPreCalculatedHeight(); + int yBase = ((ListSubMenu) popup).getYBase(); + int y = Math.max(0, yBase); + if (yBase + height > screenHeight) + y = Math.max(0, screenHeight - height); + if (mRootView.getLayoutDirection() != View.LAYOUT_DIRECTION_RTL) { + params.setMargins(CameraActivity.SETTING_LIST_WIDTH_1, y, 0, 0); + } else { + params.setMargins(0, y, CameraActivity.SETTING_LIST_WIDTH_1, 0); + } + + mSubMenuLayout.setLayoutParams(params); + + mSubMenuLayout.addView(popup); + mSubMenuLayout.setOrientation(mOrientation, true); + } + if (animate) { + if (level == 1) + mMenu.animateSlideIn(mMenuLayout, CameraActivity.SETTING_LIST_WIDTH_1, true); + if (level == 2) + mMenu.animateFadeIn(popup); + } else + popup.setAlpha(0.85f); + } + + public void removeLevel2() { + if (mSubMenuLayout != null) { + View v = mSubMenuLayout.getChildAt(0); + mSubMenuLayout.removeView(v); + } + } + + public void showPopup(AbstractSettingPopup popup) { + hideUI(); + + if (mPopup == null) { + mPopup = new PopupWindow(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + mPopup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + mPopup.setOutsideTouchable(true); + mPopup.setFocusable(true); + mPopup.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + mPopup = null; + // mMenu.popupDismissed(mDismissAll); + mDismissAll = false; + showUI(); + + // Switch back into fullscreen/lights-out mode after popup + // is dimissed. + mActivity.setSystemBarsVisibility(false); + } + }); + } + popup.setVisibility(View.VISIBLE); + mPopup.setContentView(popup); + mPopup.showAtLocation(mRootView, Gravity.CENTER, 0, 0); + } + + public void cleanupListview() { + showUI(); + mActivity.setSystemBarsVisibility(false); + } + + public void dismissPopup() { + if (mPopup != null && mPopup.isShowing()) { + mPopup.dismiss(); + } + } + + private boolean mDismissAll = false; + public void dismissAllPopup() { + mDismissAll = true; + if (mPopup != null && mPopup.isShowing()) { + mPopup.dismiss(); + } + } + + public void dismissLevel1() { + if (mMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mMenuLayout); + mMenuLayout = null; + } + } + + public void dismissLevel2() { + if (mSubMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mSubMenuLayout); + mSubMenuLayout = null; + } + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mPreviewMenuLayout.dispatchTouchEvent(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + if (mMenuLayout != null) { + View v = mMenuLayout.getChildAt(0); + return v.dispatchTouchEvent(ev); + } + return false; + } + + public void dismissSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + } + + public void removeSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + cleanupListview(); + } + + public void onShowSwitcherPopup() { + if (mPieRenderer != null && mPieRenderer.showsItems()) { + mPieRenderer.hide(); + } + } + + private void setShowMenu(boolean show) { + if (mOnScreenIndicators != null) { + mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); + } + } + + public boolean collapseCameraControls() { + // TODO: Mode switcher should behave like a popup and should hide itself when there + // is a touch outside of it. + mSwitcher.closePopup(); + // Remove all the popups/dialog boxes + boolean ret = false; + if (mMenu != null) { + mMenu.closeAllView(); + } + if (mPopup != null) { + dismissAllPopup(); + ret = true; + } + onShowSwitcherPopup(); + mCameraControls.showRefocusToast(false); + return ret; + } + + protected void showCapturedImageForReview(byte[] jpegData, int orientation, boolean mirror) { + mCameraControls.hideCameraSettings(); + mDecodeTaskForReview = new DecodeImageForReview(jpegData, orientation, mirror); + mDecodeTaskForReview.execute(); + mOnScreenIndicators.setVisibility(View.GONE); + mMenuButton.setVisibility(View.GONE); + CameraUtil.fadeIn(mReviewDoneButton); + mShutterButton.setVisibility(View.INVISIBLE); + CameraUtil.fadeIn(mReviewRetakeButton); + mMenu.hideTopMenu(true); + pauseFaceDetection(); + } + + protected void hidePostCaptureAlert() { + mCameraControls.showCameraSettings(); + if (mDecodeTaskForReview != null) { + mDecodeTaskForReview.cancel(true); + } + mReviewImage.setVisibility(View.GONE); + mOnScreenIndicators.setVisibility(View.VISIBLE); + mMenuButton.setVisibility(View.VISIBLE); + mMenu.hideTopMenu(false); + CameraUtil.fadeOut(mReviewDoneButton); + mShutterButton.setVisibility(View.VISIBLE); + CameraUtil.fadeOut(mReviewRetakeButton); + resumeFaceDetection(); + } + + public void setDisplayOrientation(int orientation) { + if (mFaceView != null) { + mFaceView.setDisplayOrientation(orientation); + } + if ((mPreviewOrientation == -1 || mPreviewOrientation != orientation) + && mMenu != null && mMenu.isPreviewMenuBeingShown()) { + dismissSceneModeMenu(); + mMenu.addModeBack(); + } + mPreviewOrientation = orientation; + } + + // shutter button handling + + public boolean isShutterPressed() { + return mShutterButton.isPressed(); + } + + /** + * Enables or disables the shutter button. + */ + public void enableShutter(boolean enabled) { + if (mShutterButton != null) { + mShutterButton.setEnabled(enabled); + } + } + + public void pressShutterButton() { + if (mShutterButton.isInTouchMode()) { + mShutterButton.requestFocusFromTouch(); + } else { + mShutterButton.requestFocus(); + } + mShutterButton.setPressed(true); + } + + private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener { + @Override + public void onZoomValueChanged(int index) { + int newZoom = mController.onZoomChanged(index); + if (mZoomRenderer != null) { + mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom)); + } + } + + @Override + public void onZoomStart() { + if (mPieRenderer != null) { + mPieRenderer.hide(); + mPieRenderer.setBlockFocus(true); + } + } + + @Override + public void onZoomEnd() { + if (mPieRenderer != null) { + mPieRenderer.setBlockFocus(false); + } + } + } + + @Override + public void onPieOpened(int centerX, int centerY) { + setSwipingEnabled(false); + if (mFaceView != null) { + mFaceView.setBlockDraw(true); + } + // Close module selection menu when pie menu is opened. + mSwitcher.closePopup(); + } + + @Override + public void onPieClosed() { + setSwipingEnabled(true); + if (mFaceView != null) { + mFaceView.setBlockDraw(false); + } + } + + public void setSwipingEnabled(boolean enable) { + mActivity.setSwipingEnabled(enable); + } + + public SurfaceHolder getSurfaceHolder() { + return mSurfaceHolder; + } + + // Countdown timer + + private void initializeCountDown() { + mActivity.getLayoutInflater().inflate(R.layout.count_down_to_capture, + (ViewGroup) mRootView, true); + mCountDownView = (CountDownView) (mRootView.findViewById(R.id.count_down_to_capture)); + mCountDownView.setCountDownFinishedListener((OnCountDownFinishedListener) mController); + mCountDownView.bringToFront(); + mCountDownView.setOrientation(mOrientation); + } + + public boolean isCountingDown() { + return mCountDownView != null && mCountDownView.isCountingDown(); + } + + public void cancelCountDown() { + if (mCountDownView == null) return; + mCountDownView.cancelCountDown(); + showUIAfterCountDown(); + } + + public void startCountDown(int sec, boolean playSound) { + if (mCountDownView == null) initializeCountDown(); + mCountDownView.startCountDown(sec, playSound); + hideUIWhileCountDown(); + } + + public void startSelfieFlash() { + if(mSelfieView == null) + mSelfieView = (SelfieFlashView) (mRootView.findViewById(R.id.selfie_flash)); + mSelfieView.bringToFront(); + mSelfieView.open(); + mScreenBrightness = setScreenBrightness(1F); + } + + public void stopSelfieFlash() { + if(mSelfieView == null) + mSelfieView = (SelfieFlashView) (mRootView.findViewById(R.id.selfie_flash)); + mSelfieView.close(); + if(mScreenBrightness != 0.0f) + setScreenBrightness(mScreenBrightness); + } + + private float setScreenBrightness(float brightness) { + float originalBrightness; + Window window = mActivity.getWindow(); + WindowManager.LayoutParams layout = window.getAttributes(); + originalBrightness = layout.screenBrightness; + layout.screenBrightness = brightness; + window.setAttributes(layout); + return originalBrightness; + } + + public void showPreferencesToast() { + if (mNotSelectableToast == null) { + String str = mActivity.getResources().getString(R.string.not_selectable_in_scene_mode); + mNotSelectableToast = RotateTextToast.makeText(mActivity, str, Toast.LENGTH_SHORT); + } + mNotSelectableToast.show(); + } + + public void showPreviewCover() { + mPreviewCover.setVisibility(View.VISIBLE); + } + + public void hidePreviewCover() { + // Hide the preview cover if need. + if (mPreviewCover.getVisibility() != View.GONE) { + mPreviewCover.setVisibility(View.GONE); + } + } + + public void onPause() { + cancelCountDown(); + + // Clear UI. + collapseCameraControls(); + if (mFaceView != null) mFaceView.clear(); + + if (mLocationDialog != null && mLocationDialog.isShowing()) { + mLocationDialog.dismiss(); + } + mLocationDialog = null; + } + + public void initDisplayChangeListener() { + ((CameraRootView) mRootView).setDisplayChangeListener(this); + } + + public void removeDisplayChangeListener() { + ((CameraRootView) mRootView).removeDisplayChangeListener(); + } + + // focus UI implementation + + private FocusIndicator getFocusIndicator() { + return (mFaceView != null && mFaceView.faceExists()) ? mFaceView : mPieRenderer; + } + + @Override + public boolean hasFaces() { + return (mFaceView != null && mFaceView.faceExists()); + } + + public void clearFaces() { + if (mFaceView != null) mFaceView.clear(); + } + + @Override + public void clearFocus() { + FocusIndicator indicator = getFocusIndicator(); + if (indicator != null) indicator.clear(); + } + + @Override + public void setFocusPosition(int x, int y) { + mPieRenderer.setFocus(x, y); + } + + @Override + public void onFocusStarted() { + FocusIndicator indicator = getFocusIndicator(); + if (indicator != null) indicator.showStart(); + } + + @Override + public void onFocusSucceeded(boolean timeout) { + FocusIndicator indicator = getFocusIndicator(); + if (indicator != null) indicator.showSuccess(timeout); + } + + @Override + public void onFocusFailed(boolean timeout) { + FocusIndicator indicator = getFocusIndicator(); + if (indicator != null) indicator.showFail(timeout); + } + + @Override + public void pauseFaceDetection() { + if (mFaceView != null) mFaceView.pause(); + } + + @Override + public void resumeFaceDetection() { + if (mFaceView != null) mFaceView.resume(); + } + + public void onStartFaceDetection(int orientation, boolean mirror) { + mFaceView.setBlockDraw(false); + mFaceView.clear(); + mFaceView.setVisibility(View.VISIBLE); + mFaceView.setDisplayOrientation(orientation); + mFaceView.setMirror(mirror); + mFaceView.resume(); + } + + public void onStopFaceDetection() { + if (mFaceView != null) { + mFaceView.setBlockDraw(true); + mFaceView.clear(); + } + } + + @Override + public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) { + mFaceView.setFaces(faces); + } + + @Override + public void onDisplayChanged() { + Log.d(TAG, "Device flip detected."); + mCameraControls.checkLayoutFlip(); + mController.updateCameraOrientation(); + } + + public void setPreference(String key, String value) { + mMenu.setPreference(key, value); + } + + public void updateRemainingPhotos(int remaining) { + mCameraControls.updateRemainingPhotos(remaining); + } + + public void setOrientation(int orientation, boolean animation) { + mOrientation = orientation; + mCameraControls.setOrientation(orientation, animation); + if (mMenuHelp != null) + mMenuHelp.setOrientation(orientation, animation); + if (mMenuLayout != null) + mMenuLayout.setOrientation(orientation, animation); + if (mSubMenuLayout != null) + mSubMenuLayout.setOrientation(orientation, animation); + if (mPreviewMenuLayout != null) { + ViewGroup vg = (ViewGroup) mPreviewMenuLayout.getChildAt(0); + if (vg != null) + vg = (ViewGroup) vg.getChildAt(0); + if (vg != null) { + for (int i = vg.getChildCount() - 1; i >= 0; --i) { + RotateLayout l = (RotateLayout) vg.getChildAt(i); + l.setOrientation(orientation, animation); + } + } + } + if(mMakeupMenuLayout != null) { + View view = mMakeupMenuLayout.getChildAt(0); + if(view instanceof RotateLayout) { + for(int i = mMakeupMenuLayout.getChildCount() -1; i >= 0; --i) { + RotateLayout l = (RotateLayout) mMakeupMenuLayout.getChildAt(i); + l.setOrientation(orientation, animation); + } + } else { + ViewGroup vg = (ViewGroup) mMakeupMenuLayout.getChildAt(1); + if(vg != null) { + for (int i = vg.getChildCount() - 1; i >= 0; --i) { + ViewGroup vewiGroup = (ViewGroup) vg.getChildAt(i); + if(vewiGroup instanceof RotateLayout) { + RotateLayout l = (RotateLayout) vewiGroup; + l.setOrientation(orientation, animation); + } + } + } + } + + } + if (mCountDownView != null) + mCountDownView.setOrientation(orientation); + RotateTextToast.setOrientation(orientation); + if (mFaceView != null) { + mFaceView.setDisplayRotation(orientation); + } + if (mZoomRenderer != null) { + mZoomRenderer.setOrientation(orientation); + } + } + + public int getOrientation() { + return mOrientation; + } + + public void adjustOrientation() { + setOrientation(mOrientation, true); + } + + public void showFirstTimeHelp() { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mActivity); + boolean isMenuShown = prefs.getBoolean(CameraSettings.KEY_SHOW_MENU_HELP, false); + if(!isMenuShown) { + showFirstTimeHelp(mTopMargin, mBottomMargin); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(CameraSettings.KEY_SHOW_MENU_HELP, true); + editor.apply(); + } + } + + public void showRefocusDialog() { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mActivity); + int prompt = prefs.getInt(CameraSettings.KEY_REFOCUS_PROMPT, 1); + if (prompt == 1) { + AlertDialog dialog = new AlertDialog.Builder(mActivity) + .setTitle(R.string.refocus_prompt_title) + .setMessage(R.string.refocus_prompt_message) + .setPositiveButton(R.string.dialog_ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int arg1) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(CameraSettings.KEY_REFOCUS_PROMPT, 0); + editor.apply(); + } + }) + .show(); + } + } + + public void hideUIWhileCountDown() { + mMenu.hideCameraControls(true); + mGestures.setZoomOnly(true); + } + + public void showUIAfterCountDown() { + mMenu.hideCameraControls(false); + mGestures.setZoomOnly(false); + } +} -- cgit v1.2.3