CaptureModule first run dialog.
* Introduce FirstRunDialog.
* Add OneCameraCharacteristics so we can query camera properties without
opening the camera.
* Refactor AspectRatioDialogLayout and LocationDialogLayout to clean up.
* Refactor to move away from portability/Size class in Camera2.
Bug: 18623223
Change-Id: I05f4eefe3ee2feeaa47b6296f8926f6be8e83051
diff --git a/res/layout-land/aspect_ratio_selector.xml b/res/layout-land/aspect_ratio_selector.xml
index 5b8ea7c..6d32f58 100644
--- a/res/layout-land/aspect_ratio_selector.xml
+++ b/res/layout-land/aspect_ratio_selector.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.camera.widget.AspectRatioSelector
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/aspect_ratio_selector"
android:orientation="vertical"
@@ -67,4 +67,4 @@
android:gravity="center"
android:layout_weight="1"/>
</LinearLayout>
-</com.android.camera.widget.AspectRatioSelector>
+</LinearLayout>
diff --git a/res/layout-port/aspect_ratio_selector.xml b/res/layout-port/aspect_ratio_selector.xml
index 69f0d80..96e8aa6 100644
--- a/res/layout-port/aspect_ratio_selector.xml
+++ b/res/layout-port/aspect_ratio_selector.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.camera.widget.AspectRatioSelector
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/aspect_ratio_selector"
android:orientation="vertical" >
@@ -38,4 +38,4 @@
android:src="@drawable/aspect_ratio_16x9"
android:layout_marginLeft="28dp"/>
</LinearLayout>
-</com.android.camera.widget.AspectRatioSelector>
+</LinearLayout>
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 66525af..91b07b3 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -19,6 +19,7 @@
import android.animation.Animator;
import android.app.ActionBar;
+import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
@@ -982,6 +983,11 @@
}
@Override
+ public Dialog createDialog() {
+ return new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
+ }
+
+ @Override
public void launchActivityByIntent(Intent intent) {
// Starting from L, we prefer not to start edit activity within camera's task.
mResetToPreviewOnResume = false;
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 7c00015..1ca4874 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -43,6 +43,7 @@
import com.android.camera.app.CameraAppUI.BottomBarUISpec;
import com.android.camera.app.LocationManager;
import com.android.camera.app.MediaSaver;
+import com.android.camera.app.FirstRunDialog;
import com.android.camera.burst.BurstFacade;
import com.android.camera.burst.BurstFacadeFactory;
import com.android.camera.burst.BurstReadyStateChangeListener;
@@ -51,6 +52,7 @@
import com.android.camera.debug.DebugPropertyHelper;
import com.android.camera.debug.Log;
import com.android.camera.debug.Log.Tag;
+import com.android.camera.exif.Rational;
import com.android.camera.gl.FrameDistributor.FrameConsumer;
import com.android.camera.gl.FrameDistributorWrapper;
import com.android.camera.gl.SurfaceTextureConsumer;
@@ -69,6 +71,7 @@
import com.android.camera.session.CaptureSession;
import com.android.camera.settings.Keys;
import com.android.camera.settings.SettingsManager;
+import com.android.camera.settings.SettingsUtil;
import com.android.camera.ui.CountDownView;
import com.android.camera.ui.PreviewStatusListener;
import com.android.camera.ui.TouchCoordinate;
@@ -149,7 +152,10 @@
private final SettingsManager mSettingsManager;
/** Application context. */
private final Context mContext;
+ /** Module UI. */
private CaptureModuleUI mUI;
+ /** First run dialog */
+ private FirstRunDialog mFirstRunDialog;
/** The camera manager used to open cameras. */
private OneCameraManager mCameraManager;
/** The currently opened camera device, or null if the camera is closed. */
@@ -320,6 +326,8 @@
cancelCountDown();
}
});
+
+ mFirstRunDialog = new FirstRunDialog(mAppController, mCameraManager);
}
@Override
@@ -503,8 +511,14 @@
|| mPreviewConsumer.getHeight() != height) {
mPreviewConsumer.setSize(width, height);
}
- closeCamera();
- openCameraAndStartPreview();
+
+ // Don't open camera until the aspect ratio preference is set.
+ final boolean isAspectRatioPreferenceSet = mAppController.getSettingsManager().getBoolean(
+ SettingsManager.SCOPE_GLOBAL, Keys.KEY_USER_SELECTED_ASPECT_RATIO);
+ if (isAspectRatioPreferenceSet) {
+ closeCamera();
+ openCameraAndStartPreview();
+ }
}
@Override
@@ -585,6 +599,20 @@
mSoundPlayer.loadSound(R.raw.timer_final_second);
mSoundPlayer.loadSound(R.raw.timer_increment);
+
+ if (mFirstRunDialog.shouldShow()) {
+ mFirstRunDialog.setListener(new FirstRunDialog.FirstRunDialogListener() {
+ public void onLocationPreferenceConfirmed(boolean locationRecordingEnabled) {
+ }
+
+ public void onAspectRatioPreferenceConfirmed(Rational chosenAspectRatio) {
+ // Open the camera. This dialog will be dismissed in onPreviewStarted() after
+ // preview is started.
+ openCameraAndStartPreview();
+ }
+ });
+ mFirstRunDialog.show();
+ }
}
@Override
@@ -1047,6 +1075,10 @@
if (mState == ModuleState.WATCH_FOR_NEXT_FRAME_AFTER_PREVIEW_STARTED) {
mState = ModuleState.UPDATE_TRANSFORM_ON_NEXT_SURFACE_TEXTURE_UPDATE;
}
+
+ // Dismiss the aspect ratio preference dialog.
+ mFirstRunDialog.dismiss();
+
mAppController.onPreviewStarted();
onReadyStateChanged(true);
}
@@ -1194,9 +1226,6 @@
* Open camera and start the preview.
*/
private void openCameraAndStartPreview() {
- // Only enable HDR on the back camera
- boolean useHdr = mHdrEnabled && mCameraFacing == Facing.BACK;
-
try {
// TODO Given the current design, we cannot guarantee that one of
// CaptureReadyCallback.onSetupFailed or onReadyForCapture will
@@ -1216,7 +1245,10 @@
mCameraOpenCloseLock.release();
return;
}
- mCameraManager.open(mCameraFacing, useHdr, getPictureSizeFromSettings(),
+ // Only enable HDR on the back camera
+ boolean useHdr = mHdrEnabled && mCameraFacing == Facing.BACK;
+ Size pictureSize = getPictureSizeFromSettings();
+ mCameraManager.open(mCameraFacing, useHdr, pictureSize,
new OpenCallback() {
@Override
public void onFailure() {
@@ -1354,7 +1386,8 @@
private Size getPictureSizeFromSettings() {
String pictureSizeKey = mCameraFacing == Facing.FRONT ? Keys.KEY_PICTURE_SIZE_FRONT
: Keys.KEY_PICTURE_SIZE_BACK;
- return mSettingsManager.getSize(SettingsManager.SCOPE_GLOBAL, pictureSizeKey);
+ return SettingsUtil.sizeFromSettingString(
+ mSettingsManager.getString(SettingsManager.SCOPE_GLOBAL, pictureSizeKey));
}
private int getPreviewOrientation(int deviceOrientationDegrees) {
@@ -1399,4 +1432,4 @@
return Flash.AUTO;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/com/android/camera/CaptureModuleUI.java b/src/com/android/camera/CaptureModuleUI.java
index 6d71660..3075435 100644
--- a/src/com/android/camera/CaptureModuleUI.java
+++ b/src/com/android/camera/CaptureModuleUI.java
@@ -132,8 +132,7 @@
mLayoutListener = layoutListener;
ViewGroup moduleRoot = (ViewGroup) mRootView.findViewById(R.id.module_layout);
- mActivity.getLayoutInflater().inflate(R.layout.capture_module,
- moduleRoot, true);
+ mActivity.getLayoutInflater().inflate(R.layout.capture_module, moduleRoot, true);
mPreviewView = (TextureView) mRootView.findViewById(R.id.preview_content);
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 4e0ebff..8ae9339 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -71,8 +71,8 @@
import com.android.camera.util.GcamHelper;
import com.android.camera.util.GservicesHelper;
import com.android.camera.util.SessionStatsCollector;
+import com.android.camera.util.Size;
import com.android.camera.util.UsageStatistics;
-import com.android.camera.widget.AspectRatioSelector;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgent;
import com.android.ex.camera2.portability.CameraAgent.CameraAFCallback;
@@ -83,7 +83,6 @@
import com.android.ex.camera2.portability.CameraCapabilities;
import com.android.ex.camera2.portability.CameraDeviceInfo.Characteristics;
import com.android.ex.camera2.portability.CameraSettings;
-import com.android.ex.camera2.portability.Size;
import com.google.common.logging.eventprotos;
import java.io.ByteArrayOutputStream;
@@ -295,17 +294,18 @@
/**
* Returns current aspect ratio that is being used to set as default.
*/
- public AspectRatioSelector.AspectRatio getCurrentAspectRatio();
+ public Rational getCurrentAspectRatio();
/**
* Gets notified when user has made the aspect ratio selection.
*
- * @param newAspectRatio aspect ratio that user has selected
+ * @param chosenAspectRatio The aspect ratio that user has selected
* @param dialogHandlingFinishedRunnable runnable to run when the operations
* needed to handle changes from dialog
* are finished.
*/
- public void onAspectRatioSelected(AspectRatioSelector.AspectRatio newAspectRatio,
+ public void onAspectRatioSelected(
+ Rational chosenAspectRatio,
Runnable dialogHandlingFinishedRunnable);
}
@@ -529,81 +529,33 @@
}
private AspectRatioDialogCallback createAspectRatioDialogCallback() {
- Size currentSize = mCameraSettings.getCurrentPhotoSize();
- float aspectRatio = (float) currentSize.width() / (float) currentSize.height();
- if (aspectRatio < 1f) {
- aspectRatio = 1 / aspectRatio;
- }
- final AspectRatioSelector.AspectRatio currentAspectRatio;
- if (Math.abs(aspectRatio - 4f / 3f) <= 0.1f) {
- currentAspectRatio = AspectRatioSelector.AspectRatio.ASPECT_RATIO_4x3;
- } else if (Math.abs(aspectRatio - 16f / 9f) <= 0.1f) {
- currentAspectRatio = AspectRatioSelector.AspectRatio.ASPECT_RATIO_16x9;
- } else {
- // TODO: Log error and not show dialog.
- return null;
- }
-
- List<Size> sizes = mCameraCapabilities.getSupportedPhotoSizes();
- List<Size> pictureSizes = ResolutionUtil
- .getDisplayableSizesFromSupported(sizes, true);
-
- // This logic below finds the largest resolution for each aspect ratio.
- // TODO: Move this somewhere that can be shared with SettingsActivity
- int aspectRatio4x3Resolution = 0;
- int aspectRatio16x9Resolution = 0;
- Size largestSize4x3 = new Size(0, 0);
- Size largestSize16x9 = new Size(0, 0);
- for (Size size : pictureSizes) {
- float pictureAspectRatio = (float) size.width() / (float) size.height();
- pictureAspectRatio = pictureAspectRatio < 1 ?
- 1f / pictureAspectRatio : pictureAspectRatio;
- int resolution = size.width() * size.height();
- if (Math.abs(pictureAspectRatio - 4f / 3f) < 0.1f) {
- if (resolution > aspectRatio4x3Resolution) {
- aspectRatio4x3Resolution = resolution;
- largestSize4x3 = size;
- }
- } else if (Math.abs(pictureAspectRatio - 16f / 9f) < 0.1f) {
- if (resolution > aspectRatio16x9Resolution) {
- aspectRatio16x9Resolution = resolution;
- largestSize16x9 = size;
- }
- }
- }
-
- // Use the largest 4x3 and 16x9 sizes as candidates for picture size selection.
- final Size size4x3ToSelect = largestSize4x3;
- final Size size16x9ToSelect = largestSize16x9;
-
+ Size currentSize = new Size(mCameraSettings.getCurrentPhotoSize());
+ final Rational currentAspectRatio = ResolutionUtil.getAspectRatio(currentSize);
AspectRatioDialogCallback callback = new AspectRatioDialogCallback() {
-
@Override
- public AspectRatioSelector.AspectRatio getCurrentAspectRatio() {
+ public Rational getCurrentAspectRatio() {
return currentAspectRatio;
}
@Override
- public void onAspectRatioSelected(AspectRatioSelector.AspectRatio newAspectRatio,
- Runnable dialogHandlingFinishedRunnable) {
- if (newAspectRatio == AspectRatioSelector.AspectRatio.ASPECT_RATIO_4x3) {
- String largestSize4x3Text = SettingsUtil.sizeToSetting(size4x3ToSelect);
- mActivity.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL,
- Keys.KEY_PICTURE_SIZE_BACK,
- largestSize4x3Text);
- } else if (newAspectRatio == AspectRatioSelector.AspectRatio.ASPECT_RATIO_16x9) {
- String largestSize16x9Text = SettingsUtil.sizeToSetting(size16x9ToSelect);
- mActivity.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL,
- Keys.KEY_PICTURE_SIZE_BACK,
- largestSize16x9Text);
- }
- mActivity.getSettingsManager().set(SettingsManager.SCOPE_GLOBAL,
- Keys.KEY_USER_SELECTED_ASPECT_RATIO, true);
+ public void onAspectRatioSelected(
+ Rational chosenAspectRatio, Runnable dialogHandlingFinishedRunnable) {
+ List<Size> supportedPhotoSizes = Size.convert(mCameraCapabilities.getSupportedPhotoSizes());
+ Size largestPictureSize = ResolutionUtil.getLargestPictureSize(
+ chosenAspectRatio, supportedPhotoSizes);
+ mActivity.getSettingsManager().set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_PICTURE_SIZE_BACK,
+ SettingsUtil.sizeToSettingString(largestPictureSize));
+ mActivity.getSettingsManager().set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_USER_SELECTED_ASPECT_RATIO,
+ true);
String aspectRatio = mActivity.getSettingsManager().getString(
SettingsManager.SCOPE_GLOBAL,
Keys.KEY_USER_SELECTED_ASPECT_RATIO);
Log.e(TAG, "aspect ratio after setting it to true=" + aspectRatio);
- if (newAspectRatio != currentAspectRatio) {
+ if (chosenAspectRatio != currentAspectRatio) {
Log.i(TAG, "changing aspect ratio from dialog");
stopPreview();
startPreview();
@@ -1113,8 +1065,7 @@
width = exifWidth;
height = exifHeight;
} else {
- Size s;
- s = mCameraSettings.getCurrentPhotoSize();
+ Size s = new Size(mCameraSettings.getCurrentPhotoSize());
if ((mJpegRotation + orientation) % 180 == 0) {
width = s.width();
height = s.height();
@@ -2125,7 +2076,8 @@
String pictureSize = settingsManager.getString(SettingsManager.SCOPE_GLOBAL,
pictureSizeKey);
- List<Size> supported = mCameraCapabilities.getSupportedPhotoSizes();
+ List<com.android.camera.util.Size> supported =
+ com.android.camera.util.Size.convert(mCameraCapabilities.getSupportedPhotoSizes());
CameraPictureSizesCacher.updateSizesForCamera(mAppController.getAndroidContext(),
mCameraDevice.getCameraId(), supported);
SettingsUtil.setCameraPictureSize(pictureSize, supported, mCameraSettings,
@@ -2143,13 +2095,13 @@
// Set a preview size that is closest to the viewfinder height and has
// the right aspect ratio.
- List<Size> sizes = mCameraCapabilities.getSupportedPreviewSizes();
+ List<Size> sizes = Size.convert(mCameraCapabilities.getSupportedPreviewSizes());
Size optimalSize = CameraUtil.getOptimalPreviewSize(mActivity, sizes,
(double) size.width() / size.height());
- Size original = mCameraSettings.getCurrentPreviewSize();
+ Size original = new Size(mCameraSettings.getCurrentPreviewSize());
if (!optimalSize.equals(original)) {
Log.v(TAG, "setting preview size. optimal: " + optimalSize + "original: " + original);
- mCameraSettings.setPreviewSize(optimalSize);
+ mCameraSettings.setPreviewSize(optimalSize.toPortabilitySize());
mCameraDevice.applySettings(mCameraSettings);
mCameraSettings = mCameraDevice.getSettings();
@@ -2186,7 +2138,6 @@
// If exposure compensation is not enabled, reset the exposure compensation value.
setExposureCompensation(0);
}
-
}
private void updateParametersSceneMode() {
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index 6e59bf9..72ab4a3 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -33,6 +33,7 @@
import com.android.camera.debug.DebugPropertyHelper;
import com.android.camera.debug.Log;
+import com.android.camera.exif.Rational;
import com.android.camera.ui.CountDownView;
import com.android.camera.ui.FaceView;
import com.android.camera.ui.PreviewOverlay;
@@ -42,7 +43,6 @@
import com.android.camera.util.CameraUtil;
import com.android.camera.util.GservicesHelper;
import com.android.camera.widget.AspectRatioDialogLayout;
-import com.android.camera.widget.AspectRatioSelector;
import com.android.camera.widget.LocationDialogLayout;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgent;
@@ -361,12 +361,11 @@
final PhotoModule.AspectRatioDialogCallback aspectRatioDialogCallback) {
setDialog(new Dialog(mActivity,
android.R.style.Theme_Black_NoTitleBar_Fullscreen));
- final LocationDialogLayout locationDialogLayout = (LocationDialogLayout) mActivity
- .getLayoutInflater().inflate(R.layout.location_dialog_layout, null);
- locationDialogLayout.setLocationTaggingSelectionListener(
- new LocationDialogLayout.LocationTaggingSelectionListener() {
+ final LocationDialogLayout locationDialogLayout = new LocationDialogLayout(
+ mActivity, true);
+ locationDialogLayout.setListener(new LocationDialogLayout.LocationDialogListener() {
@Override
- public void onLocationTaggingSelected(boolean selected) {
+ public void onConfirm(boolean selected) {
// Update setting.
locationCallback.onLocationTaggingSelected(selected);
@@ -423,15 +422,13 @@
Log.e(TAG, "Dialog for aspect ratio is null.");
return false;
}
- final AspectRatioDialogLayout aspectRatioDialogLayout =
- (AspectRatioDialogLayout) mActivity
- .getLayoutInflater().inflate(R.layout.aspect_ratio_dialog_layout, null);
- aspectRatioDialogLayout.initialize(
- new AspectRatioDialogLayout.AspectRatioChangedListener() {
+ final AspectRatioDialogLayout aspectRatioDialogLayout = new AspectRatioDialogLayout(
+ mActivity, callback.getCurrentAspectRatio());
+ aspectRatioDialogLayout.setListener(
+ new AspectRatioDialogLayout.AspectRatioDialogListener() {
@Override
- public void onAspectRatioChanged(AspectRatioSelector.AspectRatio aspectRatio) {
- // callback to set picture size.
- callback.onAspectRatioSelected(aspectRatio, new Runnable() {
+ public void onConfirm(Rational chosenAspectRatio) {
+ callback.onAspectRatioSelected(chosenAspectRatio, new Runnable() {
@Override
public void run() {
if (mDialog != null) {
@@ -440,7 +437,7 @@
}
});
}
- }, callback.getCurrentAspectRatio());
+ });
aspectRatioDialog.setContentView(aspectRatioDialogLayout, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
aspectRatioDialog.show();
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 5c30a8c..f0a15d8 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -67,6 +67,7 @@
import com.android.camera.util.ApiHelper;
import com.android.camera.util.CameraUtil;
import com.android.camera.util.UsageStatistics;
+import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgent;
import com.android.ex.camera2.portability.CameraAgent.CameraPictureCallback;
@@ -74,7 +75,6 @@
import com.android.ex.camera2.portability.CameraCapabilities;
import com.android.ex.camera2.portability.CameraDeviceInfo.Characteristics;
import com.android.ex.camera2.portability.CameraSettings;
-import com.android.ex.camera2.portability.Size;
import com.google.common.logging.eventprotos;
import java.io.File;
@@ -801,8 +801,8 @@
final int previewScreenShortSide = (previewScreenSize.x < previewScreenSize.y ?
previewScreenSize.x : previewScreenSize.y);
- List<Size> sizes = capabilities.getSupportedPreviewSizes();
- Size preferred = capabilities.getPreferredPreviewSizeForVideo();
+ List<Size> sizes = Size.convert(capabilities.getSupportedPreviewSizes());
+ Size preferred = new Size(capabilities.getPreferredPreviewSizeForVideo());
final int preferredPreviewSizeShortSide = (preferred.width() < preferred.height() ?
preferred.width() : preferred.height());
if (preferredPreviewSizeShortSide * 2 < previewScreenShortSide) {
@@ -1612,7 +1612,8 @@
// Update Desired Preview size in case video camera resolution has changed.
updateDesiredPreviewSize();
- mCameraSettings.setPreviewSize(new Size(mDesiredPreviewWidth, mDesiredPreviewHeight));
+ Size previewSize = new Size(mDesiredPreviewWidth, mDesiredPreviewHeight);
+ mCameraSettings.setPreviewSize(previewSize.toPortabilitySize());
// This is required for Samsung SGH-I337 and probably other Samsung S4 versions
if (Build.BRAND.toLowerCase().contains("samsung")) {
mCameraSettings.setSetting("video-size",
@@ -1644,12 +1645,12 @@
// The logic here is different from the logic in still-mode camera.
// There we determine the preview size based on the picture size, but
// here we determine the picture size based on the preview size.
- List<Size> supported = mCameraCapabilities.getSupportedPhotoSizes();
+ List<Size> supported = Size.convert(mCameraCapabilities.getSupportedPhotoSizes());
Size optimalSize = CameraUtil.getOptimalVideoSnapshotPictureSize(supported,
mDesiredPreviewWidth, mDesiredPreviewHeight);
Size original = new Size(mCameraSettings.getCurrentPhotoSize());
if (!original.equals(optimalSize)) {
- mCameraSettings.setPhotoSize(optimalSize);
+ mCameraSettings.setPhotoSize(optimalSize.toPortabilitySize());
}
Log.d(TAG, "Video snapshot size is " + optimalSize);
diff --git a/src/com/android/camera/app/AppController.java b/src/com/android/camera/app/AppController.java
index f749806..1ec2332 100644
--- a/src/com/android/camera/app/AppController.java
+++ b/src/com/android/camera/app/AppController.java
@@ -17,6 +17,7 @@
package com.android.camera.app;
import android.app.Activity;
+import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -71,6 +72,13 @@
public Context getAndroidContext();
/**
+ * Creates a new dialog which can be shown in the app.
+ *
+ * @return {@link android.app.Dialog} of the app.
+ */
+ public Dialog createDialog();
+
+ /**
* @return the current camera id.
*/
public int getCurrentCameraId();
diff --git a/src/com/android/camera/app/FirstRunDialog.java b/src/com/android/camera/app/FirstRunDialog.java
new file mode 100644
index 0000000..8011e6f
--- /dev/null
+++ b/src/com/android/camera/app/FirstRunDialog.java
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.app;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.graphics.ImageFormat;
+import android.view.ViewGroup;
+
+import com.android.camera.debug.Log;
+import com.android.camera.exif.Rational;
+import com.android.camera.one.OneCamera;
+import com.android.camera.one.OneCameraAccessException;
+import com.android.camera.one.OneCameraCharacteristics;
+import com.android.camera.one.OneCameraManager;
+import com.android.camera.settings.Keys;
+import com.android.camera.settings.ResolutionUtil;
+import com.android.camera.settings.SettingsManager;
+import com.android.camera.settings.SettingsUtil;
+import com.android.camera.util.ApiHelper;
+import com.android.camera.util.Size;
+import com.android.camera.widget.AspectRatioDialogLayout;
+import com.android.camera.widget.LocationDialogLayout;
+
+import java.util.List;
+
+/**
+ * The dialog to show when users open the app for the first time.
+ */
+public class FirstRunDialog {
+
+ public interface FirstRunDialogListener {
+
+ public void onLocationPreferenceConfirmed(boolean locationRecordingEnabled);
+
+ public void onAspectRatioPreferenceConfirmed(Rational chosenAspectRatio);
+ }
+
+ private static final Log.Tag TAG = new Log.Tag("FirstRunDialog");
+
+ /** The default preference of aspect ratio. */
+ private static final Rational DEFAULT_ASPECT_RATIO = ResolutionUtil.ASPECT_RATIO_4x3;
+
+ /** The default preference of whether enabling location recording. */
+ private static final boolean DEFAULT_LOCATION_RECORDING_ENABLED = true;
+
+ /** The app controller. */
+ private final AppController mAppController;
+
+ /** The camera manager used to query camera characteristics. */
+ private final OneCameraManager mCameraManager;
+
+ /** Aspect ratio preference dialog */
+ private Dialog mAspectRatioPreferenceDialog;
+
+ /** Location preference dialog */
+ private Dialog mLocationPreferenceDialog;
+
+ /** Listener to receive events. */
+ private FirstRunDialogListener mListener;
+
+ /**
+ * Constructs a first run dialog.
+ *
+ * @param appController The app controller.
+ * @param cameraManager The camera manager used to query supported aspect
+ * ratio by camera devices.
+ */
+ public FirstRunDialog(AppController appController, OneCameraManager cameraManager) {
+ mAppController = appController;
+ mCameraManager = cameraManager;
+ }
+
+ /**
+ * Set a dialog listener.
+ *
+ * @param listener The dialog listener to be set.
+ */
+ public void setListener(FirstRunDialogListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Whether first run dialogs should be presented to the user.
+ *
+ * @return Whether first run dialogs should be presented to the user.
+ */
+ public boolean shouldShow() {
+ return shouldShowAspectRatioPreferenceDialog() || shouldShowLocationPreferenceDialog();
+ }
+
+ /**
+ * Shows first run dialogs if necessary.
+ *
+ * @return Whether first run dialogs are shown.
+ */
+ public boolean show() {
+ // When people open the app for the first time, prompt two dialogs to
+ // ask preferences about
+ // location and aspect ratio.
+ if (promptLocationPreferenceDialog()) {
+ return true;
+ } else {
+ // This should be a rare case because location and aspect ratio
+ // preferences usually got
+ // set at the same time when people open the app for the first time.
+ return promptAspectRatioPreferenceDialog();
+ }
+ }
+
+ /**
+ * Dismiss all shown dialogs.
+ */
+ public void dismiss() {
+ if (mAspectRatioPreferenceDialog != null) {
+ mAspectRatioPreferenceDialog.dismiss();
+ }
+ if (mLocationPreferenceDialog != null) {
+ mLocationPreferenceDialog.dismiss();
+ }
+ }
+
+ /**
+ * Whether a aspect ratio dialog should be presented to the user.
+ *
+ * @return Whether a aspect ratio dialog should be presented to the user.
+ */
+ private boolean shouldShowAspectRatioPreferenceDialog() {
+ final SettingsManager settingsManager = mAppController.getSettingsManager();
+ final boolean isAspectRatioPreferenceSet = settingsManager.getBoolean(
+ SettingsManager.SCOPE_GLOBAL, Keys.KEY_USER_SELECTED_ASPECT_RATIO);
+ return ApiHelper.shouldShowAspectRatioDialog() && !isAspectRatioPreferenceSet;
+ }
+
+ /**
+ * Prompts a dialog to allow people to choose aspect ratio preference when
+ * people open the app for the first time. If the preference has been set,
+ * this will return false.
+ *
+ * @return Whether the dialog will be prompted or not.
+ */
+ private boolean promptAspectRatioPreferenceDialog() {
+ // Do nothing if the preference is already set.
+ if (!shouldShowAspectRatioPreferenceDialog()) {
+ return false;
+ }
+
+ // Create a content view for the dialog.
+ final AspectRatioDialogLayout dialogLayout = new AspectRatioDialogLayout(
+ mAppController.getAndroidContext(), DEFAULT_ASPECT_RATIO);
+ dialogLayout.setListener(new AspectRatioDialogLayout.AspectRatioDialogListener() {
+ @Override
+ public void onConfirm(Rational aspectRatio) {
+ try {
+ final SettingsManager settingsManager =
+ mAppController.getSettingsManager();
+
+ // Save the picture size setting for back camera.
+ OneCameraCharacteristics backCameraChars =
+ mCameraManager.getCameraCharacteristics(OneCamera.Facing.BACK);
+ List<Size> backCameraPictureSizes =
+ backCameraChars.getSupportedPictureSizes(ImageFormat.JPEG);
+ Size backCameraChosenPictureSize =
+ ResolutionUtil.getLargestPictureSize(
+ aspectRatio, backCameraPictureSizes);
+ settingsManager.set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_PICTURE_SIZE_BACK,
+ SettingsUtil.sizeToSettingString(backCameraChosenPictureSize));
+
+ // Save the picture size setting for front camera.
+ OneCameraCharacteristics frontCameraChars =
+ mCameraManager.getCameraCharacteristics(OneCamera.Facing.FRONT);
+ List<Size> frontCameraPictureSizes =
+ frontCameraChars.getSupportedPictureSizes(ImageFormat.JPEG);
+ Size frontCameraChosenPictureSize =
+ ResolutionUtil.getLargestPictureSize(
+ aspectRatio, frontCameraPictureSizes);
+ settingsManager.set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_PICTURE_SIZE_FRONT,
+ SettingsUtil.sizeToSettingString(frontCameraChosenPictureSize));
+
+ // Indicate the aspect ratio is selected.
+ settingsManager.set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_USER_SELECTED_ASPECT_RATIO,
+ true);
+ } catch (OneCameraAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ mListener.onAspectRatioPreferenceConfirmed(aspectRatio);
+ }
+ });
+
+ // Create the dialog.
+ mAspectRatioPreferenceDialog = mAppController.createDialog();
+ mAspectRatioPreferenceDialog.setContentView(dialogLayout, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ mAspectRatioPreferenceDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mAspectRatioPreferenceDialog = null;
+ }
+ });
+
+ // Show the dialog.
+ mAspectRatioPreferenceDialog.show();
+ return true;
+ }
+
+ /**
+ * Whether a location dialog should be presented to the user.
+ *
+ * @return Whether a location dialog should be presented to the user.
+ */
+ private boolean shouldShowLocationPreferenceDialog() {
+ final SettingsManager settingsManager = mAppController.getSettingsManager();
+ return !settingsManager.isSet(SettingsManager.SCOPE_GLOBAL, Keys.KEY_RECORD_LOCATION);
+ }
+
+ /**
+ * Prompts a dialog to allow people to choose location preference when
+ * people open the app for the first time. If the preference has been set,
+ * this will return false.
+ *
+ * @return Whether the dialog will be prompted or not.
+ */
+ private boolean promptLocationPreferenceDialog() {
+ // Do nothing if the preference is already set.
+ if (!shouldShowLocationPreferenceDialog()) {
+ return false;
+ }
+
+ // Create a content view for the dialog.
+ final LocationDialogLayout dialogLayout = new LocationDialogLayout(
+ mAppController.getAndroidContext(), DEFAULT_LOCATION_RECORDING_ENABLED);
+ dialogLayout.setListener(new LocationDialogLayout.LocationDialogListener() {
+ @Override
+ public void onConfirm(boolean locationRecordingEnabled) {
+ mAppController.getSettingsManager().set(
+ SettingsManager.SCOPE_GLOBAL,
+ Keys.KEY_RECORD_LOCATION,
+ locationRecordingEnabled);
+ mAppController.getLocationManager().recordLocation(
+ locationRecordingEnabled);
+
+ mListener.onLocationPreferenceConfirmed(locationRecordingEnabled);
+
+ promptAspectRatioPreferenceDialog();
+ }
+ });
+
+ // Create the dialog.
+ mLocationPreferenceDialog = mAppController.createDialog();
+ mLocationPreferenceDialog.setContentView(dialogLayout, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ mLocationPreferenceDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mLocationPreferenceDialog = null;
+ }
+ });
+
+ // Show the dialog.
+ mLocationPreferenceDialog.show();
+ return true;
+ }
+}
diff --git a/src/com/android/camera/exif/Rational.java b/src/com/android/camera/exif/Rational.java
index 96b5312..cf73e2b 100644
--- a/src/com/android/camera/exif/Rational.java
+++ b/src/com/android/camera/exif/Rational.java
@@ -16,6 +16,7 @@
package com.android.camera.exif;
+// TODO: Move this class to under util package.
/**
* The rational data type of EXIF tag. Contains a pair of longs representing the
* numerator and denominator of a Rational number.
@@ -28,11 +29,11 @@
/**
* Create a Rational with a given numerator and denominator.
*
- * @param nominator
+ * @param numerator
* @param denominator
*/
- public Rational(long nominator, long denominator) {
- mNumerator = nominator;
+ public Rational(long numerator, long denominator) {
+ mNumerator = numerator;
mDenominator = denominator;
}
diff --git a/src/com/android/camera/one/OneCameraAccessException.java b/src/com/android/camera/one/OneCameraAccessException.java
new file mode 100644
index 0000000..d0181c5
--- /dev/null
+++ b/src/com/android/camera/one/OneCameraAccessException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.one;
+
+public class OneCameraAccessException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public OneCameraAccessException(String message) {
+ super(message);
+ }
+
+ public OneCameraAccessException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/com/android/camera/one/OneCameraCharacteristics.java b/src/com/android/camera/one/OneCameraCharacteristics.java
new file mode 100644
index 0000000..9e806b8
--- /dev/null
+++ b/src/com/android/camera/one/OneCameraCharacteristics.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.one;
+
+import com.android.camera.util.Size;
+
+import java.util.List;
+
+/**
+ * The properties describing a OneCamera device. These properties are fixed for
+ * a given OneCamera device.
+ *
+ * TODO: Complete this interface to expose all camera
+ * properties.
+ */
+public interface OneCameraCharacteristics {
+ /**
+ * Gets the supported picture sizes for the given image format.
+ *
+ * @param imageFormat The specific image format listed on
+ * {@link ImageFormat}.
+ */
+ public List<Size> getSupportedPictureSizes(int imageFormat);
+}
diff --git a/src/com/android/camera/one/OneCameraManager.java b/src/com/android/camera/one/OneCameraManager.java
index cb6d142..dde1ca2 100644
--- a/src/com/android/camera/one/OneCameraManager.java
+++ b/src/com/android/camera/one/OneCameraManager.java
@@ -58,12 +58,25 @@
public abstract void open(Facing facing, boolean enableHdr, Size captureSize,
OpenCallback callback, Handler handler);
+ // TODO: Move this to OneCameraCharacteristics class.
/**
* Returns whether the device has a camera facing the given direction.
*/
public abstract boolean hasCameraFacing(Facing facing);
/**
+ * Retrieve the characteristics for the camera facing at the given direction. The first camera
+ * found in the given direction will be chosen.
+ *
+ * @param facing The facing direction of the camera.
+ * @return A #{link com.android.camera.one.OneCameraCharacteristics} object to provide camera
+ * characteristics information. Returns null if there is no camera facing the given
+ * direction.
+ */
+ public abstract OneCameraCharacteristics getCameraCharacteristics(Facing facing)
+ throws OneCameraAccessException;
+
+ /**
* Creates a camera manager that is based on Camera2 API, if available, or
* otherwise uses the portability layer API.
*
diff --git a/src/com/android/camera/one/v1/OneCameraManagerImpl.java b/src/com/android/camera/one/v1/OneCameraManagerImpl.java
index 839ca5a..3967739 100644
--- a/src/com/android/camera/one/v1/OneCameraManagerImpl.java
+++ b/src/com/android/camera/one/v1/OneCameraManagerImpl.java
@@ -20,6 +20,7 @@
import com.android.camera.one.OneCamera.Facing;
import com.android.camera.one.OneCamera.OpenCallback;
+import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.one.OneCameraManager;
import com.android.camera.util.Size;
@@ -38,4 +39,9 @@
public boolean hasCameraFacing(Facing facing) {
throw new RuntimeException("Not implemented yet.");
}
-}
+
+ @Override
+ public OneCameraCharacteristics getCameraCharacteristics(Facing facing) {
+ throw new RuntimeException("Not implemented yet.");
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java b/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java
new file mode 100644
index 0000000..77278e5
--- /dev/null
+++ b/src/com/android/camera/one/v2/OneCameraCharacteristicsImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.one.v2;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import com.android.camera.one.OneCameraCharacteristics;
+import com.android.camera.util.Size;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Describes a OneCamera device which is on top of camera2 API. This is essential a wrapper
+ * for #{link android.hardware.camera2.CameraCharacteristics}.
+ */
+public class OneCameraCharacteristicsImpl implements OneCameraCharacteristics {
+ private final CameraCharacteristics mCameraCharacteristics;
+
+ public OneCameraCharacteristicsImpl(CameraCharacteristics cameraCharacteristics) {
+ mCameraCharacteristics = cameraCharacteristics;
+ }
+
+ @Override
+ public List<Size> getSupportedPictureSizes(int imageFormat) {
+ StreamConfigurationMap configMap =
+ mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ ArrayList<Size> supportedPictureSizes = new ArrayList<>();
+ for (android.util.Size androidSize : configMap.getOutputSizes(imageFormat)) {
+ supportedPictureSizes.add(new Size(androidSize));
+ }
+ return supportedPictureSizes;
+ }
+}
diff --git a/src/com/android/camera/one/v2/OneCameraManagerImpl.java b/src/com/android/camera/one/v2/OneCameraManagerImpl.java
index 249e4ec..584cb4e 100644
--- a/src/com/android/camera/one/v2/OneCameraManagerImpl.java
+++ b/src/com/android/camera/one/v2/OneCameraManagerImpl.java
@@ -30,6 +30,8 @@
import com.android.camera.one.OneCamera;
import com.android.camera.one.OneCamera.Facing;
import com.android.camera.one.OneCamera.OpenCallback;
+import com.android.camera.one.OneCameraAccessException;
+import com.android.camera.one.OneCameraCharacteristics;
import com.android.camera.one.OneCameraManager;
import com.android.camera.util.Size;
@@ -147,6 +149,18 @@
: CameraCharacteristics.LENS_FACING_BACK) != null;
}
+ @Override
+ public OneCameraCharacteristics getCameraCharacteristics(Facing facing)
+ throws OneCameraAccessException {
+ String cameraId = getCameraId(facing);
+ try {
+ CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
+ return new OneCameraCharacteristicsImpl(characteristics);
+ } catch (CameraAccessException ex) {
+ throw new OneCameraAccessException("Unable to get camera characteristics", ex);
+ }
+ }
+
/** Returns the ID of the first camera facing the given direction. */
private String getCameraId(Facing facing) {
if (facing == Facing.FRONT) {
diff --git a/src/com/android/camera/settings/AppUpgrader.java b/src/com/android/camera/settings/AppUpgrader.java
index 9ff3dfa..b1c6336 100644
--- a/src/com/android/camera/settings/AppUpgrader.java
+++ b/src/com/android/camera/settings/AppUpgrader.java
@@ -24,10 +24,10 @@
import com.android.camera.app.ModuleManagerImpl;
import com.android.camera.debug.Log;
import com.android.camera.module.ModuleController;
+import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgentFactory;
import com.android.ex.camera2.portability.CameraDeviceInfo;
-import com.android.ex.camera2.portability.Size;
import java.util.List;
import java.util.Map;
@@ -326,7 +326,7 @@
if (supported != null) {
Size size = SettingsUtil.getPhotoSize(pictureSize, supported, camera);
settingsManager.set(SettingsManager.SCOPE_GLOBAL, key,
- SettingsUtil.sizeToSetting(size));
+ SettingsUtil.sizeToSettingString(size));
}
}
}
diff --git a/src/com/android/camera/settings/CameraPictureSizesCacher.java b/src/com/android/camera/settings/CameraPictureSizesCacher.java
index 6f0c86e..689cd9c 100644
--- a/src/com/android/camera/settings/CameraPictureSizesCacher.java
+++ b/src/com/android/camera/settings/CameraPictureSizesCacher.java
@@ -22,7 +22,7 @@
import android.os.Build;
import android.preference.PreferenceManager;
-import com.android.ex.camera2.portability.Size;
+import com.android.camera.util.Size;
import java.util.List;
diff --git a/src/com/android/camera/settings/CameraSettingsActivity.java b/src/com/android/camera/settings/CameraSettingsActivity.java
index 82b54cd..1791051 100644
--- a/src/com/android/camera/settings/CameraSettingsActivity.java
+++ b/src/com/android/camera/settings/CameraSettingsActivity.java
@@ -37,10 +37,10 @@
import com.android.camera.settings.SettingsUtil.SelectedVideoQualities;
import com.android.camera.util.CameraSettingsActivityHelper;
import com.android.camera.util.GoogleHelpHelper;
+import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraAgentFactory;
import com.android.ex.camera2.portability.CameraDeviceInfo;
-import com.android.ex.camera2.portability.Size;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -352,7 +352,7 @@
for (int i = 0; i < selectedSizes.size(); i++) {
Size size = selectedSizes.get(i);
entries[i] = getSizeSummaryString(size);
- entryValues[i] = SettingsUtil.sizeToSetting(size);
+ entryValues[i] = SettingsUtil.sizeToSettingString(size);
}
preference.setEntries(entries);
preference.setEntryValues(entryValues);
diff --git a/src/com/android/camera/settings/ResolutionUtil.java b/src/com/android/camera/settings/ResolutionUtil.java
index 8f6c929..40ee4ee 100644
--- a/src/com/android/camera/settings/ResolutionUtil.java
+++ b/src/com/android/camera/settings/ResolutionUtil.java
@@ -16,8 +16,9 @@
package com.android.camera.settings;
+import com.android.camera.exif.Rational;
import com.android.camera.util.ApiHelper;
-import com.android.ex.camera2.portability.Size;
+import com.android.camera.util.Size;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -36,6 +37,12 @@
* user with so many options.
*/
public class ResolutionUtil {
+ /**
+ * Different aspect ratio constants.
+ */
+ public static final Rational ASPECT_RATIO_16x9 = new Rational(16, 9);
+ public static final Rational ASPECT_RATIO_4x3 = new Rational(4, 3);
+ private static final double ASPECT_RATIO_TOLERANCE = 0.05;
public static final String NEXUS_5_LARGE_16_BY_9 = "1836x3264";
public static final float NEXUS_5_LARGE_16_BY_9_ASPECT_RATIO = 16f / 9f;
@@ -43,7 +50,7 @@
/**
* These are the preferred aspect ratios for the settings. We will take HAL
- * supported aspect ratios that are within RATIO_TOLERANCE of these values.
+ * supported aspect ratios that are within ASPECT_RATIO_TOLERANCE of these values.
* We will also take the maximum supported resolution for full sensor image.
*/
private static Float[] sDesiredAspectRatios = {
@@ -54,8 +61,6 @@
new Size(16, 9), new Size(4, 3)
};
- private static final float RATIO_TOLERANCE = .05f;
-
/**
* A resolution bucket holds a list of sizes that are of a given aspect
* ratio.
@@ -131,7 +136,7 @@
for (Float targetRatio : sortedDesiredAspectRatios) {
for (ResolutionBucket bucket : buckets) {
Number aspectRatio = bucket.aspectRatio;
- if (Math.abs(aspectRatio.floatValue() - targetRatio) <= RATIO_TOLERANCE) {
+ if (Math.abs(aspectRatio.floatValue() - targetRatio) <= ASPECT_RATIO_TOLERANCE) {
result.addAll(pickUpToThree(bucket.sizes));
}
}
@@ -197,12 +202,12 @@
* possible.
*
* @param aspectRatio the aspect ratio to fuzz
- * @return the closest desiredAspectRatio within RATIO_TOLERANCE, or the
+ * @return the closest desiredAspectRatio within ASPECT_RATIO_TOLERANCE, or the
* original ratio
*/
private static float fuzzAspectRatio(float aspectRatio) {
for (float desiredAspectRatio : sDesiredAspectRatios) {
- if ((Math.abs(aspectRatio - desiredAspectRatio)) < RATIO_TOLERANCE) {
+ if ((Math.abs(aspectRatio - desiredAspectRatio)) < ASPECT_RATIO_TOLERANCE) {
return desiredAspectRatio;
}
}
@@ -223,7 +228,7 @@
HashMap<Float, ResolutionBucket> aspectRatioToBuckets = new HashMap<Float, ResolutionBucket>();
for (Size size : sizes) {
- Float aspectRatio = size.width() / (float) size.height();
+ Float aspectRatio = (float) size.getWidth() / (float) size.getHeight();
// If this aspect ratio is close to a desired Aspect Ratio,
// fuzz it so that they are bucketed together
aspectRatio = fuzzAspectRatio(aspectRatio);
@@ -300,23 +305,12 @@
float fuzzy = fuzzAspectRatio(size.width() / (float) size.height());
int index = Arrays.asList(sDesiredAspectRatios).indexOf(fuzzy);
if (index != -1) {
- aspectRatio = new Size(sDesiredAspectRatioSizes[index]);
+ aspectRatio = sDesiredAspectRatioSizes[index];
}
return aspectRatio;
}
/**
- * See {@link #getApproximateSize(Size)}.
- * <p>
- * TODO: Move this whole util to {@link android.util.Size}
- */
- public static com.android.camera.util.Size getApproximateSize(
- com.android.camera.util.Size size) {
- Size result = getApproximateSize(new Size(size.getWidth(), size.getHeight()));
- return new com.android.camera.util.Size(result.width(), result.height());
- }
-
- /**
* Given a size return the numerator of its aspect ratio
*
* @param size
@@ -330,4 +324,50 @@
return denominator;
}
+ /**
+ * Returns the aspect ratio for the given size.
+ *
+ * @param size The given size.
+ * @return A {@link Rational} which represents the aspect ratio.
+ */
+ public static Rational getAspectRatio(Size size) {
+ int width = size.getWidth();
+ int height = size.getHeight();
+ int numerator = width;
+ int denominator = height;
+ if (height > width) {
+ numerator = height;
+ denominator = width;
+ }
+ return new Rational(numerator, denominator);
+ }
+
+ public static boolean hasSameAspectRatio(Rational ar1, Rational ar2) {
+ return Math.abs(ar1.toDouble() - ar2.toDouble()) < ASPECT_RATIO_TOLERANCE;
+ }
+
+ /**
+ * Selects the maximal resolution for the given aspect ratio from all available resolutions.
+ *
+ * @param desiredAspectRatio The desired aspect ratio.
+ * @param sizes All available resolutions.
+ * @return The maximal resolution for 4x3 aspect ratio
+ */
+ public static Size getLargestPictureSize(Rational desiredAspectRatio, List<Size> sizes) {
+ int maxPixelNum = 0;
+ Size maxSize = new Size(0, 0);
+ for (Size size : sizes) {
+ Rational aspectRatio = getAspectRatio(size);
+ // Skip if the aspect ratio is not desired.
+ if (!hasSameAspectRatio(aspectRatio, desiredAspectRatio)) {
+ continue;
+ }
+ int pixelNum = size.getWidth() * size.getHeight();
+ if (pixelNum > maxPixelNum) {
+ maxPixelNum = pixelNum;
+ maxSize = size;
+ }
+ }
+ return maxSize;
+ }
}
diff --git a/src/com/android/camera/settings/SettingsManager.java b/src/com/android/camera/settings/SettingsManager.java
index 6d90832..86b06ea 100644
--- a/src/com/android/camera/settings/SettingsManager.java
+++ b/src/com/android/camera/settings/SettingsManager.java
@@ -374,30 +374,6 @@
}
/**
- * Retrieve a setting's value as a {@link Size}. Returns <code>null</code>
- * if value could not be parsed as a size.
- */
- public Size getSize(String scope, String key) {
- String strValue = getString(scope, key);
- if (strValue == null) {
- return null;
- }
-
- String[] widthHeight = strValue.split("x");
- if (widthHeight.length != 2) {
- return null;
- }
-
- try {
- int width = Integer.parseInt(widthHeight[0]);
- int height = Integer.parseInt(widthHeight[1]);
- return new Size(width, height);
- } catch (NumberFormatException ex) {
- return null;
- }
- }
-
- /**
* If possible values are stored for this key, return the
* index into that list of the currently set value.
*
diff --git a/src/com/android/camera/settings/SettingsUtil.java b/src/com/android/camera/settings/SettingsUtil.java
index acf8921..732a834 100644
--- a/src/com/android/camera/settings/SettingsUtil.java
+++ b/src/com/android/camera/settings/SettingsUtil.java
@@ -26,10 +26,10 @@
import com.android.camera.debug.Log;
import com.android.camera.util.ApiHelper;
import com.android.camera.util.Callback;
+import com.android.camera.util.Size;
import com.android.camera2.R;
import com.android.ex.camera2.portability.CameraDeviceInfo;
import com.android.ex.camera2.portability.CameraSettings;
-import com.android.ex.camera2.portability.Size;
import java.util.ArrayList;
import java.util.Collections;
@@ -79,7 +79,7 @@
} else if (SIZE_SMALL.equals(sizeSetting)) {
return small;
} else if (sizeSetting != null && sizeSetting.split("x").length == 2) {
- Size desiredSize = sizeFromString(sizeSetting);
+ Size desiredSize = sizeFromSettingString(sizeSetting);
if (supportedSizes.contains(desiredSize)) {
return desiredSize;
}
@@ -162,9 +162,9 @@
public static void setCameraPictureSize(String sizeSetting, List<Size> supported,
CameraSettings settings, int cameraId) {
Size selectedSize = getCameraPictureSize(sizeSetting, supported, cameraId);
- Log.d(TAG, "Selected " + sizeSetting + " resolution: " + selectedSize.width() + "x" +
- selectedSize.height());
- settings.setPhotoSize(selectedSize);
+ Log.d(TAG, "Selected " + sizeSetting + " resolution: " + selectedSize.getWidth() + "x" +
+ selectedSize.getHeight());
+ settings.setPhotoSize(selectedSize.toPortabilitySize());
}
/**
@@ -404,27 +404,38 @@
return closestMatchIndex;
}
+ private static final String SIZE_SETTING_STRING_DIMENSION_DELIMITER = "x";
+
/**
* This is used to serialize a size to a string for storage in settings
*
* @param size The size to serialize.
* @return the string to be saved in preferences
*/
- public static String sizeToSetting(Size size) {
- return ((Integer) size.width()).toString() + "x" + ((Integer) size.height()).toString();
+ public static String sizeToSettingString(Size size) {
+ return size.width() + SIZE_SETTING_STRING_DIMENSION_DELIMITER + size.height();
}
/**
* This parses a setting string and returns the representative size.
*
- * @param sizeSetting The string to parse.
+ * @param sizeSettingString The string that stored in settings to represent a size.
* @return the represented Size.
*/
- static public Size sizeFromString(String sizeSetting) {
- String[] parts = sizeSetting.split("x");
- if (parts.length == 2) {
- return new Size(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]));
- } else {
+ static public Size sizeFromSettingString(String sizeSettingString) {
+ if (sizeSettingString == null) {
+ return null;
+ }
+ String[] parts = sizeSettingString.split(SIZE_SETTING_STRING_DIMENSION_DELIMITER);
+ if (parts.length != 2) {
+ return null;
+ }
+
+ try {
+ int width = Integer.parseInt(parts[0]);
+ int height = Integer.parseInt(parts[1]);
+ return new Size(width, height);
+ } catch (NumberFormatException ex) {
return null;
}
}
diff --git a/src/com/android/camera/util/ApiHelper.java b/src/com/android/camera/util/ApiHelper.java
index 7e8a748..624cbf2 100644
--- a/src/com/android/camera/util/ApiHelper.java
+++ b/src/com/android/camera/util/ApiHelper.java
@@ -100,4 +100,8 @@
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
|| "L".equals(Build.VERSION.CODENAME);
}
+
+ public static boolean shouldShowAspectRatioDialog() {
+ return IS_NEXUS_4 || IS_NEXUS_5 || IS_NEXUS_6;
+ }
}
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index aa8c525..71e15cb 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -458,10 +458,9 @@
return new Size(res);
}
- public static com.android.ex.camera2.portability.Size getOptimalPreviewSize(Context context,
- List<com.android.ex.camera2.portability.Size> sizes, double targetRatio) {
- int optimalPickIndex = getOptimalPreviewSizeIndex(context, Size.convert(sizes),
- targetRatio);
+ public static Size getOptimalPreviewSize(
+ Context context, List<Size> sizes, double targetRatio) {
+ int optimalPickIndex = getOptimalPreviewSizeIndex(context, sizes, targetRatio);
if (optimalPickIndex == -1) {
return null;
} else {
@@ -585,8 +584,8 @@
* @param targetHeight the ideal height of the video snapshot
* @return the Optimal Video Snapshot Picture Size
*/
- public static com.android.ex.camera2.portability.Size getOptimalVideoSnapshotPictureSize(
- List<com.android.ex.camera2.portability.Size> sizes, int targetWidth,
+ public static Size getOptimalVideoSnapshotPictureSize(
+ List<Size> sizes, int targetWidth,
int targetHeight) {
// Use a very small tolerance because we want an exact match.
@@ -595,12 +594,12 @@
return null;
}
- com.android.ex.camera2.portability.Size optimalSize = null;
+ Size optimalSize = null;
// WYSIWYG Override
// We assume that physical display constraints have already been
// imposed on the variables sizes
- for (com.android.ex.camera2.portability.Size size : sizes) {
+ for (Size size : sizes) {
if (size.height() == targetHeight && size.width() == targetWidth) {
return size;
}
@@ -608,7 +607,7 @@
// Try to find a size matches aspect ratio and has the largest width
final double targetRatio = (double) targetWidth / targetHeight;
- for (com.android.ex.camera2.portability.Size size : sizes) {
+ for (Size size : sizes) {
double ratio = (double) size.width() / size.height();
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
continue;
@@ -622,7 +621,7 @@
// happen. Ignore the requirement.
if (optimalSize == null) {
Log.w(TAG, "No picture size match the aspect ratio");
- for (com.android.ex.camera2.portability.Size size : sizes) {
+ for (Size size : sizes) {
if (optimalSize == null || size.width() > optimalSize.width()) {
optimalSize = size;
}
diff --git a/src/com/android/camera/util/Size.java b/src/com/android/camera/util/Size.java
index 20ad187..61905a0 100644
--- a/src/com/android/camera/util/Size.java
+++ b/src/com/android/camera/util/Size.java
@@ -19,6 +19,8 @@
import android.annotation.TargetApi;
import android.graphics.Point;
import android.os.Build.VERSION_CODES;
+import android.hardware.Camera;
+import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
@@ -27,9 +29,75 @@
* Simple size class until we are 'L' only and can use android.util.Size.
*/
public class Size {
+ public static final String LIST_DELIMITER = ",";
+
private final int width;
private final int height;
+ public Size(Point point) {
+ this.width = point.x;
+ this.height = point.y;
+ }
+
+ @TargetApi(VERSION_CODES.L)
+ public Size(android.util.Size size) {
+ this.width = size.getWidth();
+ this.height = size.getHeight();
+ }
+
+ public Size(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Constructor from a source {@link android.hardware.Camera.Size}.
+ *
+ * @param other The source size.
+ */
+ public Size(Camera.Size other) {
+ this.width = other.width;
+ this.height = other.height;
+ }
+
+ public Size(com.android.ex.camera2.portability.Size size) {
+ this.width = size.width();
+ this.height = size.height();
+ }
+
+ public int getWidth() {
+ return width;
+ }
+ public int getHeight() {
+ return height;
+ }
+
+ public int width() {
+ return width;
+ }
+ public int height() {
+ return height;
+ }
+
+ @Override
+ public String toString() {
+ return width + "x" + height;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Size)) {
+ return false;
+ }
+
+ Size otherSize = (Size) other;
+ return otherSize.width == this.width && otherSize.height == this.height;
+ }
+
+ public com.android.ex.camera2.portability.Size toPortabilitySize() {
+ return new com.android.ex.camera2.portability.Size(width, height);
+ }
+
@TargetApi(VERSION_CODES.L)
public static Size[] convert(android.util.Size[] sizes) {
Size[] converted = new Size[sizes.length];
@@ -47,42 +115,50 @@
return converted;
}
- public Size(Point point) {
- this.width = point.x;
- this.height = point.y;
- }
-
- @TargetApi(VERSION_CODES.L)
- public Size(android.util.Size size) {
- this.width = size.getWidth();
- this.height = size.getHeight();
- }
-
- public Size(int width, int height) {
- this.width = width;
- this.height = height;
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
- @Override
- public String toString() {
- return width + " x " + height;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof Size)) {
- return false;
+ /**
+ * Encode List of this class as comma-separated list of integers.
+ *
+ * @param sizes List of this class to encode.
+ * @return encoded string.
+ */
+ public static String listToString(List<Size> sizes) {
+ ArrayList<Integer> flatSizes = new ArrayList<>();
+ for (Size s : sizes) {
+ flatSizes.add(s.width());
+ flatSizes.add(s.height());
}
+ return TextUtils.join(LIST_DELIMITER, flatSizes);
+ }
- Size otherSize = (Size) other;
- return otherSize.width == this.width && otherSize.height == this.height;
+ /**
+ * Decode comma-separated even-length list of integers into a List of this class.
+ *
+ * @param encodedSizes encoded string.
+ * @return List of this class.
+ */
+ public static List<Size> stringToList(String encodedSizes) {
+ String[] flatSizes = TextUtils.split(encodedSizes, LIST_DELIMITER);
+ ArrayList<Size> list = new ArrayList<>();
+ for (int i = 0; i < flatSizes.length; i += 2) {
+ int width = Integer.parseInt(flatSizes[i]);
+ int height = Integer.parseInt(flatSizes[i + 1]);
+ list.add(new Size(width, height));
+ }
+ return list;
+ }
+
+ /**
+ * An helper method to build a list of this class from a list of
+ * {@link android.hardware.Camera.Size}.
+ *
+ * @param cameraSizes Source.
+ * @return The built list.
+ */
+ public static List<Size> buildListFromCameraSizes(List<Camera.Size> cameraSizes) {
+ ArrayList<Size> list = new ArrayList<Size>(cameraSizes.size());
+ for (Camera.Size cameraSize : cameraSizes) {
+ list.add(new Size(cameraSize));
+ }
+ return list;
}
}
diff --git a/src/com/android/camera/widget/AspectRatioDialogLayout.java b/src/com/android/camera/widget/AspectRatioDialogLayout.java
index 972bf35..5f551bd 100644
--- a/src/com/android/camera/widget/AspectRatioDialogLayout.java
+++ b/src/com/android/camera/widget/AspectRatioDialogLayout.java
@@ -18,74 +18,107 @@
import android.content.Context;
import android.content.res.Configuration;
-import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
+import com.android.camera.exif.Rational;
+import com.android.camera.settings.ResolutionUtil;
import com.android.camera2.R;
+/**
+ * Displays a dialog that allows people to choose aspect ratio. Please
+ * instantiate this class programmatically.
+ */
public class AspectRatioDialogLayout extends FrameLayout {
+
+ private AspectRatioDialogListener mListener;
+
+ private View mAspectRatio4x3Button;
+ private View mAspectRatio16x9Button;
private View mConfirmButton;
- private AspectRatioSelector mAspectRatioSelector;
+
+ private Rational mAspectRatio;
private int mLastOrientation;
- private AspectRatioChangedListener mListener;
- private boolean mInitialized;
- private AspectRatioSelector.AspectRatio mAspectRatio;
- public interface AspectRatioChangedListener {
- public void onAspectRatioChanged(AspectRatioSelector.AspectRatio aspectRatio);
+ /**
+ * Constructs a new AspectRatioDialogLayout object.
+ *
+ * @param context The application context.
+ * @param defaultAspectRatio The default aspect ratio to choose.
+ */
+ public AspectRatioDialogLayout(Context context, Rational defaultAspectRatio) {
+ super(context);
+ mAspectRatio = defaultAspectRatio;
+ mLastOrientation = context.getResources().getConfiguration().orientation;
+ setBackgroundResource(R.color.fullscreen_dialog_background_color);
+ inflate(context, R.layout.aspect_ratio_dialog_content, this);
+ updateSubviewReferences();
}
- public AspectRatioDialogLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- mLastOrientation = getResources().getConfiguration().orientation;
- }
-
- @Override
- public void onFinishInflate() {
- updateViewReference();
- }
-
- private void updateViewReference() {
- mAspectRatioSelector = (AspectRatioSelector) findViewById(R.id.aspect_ratio_selector);
- mConfirmButton = findViewById(R.id.confirm_button);
- mConfirmButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mListener != null) {
- mListener.onAspectRatioChanged(mAspectRatioSelector.getAspectRatio());
- }
- }
- });
- if (mInitialized) {
- mAspectRatioSelector.setAspectRatio(mAspectRatio);
- }
+ public void setListener(AspectRatioDialogListener listener) {
+ mListener = listener;
}
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
+
if (config.orientation == mLastOrientation) {
return;
}
mLastOrientation = config.orientation;
- mAspectRatio = mAspectRatioSelector.getAspectRatio();
+
removeAllViews();
inflate(getContext(), R.layout.aspect_ratio_dialog_content, this);
- updateViewReference();
+ updateSubviewReferences();
}
- public void setAspectRatio(AspectRatioSelector.AspectRatio aspectRatio) {
- mAspectRatioSelector.setAspectRatio(aspectRatio);
+ private void updateSubviewReferences() {
+ mAspectRatio4x3Button = findViewById(R.id.aspect_ratio_4x3_button);
+ mAspectRatio16x9Button = findViewById(R.id.aspect_ratio_16x9_button);
+ mConfirmButton = findViewById(R.id.confirm_button);
+
+ // Set aspect ratio after references to views are established.
+ setAspectRatio(mAspectRatio);
+
+ // Hook onclick events.
+ mAspectRatio4x3Button.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setAspectRatio(ResolutionUtil.ASPECT_RATIO_4x3);
+ }
+ });
+ mAspectRatio16x9Button.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setAspectRatio(ResolutionUtil.ASPECT_RATIO_16x9);
+ }
+ });
+ mConfirmButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mListener != null) {
+ mListener.onConfirm(mAspectRatio);
+ }
+ }
+ });
}
- public void initialize(AspectRatioChangedListener listener,
- AspectRatioSelector.AspectRatio aspectRatio) {
- mInitialized = true;
- mListener = listener;
+ private void setAspectRatio(Rational aspectRatio) {
mAspectRatio = aspectRatio;
- if (mAspectRatioSelector != null) {
- mAspectRatioSelector.setAspectRatio(mAspectRatio);
+
+ if (mAspectRatio.equals(ResolutionUtil.ASPECT_RATIO_4x3)) {
+ // Select 4x3 view and unselect 16x9 view.
+ mAspectRatio4x3Button.setSelected(true);
+ mAspectRatio16x9Button.setSelected(false);
+ } else if (mAspectRatio.equals(ResolutionUtil.ASPECT_RATIO_16x9)) {
+ // Select 16x9 view and unselect 4x3 view.
+ mAspectRatio16x9Button.setSelected(true);
+ mAspectRatio4x3Button.setSelected(false);
}
}
+
+ public interface AspectRatioDialogListener {
+ public void onConfirm(Rational chosenAspectRatio);
+ }
}
diff --git a/src/com/android/camera/widget/AspectRatioSelector.java b/src/com/android/camera/widget/AspectRatioSelector.java
deleted file mode 100644
index fbc550c..0000000
--- a/src/com/android/camera/widget/AspectRatioSelector.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.camera.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.camera2.R;
-
-public class AspectRatioSelector extends LinearLayout {
- public static enum AspectRatio {
- ASPECT_RATIO_4x3,
- ASPECT_RATIO_16x9
- };
-
- private AspectRatio mAspectRatio = AspectRatio.ASPECT_RATIO_4x3;
- private View mAspectRatio4x3Button;
- private View mAspectRatio16x9Button;
-
- public AspectRatioSelector(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void onFinishInflate() {
- mAspectRatio4x3Button = findViewById(R.id.aspect_ratio_4x3_button);
- mAspectRatio4x3Button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- setAspectRatio(AspectRatio.ASPECT_RATIO_4x3);
- }
- });
- mAspectRatio16x9Button = findViewById(R.id.aspect_ratio_16x9_button);
- mAspectRatio16x9Button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- setAspectRatio(AspectRatio.ASPECT_RATIO_16x9);
- }
- });
- }
-
- public void setAspectRatio(AspectRatio aspectRatio) {
- if (aspectRatio == AspectRatio.ASPECT_RATIO_4x3) {
- // Select 4x3 view.
- mAspectRatio4x3Button.setSelected(true);
- // Unselect 16x9 view.
- mAspectRatio16x9Button.setSelected(false);
- } else if (aspectRatio == AspectRatio.ASPECT_RATIO_16x9) {
- // Select 16x9 view.
- mAspectRatio16x9Button.setSelected(true);
- // Unselect 4x3 view.
- mAspectRatio4x3Button.setSelected(false);
- } else {
- // Log error.
- return;
- }
- mAspectRatio = aspectRatio;
- }
-
- public AspectRatio getAspectRatio() {
- return mAspectRatio;
- }
-}
diff --git a/src/com/android/camera/widget/LocationDialogLayout.java b/src/com/android/camera/widget/LocationDialogLayout.java
index 5c6351b..94b829c 100644
--- a/src/com/android/camera/widget/LocationDialogLayout.java
+++ b/src/com/android/camera/widget/LocationDialogLayout.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.res.Configuration;
-import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -26,49 +25,62 @@
import com.android.camera2.R;
+/**
+ * Displays a dialog that allows people to choose whether they like to enable
+ * location recording or not. Please instantiate this class programmatically.
+ */
public class LocationDialogLayout extends FrameLayout {
- public interface LocationTaggingSelectionListener {
- public void onLocationTaggingSelected(boolean selected);
+ public interface LocationDialogListener {
+ public void onConfirm(boolean locationRecordingEnabled);
}
- private View mConfirmButton;
+ private LocationDialogListener mListener;
private CheckBox mCheckBox;
+ private View mConfirmButton;
private int mLastOrientation;
- private LocationTaggingSelectionListener mListener;
- private boolean mCheckBoxChecked = true;
+ private boolean mLocationRecordingEnabled;
- public LocationDialogLayout(Context context, AttributeSet attributeSet) {
- super(context, attributeSet);
+ /**
+ * Constructs a new LocationDialogLayout object.
+ *
+ * @param context The application context.
+ * @param defaultLocationRecordingEnabled Whether to enable location
+ * recording by default.
+ */
+ public LocationDialogLayout(Context context, boolean defaultLocationRecordingEnabled) {
+ super(context);
+ mLocationRecordingEnabled = defaultLocationRecordingEnabled;
mLastOrientation = context.getResources().getConfiguration().orientation;
+ setBackgroundResource(R.color.fullscreen_dialog_background_color);
+ inflate(context, R.layout.location_dialog_content, this);
+ updateSubviewReferences();
}
- @Override
- public void onFinishInflate() {
- updateViewReference();
+ public void setListener(LocationDialogListener listener) {
+ mListener = listener;
}
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
- // TODO: Extract the orientation checking logic in a super class as it
- // is also used in the aspect ratio dialog.
if (config.orientation == mLastOrientation) {
return;
}
mLastOrientation = config.orientation;
+
removeAllViews();
inflate(getContext(), R.layout.location_dialog_content, this);
- updateViewReference();
+ updateSubviewReferences();
}
- private void updateViewReference() {
+ private void updateSubviewReferences() {
mCheckBox = (CheckBox) findViewById(R.id.check_box);
- mCheckBox.setChecked(mCheckBoxChecked);
+ mCheckBox.setChecked(mLocationRecordingEnabled);
mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mCheckBoxChecked = isChecked;
+ mLocationRecordingEnabled = isChecked;
}
});
@@ -77,14 +89,9 @@
@Override
public void onClick(View v) {
if (mListener != null) {
- mListener.onLocationTaggingSelected(mCheckBoxChecked);
+ mListener.onConfirm(mLocationRecordingEnabled);
}
}
});
}
-
- public void setLocationTaggingSelectionListener(LocationTaggingSelectionListener listener) {
- mListener = listener;
- }
-
}