Update camera parameters when setting has changed.

Bug: 12250474

* Implemented for photo mode only.
* To be extended to all other modules.

Change-Id: Ie5218f3a76acb757ac526d3f987ef3165736b46d
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 0d4747f..1374a02 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -901,7 +901,8 @@
         mPreferences = new ComboPreferences(getAndroidContext());
         mContentResolver = this.getContentResolver();
 
-        mSettingsManager = new SettingsManager(this, null, mCameraController.getNumberOfCameras());
+        mSettingsManager = new SettingsManager(this, mCameraController.getNumberOfCameras());
+
         // Remove this after we get rid of ComboPreferences.
         int cameraId = Integer.parseInt(mSettingsManager.get(SettingsManager.SETTING_CAMERA_ID));
         mPreferences.setLocalId(this, cameraId);
@@ -1095,6 +1096,7 @@
         // Delete photos that are pending deletion
         performDeletion();
         mCurrentModule.pause();
+        mSettingsManager.removeOnSettingChangedListener();
         mOrientationManager.pause();
         // Close the camera and wait for the operation done.
         mCameraController.closeCamera();
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 1fbd1b2..433b552 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -89,7 +89,8 @@
         MemoryListener,
         FocusOverlayManager.Listener,
         ShutterButton.OnShutterButtonListener,
-        SensorEventListener {
+        SensorEventListener,
+        SettingsManager.OnSettingChangedListener {
 
     private static final String TAG = "CAM_PhotoModule";
 
@@ -996,9 +997,15 @@
         }
         mFocusManager.setParameters(mInitialParams);
 
+        // Do camera parameter dependent initialization.
         mParameters = mCameraDevice.getParameters();
         setCameraParameters(UPDATE_PARAM_ALL);
+        // Set a listener which updates camera parameters based
+        // on changed settings.
+        SettingsManager settingsManager = mActivity.getSettingsManager();
+        settingsManager.setOnSettingChangedListener(this);
         mCameraPreviewParamsReady = true;
+
         startPreview();
 
         onCameraOpened();
@@ -1521,6 +1528,29 @@
         stopSmartCamera();
     }
 
+    @Override
+    public void onSettingChanged(int id) {
+        switch (id) {
+            case SettingsManager.SETTING_FLASH_MODE: {
+                updateParametersFlashMode();
+                break;
+            }
+            case SettingsManager.SETTING_PICTURE_SIZE: {
+                updateParametersPictureSize();
+                break;
+            }
+            case SettingsManager.SETTING_RECORD_LOCATION: {
+                SettingsController settingsController = mActivity.getSettingsController();
+                settingsController.syncLocationManager();
+                break;
+            }
+            default: {
+                // Do nothing.
+            }
+        }
+        mCameraDevice.setParameters(mParameters);
+    }
+
     private void updateCameraParametersInitialize() {
         // Reset preview frame rate to the maximum because it may be lowered by
         // video camera application.
@@ -1587,6 +1617,28 @@
         mParameters.setFocusMode(mFocusManager.getFocusMode());
 
         // Set picture size.
+        updateParametersPictureSize();
+
+        // Set JPEG quality.
+        updateParametersPictureQuality();
+
+        // 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
+        updateParametersExposureCompensation();
+
+        // Set the scene mode: also sets flash and white balance.
+        updateParametersSceneMode();
+
+        if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
+            updateAutoFocusMoveCallback();
+        }
+    }
+
+    private void updateParametersPictureSize() {
+        SettingsManager settingsManager = mActivity.getSettingsManager();
+
         String pictureSize = settingsManager.get(SettingsManager.SETTING_PICTURE_SIZE);
         if (pictureSize == null) {
             //TODO: deprecate CameraSettings.
@@ -1624,16 +1676,17 @@
                     / (float) optimalSize.height);
         }
         Log.v(TAG, "Preview size is " + optimalSize.width + "x" + optimalSize.height);
+    }
 
-        // Set JPEG quality.
+    private void updateParametersPictureQuality() {
         int 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.
+    private void updateParametersExposureCompensation() {
+        SettingsManager settingsManager = mActivity.getSettingsManager();
 
-        // Set exposure compensation
         int value = Integer.parseInt(settingsManager.get(SettingsManager.SETTING_EXPOSURE));
         int max = mParameters.getMaxExposureCompensation();
         int min = mParameters.getMinExposureCompensation();
@@ -1642,18 +1695,12 @@
         } else {
             Log.w(TAG, "invalid exposure range: " + value);
         }
-
-        mSceneMode = settingsManager.get(SettingsManager.SETTING_SCENE_MODE);
-        updateParametersSceneMode();
-
-        if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
-            updateAutoFocusMoveCallback();
-        }
     }
 
-    public void updateParametersSceneMode() {
+    private void updateParametersSceneMode() {
         SettingsManager settingsManager = mActivity.getSettingsManager();
 
+        mSceneMode = settingsManager.get(SettingsManager.SETTING_SCENE_MODE);
         if (CameraUtil.isSupported(mSceneMode, mParameters.getSupportedSceneModes())) {
             if (!mParameters.getSceneMode().equals(mSceneMode)) {
                 mParameters.setSceneMode(mSceneMode);
@@ -1673,29 +1720,10 @@
 
         if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
             // Set flash mode.
-            String flashMode = settingsManager.get(SettingsManager.SETTING_FLASH_MODE);
-            List<String> 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);
-                }
-            }
+            updateParametersFlashMode();
 
-            // Set white balance parameter.
-            String whiteBalance = settingsManager.get(SettingsManager.SETTING_WHITE_BALANCE);
-            if (CameraUtil.isSupported(whiteBalance,
-                    mParameters.getSupportedWhiteBalance())) {
-                mParameters.setWhiteBalance(whiteBalance);
-            } else {
-                whiteBalance = mParameters.getWhiteBalance();
-                if (whiteBalance == null) {
-                    whiteBalance = Parameters.WHITE_BALANCE_AUTO;
-                }
-            }
+            // Set white balance mode.
+            updateParametersWhiteBalanceMode();
 
             // Set focus mode.
             mFocusManager.overrideFocusMode(null);
@@ -1705,6 +1733,27 @@
         }
     }
 
+    private void updateParametersFlashMode() {
+        SettingsManager settingsManager = mActivity.getSettingsManager();
+
+        String flashMode = settingsManager.get(SettingsManager.SETTING_FLASH_MODE);
+        List<String> supportedFlash = mParameters.getSupportedFlashModes();
+        if (CameraUtil.isSupported(flashMode, supportedFlash)) {
+            mParameters.setFlashMode(flashMode);
+        }
+    }
+
+    private void updateParametersWhiteBalanceMode() {
+        SettingsManager settingsManager = mActivity.getSettingsManager();
+
+        // Set white balance parameter.
+        String whiteBalance = settingsManager.get(SettingsManager.SETTING_WHITE_BALANCE);
+        if (CameraUtil.isSupported(whiteBalance,
+            mParameters.getSupportedWhiteBalance())) {
+            mParameters.setWhiteBalance(whiteBalance);
+        }
+    }
+
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
     private void updateAutoFocusMoveCallback() {
         if (mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE)) {
diff --git a/src/com/android/camera/settings/SettingsManager.java b/src/com/android/camera/settings/SettingsManager.java
index 823591f..03567c2 100644
--- a/src/com/android/camera/settings/SettingsManager.java
+++ b/src/com/android/camera/settings/SettingsManager.java
@@ -45,16 +45,14 @@
 
     private int mCameraId = -1;
 
-    public SettingsManager(Context context,
-            OnSharedPreferenceChangeListener globalListener,
-            int nCameras) {
+    public SettingsManager(Context context, int nCameras) {
         mContext = context;
 
         SettingsCache.ExtraSettings extraSettings = new SettingsHelper();
         mSettingsCache = new SettingsCache(mContext, extraSettings);
 
         mDefaultSettings = PreferenceManager.getDefaultSharedPreferences(context);
-        initGlobal(globalListener);
+        initGlobal();
 
         int cameraId = Integer.parseInt(get(SETTING_CAMERA_ID));
         if (cameraId < 0 || cameraId >= nCameras) {
@@ -65,11 +63,10 @@
     /**
      * Initialize global SharedPreferences.
      */
-    private void initGlobal(OnSharedPreferenceChangeListener listener) {
+    private void initGlobal() {
         String globalKey = mContext.getPackageName() + "_preferences_camera";
         mGlobalSettings = mContext.getSharedPreferences(
             globalKey, Context.MODE_PRIVATE);
-        mGlobalSettings.registerOnSharedPreferenceChangeListener(listener);
     }
 
     /**
@@ -80,9 +77,7 @@
         mSettingsCache.setCapabilities(mCapabilities);
 
         if (cameraId == mCameraId) {
-            if (mCameraSettings != null) {
-                mCameraSettings.registerOnSharedPreferenceChangeListener(mListener);
-            }
+            removeOnSettingChangedListener();
             return;
         }
 
@@ -97,29 +92,39 @@
         String cameraKey = mContext.getPackageName() + "_preferences_" + cameraId;
         mCameraSettings = mContext.getSharedPreferences(
             cameraKey, Context.MODE_PRIVATE);
-        mCameraSettings.registerOnSharedPreferenceChangeListener(mListener);
     }
 
     /**
      * Interface with Camera Parameters and Modules.
      */
-    public interface SettingsListener {
-        public void onSettingsChanged();
+    public interface OnSettingChangedListener {
+        /**
+         * Called every time a SharedPreference has been changed.
+         */
+        public void onSettingChanged(int setting);
     }
 
     /**
-     * Add a SettingsListener to the SettingsManager, which will execute
+     * Set a OnSettingChangedListener on the SettingsManager, which will execute
      * onSettingsChanged when camera specific SharedPreferences has been updated.
      */
-    public void addListener(final SettingsListener listener) {
+    public void setOnSettingChangedListener(final OnSettingChangedListener listener) {
         mListener =
             new OnSharedPreferenceChangeListener() {
                 @Override
                 public void onSharedPreferenceChanged(
                         SharedPreferences sharedPreferences, String key) {
-                    listener.onSettingsChanged();
+                    int settingId = mSettingsCache.getId(key);
+                    listener.onSettingChanged(settingId);
                 }
             };
+
+        if (mCameraSettings != null) {
+            mCameraSettings.registerOnSharedPreferenceChangeListener(mListener);
+        }
+        if (mGlobalSettings != null) {
+            mGlobalSettings.registerOnSharedPreferenceChangeListener(mListener);
+        }
     }
 
     /**
@@ -127,9 +132,14 @@
      *
      * This should be done in onPause if a listener has been set.
      */
-    public void removeListener() {
-        if (mCameraSettings != null && mListener != null) {
-            mCameraSettings.unregisterOnSharedPreferenceChangeListener(mListener);
+    public void removeOnSettingChangedListener() {
+        if (mListener != null) {
+            if (mCameraSettings != null) {
+                mCameraSettings.unregisterOnSharedPreferenceChangeListener(mListener);
+            }
+            if (mGlobalSettings != null) {
+                mGlobalSettings.unregisterOnSharedPreferenceChangeListener(mListener);
+            }
             mListener = null;
         }
     }