--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <size
+ android:width="@dimen/option_button_circle_size"
+ android:height="@dimen/option_button_circle_size" />
+ <solid
+ android:color="@color/camera_mode_color" />
+</shape>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:constantSize="true">
+ <item android:state_enabled="false">
+ <bitmap
+ android:gravity="center"
+ android:src="@drawable/ic_exposure_disabled" />
+ </item>
+ <item android:state_pressed="true">
+ <layer-list>
+ <item android:drawable="@drawable/button_background_pressed_dark" />
+ <item>
+ <bitmap
+ android:gravity="center"
+ android:src="@drawable/ic_exposure_normal" />
+ </item>
+ </layer-list>
+ </item>
+ <item>
+ <bitmap
+ android:gravity="center"
+ android:src="@drawable/ic_exposure_normal" />
+ </item>
+</selector>
android:background="@drawable/bg_options_indicator"
android:layout_gravity="top|right" >
<ImageView
+ android:id="@+id/exposure_n2_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_n2_indicator" />
+ <ImageView
+ android:id="@+id/exposure_n1_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_n1_indicator" />
+ <ImageView
+ android:id="@+id/exposure_p1_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_p1_indicator" />
+ <ImageView
+ android:id="@+id/exposure_p2_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_p2_indicator" />
+ <ImageView
android:id="@+id/pano_indicator"
style="@style/IndicatorIcon" />
<ImageView
android:layout_gravity="right"
android:visibility="invisible"
android:background="#00000000" >
- <com.android.camera.ui.TopRightWeightedLayout
- android:id="@+id/mode_options_buttons"
+ <FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center"
- android:layout_gravity="top"
- android:visibility="visible"
- android:background="@null"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:alpha="0.0" >
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/camera_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/camera_id_icons"
- camera:contentDescriptionIds="@array/camera_id_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/flash_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/camera_flashmode_icons"
- camera:contentDescriptionIds="@array/camera_flash_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/hdr_plus_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/pref_camera_hdr_plus_icons"
- camera:contentDescriptionIds="@array/hdr_plus_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/grid_lines_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/grid_lines_icons"
- camera:contentDescriptionIds="@array/grid_lines_descriptions" />
- <!-- pano image ids and descriptions are added at runtime -->
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/pano_orientation_toggle_button"
- style="@style/ModeOption" />
- </com.android.camera.ui.TopRightWeightedLayout>
+ android:layout_height="match_parent" >
+
+ <com.android.camera.ui.TopRightWeightedLayout
+ android:id="@+id/mode_options_exposure"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:layout_gravity="right"
+ android:background="@null"
+ android:visibility="invisible" >
+
+ <ImageButton
+ android:id="@+id/exposure_n2"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_n2" />
+ <ImageButton
+ android:id="@+id/exposure_n1"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_n1" />
+ <ImageButton
+ android:id="@+id/exposure_0"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_0" />
+ <ImageButton
+ android:id="@+id/exposure_p1"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_p1" />
+ <ImageButton
+ android:id="@+id/exposure_p2"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_p2" />
+ </com.android.camera.ui.TopRightWeightedLayout>
+
+ <com.android.camera.ui.TopRightWeightedLayout
+ android:id="@+id/mode_options_buttons"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:layout_gravity="top"
+ android:visibility="visible"
+ android:background="@null"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:alpha="0.0" >
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/camera_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/camera_id_icons"
+ camera:contentDescriptionIds="@array/camera_id_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/flash_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/camera_flashmode_icons"
+ camera:contentDescriptionIds="@array/camera_flash_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/hdr_plus_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/pref_camera_hdr_plus_icons"
+ camera:contentDescriptionIds="@array/hdr_plus_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/grid_lines_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/grid_lines_icons"
+ camera:contentDescriptionIds="@array/grid_lines_descriptions" />
+ <!-- pano image ids and descriptions are added at runtime -->
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/pano_orientation_toggle_button"
+ style="@style/ModeOption" />
+ <ImageButton
+ android:id="@+id/exposure_button"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure" />
+ </com.android.camera.ui.TopRightWeightedLayout>
+ </FrameLayout>
</com.android.camera.widget.ModeOptions>
<include layout="@layout/indicators" />
android:background="@drawable/bg_options_indicator"
android:layout_gravity="bottom|right" >
<ImageView
+ android:id="@+id/exposure_n2_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_n2_indicator" />
+ <ImageView
+ android:id="@+id/exposure_n1_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_n1_indicator" />
+ <ImageView
+ android:id="@+id/exposure_p1_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_p1_indicator" />
+ <ImageView
+ android:id="@+id/exposure_p2_indicator"
+ style="@style/IndicatorIcon"
+ android:src="@drawable/ic_exposure_p2_indicator" />
+ <ImageView
android:id="@+id/pano_indicator"
style="@style/IndicatorIcon" />
<ImageView
android:layout_gravity="bottom"
android:visibility="invisible"
android:background="#00000000" >
- <com.android.camera.ui.TopRightWeightedLayout
- android:id="@+id/mode_options_buttons"
+ <FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:gravity="center"
- android:layout_gravity="right"
- android:visibility="visible"
- android:background="@null"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:alpha="0.0" >
- <!-- pano image ids and descriptions are added at runtime -->
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/pano_orientation_toggle_button"
- style="@style/ModeOption" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/grid_lines_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/grid_lines_icons"
- camera:contentDescriptionIds="@array/grid_lines_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/hdr_plus_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/pref_camera_hdr_plus_icons"
- camera:contentDescriptionIds="@array/hdr_plus_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/flash_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/camera_flashmode_icons"
- camera:contentDescriptionIds="@array/camera_flash_descriptions" />
- <com.android.camera.MultiToggleImageButton
- android:id="@+id/camera_toggle_button"
- style="@style/ModeOption"
- camera:imageIds="@array/camera_id_icons"
- camera:contentDescriptionIds="@array/camera_id_descriptions" />
- </com.android.camera.ui.TopRightWeightedLayout>
+ android:layout_height="match_parent" >
+
+ <com.android.camera.ui.TopRightWeightedLayout
+ android:id="@+id/mode_options_exposure"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:layout_gravity="right"
+ android:background="@null"
+ android:visibility="invisible" >
+
+ <ImageButton
+ android:id="@+id/exposure_n2"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_n2" />
+ <ImageButton
+ android:id="@+id/exposure_n1"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_n1" />
+ <ImageButton
+ android:id="@+id/exposure_0"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_0" />
+ <ImageButton
+ android:id="@+id/exposure_p1"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_p1" />
+ <ImageButton
+ android:id="@+id/exposure_p2"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure_p2" />
+ </com.android.camera.ui.TopRightWeightedLayout>
+
+ <com.android.camera.ui.TopRightWeightedLayout
+ android:id="@+id/mode_options_buttons"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:layout_gravity="right"
+ android:visibility="visible"
+ android:background="@null"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:alpha="0.0" >
+ <ImageButton
+ android:id="@+id/exposure_button"
+ style="@style/ModeOption"
+ android:background="@null"
+ android:src="@drawable/ic_exposure" />
+ <!-- pano image ids and descriptions are added at runtime -->
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/pano_orientation_toggle_button"
+ style="@style/ModeOption" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/grid_lines_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/grid_lines_icons"
+ camera:contentDescriptionIds="@array/grid_lines_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/hdr_plus_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/pref_camera_hdr_plus_icons"
+ camera:contentDescriptionIds="@array/hdr_plus_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/flash_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/camera_flashmode_icons"
+ camera:contentDescriptionIds="@array/camera_flash_descriptions" />
+ <com.android.camera.MultiToggleImageButton
+ android:id="@+id/camera_toggle_button"
+ style="@style/ModeOption"
+ camera:imageIds="@array/camera_id_icons"
+ camera:contentDescriptionIds="@array/camera_id_descriptions" />
+ </com.android.camera.ui.TopRightWeightedLayout>
+ </FrameLayout>
</com.android.camera.widget.ModeOptions>
<include layout="@layout/indicators" />
</com.android.camera.widget.ModeOptionsOverlay>
-
<string name="pref_video_quality_entry_low">Low</string>
<!-- Video quality setting entry. Videos will be recorded in the highest quality available on the device. [CHAR LIMIT=24] -->
<string name="pref_video_quality_entry_high">High</string>
- <!-- Video quality setting entry. Videos will be recorded in quarter CIF quality. [CHAR LIMIT=24] -->
+ <!-- Video quality setting entry. Videos will be recorded in quarter CIF quality. [CHAR LIMIT=24] -->
<string name="pref_video_quality_entry_qcif" translatable="false">QCIF</string>
- <!-- Video quality setting entry. Videos will be recorded in CIF quality. [CHAR LIMIT=24] -->
+ <!-- Video quality setting entry. Videos will be recorded in CIF quality. [CHAR LIMIT=24] -->
<string name="pref_video_quality_entry_cif" translatable="false">CIF</string>
<!-- Video quality setting entry. Videos will be recorded in 480p quality. [CHAR LIMIT=24] -->
<string name="pref_video_quality_entry_480p" translatable="false">SD 480p</string>
<!-- Text shown above the button that opens to editor for images created from lens blur mode. [CHAR LIMIT=60] -->
<string name="cling_text_for_refocus_editor_button">Click here to edit the lens blur image.</string>
+
+ <!-- Title of a preference group for advanced preferences. [CHAR LIMIT=30] -->
+ <string name="pref_category_advanced">Advanced</string>
+ <!-- Title of a preference for enabling manual exposure compensation. [CHAR LIMIT=30] -->
+ <string name="pref_camera_exposure_compensation">Enable manual exposure compensation</string>
</resources>
android:defaultValue="false"
android:key="pref_camera_recordlocation_key"
android:title="@string/pref_camera_save_location_title" />
+
+ <!-- Exposure Compensation -->
+ <PreferenceScreen
+ android:key="pref_category_advanced"
+ android:title="@string/pref_category_advanced" >
+
+ <SwitchPreference
+ android:defaultValue="false"
+ android:key="pref_camera_exposure_compensation_key"
+ android:title="@string/pref_camera_exposure_compensation" />
+ </PreferenceScreen>
+
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_about" >
package com.android.camera;
import android.content.Context;
+import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageButton;
import com.android.camera.app.AppController;
-import com.android.camera.module.ModuleController;
+import com.android.camera.app.CameraAppUI;
import com.android.camera.settings.SettingsManager;
import com.android.camera.util.PhotoSphereHelper;
public static final int BUTTON_REVIEW = 9;
public static final int BUTTON_PANO_ORIENTATION = 10;
public static final int BUTTON_GRID_LINES = 11;
+ public static final int BUTTON_EXPOSURE_COMPENSATION = 12;
/** For two state MultiToggleImageButtons, the off index. */
public static final int OFF = 0;
private ImageButton mButtonDone;
private ImageButton mButtonRetake; // same as review.
+ private ImageButton mButtonExposureCompensation;
+ private ImageButton mExposureN2;
+ private ImageButton mExposureN1;
+ private ImageButton mExposure0;
+ private ImageButton mExposureP1;
+ private ImageButton mExposureP2;
+
/** A listener for button enabled and visibility
state changes. */
private ButtonStatusListener mListener;
= (ImageButton) root.findViewById(R.id.done_button);
mButtonRetake
= (ImageButton) root.findViewById(R.id.retake_button);
+
+ mButtonExposureCompensation =
+ (ImageButton) root.findViewById(R.id.exposure_button);
+ mExposureN2 = (ImageButton) root.findViewById(R.id.exposure_n2);
+ mExposureN1 = (ImageButton) root.findViewById(R.id.exposure_n1);
+ mExposure0 = (ImageButton) root.findViewById(R.id.exposure_0);
+ mExposureP1 = (ImageButton) root.findViewById(R.id.exposure_p1);
+ mExposureP2 = (ImageButton) root.findViewById(R.id.exposure_p2);
}
@Override
button = getButtonOrError(BUTTON_PANO_ORIENTATION);
break;
}
+ case SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE: {
+ updateExposureButtons();
+ break;
+ }
default: {
// Do nothing.
}
throw new IllegalStateException("Review button could not be found.");
}
return mButtonRetake;
+ case BUTTON_EXPOSURE_COMPENSATION:
+ if (mButtonExposureCompensation == null) {
+ throw new IllegalStateException("Exposure Compensation button could not be found.");
+ }
+ return mButtonExposureCompensation;
default:
throw new IllegalArgumentException("button not known by id=" + buttonId);
}
*/
public void initializePushButton(int buttonId, View.OnClickListener cb) {
ImageButton button = getImageButtonOrError(buttonId);
- button.setOnClickListener(cb);
+ if (cb != null) {
+ button.setOnClickListener(cb);
+ }
if (!button.isEnabled()) {
button.setEnabled(true);
}
}
+ public void setExposureCompensationCallback(final CameraAppUI.BottomBarUISpec
+ .ExposureCompensationSetCallback cb) {
+ if (cb == null) {
+ mExposureN2.setOnClickListener(null);
+ mExposureN1.setOnClickListener(null);
+ mExposure0.setOnClickListener(null);
+ mExposureP1.setOnClickListener(null);
+ mExposureP2.setOnClickListener(null);
+ } else {
+ View.OnClickListener onClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int comp = 0;
+ switch(v.getId()) {
+ case R.id.exposure_n2:
+ comp = -2;
+ break;
+ case R.id.exposure_n1:
+ comp = -1;
+ break;
+ case R.id.exposure_0:
+ comp = 0;
+ break;
+ case R.id.exposure_p1:
+ comp = 1;
+ break;
+ case R.id.exposure_p2:
+ comp = 2;
+ }
+ // Each integer compensation represent 1/6 of a stop.
+ cb.setExposure(comp * 6);
+ }
+ };
+
+ mExposureN2.setOnClickListener(onClickListener);
+ mExposureN1.setOnClickListener(onClickListener);
+ mExposure0.setOnClickListener(onClickListener);
+ mExposureP1.setOnClickListener(onClickListener);
+ mExposureP2.setOnClickListener(onClickListener);
+ }
+ }
+
/**
* Check if a button is enabled with the given button id..
*/
}
}
+ /**
+ * Update the visual state of the manual exposure buttons
+ */
+ public void updateExposureButtons() {
+ String compString = mSettingsManager.get(SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE);
+ int comp = Integer.parseInt(compString);
+
+ // Reset all button states.
+ mExposureN2.setBackground(null);
+ mExposureN1.setBackground(null);
+ mExposure0.setBackground(null);
+ mExposureP1.setBackground(null);
+ mExposureP2.setBackground(null);
+
+ // Highlight the appropriate button.
+ Context context = mAppController.getAndroidContext();
+ Drawable background = context.getResources()
+ .getDrawable(R.drawable.button_background_selected_photo);
+
+ // Each integer compensation represent 1/6 of a stop.
+ switch (comp / 6) {
+ case -2:
+ mExposureN2.setBackground(background);
+ break;
+ case -1:
+ mExposureN1.setBackground(background);
+ break;
+ case 0:
+ mExposure0.setBackground(background);
+ break;
+ case 1:
+ mExposureP1.setBackground(background);
+ break;
+ case 2:
+ mExposureP2.setBackground(background);
+ }
+ }
/**
* Initialize a grid lines button.
import android.graphics.SurfaceTexture;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.hardware.Camera;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateBeamUrisCallback;
SettingsCapabilities capabilities =
SettingsUtil.getSettingsCapabilities(camera);
mSettingsManager.changeCamera(camera.getCameraId(), capabilities);
+ resetExposureCompensationToDefault(camera);
mCurrentModule.onCameraAvailable(camera);
}
mCameraAppUI.onChangeCamera();
}
+ private void resetExposureCompensationToDefault(CameraManager.CameraProxy camera) {
+ // Reset the exposure compensation before handing the camera to module.
+ Camera.Parameters parameters = camera.getParameters();
+ parameters.setExposureCompensation(0);
+ camera.setParameters(parameters);
+ }
+
@Override
public void onCameraDisabled(int cameraId) {
UsageStatistics.instance().cameraFailure(
bottomBarSpec.enableHdr = true;
bottomBarSpec.hdrCallback = mHdrPlusCallback;
bottomBarSpec.enableGridLines = true;
+ bottomBarSpec.enableExposureCompensation = true;
+ bottomBarSpec.exposureCompensationSetCallback =
+ new CameraAppUI.BottomBarUISpec.ExposureCompensationSetCallback() {
+ @Override
+ public void setExposure(int value) {
+ setExposureCompensation(value);
+ }
+ };
if (isImageCaptureIntent()) {
bottomBarSpec.showCancel = true;
Log.e(TAG, "Settings manager is null!");
return;
}
- settingsManager.setDefault(SettingsManager.SETTING_EXPOSURE);
+ settingsManager.setDefault(SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE);
}
// Snapshots can only be taken after this is called. It should be called
}
mCameraDevice = cameraProxy;
- resetExposureCompensation();
initializeCapabilities();
// Reset zoom value index.
public void pause() {
mPaused = true;
SessionStatsCollector.instance().sessionActive(false);
+
Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (gsensor != null) {
mSensorManager.unregisterListener(this, gsensor);
private void updateParametersExposureCompensation() {
SettingsManager settingsManager = mActivity.getSettingsManager();
-
- int value = Integer.parseInt(settingsManager.get(SettingsManager.SETTING_EXPOSURE));
- int max = mParameters.getMaxExposureCompensation();
- int min = mParameters.getMinExposureCompensation();
- if (value >= min && value <= max) {
- mParameters.setExposureCompensation(value);
+ if (settingsManager.getBoolean(SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED)) {
+ int value = Integer.parseInt(settingsManager.get(SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE));
+ int max = mParameters.getMaxExposureCompensation();
+ int min = mParameters.getMinExposureCompensation();
+ if (value >= min && value <= max) {
+ mParameters.setExposureCompensation(value);
+ } else {
+ Log.w(TAG, "invalid exposure range: " + value);
+ }
} else {
- Log.w(TAG, "invalid exposure range: " + value);
+ // If exposure compensation is not enabled, reset the exposure compensation value.
+ setExposureCompensation(0);
}
+
}
private void updateParametersSceneMode() {
}
}
+ /**
+ * Sets the exposure compensation to the given value and also updates settings.
+ *
+ * @param value exposure compensation value to be set
+ */
+ public void setExposureCompensation(int value) {
+ int max = mParameters.getMaxExposureCompensation();
+ int min = mParameters.getMinExposureCompensation();
+ if (value >= min && value <= max) {
+ mParameters.setExposureCompensation(value);
+ SettingsManager settingsManager = mActivity.getSettingsManager();
+ settingsManager.set(SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE, Integer.toString(value));
+ } else {
+ Log.w(TAG, "invalid exposure range: " + value);
+ }
+ }
+
// 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.
import com.android.camera.util.CameraUtil;
import com.android.camera.util.Gusterpolator;
import com.android.camera.util.PhotoSphereHelper;
-import com.android.camera.util.UsageStatistics;
import com.android.camera.widget.Cling;
import com.android.camera.widget.FilmstripLayout;
import com.android.camera.widget.IndicatorIconController;
import com.android.camera.widget.ModeOptionsOverlay;
import com.android.camera.widget.PeekView;
import com.android.camera2.R;
-import com.google.common.logging.eventprotos;
/**
* CameraAppUI centralizes control of views shared across modules. Whereas module
*/
public boolean enablePanoOrientation;
+ public boolean enableExposureCompensation;
+
/** Intent UI */
/**
* when the review option is pressed. This callback can be null.
*/
public View.OnClickListener reviewCallback;
+
+ /**
+ * A ExposureCompensationSetCallback that will execute
+ * when an expsosure button is pressed. This callback can be null.
+ */
+ public interface ExposureCompensationSetCallback {
+ public abstract void setExposure(int value);
+ }
+ public ExposureCompensationSetCallback exposureCompensationSetCallback;
}
buttonManager.hideButton(ButtonManager.BUTTON_PANO_ORIENTATION);
}
+ boolean enableExposureCompensation = bottomBarSpec.enableExposureCompensation &&
+ mController.getSettingsManager()
+ .getBoolean(SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED);
+ if (enableExposureCompensation) {
+ buttonManager.initializePushButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION, null);
+ buttonManager.setExposureCompensationCallback(
+ bottomBarSpec.exposureCompensationSetCallback);
+ buttonManager.updateExposureButtons();
+ } else {
+ buttonManager.hideButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION);
+ buttonManager.setExposureCompensationCallback(null);
+ }
+
/** Intent UI */
if (bottomBarSpec.showCancel) {
buttonManager.initializePushButton(ButtonManager.BUTTON_CANCEL,
public static class CameraSettingsFragment extends PreferenceFragment implements
OnSharedPreferenceChangeListener {
public static final String PREF_CATEGORY_RESOLUTION = "pref_category_resolution";
+ public static final String PREF_CATEGORY_ADVANCED = "pref_category_advanced";
private static final String BUILD_VERSION = "build_version";
private static DecimalFormat sMegaPixelFormat = new DecimalFormat("##0.0");
private FeedbackHelper mFeedbackHelper;
final PreferenceScreen resolutionScreen =
(PreferenceScreen) findPreference(PREF_CATEGORY_RESOLUTION);
fillEntriesAndSummaries(resolutionScreen);
+ configureHomeAsUp(resolutionScreen);
- // Make sure the sub-screen has home-as-up configured.
- resolutionScreen.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- setUpHomeButton(resolutionScreen);
- return false;
- }
- });
+ final PreferenceScreen advancedScreen =
+ (PreferenceScreen) findPreference(PREF_CATEGORY_ADVANCED);
+ configureHomeAsUp(advancedScreen);
// Set build number.
try {
});
}
+ /**
+ * Configure home-as-up for sub-screens.
+ */
+ private void configureHomeAsUp(final PreferenceScreen preferenceScreen) {
+ preferenceScreen.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ setUpHomeButton(preferenceScreen);
+ return false;
+ }
+ });
+ }
+
private void setUpHomeButton(PreferenceScreen preferenceScreen) {
final Dialog dialog = preferenceScreen.getDialog();
dialog.getActionBar().setDisplayHomeAsUpEnabled(true);
mKeyMap.put(SettingsManager.KEY_VIDEOCAMERA_FLASH_MODE,
SettingsManager.SETTING_VIDEOCAMERA_FLASH_MODE);
mKeyMap.put(SettingsManager.KEY_SCENE_MODE, SettingsManager.SETTING_SCENE_MODE);
- mKeyMap.put(SettingsManager.KEY_EXPOSURE, SettingsManager.SETTING_EXPOSURE);
+ mKeyMap.put(SettingsManager.KEY_EXPOSURE, SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE);
mKeyMap.put(SettingsManager.KEY_VIDEO_EFFECT, SettingsManager.SETTING_VIDEO_EFFECT);
mKeyMap.put(SettingsManager.KEY_CAMERA_ID, SettingsManager.SETTING_CAMERA_ID);
mKeyMap.put(SettingsManager.KEY_CAMERA_HDR, SettingsManager.SETTING_CAMERA_HDR);
SettingsManager.SETTING_REQUEST_RETURN_HDR_PLUS);
mKeyMap.put(SettingsManager.KEY_SHOULD_SHOW_REFOCUS_VIEWER_CLING,
SettingsManager.SETTING_SHOULD_SHOW_REFOCUS_VIEWER_CLING);
+ mKeyMap.put(SettingsManager.KEY_EXPOSURE_COMPENSATION_ENABLED,
+ SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED);
}
/**
return SettingsManager.getVideoFlashSetting(mContext);
case SettingsManager.SETTING_SCENE_MODE:
return SettingsManager.getSceneModeSetting(mContext);
- case SettingsManager.SETTING_EXPOSURE:
+ case SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE:
return SettingsManager.getExposureSetting(mContext, mCapabilities);
case SettingsManager.SETTING_VIDEO_EFFECT:
return SettingsManager.getVideoEffectSetting(mContext);
return SettingsManager.getRequestReturnHdrPlusSetting(mContext);
case SettingsManager.SETTING_SHOULD_SHOW_REFOCUS_VIEWER_CLING:
return SettingsManager.getShouldShowRefocusViewerCling(mContext);
+ case SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED:
+ return SettingsManager.getManualExposureCompensationSetting(mContext);
default:
return mExtraSettings.settingFromId(id, mContext);
}
public static final int SETTING_FLASH_MODE = 8;
public static final int SETTING_VIDEOCAMERA_FLASH_MODE = 9;
public static final int SETTING_SCENE_MODE = 11;
- public static final int SETTING_EXPOSURE = 12;
+ public static final int SETTING_EXPOSURE_COMPENSATION_VALUE = 12;
public static final int SETTING_VIDEO_EFFECT = 15;
public static final int SETTING_CAMERA_ID = 16;
public static final int SETTING_CAMERA_HDR = 17;
// that forces them to leave HDR plus.
public static final int SETTING_REQUEST_RETURN_HDR_PLUS = 30;
public static final int SETTING_SHOULD_SHOW_REFOCUS_VIEWER_CLING = 31;
+ public static final int SETTING_EXPOSURE_COMPENSATION_ENABLED = 32;
// Shared preference keys.
public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
public static final String KEY_REQUEST_RETURN_HDR_PLUS = "pref_request_return_hdr_plus";
public static final String KEY_SHOULD_SHOW_REFOCUS_VIEWER_CLING =
"pref_should_show_refocus_viewer_cling";
+ public static final String KEY_EXPOSURE_COMPENSATION_ENABLED =
+ "pref_camera_exposure_compensation_key";
+
+ public static final int WHITE_BALANCE_DEFAULT_INDEX = 2;
/**
* Defines a simple class for holding a the spec of a setting. This spec is
values, FLUSH_OFF);
}
+ public static Setting getManualExposureCompensationSetting(Context context) {
+ String defaultValue = context.getString(R.string.setting_off_value);
+ String[] values = null;
+ return new Setting(SOURCE_DEFAULT, TYPE_BOOLEAN, defaultValue,
+ KEY_EXPOSURE_COMPENSATION_ENABLED, values, FLUSH_OFF);
+ }
public static Setting getPictureSizeBackSetting(Context context) {
String defaultValue = null;
String[] values = context.getResources().getStringArray(
locationManager.recordLocation(on);
}
+ public void setManualExposureCompensation(boolean on) {
+ setBoolean(SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED, on);
+ }
+
/**
* Reads the current location recording settings and passes it on to the
* given location manager.
private ImageView mHdrIndicator;
private ImageView mPanoIndicator;
+ private ImageView mExposureIndicatorN2;
+ private ImageView mExposureIndicatorN1;
+ private ImageView mExposureIndicatorP1;
+ private ImageView mExposureIndicatorP2;
+
private TypedArray mFlashIndicatorPhotoIcons;
private TypedArray mFlashIndicatorVideoIcons;
private TypedArray mHdrPlusIndicatorIcons;
mPanoIndicatorIcons =
context.getResources().obtainTypedArray(panoIndicatorArrayId);
}
+
+ mExposureIndicatorN2 = (ImageView) root.findViewById(R.id.exposure_n2_indicator);
+ mExposureIndicatorN1 = (ImageView) root.findViewById(R.id.exposure_n1_indicator);
+ mExposureIndicatorP1 = (ImageView) root.findViewById(R.id.exposure_p1_indicator);
+ mExposureIndicatorP2 = (ImageView) root.findViewById(R.id.exposure_p2_indicator);
}
@Override
syncPanoIndicator();
break;
}
+ case ButtonManager.BUTTON_EXPOSURE_COMPENSATION: {
+ syncExposureIndicator();
+ break;
+ }
default:
// Do nothing. The indicator doesn't care
// about button that don't correspond to indicators.
syncFlashIndicator();
syncHdrIndicator();
syncPanoIndicator();
+ syncExposureIndicator();
}
/**
* on a view, change the visibility and call any registered
* {@link OnIndicatorVisibilityChangedListener}.
*/
- private void changeVisibility(View view, int visibility) {
+ private static void changeVisibility(View view, int visibility) {
if (view.getVisibility() != visibility) {
view.setVisibility(visibility);
}
}
}
+ private void syncExposureIndicator() {
+ if (mExposureIndicatorN2 == null
+ || mExposureIndicatorN1 == null
+ || mExposureIndicatorP1 == null
+ || mExposureIndicatorP2 == null) {
+ Log.w(TAG, "Trying to sync exposure indicators that are not initialized.");
+ return;
+ }
+
+
+ // Reset all exposure indicator icons.
+ changeVisibility(mExposureIndicatorN2, View.GONE);
+ changeVisibility(mExposureIndicatorN1, View.GONE);
+ changeVisibility(mExposureIndicatorP1, View.GONE);
+ changeVisibility(mExposureIndicatorP2, View.GONE);
+
+ ButtonManager buttonManager = mController.getButtonManager();
+ if (buttonManager.isEnabled(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)
+ && buttonManager.isVisible(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)) {
+
+ String compString = mController.getSettingsManager().get(
+ SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE);
+ int comp = Integer.parseInt(compString);
+ // Turn on the appropriate indicator.
+ // Each integer compensation represent 1/6 of a stop.
+ switch (comp / 6) {
+ case -2:
+ changeVisibility(mExposureIndicatorN2, View.VISIBLE);
+ break;
+ case -1:
+ changeVisibility(mExposureIndicatorN1, View.VISIBLE);
+ break;
+ case 0:
+ // Do nothing.
+ break;
+ case 1:
+ changeVisibility(mExposureIndicatorP1, View.VISIBLE);
+ break;
+ case 2:
+ changeVisibility(mExposureIndicatorP2, View.VISIBLE);
+ }
+ }
+ }
+
/**
* Sets the image resource and visibility of the indicator
* based on the indicator's corresponding setting state.
syncPanoIndicator();
break;
}
+ case SettingsManager.SETTING_EXPOSURE_COMPENSATION_ENABLED:
+ // Fall through to the next case.
+ case SettingsManager.SETTING_EXPOSURE_COMPENSATION_VALUE: {
+ syncExposureIndicator();
+ break;
+ }
default: {
// Do nothing.
}
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.util.AttributeSet;
private RectF mAnimateFrom = new RectF();
private View mViewToShowHide;
private TopRightWeightedLayout mModeOptionsButtons;
+ private TopRightWeightedLayout mModeOptionsExposure;
private AnimatorSet mVisibleAnimator;
private AnimatorSet mHiddenAnimator;
mPaint.setAntiAlias(true);
mPaint.setColor(mBackgroundColor);
mModeOptionsButtons = (TopRightWeightedLayout) findViewById(R.id.mode_options_buttons);
+
+ mModeOptionsExposure = (TopRightWeightedLayout) findViewById(R.id.mode_options_exposure);
+ ImageButton exposureButton = (ImageButton) findViewById(R.id.exposure_button);
+ exposureButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mModeOptionsButtons.setVisibility(View.INVISIBLE);
+ mModeOptionsExposure.setVisibility(View.VISIBLE);
+ }
+ });
}
@Override
mModeOptionsButtons.setLayoutParams(params);
}
+ @Override
+ public void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ if (visibility != VISIBLE && !mIsHiddenOrHiding) {
+ // Collapse mode options when window is not visible.
+ setVisibility(INVISIBLE);
+ if (mModeOptionsButtons != null) {
+ mModeOptionsButtons.setVisibility(VISIBLE);
+ mModeOptionsExposure.setVisibility(INVISIBLE);
+ }
+ if (mViewToShowHide != null) {
+ mViewToShowHide.setVisibility(VISIBLE);
+ }
+ mIsHiddenOrHiding = true;
+ }
+ }
+
@Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mModeOptionsButtons.setAlpha((Float) animation.getAnimatedValue());
+ mModeOptionsExposure.setAlpha((Float) animation.getAnimatedValue());
invalidate();
}
});
alphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mModeOptionsButtons.setAlpha(0.0f);
setVisibility(View.INVISIBLE);
+ mModeOptionsButtons.setAlpha(1.0f);
+ mModeOptionsButtons.setVisibility(View.VISIBLE);
+ mModeOptionsExposure.setVisibility(View.INVISIBLE);
+ mModeOptionsExposure.setAlpha(1.0f);
invalidate();
}
});