package com.android.camera.app;
-import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
+import com.android.camera.AccessibilityUtil;
import com.android.camera.AnimationManager;
import com.android.camera.ButtonManager;
import com.android.camera.CaptureLayoutHelper;
import com.android.camera.ui.CaptureAnimationOverlay;
import com.android.camera.ui.GridLines;
import com.android.camera.ui.MainActivityLayout;
-import com.android.camera.ui.MarginDrawable;
import com.android.camera.ui.ModeListView;
import com.android.camera.ui.ModeTransitionView;
import com.android.camera.ui.PreviewOverlay;
import com.android.camera.widget.RoundedThumbnailView;
import com.android.camera2.R;
-import java.util.List;
-
/**
* CameraAppUI centralizes control of views shared across modules. Whereas module
* specific views will be handled in each Module UI. For example, we can now
*/
public boolean enablePanoOrientation;
+ /**
+ * Set true if manual exposure compensation should be visible.
+ *
+ * This option is not constrained by hardware limitations.
+ * For example, this is false in HDR+ mode.
+ */
public boolean enableExposureCompensation;
+ /**
+ * Set true if the device and module support exposure compensation.
+ * Used only to show exposure button in disabled (greyed out) state.
+ */
+ public boolean isExposureCompensationSupported;
+
/** Intent UI */
/**
private View mModeOptionsToggle;
private final RoundedThumbnailView mRoundedThumbnailView;
private final CaptureLayoutHelper mCaptureLayoutHelper;
- private boolean mAccessibilityEnabled;
private final View mAccessibilityAffordances;
+ private AccessibilityUtil mAccessibilityUtil;
private boolean mDisableAllUserInteractions;
/** Whether to prevent capture indicator from being triggered. */
// Show UI that is meant to only be used when spoken feedback is
// enabled.
- mAccessibilityEnabled = isSpokenFeedbackAccessibilityEnabled();
mAccessibilityAffordances.setVisibility(
- (!mIsCaptureIntent && mAccessibilityEnabled) ? View.VISIBLE : View.GONE);
- }
-
- /**
- * @return Whether any spoken feedback accessibility feature is currently
- * enabled.
- */
- private boolean isSpokenFeedbackAccessibilityEnabled() {
- AccessibilityManager accessibilityManager = AndroidServices.instance()
- .provideAccessibilityManager();
- List<AccessibilityServiceInfo> infos = accessibilityManager
- .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
- return infos != null && !infos.isEmpty();
+ (!mIsCaptureIntent && mAccessibilityUtil.isAccessibilityEnabled()) ? View.VISIBLE
+ : View.GONE);
}
/**
mModeListView.onMenuPressed();
}
+ public void showAccessibilityZoomUI(float maxZoom) {
+ mAccessibilityUtil.showZoomUI(maxZoom);
+ }
+
+ public void hideAccessibilityZoomUI() {
+ mAccessibilityUtil.hideZoomUI();
+ }
+
/**
* A cover view showing the mode theme color and mode icon will be visible on
* top of preview until preview is ready (i.e. camera preview is started and
mAccessibilityAffordances.setVisibility(View.GONE);
} else {
setIndicatorBottomBarWrapperVisible(true);
- if (!mIsCaptureIntent && mAccessibilityEnabled) {
+ if (!mIsCaptureIntent && mAccessibilityUtil.isAccessibilityEnabled()) {
mAccessibilityAffordances.setVisibility(View.VISIBLE);
} else {
mAccessibilityAffordances.setVisibility(View.GONE);
@Override
public void onModeListOpenProgress(float progress) {
+ // When the mode list is in transition, ensure the large layers are
+ // hardware accelerated.
+ if (progress >= 1.0f || progress <= 0.0f) {
+ // Convert hardware layers back to default layer types when animation stops
+ // to prevent accidental artifacting.
+ if(mModeOptionsToggle.getLayerType() == View.LAYER_TYPE_HARDWARE ||
+ mShutterButton.getLayerType() == View.LAYER_TYPE_HARDWARE) {
+ Log.v(TAG, "Disabling hardware layer for the Mode Options Toggle Button.");
+ mModeOptionsToggle.setLayerType(View.LAYER_TYPE_NONE, null);
+ Log.v(TAG, "Disabling hardware layer for the Shutter Button.");
+ mShutterButton.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ } else {
+ if(mModeOptionsToggle.getLayerType() != View.LAYER_TYPE_HARDWARE ||
+ mShutterButton.getLayerType() != View.LAYER_TYPE_HARDWARE) {
+ Log.v(TAG, "Enabling hardware layer for the Mode Options Toggle Button.");
+ mModeOptionsToggle.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Log.v(TAG, "Enabling hardware layer for the Shutter Button.");
+ mShutterButton.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+ }
+
progress = 1 - progress;
float interpolatedProgress = Gusterpolator.INSTANCE.getInterpolation(progress);
mModeOptionsToggle.setAlpha(interpolatedProgress);
@Override
public void onModeListClosed() {
+ // Convert hardware layers back to default layer types when animation stops
+ // to prevent accidental artifacting.
+ if(mModeOptionsToggle.getLayerType() == View.LAYER_TYPE_HARDWARE ||
+ mShutterButton.getLayerType() == View.LAYER_TYPE_HARDWARE) {
+ Log.v(TAG, "Disabling hardware layer for the Mode Options Toggle Button.");
+ mModeOptionsToggle.setLayerType(View.LAYER_TYPE_NONE, null);
+ Log.v(TAG, "Disabling hardware layer for the Shutter Button.");
+ mShutterButton.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+
// Make sure the alpha on mode options ellipse is reset when mode drawer
// is closed.
mModeOptionsToggle.setAlpha(1f);
public void onChangeCamera() {
ModuleController moduleController = mController.getCurrentModuleController();
applyModuleSpecs(moduleController.getHardwareSpec(), moduleController.getBottomBarSpec());
+ syncModeOptionIndicators();
+ }
+ /**
+ * Updates the mode option indicators according to the current settings.
+ */
+ public void syncModeOptionIndicators() {
if (mIndicatorIconController != null) {
// Sync the settings state with the indicator state.
mIndicatorIconController.syncIndicators();
mModuleUI = (FrameLayout) mCameraRootView.findViewById(R.id.module_layout);
mTextureView = (TextureView) mCameraRootView.findViewById(R.id.preview_content);
mTextureViewHelper = new TextureViewHelper(mTextureView, mCaptureLayoutHelper,
- mController.getCameraProvider());
+ mController.getCameraProvider(), mController);
mTextureViewHelper.setSurfaceTextureListener(this);
mTextureViewHelper.setOnLayoutChangeListener(mPreviewLayoutChangeListener);
mPreviewOverlay = (PreviewOverlay) mCameraRootView.findViewById(R.id.preview_overlay);
mPreviewOverlay.setOnTouchListener(new MyTouchListener());
mPreviewOverlay.setOnPreviewTouchedListener(mModeOptionsOverlay);
+ mAccessibilityUtil = new AccessibilityUtil(mPreviewOverlay, mAccessibilityAffordances);
mCaptureOverlay = (CaptureAnimationOverlay)
mCameraRootView.findViewById(R.id.capture_overlay);
if (mSuppressCaptureIndicator || mFilmstripLayout.getVisibility() == View.VISIBLE) {
return;
}
- mRoundedThumbnailView.setThumbnail(thumbnailBitmap);
- mRoundedThumbnailView.setRotation(rotation);
+ mRoundedThumbnailView.setThumbnail(thumbnailBitmap, rotation);
}
/**
applyModuleSpecs(moduleController.getHardwareSpec(),
moduleController.getBottomBarSpec());
mBottomBar.transitionToCapture();
- showModeOptions();
}
/**
applyModuleSpecs(moduleController.getHardwareSpec(),
moduleController.getBottomBarSpec());
mBottomBar.transitionToCancel();
- hideModeOptions();
}
/**
buttonManager.hideButton(ButtonManager.BUTTON_CAMERA);
}
- if (bottomBarSpec.hideFlash) {
+ if (bottomBarSpec.hideFlash || !hardwareSpec.isFlashSupported()) {
// Hide both flash and torch button in flash disable logic
buttonManager.hideButton(ButtonManager.BUTTON_FLASH);
buttonManager.hideButton(ButtonManager.BUTTON_TORCH);
} else {
- if (hardwareSpec.isFlashSupported()) {
- if (bottomBarSpec.enableFlash) {
- buttonManager.initializeButton(ButtonManager.BUTTON_FLASH,
- bottomBarSpec.flashCallback);
- } else if (bottomBarSpec.enableTorchFlash) {
- buttonManager.initializeButton(ButtonManager.BUTTON_TORCH,
- bottomBarSpec.flashCallback);
- } else if (bottomBarSpec.enableHdrPlusFlash) {
- buttonManager.initializeButton(ButtonManager.BUTTON_HDR_PLUS_FLASH,
- bottomBarSpec.flashCallback);
- } else {
- // Hide both flash and torch button in flash disable logic
- buttonManager.disableButton(ButtonManager.BUTTON_FLASH);
- buttonManager.disableButton(ButtonManager.BUTTON_TORCH);
- }
+ if (bottomBarSpec.enableFlash) {
+ buttonManager.initializeButton(ButtonManager.BUTTON_FLASH,
+ bottomBarSpec.flashCallback);
+ } else if (bottomBarSpec.enableTorchFlash) {
+ buttonManager.initializeButton(ButtonManager.BUTTON_TORCH,
+ bottomBarSpec.flashCallback);
+ } else if (bottomBarSpec.enableHdrPlusFlash) {
+ buttonManager.initializeButton(ButtonManager.BUTTON_HDR_PLUS_FLASH,
+ bottomBarSpec.flashCallback);
} else {
- // Disable both flash and torch icon if not supported
- // by the chosen camera hardware.
+ // Disable both flash and torch button in flash disable logic
buttonManager.disableButton(ButtonManager.BUTTON_FLASH);
buttonManager.disableButton(ButtonManager.BUTTON_TORCH);
}
buttonManager.hideButton(ButtonManager.BUTTON_HDR_PLUS);
} else {
if (hardwareSpec.isHdrPlusSupported()) {
- if (bottomBarSpec.enableHdr && Keys.isCameraBackFacing(settingsManager,
- mController.getModuleScope())) {
+ if (bottomBarSpec.enableHdr) {
buttonManager.initializeButton(ButtonManager.BUTTON_HDR_PLUS,
bottomBarSpec.hdrCallback);
} else {
buttonManager.disableButton(ButtonManager.BUTTON_HDR_PLUS);
}
} else if (hardwareSpec.isHdrSupported()) {
- if (bottomBarSpec.enableHdr && Keys.isCameraBackFacing(settingsManager,
- mController.getModuleScope())) {
+ if (bottomBarSpec.enableHdr) {
buttonManager.initializeButton(ButtonManager.BUTTON_HDR,
bottomBarSpec.hdrCallback);
} else {
buttonManager.initializePanoOrientationButtons(bottomBarSpec.panoOrientationCallback);
}
- boolean enableExposureCompensation = bottomBarSpec.enableExposureCompensation &&
- !(bottomBarSpec.minExposureCompensation == 0 && bottomBarSpec.maxExposureCompensation == 0) &&
- mController.getSettingsManager().getBoolean(SettingsManager.SCOPE_GLOBAL,
- Keys.KEY_EXPOSURE_COMPENSATION_ENABLED);
- if (enableExposureCompensation) {
+
+
+ // If manual exposure is enabled both in SettingsManager and
+ // BottomBarSpec,then show the exposure button.
+ // If manual exposure is disabled in the BottomBarSpec (eg. HDR+
+ // enabled), but the device/module has the feature, then disable the exposure
+ // button.
+ // Otherwise, hide the button.
+ if (bottomBarSpec.enableExposureCompensation
+ && !(bottomBarSpec.minExposureCompensation == 0 && bottomBarSpec.maxExposureCompensation == 0)
+ && mController.getSettingsManager().getBoolean(SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_EXPOSURE_COMPENSATION_ENABLED)) {
buttonManager.initializePushButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION,
new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mModeOptionsOverlay.showExposureOptions();
- }
- });
+ @Override
+ public void onClick(View v) {
+ mModeOptionsOverlay.showExposureOptions();
+ }
+ });
buttonManager.setExposureCompensationParameters(
- bottomBarSpec.minExposureCompensation,
- bottomBarSpec.maxExposureCompensation,
- bottomBarSpec.exposureCompensationStep);
+ bottomBarSpec.minExposureCompensation,
+ bottomBarSpec.maxExposureCompensation,
+ bottomBarSpec.exposureCompensationStep);
buttonManager.setExposureCompensationCallback(
bottomBarSpec.exposureCompensationSetCallback);
buttonManager.updateExposureButtons();
+ } else if (mController.getSettingsManager().getBoolean(SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_EXPOSURE_COMPENSATION_ENABLED)
+ && bottomBarSpec.isExposureCompensationSupported) {
+ buttonManager.disableButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION);
} else {
buttonManager.hideButton(ButtonManager.BUTTON_EXPOSURE_COMPENSATION);
buttonManager.setExposureCompensationCallback(null);
public void hideFilmstrip() {
mFilmstripLayout.hideFilmstrip();
}
+
+ public int getFilmstripVisibility() {
+ return mFilmstripLayout.getVisibility();
+ }
}