diff options
7 files changed, 158 insertions, 24 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 04398017d..280ff4a0f 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -315,6 +315,13 @@ public class CaptureModule extends CameraModule String action = activity.getIntent().getAction(); mIsImageCaptureIntent = (MediaStore.ACTION_IMAGE_CAPTURE.equals(action) || CameraActivity.ACTION_IMAGE_CAPTURE_SECURE.equals(action)); + View cancelButton = activity.findViewById(R.id.shutter_cancel_button); + cancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + cancelCountDown(); + } + }); } @Override @@ -393,12 +400,21 @@ public class CaptureModule extends CameraModule } } + private void cancelCountDown() { + if (mUI.isCountingDown()) { + // Cancel on-going countdown. + mUI.cancelCountDown(); + } + mAppController.getCameraAppUI().showModeOptions(); + mAppController.getCameraAppUI().transitionToCapture(); + } + @Override public void onPreviewAreaChanged(RectF previewArea) { mPreviewArea = previewArea; mUI.onPreviewAreaChanged(previewArea); // mUI.updatePreviewAreaRect(previewArea); - // mUI.positionProgressOverlay(previewArea); + mUI.positionProgressOverlay(previewArea); } @Override @@ -545,9 +561,11 @@ public class CaptureModule extends CameraModule @Override public void pause() { mPaused = true; + cancelCountDown(); resetTextureBufferSize(); closeCamera(); - mCountdownSoundPlayer.release(); + mCountdownSoundPlayer.unloadSound(R.raw.beep_once); + mCountdownSoundPlayer.unloadSound(R.raw.beep_twice); // Remove delayed resume trigger, if it hasn't been executed yet. mMainHandler.removeCallbacksAndMessages(null); @@ -562,6 +580,7 @@ public class CaptureModule extends CameraModule @Override public void destroy() { + mCountdownSoundPlayer.release(); } @Override @@ -648,7 +667,9 @@ public class CaptureModule extends CameraModule switch (keyCode) { case KeyEvent.KEYCODE_CAMERA: case KeyEvent.KEYCODE_DPAD_CENTER: - if (event.getRepeatCount() == 0) { + if (mUI.isCountingDown()) { + cancelCountDown(); + } else if (event.getRepeatCount() == 0) { onShutterButtonClick(); } return true; diff --git a/src/com/android/camera/one/v2/OneCameraZslImpl.java b/src/com/android/camera/one/v2/OneCameraZslImpl.java index 7a4da7461..4d5fdef39 100644 --- a/src/com/android/camera/one/v2/OneCameraZslImpl.java +++ b/src/com/android/camera/one/v2/OneCameraZslImpl.java @@ -183,12 +183,15 @@ public class OneCameraZslImpl extends AbstractOneCamera { private MeteringRectangle[] mAERegions = ZERO_WEIGHT_3A_REGION; /** - * Ready state depends on two things:<br> + * Ready state (typically displayed by the UI shutter-button) depends on two + * things:<br> * <ol> * <li>{@link #mCaptureManager} must be ready.</li> * <li>We must not be in the process of capturing a single, high-quality, * image.</li> * </ol> + * See {@link ConjunctionListenerMux} and {@link #mReadyStateManager} for + * details of how this is managed. */ private static enum ReadyStateRequirement { CAPTURE_MANAGER_READY, @@ -201,7 +204,12 @@ public class OneCameraZslImpl extends AbstractOneCamera { */ private final ConjunctionListenerMux<ReadyStateRequirement> mReadyStateManager = new ConjunctionListenerMux<ReadyStateRequirement>( - ReadyStateRequirement.class); + ReadyStateRequirement.class, new ConjunctionListenerMux.OutputChangeListener() { + @Override + public void onOutputChange(boolean state) { + broadcastReadyState(state); + } + }); /** * An {@link ImageCaptureListener} which will compress and save an image to @@ -286,13 +294,6 @@ public class OneCameraZslImpl extends AbstractOneCamera { } }); - mReadyStateManager.addListener(new ConjunctionListenerMux.OutputChangeListener() { - @Override - public void onOutputChange(boolean state) { - broadcastReadyState(state); - } - }); - // Listen for changes to auto focus state and dispatch to // mFocusStateListener. mCaptureManager.addMetadataChangeListener(CaptureResult.CONTROL_AF_STATE, @@ -308,6 +309,11 @@ public class OneCameraZslImpl extends AbstractOneCamera { // Allocate the image reader to store all images received from the // camera. + if (pictureSize == null) { + // TODO The default should be selected by the caller, and + // pictureSize should never be null. + pictureSize = getDefaultPictureSize(); + } mCaptureImageReader = ImageReader.newInstance(pictureSize.getWidth(), pictureSize.getHeight(), sCaptureImageFormat, MAX_CAPTURE_IMAGES); @@ -316,6 +322,30 @@ public class OneCameraZslImpl extends AbstractOneCamera { } /** + * @return The largest supported picture size. + */ + public Size getDefaultPictureSize() { + StreamConfigurationMap configs = mCharacteristics.get( + CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); + android.util.Size[] supportedSizes = configs.getOutputSizes(sCaptureImageFormat); + + // Find the largest supported size. + android.util.Size largestSupportedSize = supportedSizes[0]; + long largestSupportedSizePixels = largestSupportedSize.getWidth() + * largestSupportedSize.getHeight(); + for (int i = 0; i < supportedSizes.length; i++) { + long numPixels = supportedSizes[i].getWidth() * supportedSizes[i].getHeight(); + if (numPixels > largestSupportedSizePixels) { + largestSupportedSize = supportedSizes[i]; + largestSupportedSizePixels = numPixels; + } + } + + return new Size(largestSupportedSize.getWidth(), + largestSupportedSize.getHeight()); + } + + /** * Take a picture. */ @Override @@ -615,6 +645,9 @@ public class OneCameraZslImpl extends AbstractOneCamera { mCropRegion = cropRegionForZoom(mZoomValue); boolean success = sendRepeatingCaptureRequest(); if (success) { + mReadyStateManager.setInput(ReadyStateRequirement.CAPTURE_NOT_IN_PROGRESS, + true); + mReadyStateManager.notifyListeners(); listener.onReadyForCapture(); } else { listener.onSetupFailed(); @@ -935,7 +968,7 @@ public class OneCameraZslImpl extends AbstractOneCamera { // Waits Settings3A.getFocusHoldMillis() milliseconds before sending // a request for a regular preview stream to resume. mCameraHandler.postAtTime(new Runnable() { - @Override + @Override public void run() { mAERegions = ZERO_WEIGHT_3A_REGION; mAFRegions = ZERO_WEIGHT_3A_REGION; @@ -963,6 +996,11 @@ public class OneCameraZslImpl extends AbstractOneCamera { @Override public Size pickPreviewSize(Size pictureSize, Context context) { + if (pictureSize == null) { + // TODO The default should be selected by the caller, and + // pictureSize should never be null. + pictureSize = getDefaultPictureSize(); + } float pictureAspectRatio = pictureSize.getWidth() / (float) pictureSize.getHeight(); return CaptureModuleUtil.getOptimalPreviewSize(context, getSupportedSizes(), pictureAspectRatio); diff --git a/src/com/android/camera/settings/AppUpgrader.java b/src/com/android/camera/settings/AppUpgrader.java index a4cc0bb61..8e4d1db2e 100644 --- a/src/com/android/camera/settings/AppUpgrader.java +++ b/src/com/android/camera/settings/AppUpgrader.java @@ -117,14 +117,17 @@ public class AppUpgrader extends SettingsUpgrader { SettingsUtil.CAMERA_FACING_FRONT); upgradeCameraSizeSetting(settingsManager, context, infos, SettingsUtil.CAMERA_FACING_BACK); + // We changed size handling and aspect ratio placement, put user + // back into Camera mode this time to ensure they see the ratio + // chooser if applicable. + settingsManager.remove(SettingsManager.SCOPE_GLOBAL, + Keys.KEY_STARTUP_MODULE_INDEX); } if (lastVersion < CAMERA_MODULE_SETTINGS_FILES_RENAMED_VERSION) { upgradeCameraSettingsFiles(settingsManager, context); upgradeModuleSettingsFiles(settingsManager, context, mAppController); - settingsManager.remove(SettingsManager.SCOPE_GLOBAL, - Keys.KEY_STARTUP_MODULE_INDEX); } if (lastVersion < CAMERA_SETTINGS_SELECTED_MODULE_INDEX) { @@ -229,6 +232,31 @@ public class AppUpgrader extends SettingsUpgrader { settingsManager.set(SettingsManager.SCOPE_GLOBAL, Keys.KEY_SHOULD_SHOW_SETTINGS_BUTTON_CLING, shouldShowSettingsButtonCling); } + + // HDR plus on setting: String on/off -> String, from old global. + if (oldGlobalPreferences.contains(Keys.KEY_CAMERA_HDR_PLUS)) { + String hdrPlus = removeString(oldGlobalPreferences, Keys.KEY_CAMERA_HDR_PLUS); + if (OLD_SETTINGS_VALUE_ON.equals(hdrPlus)) { + settingsManager.set(SettingsManager.SCOPE_GLOBAL, Keys.KEY_CAMERA_HDR_PLUS, true); + } + } + + // HDR on setting: String on/off -> String, from old global. + if (oldGlobalPreferences.contains(Keys.KEY_CAMERA_HDR)) { + String hdrPlus = removeString(oldGlobalPreferences, Keys.KEY_CAMERA_HDR); + if (OLD_SETTINGS_VALUE_ON.equals(hdrPlus)) { + settingsManager.set(SettingsManager.SCOPE_GLOBAL, Keys.KEY_CAMERA_HDR, true); + } + } + + // Grid on setting: String on/off -> String, from old global. + if (oldGlobalPreferences.contains(Keys.KEY_CAMERA_GRID_LINES)) { + String hdrPlus = removeString(oldGlobalPreferences, Keys.KEY_CAMERA_GRID_LINES); + if (OLD_SETTINGS_VALUE_ON.equals(hdrPlus)) { + settingsManager.set(SettingsManager.SCOPE_GLOBAL, Keys.KEY_CAMERA_GRID_LINES, + true); + } + } } /** @@ -236,7 +264,9 @@ public class AppUpgrader extends SettingsUpgrader { * again if it was originally set to false. */ private void forceLocationChoice(SettingsManager settingsManager) { - // Show the location dialog on upgrade if + SharedPreferences oldGlobalPreferences = + settingsManager.openPreferences(OLD_GLOBAL_PREFERENCES_FILENAME); + // Show the location dialog on upgrade if // (a) the user has never set this option (status quo). // (b) the user opt'ed out previously. if (settingsManager.isSet(SettingsManager.SCOPE_GLOBAL, @@ -247,6 +277,14 @@ public class AppUpgrader extends SettingsUpgrader { Keys.KEY_RECORD_LOCATION)) { settingsManager.remove(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION); } + } else if (oldGlobalPreferences.contains(Keys.KEY_RECORD_LOCATION)) { + // Location is not set, check to see if we're upgrading from + // a different source file. + String location = removeString(oldGlobalPreferences, Keys.KEY_RECORD_LOCATION); + if (OLD_SETTINGS_VALUE_ON.equals(location)) { + settingsManager.set(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION, + true); + } } } diff --git a/src/com/android/camera/settings/SettingsManager.java b/src/com/android/camera/settings/SettingsManager.java index 7141b67ea..2418882d6 100644 --- a/src/com/android/camera/settings/SettingsManager.java +++ b/src/com/android/camera/settings/SettingsManager.java @@ -116,7 +116,7 @@ public class SettingsManager { */ protected SharedPreferences openPreferences(String scope) { SharedPreferences preferences = mContext.getSharedPreferences( - scope, Context.MODE_PRIVATE); + mPackageName + scope, Context.MODE_PRIVATE); for (OnSharedPreferenceChangeListener listener : mSharedPreferenceListeners) { preferences.registerOnSharedPreferenceChangeListener(listener); diff --git a/src/com/android/camera/settings/SettingsUpgrader.java b/src/com/android/camera/settings/SettingsUpgrader.java index 2b8b92465..96797ace6 100644 --- a/src/com/android/camera/settings/SettingsUpgrader.java +++ b/src/com/android/camera/settings/SettingsUpgrader.java @@ -30,6 +30,15 @@ public abstract class SettingsUpgrader { private final String mVersionKey; private final int mTargetVersion; + // These values were in use by the original preferences management, before + // SettingsManager, to represent string-based booleans via typed string + // resource arrays. We no longer utilize such value arrays, and reference + // these constants only within SettingsUpgraders to convert to new string- + // based booleans. + protected static final String OLD_SETTINGS_VALUE_NONE = "none"; + protected static final String OLD_SETTINGS_VALUE_ON = "on"; + protected static final String OLD_SETTINGS_VALUE_OFF = "off"; + public SettingsUpgrader(String versionKey, int targetVersion) { mVersionKey = versionKey; mTargetVersion = targetVersion; @@ -98,4 +107,18 @@ public abstract class SettingsUpgrader { return value; } + /** + * A helper function that is used to remove a setting stored as a String, + * and return the value that was removed. + * <p> + * This is used in the upgrade path to change all underlying + * SharedPreferences values to Strings. It can be used by third party + * modules to upgrade their boolean settings to Strings. + */ + protected String removeString(SharedPreferences oldPreferencesLocation, String key) { + String value = oldPreferencesLocation.getString(key, null); + oldPreferencesLocation.edit().remove(key).apply(); + return value; + } + } diff --git a/src/com/android/camera/util/ConjunctionListenerMux.java b/src/com/android/camera/util/ConjunctionListenerMux.java index 866b2f5fb..a32072400 100644 --- a/src/com/android/camera/util/ConjunctionListenerMux.java +++ b/src/com/android/camera/util/ConjunctionListenerMux.java @@ -95,9 +95,7 @@ public class ConjunctionListenerMux<Input extends Enum<Input>> { // If the output has changed, notify the listeners. if (oldOutput != mOutput) { - for (OutputChangeListener listener : mListeners) { - listener.onOutputChange(mOutput); - } + notifyListeners(); } return mOutput; @@ -105,6 +103,11 @@ public class ConjunctionListenerMux<Input extends Enum<Input>> { } } + public ConjunctionListenerMux(Class<Input> clazz, OutputChangeListener listener) { + this(clazz); + addListener(listener); + } + public ConjunctionListenerMux(Class<Input> clazz) { mInputs = new EnumMap<Input, Boolean>(clazz); @@ -114,4 +117,16 @@ public class ConjunctionListenerMux<Input extends Enum<Input>> { mOutput = false; } + + /** + * Notifies all listeners of the current state, regardless of whether or not + * it has actually changed. + */ + public void notifyListeners() { + synchronized (mLock) { + for (OutputChangeListener listener : mListeners) { + listener.onOutputChange(mOutput); + } + } + } } diff --git a/src/com/android/camera/widget/IndicatorIconController.java b/src/com/android/camera/widget/IndicatorIconController.java index fa88c8851..41f1fe6d9 100644 --- a/src/com/android/camera/widget/IndicatorIconController.java +++ b/src/com/android/camera/widget/IndicatorIconController.java @@ -252,10 +252,9 @@ public class IndicatorIconController if (buttonManager.isEnabled(ButtonManager.BUTTON_EXPOSURE_COMPENSATION) && buttonManager.isVisible(ButtonManager.BUTTON_EXPOSURE_COMPENSATION)) { - String compString = mController.getSettingsManager().getString( - mController.getCameraScope(), Keys.KEY_EXPOSURE); - int comp = Math.round( - Integer.parseInt(compString) * buttonManager.getExposureCompensationStep()); + int compValue = mController.getSettingsManager().getInteger( + mController.getCameraScope(), Keys.KEY_EXPOSURE); + int comp = Math.round(compValue * buttonManager.getExposureCompensationStep()); // Turn on the appropriate indicator. switch (comp) { |