summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml91
-rw-r--r--src/com/android/camera/AndroidCameraManagerImpl.java779
-rw-r--r--src/com/android/camera/AnimationManager.java157
-rw-r--r--src/com/android/camera/CameraActivity.java652
-rw-r--r--src/com/android/camera/CameraBackupAgent.java32
-rw-r--r--src/com/android/camera/CameraButtonIntentReceiver.java53
-rw-r--r--src/com/android/camera/CameraDisabledException.java24
-rw-r--r--src/com/android/camera/CameraErrorCallback.java35
-rw-r--r--src/com/android/camera/CameraHardwareException.java28
-rw-r--r--src/com/android/camera/CameraHolder.java299
-rw-r--r--src/com/android/camera/CameraManager.java317
-rw-r--r--src/com/android/camera/CameraManagerFactory.java37
-rw-r--r--src/com/android/camera/CameraModule.java70
-rw-r--r--src/com/android/camera/CameraPreference.java63
-rw-r--r--src/com/android/camera/CameraScreenNail.java524
-rw-r--r--src/com/android/camera/CameraSettings.java570
-rw-r--r--src/com/android/camera/CaptureAnimManager.java228
-rw-r--r--src/com/android/camera/ComboPreferences.java335
-rw-r--r--src/com/android/camera/CountDownTimerPreference.java48
-rw-r--r--src/com/android/camera/DisableCameraReceiver.java85
-rw-r--r--src/com/android/camera/EffectsRecorder.java1239
-rw-r--r--src/com/android/camera/Exif.java54
-rw-r--r--src/com/android/camera/FocusOverlayManager.java558
-rw-r--r--src/com/android/camera/IconListPreference.java117
-rw-r--r--src/com/android/camera/ImageTaskManager.java48
-rw-r--r--src/com/android/camera/IntArray.java45
-rw-r--r--src/com/android/camera/ListPreference.java202
-rw-r--r--src/com/android/camera/LocationManager.java181
-rw-r--r--src/com/android/camera/MediaSaveService.java233
-rw-r--r--src/com/android/camera/OnClickAttr.java31
-rw-r--r--src/com/android/camera/OnScreenHint.java190
-rw-r--r--src/com/android/camera/OnScreenIndicators.java190
-rw-r--r--src/com/android/camera/PhotoController.java65
-rw-r--r--src/com/android/camera/PhotoMenu.java200
-rw-r--r--src/com/android/camera/PhotoModule.java1985
-rw-r--r--src/com/android/camera/PhotoUI.java854
-rw-r--r--src/com/android/camera/PieController.java259
-rw-r--r--src/com/android/camera/PreferenceGroup.java79
-rw-r--r--src/com/android/camera/PreferenceInflater.java108
-rw-r--r--src/com/android/camera/PreviewFrameLayout.java136
-rw-r--r--src/com/android/camera/PreviewGestures.java199
-rw-r--r--src/com/android/camera/ProxyLauncher.java46
-rw-r--r--src/com/android/camera/RecordLocationPreference.java58
-rw-r--r--src/com/android/camera/RotateDialogController.java169
-rw-r--r--src/com/android/camera/SecureCameraActivity.java23
-rwxr-xr-xsrc/com/android/camera/ShutterButton.java130
-rw-r--r--src/com/android/camera/SoundClips.java197
-rw-r--r--src/com/android/camera/StaticBitmapScreenNail.java32
-rw-r--r--src/com/android/camera/Storage.java181
-rw-r--r--src/com/android/camera/SurfaceTextureRenderer.java224
-rw-r--r--src/com/android/camera/SwitchAnimManager.java146
-rw-r--r--src/com/android/camera/Thumbnail.java68
-rw-r--r--src/com/android/camera/Util.java817
-rw-r--r--src/com/android/camera/VideoController.java42
-rw-r--r--src/com/android/camera/VideoMenu.java205
-rw-r--r--src/com/android/camera/VideoModule.java2225
-rw-r--r--src/com/android/camera/VideoUI.java717
-rw-r--r--src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java100
-rw-r--r--src/com/android/camera/data/CameraDataAdapter.java373
-rw-r--r--src/com/android/camera/data/CameraPreviewData.java63
-rw-r--r--src/com/android/camera/data/FixedFirstDataAdapter.java175
-rw-r--r--src/com/android/camera/data/FixedLastDataAdapter.java160
-rw-r--r--src/com/android/camera/data/LocalData.java822
-rw-r--r--src/com/android/camera/data/LocalDataAdapter.java118
-rw-r--r--src/com/android/camera/data/PanoramaMetadataLoader.java106
-rw-r--r--src/com/android/camera/drawable/TextDrawable.java121
-rw-r--r--src/com/android/camera/ui/AbstractSettingPopup.java44
-rw-r--r--src/com/android/camera/ui/CameraControls.java262
-rw-r--r--src/com/android/camera/ui/CameraRootView.java181
-rw-r--r--src/com/android/camera/ui/CameraSwitcher.java378
-rw-r--r--src/com/android/camera/ui/CheckedLinearLayout.java60
-rw-r--r--src/com/android/camera/ui/CountDownView.java131
-rw-r--r--src/com/android/camera/ui/CountdownTimerPopup.java145
-rw-r--r--src/com/android/camera/ui/EffectSettingPopup.java214
-rw-r--r--src/com/android/camera/ui/ExpandedGridView.java36
-rw-r--r--src/com/android/camera/ui/FaceView.java226
-rw-r--r--src/com/android/camera/ui/FilmStripGestureRecognizer.java112
-rw-r--r--src/com/android/camera/ui/FilmStripView.java1724
-rw-r--r--src/com/android/camera/ui/FocusIndicator.java24
-rw-r--r--src/com/android/camera/ui/InLineSettingCheckBox.java83
-rw-r--r--src/com/android/camera/ui/InLineSettingItem.java94
-rw-r--r--src/com/android/camera/ui/InLineSettingMenu.java78
-rw-r--r--src/com/android/camera/ui/LayoutChangeHelper.java43
-rw-r--r--src/com/android/camera/ui/LayoutChangeNotifier.java28
-rw-r--r--src/com/android/camera/ui/LayoutNotifyView.java48
-rw-r--r--src/com/android/camera/ui/ListPrefSettingPopup.java127
-rw-r--r--src/com/android/camera/ui/MoreSettingPopup.java203
-rw-r--r--src/com/android/camera/ui/OnIndicatorEventListener.java25
-rw-r--r--src/com/android/camera/ui/OverlayRenderer.java95
-rw-r--r--src/com/android/camera/ui/PieItem.java170
-rw-r--r--src/com/android/camera/ui/PieMenuButton.java62
-rw-r--r--src/com/android/camera/ui/PieRenderer.java1091
-rw-r--r--src/com/android/camera/ui/PopupManager.java66
-rw-r--r--src/com/android/camera/ui/PreviewSurfaceView.java50
-rw-r--r--src/com/android/camera/ui/RenderOverlay.java176
-rw-r--r--src/com/android/camera/ui/Rotatable.java22
-rw-r--r--src/com/android/camera/ui/RotatableLayout.java283
-rw-r--r--src/com/android/camera/ui/RotateImageView.java176
-rw-r--r--src/com/android/camera/ui/RotateLayout.java203
-rw-r--r--src/com/android/camera/ui/RotateTextToast.java59
-rw-r--r--src/com/android/camera/ui/Switch.java505
-rw-r--r--src/com/android/camera/ui/TimeIntervalPopup.java164
-rw-r--r--src/com/android/camera/ui/TwoStateImageView.java55
-rw-r--r--src/com/android/camera/ui/ZoomRenderer.java158
-rw-r--r--src/com/android/gallery3d/app/GalleryApp.java1
-rw-r--r--src/com/android/gallery3d/app/GalleryAppImpl.java11
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java76
-rw-r--r--src/com/android/gallery3d/app/StateManager.java1
-rw-r--r--src/com/android/gallery3d/data/Exif.java44
-rw-r--r--src/com/android/gallery3d/data/LocalImage.java5
-rw-r--r--src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java2
-rw-r--r--src/com/android/photos/GalleryActivity.java11
-rw-r--r--src_pd/com/android/camera/PanoramaStitchingManager.java41
-rw-r--r--src_pd/com/android/gallery3d/util/LightCycleHelper.java21
-rw-r--r--src_pd/com/android/gallery3d/util/RefocusHelper.java25
-rwxr-xr-xtests/src/com/android/gallery3d/CameraTestRunner.java46
-rwxr-xr-xtests/src/com/android/gallery3d/StressTests.java47
-rw-r--r--tests/src/com/android/gallery3d/data/GalleryAppStub.java2
-rw-r--r--tests/src/com/android/gallery3d/functional/CameraTest.java81
-rw-r--r--tests/src/com/android/gallery3d/functional/ImageCaptureIntentTest.java148
-rw-r--r--tests/src/com/android/gallery3d/functional/VideoCaptureIntentTest.java258
-rwxr-xr-xtests/src/com/android/gallery3d/stress/CameraLatency.java148
-rw-r--r--tests/src/com/android/gallery3d/stress/CameraStartUp.java155
-rwxr-xr-xtests/src/com/android/gallery3d/stress/CameraStressTestRunner.java61
-rwxr-xr-xtests/src/com/android/gallery3d/stress/ImageCapture.java119
-rw-r--r--tests/src/com/android/gallery3d/stress/ShotToShotLatency.java142
-rwxr-xr-xtests/src/com/android/gallery3d/stress/SwitchPreview.java116
-rw-r--r--tests/src/com/android/gallery3d/stress/TestUtil.java57
-rwxr-xr-xtests/src/com/android/gallery3d/stress/VideoCapture.java112
-rw-r--r--tests/src/com/android/gallery3d/unittest/CameraUnitTest.java107
-rw-r--r--tests_camera/Android.mk16
-rw-r--r--tests_camera/AndroidManifest.xml44
-rw-r--r--tests_camera/src/com/android/camera/CameraLaunchPerformance.java47
-rwxr-xr-xtests_camera/src/com/android/camera/CameraTestRunner.java48
-rwxr-xr-xtests_camera/src/com/android/camera/StressTests.java47
-rw-r--r--tests_camera/src/com/android/camera/UnitTests.java35
-rw-r--r--tests_camera/src/com/android/camera/activity/CameraActivityTest.java53
-rw-r--r--tests_camera/src/com/android/camera/activity/CameraTestCase.java246
-rw-r--r--tests_camera/src/com/android/camera/functional/CameraTest.java81
-rw-r--r--tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java148
-rw-r--r--tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java258
-rwxr-xr-xtests_camera/src/com/android/camera/power/ImageAndVideoCapture.java116
-rwxr-xr-xtests_camera/src/com/android/camera/stress/CameraLatency.java149
-rw-r--r--tests_camera/src/com/android/camera/stress/CameraStartUp.java157
-rwxr-xr-xtests_camera/src/com/android/camera/stress/CameraStressTestRunner.java61
-rwxr-xr-xtests_camera/src/com/android/camera/stress/ImageCapture.java121
-rw-r--r--tests_camera/src/com/android/camera/stress/ShotToShotLatency.java143
-rwxr-xr-xtests_camera/src/com/android/camera/stress/SwitchPreview.java117
-rw-r--r--tests_camera/src/com/android/camera/stress/TestUtil.java57
-rwxr-xr-xtests_camera/src/com/android/camera/stress/VideoCapture.java115
-rw-r--r--tests_camera/src/com/android/camera/unittest/CameraUnitTest.java107
151 files changed, 54 insertions, 30268 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ef1d91459..7aee8663d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,11 +42,8 @@
android:logo="@mipmap/ic_launcher_gallery"
android:hardwareAccelerated="true"
android:largeHeap="true"
- android:backupAgent="com.android.camera.CameraBackupAgent"
android:restoreAnyVersion="true">
<uses-library android:name="com.google.android.media.effects" android:required="false" />
- <meta-data android:name="com.google.android.backup.api_key"
- android:value="AEdPqrEAAAAIRIXquXawbz6duuuCIUAZ_YJv1zbFMMcjZ0NoVw" />
<activity android:name="com.android.gallery3d.app.MovieActivity"
android:label="@string/movie_view_label"
android:configChanges="orientation|keyboardHidden|screenSize">
@@ -288,81 +285,6 @@
<activity android:name="com.android.gallery3d.gadget.WidgetTypeChooser"
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.Gallery.Dialog"/>
- <activity android:name="com.android.camera.CameraActivity"
- android:taskAffinity="com.android.camera.CameraActivity"
- android:label="@string/camera_label"
- android:theme="@style/Theme.Camera"
- android:icon="@mipmap/ic_launcher_camera"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:clearTaskOnLaunch="true"
- android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
- <intent-filter>
- <action android:name="android.media.action.IMAGE_CAPTURE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <meta-data android:name="com.android.keyguard.layout"
- android:resource="@layout/keyguard_widget" />
- </activity>
-
- <activity android:name="com.android.camera.SecureCameraActivity"
- android:taskAffinity="com.android.camera.SecureCameraActivity"
- android:excludeFromRecents="true"
- android:label="@string/camera_label"
- android:theme="@style/Theme.Camera"
- android:icon="@mipmap/ic_launcher_camera"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:clearTaskOnLaunch="true"
- android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
- <intent-filter>
- <action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.media.action.IMAGE_CAPTURE_SECURE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <meta-data android:name="com.android.keyguard.layout"
- android:resource="@layout/keyguard_widget" />
- </activity>
-
- <activity-alias android:icon="@mipmap/ic_launcher_camera"
- android:label="@string/camera_label"
- android:name="com.android.camera.CameraLauncher"
- android:targetActivity="com.android.camera.CameraActivity" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
-
- <activity-alias android:icon="@mipmap/ic_launcher_camera"
- android:label="@string/camera_label"
- android:name="com.android.camera.Camera"
- android:targetActivity="com.android.camera.CameraActivity" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity-alias>
-
- <activity-alias android:icon="@mipmap/ic_launcher_video_camera"
- android:label="@string/video_camera_label"
- android:name="com.android.camera.VideoCamera"
- android:targetActivity="com.android.camera.CameraActivity" >
- <intent-filter>
- <action android:name="android.media.action.VIDEO_CAMERA" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.media.action.VIDEO_CAPTURE" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity-alias>
<receiver android:name="com.android.gallery3d.gadget.PhotoAppWidgetProvider"
android:label="@string/appwidget_title">
@@ -381,16 +303,6 @@
</intent-filter>
</receiver>
<service android:name="com.android.gallery3d.app.PackagesMonitor$AsyncService"/>
- <receiver android:name="com.android.camera.CameraButtonIntentReceiver">
- <intent-filter>
- <action android:name="android.intent.action.CAMERA_BUTTON"/>
- </intent-filter>
- </receiver>
- <receiver android:name="com.android.camera.DisableCameraReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
<service android:name="com.android.gallery3d.gadget.WidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"/>
<activity android:name="com.android.gallery3d.gadget.WidgetConfigure"
@@ -400,9 +312,6 @@
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
- <activity android:name="com.android.camera.ProxyLauncher"
- android:theme="@style/Theme.ProxyLauncher">
- </activity>
<service android:name="com.android.gallery3d.app.BatchService" />
<service android:name="com.android.camera.MediaSaveService" />
</application>
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
deleted file mode 100644
index 897aa9252..000000000
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import static com.android.camera.Util.Assert;
-
-import android.annotation.TargetApi;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.Camera.AutoFocusCallback;
-import android.hardware.Camera.AutoFocusMoveCallback;
-import android.hardware.Camera.ErrorCallback;
-import android.hardware.Camera.FaceDetectionListener;
-import android.hardware.Camera.OnZoomChangeListener;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.PictureCallback;
-import android.hardware.Camera.PreviewCallback;
-import android.hardware.Camera.ShutterCallback;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import com.android.gallery3d.common.ApiHelper;
-
-import java.io.IOException;
-
-/**
- * A class to implement {@link CameraManager} of the Android camera framework.
- */
-class AndroidCameraManagerImpl implements CameraManager {
- private static final String TAG = "CAM_" +
- AndroidCameraManagerImpl.class.getSimpleName();
-
- private Parameters mParameters;
- private boolean mParametersIsDirty;
- private IOException mReconnectIOException;
-
- /* Messages used in CameraHandler. */
- // Camera initialization/finalization
- private static final int OPEN_CAMERA = 1;
- private static final int RELEASE = 2;
- private static final int RECONNECT = 3;
- private static final int UNLOCK = 4;
- private static final int LOCK = 5;
- // Preview
- private static final int SET_PREVIEW_TEXTURE_ASYNC = 101;
- private static final int START_PREVIEW_ASYNC = 102;
- private static final int STOP_PREVIEW = 103;
- private static final int SET_PREVIEW_CALLBACK_WITH_BUFFER = 104;
- private static final int ADD_CALLBACK_BUFFER = 105;
- private static final int SET_PREVIEW_DISPLAY_ASYNC = 106;
- private static final int SET_PREVIEW_CALLBACK = 107;
- // Parameters
- private static final int SET_PARAMETERS = 201;
- private static final int GET_PARAMETERS = 202;
- private static final int REFRESH_PARAMETERS = 203;
- // Focus, Zoom
- private static final int AUTO_FOCUS = 301;
- private static final int CANCEL_AUTO_FOCUS = 302;
- private static final int SET_AUTO_FOCUS_MOVE_CALLBACK = 303;
- private static final int SET_ZOOM_CHANGE_LISTENER = 304;
- // Face detection
- private static final int SET_FACE_DETECTION_LISTENER = 461;
- private static final int START_FACE_DETECTION = 462;
- private static final int STOP_FACE_DETECTION = 463;
- private static final int SET_ERROR_CALLBACK = 464;
- // Presentation
- private static final int ENABLE_SHUTTER_SOUND = 501;
- private static final int SET_DISPLAY_ORIENTATION = 502;
-
- private CameraHandler mCameraHandler;
- private android.hardware.Camera mCamera;
-
- // Used to retain a copy of Parameters for setting parameters.
- private Parameters mParamsToSet;
-
- AndroidCameraManagerImpl() {
- HandlerThread ht = new HandlerThread("Camera Handler Thread");
- ht.start();
- mCameraHandler = new CameraHandler(ht.getLooper());
- }
-
- private class CameraHandler extends Handler {
- CameraHandler(Looper looper) {
- super(looper);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void startFaceDetection() {
- mCamera.startFaceDetection();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void stopFaceDetection() {
- mCamera.stopFaceDetection();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void setFaceDetectionListener(FaceDetectionListener listener) {
- mCamera.setFaceDetectionListener(listener);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- private void setPreviewTexture(Object surfaceTexture) {
- try {
- mCamera.setPreviewTexture((SurfaceTexture) surfaceTexture);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN_MR1)
- private void enableShutterSound(boolean enable) {
- mCamera.enableShutterSound(enable);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void setAutoFocusMoveCallback(
- android.hardware.Camera camera, Object cb) {
- camera.setAutoFocusMoveCallback((AutoFocusMoveCallback) cb);
- }
-
- public void requestTakePicture(
- final ShutterCallback shutter,
- final PictureCallback raw,
- final PictureCallback postView,
- final PictureCallback jpeg) {
- post(new Runnable() {
- @Override
- public void run() {
- try {
- mCamera.takePicture(shutter, raw, postView, jpeg);
- } catch (RuntimeException e) {
- // TODO: output camera state and focus state for debugging.
- Log.e(TAG, "take picture failed.");
- throw e;
- }
- }
- });
- }
-
- /**
- * Waits for all the {@code Message} and {@code Runnable} currently in the queue
- * are processed.
- *
- * @return {@code false} if the wait was interrupted, {@code true} otherwise.
- */
- public boolean waitDone() {
- final Object waitDoneLock = new Object();
- final Runnable unlockRunnable = new Runnable() {
- @Override
- public void run() {
- synchronized (waitDoneLock) {
- waitDoneLock.notifyAll();
- }
- }
- };
-
- synchronized (waitDoneLock) {
- mCameraHandler.post(unlockRunnable);
- try {
- waitDoneLock.wait();
- } catch (InterruptedException ex) {
- Log.v(TAG, "waitDone interrupted");
- return false;
- }
- }
- return true;
- }
-
- /**
- * This method does not deal with the API level check. Everyone should
- * check first for supported operations before sending message to this handler.
- */
- @Override
- public void handleMessage(final Message msg) {
- try {
- switch (msg.what) {
- case OPEN_CAMERA:
- mCamera = android.hardware.Camera.open(msg.arg1);
- if (mCamera != null) {
- mParametersIsDirty = true;
-
- // Get a instance of Camera.Parameters for later use.
- if (mParamsToSet == null) {
- mParamsToSet = mCamera.getParameters();
- }
- }
- return;
-
- case RELEASE:
- mCamera.release();
- mCamera = null;
- return;
-
- case RECONNECT:
- mReconnectIOException = null;
- try {
- mCamera.reconnect();
- } catch (IOException ex) {
- mReconnectIOException = ex;
- }
- return;
-
- case UNLOCK:
- mCamera.unlock();
- return;
-
- case LOCK:
- mCamera.lock();
- return;
-
- case SET_PREVIEW_TEXTURE_ASYNC:
- setPreviewTexture(msg.obj);
- return;
-
- case SET_PREVIEW_DISPLAY_ASYNC:
- try {
- mCamera.setPreviewDisplay((SurfaceHolder) msg.obj);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return;
-
- case START_PREVIEW_ASYNC:
- mCamera.startPreview();
- return;
-
- case STOP_PREVIEW:
- mCamera.stopPreview();
- return;
-
- case SET_PREVIEW_CALLBACK_WITH_BUFFER:
- mCamera.setPreviewCallbackWithBuffer(
- (PreviewCallback) msg.obj);
- return;
-
- case ADD_CALLBACK_BUFFER:
- mCamera.addCallbackBuffer((byte[]) msg.obj);
- return;
-
- case AUTO_FOCUS:
- mCamera.autoFocus((AutoFocusCallback) msg.obj);
- return;
-
- case CANCEL_AUTO_FOCUS:
- mCamera.cancelAutoFocus();
- return;
-
- case SET_AUTO_FOCUS_MOVE_CALLBACK:
- setAutoFocusMoveCallback(mCamera, msg.obj);
- return;
-
- case SET_DISPLAY_ORIENTATION:
- mCamera.setDisplayOrientation(msg.arg1);
- return;
-
- case SET_ZOOM_CHANGE_LISTENER:
- mCamera.setZoomChangeListener(
- (OnZoomChangeListener) msg.obj);
- return;
-
- case SET_FACE_DETECTION_LISTENER:
- setFaceDetectionListener((FaceDetectionListener) msg.obj);
- return;
-
- case START_FACE_DETECTION:
- startFaceDetection();
- return;
-
- case STOP_FACE_DETECTION:
- stopFaceDetection();
- return;
-
- case SET_ERROR_CALLBACK:
- mCamera.setErrorCallback((ErrorCallback) msg.obj);
- return;
-
- case SET_PARAMETERS:
- mParametersIsDirty = true;
- mParamsToSet.unflatten((String) msg.obj);
- mCamera.setParameters(mParamsToSet);
- return;
-
- case GET_PARAMETERS:
- if (mParametersIsDirty) {
- mParameters = mCamera.getParameters();
- mParametersIsDirty = false;
- }
- return;
-
- case SET_PREVIEW_CALLBACK:
- mCamera.setPreviewCallback((PreviewCallback) msg.obj);
- return;
-
- case ENABLE_SHUTTER_SOUND:
- enableShutterSound((msg.arg1 == 1) ? true : false);
- return;
-
- case REFRESH_PARAMETERS:
- mParametersIsDirty = true;
- return;
-
- default:
- throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
- }
- } catch (RuntimeException e) {
- if (msg.what != RELEASE && mCamera != null) {
- try {
- mCamera.release();
- } catch (Exception ex) {
- Log.e(TAG, "Fail to release the camera.");
- }
- mCamera = null;
- }
- throw e;
- }
- }
- }
-
- @Override
- public CameraManager.CameraProxy cameraOpen(int cameraId) {
- mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0).sendToTarget();
- mCameraHandler.waitDone();
- if (mCamera != null) {
- return new AndroidCameraProxyImpl();
- } else {
- return null;
- }
- }
-
- /**
- * A class which implements {@link CameraManager.CameraProxy} and
- * camera handler thread.
- */
- public class AndroidCameraProxyImpl implements CameraManager.CameraProxy {
-
- private AndroidCameraProxyImpl() {
- Assert(mCamera != null);
- }
-
- @Override
- public android.hardware.Camera getCamera() {
- return mCamera;
- }
-
- @Override
- public void release() {
- // release() must be synchronous so we know exactly when the camera
- // is released and can continue on.
- mCameraHandler.sendEmptyMessage(RELEASE);
- mCameraHandler.waitDone();
- }
-
- @Override
- public void reconnect() throws IOException {
- mCameraHandler.sendEmptyMessage(RECONNECT);
- mCameraHandler.waitDone();
- if (mReconnectIOException != null) {
- throw mReconnectIOException;
- }
- }
-
- @Override
- public void unlock() {
- mCameraHandler.sendEmptyMessage(UNLOCK);
- mCameraHandler.waitDone();
- }
-
- @Override
- public void lock() {
- mCameraHandler.sendEmptyMessage(LOCK);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- @Override
- public void setPreviewTexture(SurfaceTexture surfaceTexture) {
- mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture).sendToTarget();
- }
-
- @Override
- public void setPreviewDisplay(SurfaceHolder surfaceHolder) {
- mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder).sendToTarget();
- }
-
- @Override
- public void startPreview() {
- mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
- }
-
- @Override
- public void stopPreview() {
- mCameraHandler.sendEmptyMessage(STOP_PREVIEW);
- mCameraHandler.waitDone();
- }
-
- @Override
- public void setPreviewDataCallback(
- Handler handler, CameraPreviewDataCallback cb) {
- mCameraHandler.obtainMessage(
- SET_PREVIEW_CALLBACK,
- PreviewCallbackForward.getNewInstance(handler, this, cb)).sendToTarget();
- }
-
- @Override
- public void setPreviewDataCallbackWithBuffer(
- Handler handler, CameraPreviewDataCallback cb) {
- mCameraHandler.obtainMessage(
- SET_PREVIEW_CALLBACK_WITH_BUFFER,
- PreviewCallbackForward.getNewInstance(handler, this, cb)).sendToTarget();
- }
-
- @Override
- public void addCallbackBuffer(byte[] callbackBuffer) {
- mCameraHandler.obtainMessage(ADD_CALLBACK_BUFFER, callbackBuffer).sendToTarget();
- }
-
- @Override
- public void autoFocus(Handler handler, CameraAFCallback cb) {
- mCameraHandler.obtainMessage(
- AUTO_FOCUS,
- AFCallbackForward.getNewInstance(handler, this, cb)).sendToTarget();
- }
-
- @Override
- public void cancelAutoFocus() {
- mCameraHandler.removeMessages(AUTO_FOCUS);
- mCameraHandler.sendEmptyMessage(CANCEL_AUTO_FOCUS);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- @Override
- public void setAutoFocusMoveCallback(
- Handler handler, CameraAFMoveCallback cb) {
- mCameraHandler.obtainMessage(
- SET_AUTO_FOCUS_MOVE_CALLBACK,
- AFMoveCallbackForward.getNewInstance(handler, this, cb)).sendToTarget();
- }
-
- @Override
- public void takePicture(
- Handler handler,
- CameraShutterCallback shutter,
- CameraPictureCallback raw,
- CameraPictureCallback post,
- CameraPictureCallback jpeg) {
- mCameraHandler.requestTakePicture(
- ShutterCallbackForward.getNewInstance(handler, this, shutter),
- PictureCallbackForward.getNewInstance(handler, this, raw),
- PictureCallbackForward.getNewInstance(handler, this, post),
- PictureCallbackForward.getNewInstance(handler, this, jpeg));
- }
-
- @Override
- public void setDisplayOrientation(int degrees) {
- mCameraHandler.obtainMessage(SET_DISPLAY_ORIENTATION, degrees, 0)
- .sendToTarget();
- }
-
- @Override
- public void setZoomChangeListener(OnZoomChangeListener listener) {
- mCameraHandler.obtainMessage(SET_ZOOM_CHANGE_LISTENER, listener).sendToTarget();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- public void setFaceDetectionCallback(
- Handler handler, CameraFaceDetectionCallback cb) {
- mCameraHandler.obtainMessage(
- SET_FACE_DETECTION_LISTENER,
- FaceDetectionCallbackForward.getNewInstance(handler, this, cb)).sendToTarget();
- }
-
- @Override
- public void startFaceDetection() {
- mCameraHandler.sendEmptyMessage(START_FACE_DETECTION);
- }
-
- @Override
- public void stopFaceDetection() {
- mCameraHandler.sendEmptyMessage(STOP_FACE_DETECTION);
- }
-
- @Override
- public void setErrorCallback(ErrorCallback cb) {
- mCameraHandler.obtainMessage(SET_ERROR_CALLBACK, cb).sendToTarget();
- }
-
- @Override
- public void setParameters(Parameters params) {
- if (params == null) {
- Log.v(TAG, "null parameters in setParameters()");
- return;
- }
- mCameraHandler.obtainMessage(SET_PARAMETERS, params.flatten())
- .sendToTarget();
- }
-
- @Override
- public Parameters getParameters() {
- mCameraHandler.sendEmptyMessage(GET_PARAMETERS);
- mCameraHandler.waitDone();
- return mParameters;
- }
-
- @Override
- public void refreshParameters() {
- mCameraHandler.sendEmptyMessage(REFRESH_PARAMETERS);
- }
-
- @Override
- public void enableShutterSound(boolean enable) {
- mCameraHandler.obtainMessage(
- ENABLE_SHUTTER_SOUND, (enable ? 1 : 0), 0).sendToTarget();
- }
- }
-
- /**
- * A helper class to forward AutoFocusCallback to another thread.
- */
- private static class AFCallbackForward implements AutoFocusCallback {
- private final Handler mHandler;
- private final CameraProxy mCamera;
- private final CameraAFCallback mCallback;
-
- /**
- * Returns a new instance of {@link AFCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link AFCallbackForward},
- * or null if any parameter is null.
- */
- public static AFCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraAFCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new AFCallbackForward(handler, camera, cb);
- }
-
- private AFCallbackForward(
- Handler h, CameraProxy camera, CameraAFCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onAutoFocus(final boolean b, Camera camera) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onAutoFocus(b, mCamera);
- }
- });
- }
- }
-
- /** A helper class to forward AutoFocusMoveCallback to another thread. */
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private static class AFMoveCallbackForward implements AutoFocusMoveCallback {
- private final Handler mHandler;
- private final CameraAFMoveCallback mCallback;
- private final CameraProxy mCamera;
-
- /**
- * Returns a new instance of {@link AFMoveCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link AFMoveCallbackForward},
- * or null if any parameter is null.
- */
- public static AFMoveCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraAFMoveCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new AFMoveCallbackForward(handler, camera, cb);
- }
-
- private AFMoveCallbackForward(
- Handler h, CameraProxy camera, CameraAFMoveCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onAutoFocusMoving(
- final boolean moving, android.hardware.Camera camera) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onAutoFocusMoving(moving, mCamera);
- }
- });
- }
- }
-
- /**
- * A helper class to forward ShutterCallback to to another thread.
- */
- private static class ShutterCallbackForward implements ShutterCallback {
- private final Handler mHandler;
- private final CameraShutterCallback mCallback;
- private final CameraProxy mCamera;
-
- /**
- * Returns a new instance of {@link ShutterCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link ShutterCallbackForward},
- * or null if any parameter is null.
- */
- public static ShutterCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraShutterCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new ShutterCallbackForward(handler, camera, cb);
- }
-
- private ShutterCallbackForward(
- Handler h, CameraProxy camera, CameraShutterCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onShutter() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onShutter(mCamera);
- }
- });
- }
- }
-
- /**
- * A helper class to forward PictureCallback to another thread.
- */
- private static class PictureCallbackForward implements PictureCallback {
- private final Handler mHandler;
- private final CameraPictureCallback mCallback;
- private final CameraProxy mCamera;
-
- /**
- * Returns a new instance of {@link PictureCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link PictureCallbackForward},
- * or null if any parameters is null.
- */
- public static PictureCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraPictureCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new PictureCallbackForward(handler, camera, cb);
- }
-
- private PictureCallbackForward(
- Handler h, CameraProxy camera, CameraPictureCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onPictureTaken(
- final byte[] data, android.hardware.Camera camera) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onPictureTaken(data, mCamera);
- }
- });
- }
- }
-
- /**
- * A helper class to forward PreviewCallback to another thread.
- */
- private static class PreviewCallbackForward implements PreviewCallback {
- private final Handler mHandler;
- private final CameraPreviewDataCallback mCallback;
- private final CameraProxy mCamera;
-
- /**
- * Returns a new instance of {@link PreviewCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link PreviewCallbackForward},
- * or null if any parameters is null.
- */
- public static PreviewCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new PreviewCallbackForward(handler, camera, cb);
- }
-
- private PreviewCallbackForward(
- Handler h, CameraProxy camera, CameraPreviewDataCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onPreviewFrame(
- final byte[] data, android.hardware.Camera camera) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onPreviewFrame(data, mCamera);
- }
- });
- }
- }
-
- private static class FaceDetectionCallbackForward implements FaceDetectionListener {
- private final Handler mHandler;
- private final CameraFaceDetectionCallback mCallback;
- private final CameraProxy mCamera;
-
- /**
- * Returns a new instance of {@link FaceDetectionCallbackForward}.
- *
- * @param handler The handler in which the callback will be invoked in.
- * @param camera The {@link CameraProxy} which the callback is from.
- * @param cb The callback to be invoked.
- * @return The instance of the {@link FaceDetectionCallbackForward},
- * or null if any parameter is null.
- */
- public static FaceDetectionCallbackForward getNewInstance(
- Handler handler, CameraProxy camera, CameraFaceDetectionCallback cb) {
- if (handler == null || camera == null || cb == null) return null;
- return new FaceDetectionCallbackForward(handler, camera, cb);
- }
-
- private FaceDetectionCallbackForward(
- Handler h, CameraProxy camera, CameraFaceDetectionCallback cb) {
- mHandler = h;
- mCamera = camera;
- mCallback = cb;
- }
-
- @Override
- public void onFaceDetection(
- final Camera.Face[] faces, Camera camera) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mCallback.onFaceDetection(faces, mCamera);
- }
- });
- }
- }
-}
diff --git a/src/com/android/camera/AnimationManager.java b/src/com/android/camera/AnimationManager.java
deleted file mode 100644
index 41aa4b862..000000000
--- a/src/com/android/camera/AnimationManager.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.view.View;
-
-/**
- * Class to handle animations.
- */
-
-public class AnimationManager {
-
- public static final float FLASH_ALPHA_START = 0.3f;
- public static final float FLASH_ALPHA_END = 0f;
- public static final int FLASH_DURATION = 300;
-
- public static final int SHRINK_DURATION = 400;
- public static final int HOLD_DURATION = 2500;
- public static final int SLIDE_DURATION = 1100;
-
- private ObjectAnimator mFlashAnim;
- private AnimatorSet mCaptureAnimator;
-
- /**
- * Starts capture animation.
- * @param view a thumbnail view that shows a picture captured and gets animated
- */
- public void startCaptureAnimation(final View view) {
- if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
- mCaptureAnimator.cancel();
- }
- View parentView = (View) view.getParent();
- float slideDistance = (float) (parentView.getWidth() - view.getLeft());
-
- float scaleX = ((float) parentView.getWidth()) / ((float) view.getWidth());
- float scaleY = ((float) parentView.getHeight()) / ((float) view.getHeight());
- float scale = scaleX > scaleY ? scaleX : scaleY;
-
- int centerX = view.getLeft() + view.getWidth() / 2;
- int centerY = view.getTop() + view.getHeight() / 2;
-
- ObjectAnimator slide = ObjectAnimator.ofFloat(view, "translationX", 0f, slideDistance)
- .setDuration(AnimationManager.SLIDE_DURATION);
- slide.setStartDelay(AnimationManager.SHRINK_DURATION + AnimationManager.HOLD_DURATION);
- mCaptureAnimator = new AnimatorSet();
- mCaptureAnimator.playTogether(
- ObjectAnimator.ofFloat(view, "scaleX", scale, 1f)
- .setDuration(AnimationManager.SHRINK_DURATION),
- ObjectAnimator.ofFloat(view, "scaleY", scale, 1f)
- .setDuration(AnimationManager.SHRINK_DURATION),
- ObjectAnimator.ofFloat(view, "translationX",
- parentView.getWidth() / 2 - centerX, 0f)
- .setDuration(AnimationManager.SHRINK_DURATION),
- ObjectAnimator.ofFloat(view, "translationY",
- parentView.getHeight() / 2 - centerY, 0f)
- .setDuration(AnimationManager.SHRINK_DURATION),
- slide);
- mCaptureAnimator.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animator) {
- view.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- view.setScaleX(1f);
- view.setScaleX(1f);
- view.setTranslationX(0f);
- view.setTranslationY(0f);
- view.setVisibility(View.INVISIBLE);
- mCaptureAnimator.removeAllListeners();
- mCaptureAnimator = null;
- }
-
- @Override
- public void onAnimationCancel(Animator animator) {
- view.setVisibility(View.INVISIBLE);
- }
-
- @Override
- public void onAnimationRepeat(Animator animator) {
- // Do nothing.
- }
- });
- mCaptureAnimator.start();
- }
-
- /**
- * Starts flash animation.
- * @params flashOverlay the overlay that will animate on alpha to make the flash impression
- */
- public void startFlashAnimation(final View flashOverlay) {
- // End the previous animation if the previous one is still running
- if (mFlashAnim != null && mFlashAnim.isRunning()) {
- mFlashAnim.cancel();
- }
- // Start new flash animation.
- mFlashAnim = ObjectAnimator.ofFloat(flashOverlay, "alpha",
- AnimationManager.FLASH_ALPHA_START, AnimationManager.FLASH_ALPHA_END);
- mFlashAnim.setDuration(AnimationManager.FLASH_DURATION);
- mFlashAnim.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animator) {
- flashOverlay.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- flashOverlay.setAlpha(0f);
- flashOverlay.setVisibility(View.GONE);
- mFlashAnim.removeAllListeners();
- mFlashAnim = null;
- }
-
- @Override
- public void onAnimationCancel(Animator animator) {
- // Do nothing.
- }
-
- @Override
- public void onAnimationRepeat(Animator animator) {
- // Do nothing.
- }
- });
- mFlashAnim.start();
- }
-
- /**
- * Cancels on-going flash animation and capture animation, if any.
- */
- public void cancelAnimations() {
- // End the previous animation if the previous one is still running
- if (mFlashAnim != null && mFlashAnim.isRunning()) {
- mFlashAnim.cancel();
- }
- if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
- mCaptureAnimator.cancel();
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
deleted file mode 100644
index d4e7f1865..000000000
--- a/src/com/android/camera/CameraActivity.java
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.OrientationEventListener;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.ImageView;
-import android.widget.ProgressBar;
-
-import com.android.camera.data.CameraDataAdapter;
-import com.android.camera.data.CameraPreviewData;
-import com.android.camera.data.FixedFirstDataAdapter;
-import com.android.camera.data.FixedLastDataAdapter;
-import com.android.camera.data.LocalData;
-import com.android.camera.data.LocalDataAdapter;
-import com.android.camera.ui.CameraSwitcher;
-import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
-import com.android.camera.ui.FilmStripView;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.util.LightCycleHelper;
-import com.android.gallery3d.util.PanoramaViewHelper;
-import com.android.gallery3d.util.RefocusHelper;
-
-public class CameraActivity extends Activity
- implements CameraSwitchListener {
-
- private static final String TAG = "CAM_Activity";
-
- private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
- "android.media.action.STILL_IMAGE_CAMERA_SECURE";
- public static final String ACTION_IMAGE_CAPTURE_SECURE =
- "android.media.action.IMAGE_CAPTURE_SECURE";
-
- // The intent extra for camera from secure lock screen. True if the gallery
- // should only show newly captured pictures. sSecureAlbumId does not
- // increment. This is used when switching between camera, camcorder, and
- // panorama. If the extra is not set, it is in the normal camera mode.
- public static final String SECURE_CAMERA_EXTRA = "secure_camera";
-
- /** This data adapter is used by FilmStirpView. */
- private LocalDataAdapter mDataAdapter;
- /** This data adapter represents the real local camera data. */
- private LocalDataAdapter mWrappedDataAdapter;
-
- private PanoramaStitchingManager mPanoramaManager;
- private int mCurrentModuleIndex;
- private CameraModule mCurrentModule;
- private View mRootView;
- private FilmStripView mFilmStripView;
- private ProgressBar mBottomProgress;
- private View mPanoStitchingPanel;
- private int mResultCodeForTesting;
- private Intent mResultDataForTesting;
- private OnScreenHint mStorageHint;
- private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
- private boolean mAutoRotateScreen;
- private boolean mSecureCamera;
- // This is a hack to speed up the start of SecureCamera.
- private static boolean sFirstStartAfterScreenOn = true;
- private boolean mShowCameraPreview;
- private int mLastRawOrientation;
- private MyOrientationEventListener mOrientationListener;
- private Handler mMainHandler;
- private PanoramaViewHelper mPanoramaViewHelper;
- private CameraPreviewData mCameraPreviewData;
-
- private class MyOrientationEventListener
- extends OrientationEventListener {
- public MyOrientationEventListener(Context context) {
- super(context);
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- // We keep the last known orientation. So if the user first orient
- // the camera then point the camera to floor or sky, we still have
- // the correct orientation.
- if (orientation == ORIENTATION_UNKNOWN) return;
- mLastRawOrientation = orientation;
- mCurrentModule.onOrientationChanged(orientation);
- }
- }
-
- private MediaSaveService mMediaSaveService;
- private ServiceConnection mConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName className, IBinder b) {
- mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
- mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
- }
- @Override
- public void onServiceDisconnected(ComponentName className) {
- mMediaSaveService = null;
- }};
-
- // close activity when screen turns off
- private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- finish();
- }
- };
-
- private static BroadcastReceiver sScreenOffReceiver;
- private static class ScreenOffReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- sFirstStartAfterScreenOn = true;
- }
- }
-
- public static boolean isFirstStartAfterScreenOn() {
- return sFirstStartAfterScreenOn;
- }
-
- public static void resetFirstStartAfterScreenOn() {
- sFirstStartAfterScreenOn = false;
- }
-
- private FilmStripView.Listener mFilmStripListener =
- new FilmStripView.Listener() {
- @Override
- public void onDataPromoted(int dataID) {
- removeData(dataID);
- }
-
- @Override
- public void onDataDemoted(int dataID) {
- removeData(dataID);
- }
-
- @Override
- public void onDataFullScreenChange(int dataID, boolean full) {
- }
-
- @Override
- public void onSwitchMode(boolean toCamera) {
- mCurrentModule.onSwitchMode(toCamera);
- }
-
- @Override
- public void onCurrentDataChanged(int dataID, boolean current) {
- if (!current) {
- hidePanoStitchingProgress();
- } else {
- LocalData currentData = mDataAdapter.getLocalData(dataID);
- if (currentData == null) {
- Log.w(TAG, "Current data ID not found.");
- hidePanoStitchingProgress();
- return;
- }
- Uri contentUri = currentData.getContentUri();
- if (contentUri == null) {
- hidePanoStitchingProgress();
- return;
- }
- int panoStitchingProgress = mPanoramaManager.getTaskProgress(contentUri);
- if (panoStitchingProgress < 0) {
- hidePanoStitchingProgress();
- return;
- }
- showPanoStitchingProgress();
- updateStitchingProgress(panoStitchingProgress);
- }
- }
- };
-
- private void hidePanoStitchingProgress() {
- mPanoStitchingPanel.setVisibility(View.GONE);
- }
-
- private void showPanoStitchingProgress() {
- mPanoStitchingPanel.setVisibility(View.VISIBLE);
- }
-
- private void updateStitchingProgress(int progress) {
- mBottomProgress.setProgress(progress);
- }
-
- private Runnable mDeletionRunnable = new Runnable() {
- @Override
- public void run() {
- mDataAdapter.executeDeletion(CameraActivity.this);
- }
- };
-
- private ImageTaskManager.TaskListener mStitchingListener =
- new ImageTaskManager.TaskListener() {
- @Override
- public void onTaskQueued(String filePath, final Uri imageUri) {
- mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyNewMedia(imageUri);
- }
- });
- }
-
- @Override
- public void onTaskDone(String filePath, final Uri imageUri) {
- Log.v(TAG, "onTaskDone:" + filePath);
- mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- int doneID = mDataAdapter.findDataByContentUri(imageUri);
- int currentDataId = mFilmStripView.getCurrentId();
-
- if (currentDataId == doneID) {
- hidePanoStitchingProgress();
- updateStitchingProgress(0);
- }
-
- mDataAdapter.refresh(getContentResolver(), imageUri);
- }
- });
- }
-
- @Override
- public void onTaskProgress(
- String filePath, final Uri imageUri, final int progress) {
- mMainHandler.post(new Runnable() {
- @Override
- public void run() {
- int currentDataId = mFilmStripView.getCurrentId();
- if (currentDataId == -1) {
- return;
- }
- if (imageUri.equals(
- mDataAdapter.getLocalData(currentDataId).getContentUri())) {
- updateStitchingProgress(progress);
- }
- }
- });
- }
- };
-
- public MediaSaveService getMediaSaveService() {
- return mMediaSaveService;
- }
-
- public void notifyNewMedia(Uri uri) {
- ContentResolver cr = getContentResolver();
- String mimeType = cr.getType(uri);
- if (mimeType.startsWith("video/")) {
- sendBroadcast(new Intent(Util.ACTION_NEW_VIDEO, uri));
- mDataAdapter.addNewVideo(cr, uri);
- } else if (mimeType.startsWith("image/")) {
- Util.broadcastNewPicture(this, uri);
- mDataAdapter.addNewPhoto(cr, uri);
- } else if (mimeType.startsWith("application/stitching-preview")) {
- mDataAdapter.addNewPhoto(cr, uri);
- } else {
- android.util.Log.w(TAG, "Unknown new media with MIME type:"
- + mimeType + ", uri:" + uri);
- }
- }
-
- private void removeData(int dataID) {
- mDataAdapter.removeData(CameraActivity.this, dataID);
- mMainHandler.removeCallbacks(mDeletionRunnable);
- mMainHandler.postDelayed(mDeletionRunnable, 3000);
- }
-
- private void bindMediaSaveService() {
- Intent intent = new Intent(this, MediaSaveService.class);
- startService(intent); // start service before binding it so the
- // service won't be killed if we unbind it.
- bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
- }
-
- private void unbindMediaSaveService() {
- if (mMediaSaveService != null) {
- mMediaSaveService.setListener(null);
- }
- if (mConnection != null) {
- unbindService(mConnection);
- }
- }
-
- @Override
- public void onCreate(Bundle state) {
- super.onCreate(state);
- setContentView(R.layout.camera_filmstrip);
- if (ApiHelper.HAS_ROTATION_ANIMATION) {
- setRotationAnimation();
- }
- // Check if this is in the secure camera mode.
- Intent intent = getIntent();
- String action = intent.getAction();
- if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
- || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
- mSecureCamera = true;
- } else {
- mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
- }
-
- if (mSecureCamera) {
- // Change the window flags so that secure camera can show when locked
- Window win = getWindow();
- WindowManager.LayoutParams params = win.getAttributes();
- params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
- win.setAttributes(params);
-
- // Filter for screen off so that we can finish secure camera activity
- // when screen is off.
- IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
- registerReceiver(mScreenOffReceiver, filter);
- // TODO: This static screen off event receiver is a workaround to the
- // double onResume() invocation (onResume->onPause->onResume). We should
- // find a better solution to this.
- if (sScreenOffReceiver == null) {
- sScreenOffReceiver = new ScreenOffReceiver();
- registerReceiver(sScreenOffReceiver, filter);
- }
- }
- mPanoramaManager = new PanoramaStitchingManager(CameraActivity.this);
- mPanoramaManager.addTaskListener(mStitchingListener);
- LayoutInflater inflater = getLayoutInflater();
- View rootLayout = inflater.inflate(R.layout.camera, null, false);
- mRootView = rootLayout.findViewById(R.id.camera_app_root);
- mPanoStitchingPanel = (View) findViewById(R.id.pano_stitching_progress_panel);
- mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);
- mCameraPreviewData = new CameraPreviewData(rootLayout,
- FilmStripView.ImageData.SIZE_FULL,
- FilmStripView.ImageData.SIZE_FULL);
- // Put a CameraPreviewData at the first position.
- mWrappedDataAdapter = new FixedFirstDataAdapter(
- new CameraDataAdapter(new ColorDrawable(
- getResources().getColor(R.color.photo_placeholder))),
- mCameraPreviewData);
- mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
- mFilmStripView.setViewGap(
- getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
- mPanoramaViewHelper = new PanoramaViewHelper(this);
- mPanoramaViewHelper.onCreate();
- mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
- // Set up the camera preview first so the preview shows up ASAP.
- mFilmStripView.setListener(mFilmStripListener);
- mCurrentModule = new PhotoModule();
- mCurrentModule.init(this, mRootView);
- mOrientationListener = new MyOrientationEventListener(this);
- mMainHandler = new Handler(getMainLooper());
- bindMediaSaveService();
-
- if (!mSecureCamera) {
- mDataAdapter = mWrappedDataAdapter;
- mDataAdapter.requestLoad(getContentResolver());
- } else {
- // Put a lock placeholder as the last image by setting its date to 0.
- ImageView v = (ImageView) getLayoutInflater().inflate(
- R.layout.secure_album_placeholder, null);
- mDataAdapter = new FixedLastDataAdapter(
- mWrappedDataAdapter,
- new LocalData.LocalViewData(
- v,
- v.getDrawable().getIntrinsicWidth(),
- v.getDrawable().getIntrinsicHeight(),
- 0, 0));
- // Flush out all the original data.
- mDataAdapter.flush();
- }
- mFilmStripView.setDataAdapter(mDataAdapter);
- }
-
- private void setRotationAnimation() {
- int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
- rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
- Window win = getWindow();
- WindowManager.LayoutParams winParams = win.getAttributes();
- winParams.rotationAnimation = rotationAnimation;
- win.setAttributes(winParams);
- }
-
- @Override
- public void onUserInteraction() {
- super.onUserInteraction();
- mCurrentModule.onUserInteraction();
- }
-
- @Override
- public void onPause() {
- mOrientationListener.disable();
- mCurrentModule.onPauseBeforeSuper();
- super.onPause();
- mCurrentModule.onPauseAfterSuper();
- }
-
- @Override
- public void onResume() {
- if (Settings.System.getInt(getContentResolver(),
- Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {// auto-rotate off
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- mAutoRotateScreen = false;
- } else {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
- mAutoRotateScreen = true;
- }
- mOrientationListener.enable();
- mCurrentModule.onResumeBeforeSuper();
- super.onResume();
- mCurrentModule.onResumeAfterSuper();
-
- setSwipingEnabled(true);
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- mPanoramaViewHelper.onStart();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- mPanoramaViewHelper.onStop();
- }
-
- @Override
- public void onDestroy() {
- unbindMediaSaveService();
- if (mSecureCamera) unregisterReceiver(mScreenOffReceiver);
- super.onDestroy();
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- super.onConfigurationChanged(config);
- mCurrentModule.onConfigurationChanged(config);
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mCurrentModule.onKeyDown(keyCode, event)) return true;
- // Prevent software keyboard or voice search from showing up.
- if (keyCode == KeyEvent.KEYCODE_SEARCH
- || keyCode == KeyEvent.KEYCODE_MENU) {
- if (event.isLongPress()) return true;
- }
- if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraPreview) {
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mCurrentModule.onKeyUp(keyCode, event)) return true;
- if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraPreview) {
- return true;
- }
- return super.onKeyUp(keyCode, event);
- }
-
- public boolean isAutoRotateScreen() {
- return mAutoRotateScreen;
- }
-
- protected void updateStorageSpace() {
- mStorageSpace = Storage.getAvailableSpace();
- }
-
- protected long getStorageSpace() {
- return mStorageSpace;
- }
-
- protected void updateStorageSpaceAndHint() {
- updateStorageSpace();
- updateStorageHint(mStorageSpace);
- }
-
- protected void updateStorageHint() {
- updateStorageHint(mStorageSpace);
- }
-
- protected boolean updateStorageHintOnResume() {
- return true;
- }
-
- protected void updateStorageHint(long storageSpace) {
- String message = null;
- if (storageSpace == Storage.UNAVAILABLE) {
- message = getString(R.string.no_storage);
- } else if (storageSpace == Storage.PREPARING) {
- message = getString(R.string.preparing_sd);
- } else if (storageSpace == Storage.UNKNOWN_SIZE) {
- message = getString(R.string.access_sd_fail);
- } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
- message = getString(R.string.spaceIsLow_content);
- }
-
- if (message != null) {
- if (mStorageHint == null) {
- mStorageHint = OnScreenHint.makeText(this, message);
- } else {
- mStorageHint.setText(message);
- }
- mStorageHint.show();
- } else if (mStorageHint != null) {
- mStorageHint.cancel();
- mStorageHint = null;
- }
- }
-
- protected void setResultEx(int resultCode) {
- mResultCodeForTesting = resultCode;
- setResult(resultCode);
- }
-
- protected void setResultEx(int resultCode, Intent data) {
- mResultCodeForTesting = resultCode;
- mResultDataForTesting = data;
- setResult(resultCode, data);
- }
-
- public int getResultCode() {
- return mResultCodeForTesting;
- }
-
- public Intent getResultData() {
- return mResultDataForTesting;
- }
-
- public boolean isSecureCamera() {
- return mSecureCamera;
- }
-
- @Override
- public void onCameraSelected(int i) {
- if (mCurrentModuleIndex == i) return;
-
- CameraHolder.instance().keep();
- closeModule(mCurrentModule);
- mCurrentModuleIndex = i;
- switch (i) {
- case CameraSwitcher.VIDEO_MODULE_INDEX:
- mCurrentModule = new VideoModule();
- break;
- case CameraSwitcher.PHOTO_MODULE_INDEX:
- mCurrentModule = new PhotoModule();
- break;
- case CameraSwitcher.LIGHTCYCLE_MODULE_INDEX:
- mCurrentModule = LightCycleHelper.createPanoramaModule();
- break;
- case CameraSwitcher.REFOCUS_MODULE_INDEX:
- mCurrentModule = RefocusHelper.createRefocusModule();
- break;
- default:
- break;
- }
-
- openModule(mCurrentModule);
- mCurrentModule.onOrientationChanged(mLastRawOrientation);
- if (mMediaSaveService != null) {
- mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
- }
- }
-
- private void openModule(CameraModule module) {
- module.init(this, mRootView);
- module.onResumeBeforeSuper();
- module.onResumeAfterSuper();
- }
-
- private void closeModule(CameraModule module) {
- module.onPauseBeforeSuper();
- module.onPauseAfterSuper();
- ((ViewGroup) mRootView).removeAllViews();
- }
-
- @Override
- public void onShowSwitcherPopup() {
- }
-
- public void setSwipingEnabled(boolean enable) {
- mCameraPreviewData.lockPreview(!enable);
- }
-
- // Accessor methods for getting latency times used in performance testing
- public long getAutoFocusTime() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
- }
-
- public long getShutterLag() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mShutterLag : -1;
- }
-
- public long getShutterToPictureDisplayedTime() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
- }
-
- public long getPictureDisplayedToJpegCallbackTime() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
- }
-
- public long getJpegCallbackFinishTime() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
- }
-
- public long getCaptureStartTime() {
- return (mCurrentModule instanceof PhotoModule) ?
- ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
- }
-
- public boolean isRecording() {
- return (mCurrentModule instanceof VideoModule) ?
- ((VideoModule) mCurrentModule).isRecording() : false;
- }
-}
diff --git a/src/com/android/camera/CameraBackupAgent.java b/src/com/android/camera/CameraBackupAgent.java
deleted file mode 100644
index 30ba212df..000000000
--- a/src/com/android/camera/CameraBackupAgent.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.SharedPreferencesBackupHelper;
-import android.content.Context;
-
-public class CameraBackupAgent extends BackupAgentHelper {
- private static final String CAMERA_BACKUP_KEY = "camera_prefs";
-
- public void onCreate () {
- Context context = getApplicationContext();
- String prefNames[] = ComboPreferences.getSharedPreferencesNames(context);
-
- addHelper(CAMERA_BACKUP_KEY, new SharedPreferencesBackupHelper(context, prefNames));
- }
-}
diff --git a/src/com/android/camera/CameraButtonIntentReceiver.java b/src/com/android/camera/CameraButtonIntentReceiver.java
deleted file mode 100644
index a65942d57..000000000
--- a/src/com/android/camera/CameraButtonIntentReceiver.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * {@code CameraButtonIntentReceiver} is invoked when the camera button is
- * long-pressed.
- *
- * It is declared in {@code AndroidManifest.xml} to receive the
- * {@code android.intent.action.CAMERA_BUTTON} intent.
- *
- * After making sure we can use the camera hardware, it starts the Camera
- * activity.
- */
-public class CameraButtonIntentReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // Try to get the camera hardware
- CameraHolder holder = CameraHolder.instance();
- ComboPreferences pref = new ComboPreferences(context);
- int cameraId = CameraSettings.readPreferredCameraId(pref);
- if (holder.tryOpen(cameraId) == null) return;
-
- // We are going to launch the camera, so hold the camera for later use
- holder.keep();
- holder.release();
- Intent i = new Intent(Intent.ACTION_MAIN);
- i.setClass(context, CameraActivity.class);
- i.addCategory(Intent.CATEGORY_LAUNCHER);
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- context.startActivity(i);
- }
-}
diff --git a/src/com/android/camera/CameraDisabledException.java b/src/com/android/camera/CameraDisabledException.java
deleted file mode 100644
index 512809be6..000000000
--- a/src/com/android/camera/CameraDisabledException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-/**
- * This class represents the condition that device policy manager has disabled
- * the camera.
- */
-public class CameraDisabledException extends Exception {
-}
diff --git a/src/com/android/camera/CameraErrorCallback.java b/src/com/android/camera/CameraErrorCallback.java
deleted file mode 100644
index 22f800ef9..000000000
--- a/src/com/android/camera/CameraErrorCallback.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.util.Log;
-
-public class CameraErrorCallback
- implements android.hardware.Camera.ErrorCallback {
- private static final String TAG = "CameraErrorCallback";
-
- @Override
- public void onError(int error, android.hardware.Camera camera) {
- Log.e(TAG, "Got camera error callback. error=" + error);
- if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
- // We are not sure about the current state of the app (in preview or
- // snapshot or recording). Closing the app is better than creating a
- // new Camera object.
- throw new RuntimeException("Media server died.");
- }
- }
-}
diff --git a/src/com/android/camera/CameraHardwareException.java b/src/com/android/camera/CameraHardwareException.java
deleted file mode 100644
index 82090554d..000000000
--- a/src/com/android/camera/CameraHardwareException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-/**
- * This class represents the condition that we cannot open the camera hardware
- * successfully. For example, another process is using the camera.
- */
-public class CameraHardwareException extends Exception {
-
- public CameraHardwareException(Throwable t) {
- super(t);
- }
-}
diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java
deleted file mode 100644
index d913df709..000000000
--- a/src/com/android/camera/CameraHolder.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import static com.android.camera.Util.Assert;
-
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.os.Build;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.camera.CameraManager.CameraProxy;
-
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-
-/**
- * The class is used to hold an {@code android.hardware.Camera} instance.
- *
- * <p>The {@code open()} and {@code release()} calls are similar to the ones
- * in {@code android.hardware.Camera}. The difference is if {@code keep()} is
- * called before {@code release()}, CameraHolder will try to hold the {@code
- * android.hardware.Camera} instance for a while, so if {@code open()} is
- * called soon after, we can avoid the cost of {@code open()} in {@code
- * android.hardware.Camera}.
- *
- * <p>This is used in switching between different modules.
- */
-public class CameraHolder {
- private static final String TAG = "CameraHolder";
- private static final int KEEP_CAMERA_TIMEOUT = 3000; // 3 seconds
- private CameraProxy mCameraDevice;
- private long mKeepBeforeTime; // Keep the Camera before this time.
- private final Handler mHandler;
- private boolean mCameraOpened; // true if camera is opened
- private final int mNumberOfCameras;
- private int mCameraId = -1; // current camera id
- private int mBackCameraId = -1;
- private int mFrontCameraId = -1;
- private final CameraInfo[] mInfo;
- private static CameraProxy mMockCamera[];
- private static CameraInfo mMockCameraInfo[];
-
- /* Debug double-open issue */
- private static final boolean DEBUG_OPEN_RELEASE = true;
- private static class OpenReleaseState {
- long time;
- int id;
- String device;
- String[] stack;
- }
- private static ArrayList<OpenReleaseState> sOpenReleaseStates =
- new ArrayList<OpenReleaseState>();
- private static SimpleDateFormat sDateFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH:mm:ss.SSS");
-
- private static synchronized void collectState(int id, CameraProxy device) {
- OpenReleaseState s = new OpenReleaseState();
- s.time = System.currentTimeMillis();
- s.id = id;
- if (device == null) {
- s.device = "(null)";
- } else {
- s.device = device.toString();
- }
-
- StackTraceElement[] stack = Thread.currentThread().getStackTrace();
- String[] lines = new String[stack.length];
- for (int i = 0; i < stack.length; i++) {
- lines[i] = stack[i].toString();
- }
- s.stack = lines;
-
- if (sOpenReleaseStates.size() > 10) {
- sOpenReleaseStates.remove(0);
- }
- sOpenReleaseStates.add(s);
- }
-
- private static synchronized void dumpStates() {
- for (int i = sOpenReleaseStates.size() - 1; i >= 0; i--) {
- OpenReleaseState s = sOpenReleaseStates.get(i);
- String date = sDateFormat.format(new Date(s.time));
- Log.d(TAG, "State " + i + " at " + date);
- Log.d(TAG, "mCameraId = " + s.id + ", mCameraDevice = " + s.device);
- Log.d(TAG, "Stack:");
- for (int j = 0; j < s.stack.length; j++) {
- Log.d(TAG, " " + s.stack[j]);
- }
- }
- }
-
- // We store the camera parameters when we actually open the device,
- // so we can restore them in the subsequent open() requests by the user.
- // This prevents the parameters set by PhotoModule used by VideoModule
- // inadvertently.
- private Parameters mParameters;
-
- // Use a singleton.
- private static CameraHolder sHolder;
- public static synchronized CameraHolder instance() {
- if (sHolder == null) {
- sHolder = new CameraHolder();
- }
- return sHolder;
- }
-
- private static final int RELEASE_CAMERA = 1;
- private class MyHandler extends Handler {
- MyHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case RELEASE_CAMERA:
- synchronized (CameraHolder.this) {
- // In 'CameraHolder.open', the 'RELEASE_CAMERA' message
- // will be removed if it is found in the queue. However,
- // there is a chance that this message has been handled
- // before being removed. So, we need to add a check
- // here:
- if (!mCameraOpened) release();
- }
- break;
- }
- }
- }
-
- public static void injectMockCamera(CameraInfo[] info, CameraProxy[] camera) {
- mMockCameraInfo = info;
- mMockCamera = camera;
- sHolder = new CameraHolder();
- }
-
- private CameraHolder() {
- HandlerThread ht = new HandlerThread("CameraHolder");
- ht.start();
- mHandler = new MyHandler(ht.getLooper());
- if (mMockCameraInfo != null) {
- mNumberOfCameras = mMockCameraInfo.length;
- mInfo = mMockCameraInfo;
- } else {
- mNumberOfCameras = android.hardware.Camera.getNumberOfCameras();
- mInfo = new CameraInfo[mNumberOfCameras];
- for (int i = 0; i < mNumberOfCameras; i++) {
- mInfo[i] = new CameraInfo();
- android.hardware.Camera.getCameraInfo(i, mInfo[i]);
- }
- }
-
- // get the first (smallest) back and first front camera id
- for (int i = 0; i < mNumberOfCameras; i++) {
- if (mBackCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_BACK) {
- mBackCameraId = i;
- } else if (mFrontCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_FRONT) {
- mFrontCameraId = i;
- }
- }
- }
-
- public int getNumberOfCameras() {
- return mNumberOfCameras;
- }
-
- public CameraInfo[] getCameraInfo() {
- return mInfo;
- }
-
- public synchronized CameraProxy open(int cameraId)
- throws CameraHardwareException {
- if (DEBUG_OPEN_RELEASE) {
- collectState(cameraId, mCameraDevice);
- if (mCameraOpened) {
- Log.e(TAG, "double open");
- dumpStates();
- }
- }
- Assert(!mCameraOpened);
- if (mCameraDevice != null && mCameraId != cameraId) {
- mCameraDevice.release();
- mCameraDevice = null;
- mCameraId = -1;
- }
- if (mCameraDevice == null) {
- try {
- Log.v(TAG, "open camera " + cameraId);
- if (mMockCameraInfo == null) {
- mCameraDevice = CameraManagerFactory
- .getAndroidCameraManager().cameraOpen(cameraId);
- } else {
- if (mMockCamera == null)
- throw new RuntimeException();
- mCameraDevice = mMockCamera[cameraId];
- }
- mCameraId = cameraId;
- } catch (RuntimeException e) {
- Log.e(TAG, "fail to connect Camera", e);
- throw new CameraHardwareException(e);
- }
- mParameters = mCameraDevice.getParameters();
- } else {
- try {
- mCameraDevice.reconnect();
- } catch (IOException e) {
- Log.e(TAG, "reconnect failed.");
- throw new CameraHardwareException(e);
- }
- mCameraDevice.setParameters(mParameters);
- }
- mCameraOpened = true;
- mHandler.removeMessages(RELEASE_CAMERA);
- mKeepBeforeTime = 0;
- return mCameraDevice;
- }
-
- /**
- * Tries to open the hardware camera. If the camera is being used or
- * unavailable then return {@code null}.
- */
- public synchronized CameraProxy tryOpen(int cameraId) {
- try {
- return !mCameraOpened ? open(cameraId) : null;
- } catch (CameraHardwareException e) {
- // In eng build, we throw the exception so that test tool
- // can detect it and report it
- if ("eng".equals(Build.TYPE)) {
- throw new RuntimeException(e);
- }
- return null;
- }
- }
-
- public synchronized void release() {
- if (DEBUG_OPEN_RELEASE) {
- collectState(mCameraId, mCameraDevice);
- }
-
- if (mCameraDevice == null) return;
-
- long now = System.currentTimeMillis();
- if (now < mKeepBeforeTime) {
- if (mCameraOpened) {
- mCameraOpened = false;
- mCameraDevice.stopPreview();
- }
- mHandler.sendEmptyMessageDelayed(RELEASE_CAMERA,
- mKeepBeforeTime - now);
- return;
- }
- mCameraOpened = false;
- mCameraDevice.release();
- mCameraDevice = null;
- // We must set this to null because it has a reference to Camera.
- // Camera has references to the listeners.
- mParameters = null;
- mCameraId = -1;
- }
-
- public void keep() {
- keep(KEEP_CAMERA_TIMEOUT);
- }
-
- public synchronized void keep(int time) {
- // We allow mCameraOpened in either state for the convenience of the
- // calling activity. The activity may not have a chance to call open()
- // before the user switches to another activity.
- mKeepBeforeTime = System.currentTimeMillis() + time;
- }
-
- public int getBackCameraId() {
- return mBackCameraId;
- }
-
- public int getFrontCameraId() {
- return mFrontCameraId;
- }
-}
diff --git a/src/com/android/camera/CameraManager.java b/src/com/android/camera/CameraManager.java
deleted file mode 100644
index 90a838ca6..000000000
--- a/src/com/android/camera/CameraManager.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.Camera.ErrorCallback;
-import android.hardware.Camera.OnZoomChangeListener;
-import android.hardware.Camera.Parameters;
-import android.os.Handler;
-import android.view.SurfaceHolder;
-
-import com.android.gallery3d.common.ApiHelper;
-
-import java.io.IOException;
-
-/**
- * An interface which provides possible camera device operations.
- *
- * The client should call {@code CameraManager.cameraOpen} to get an instance
- * of {@link CameraManager.CameraProxy} to control the camera. Classes
- * implementing this interface should have its own one unique {@code Thread}
- * other than the main thread for camera operations. Camera device callbacks
- * are wrapped since the client should not deal with
- * {@code android.hardware.Camera} directly.
- *
- * TODO: provide callback interfaces for:
- * {@code android.hardware.Camera.ErrorCallback},
- * {@code android.hardware.Camera.OnZoomChangeListener}, and
- * {@code android.hardware.Camera.Parameters}.
- */
-public interface CameraManager {
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.AutoFocusCallback}.
- */
- public interface CameraAFCallback {
- public void onAutoFocus(boolean focused, CameraProxy camera);
- }
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.AutoFocusMoveCallback}.
- */
- public interface CameraAFMoveCallback {
- public void onAutoFocusMoving(boolean moving, CameraProxy camera);
- }
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.ShutterCallback}.
- */
- public interface CameraShutterCallback {
- public void onShutter(CameraProxy camera);
- }
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.PictureCallback}.
- */
- public interface CameraPictureCallback {
- public void onPictureTaken(byte[] data, CameraProxy camera);
- }
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.PreviewCallback}.
- */
- public interface CameraPreviewDataCallback {
- public void onPreviewFrame(byte[] data, CameraProxy camera);
- }
-
- /**
- * An interface which wraps
- * {@link android.hardware.Camera.FaceDetectionListener}.
- */
- public interface CameraFaceDetectionCallback {
- /**
- * Callback for face detection.
- *
- * @param faces Recognized face in the preview.
- * @param camera The camera which the preview image comes from.
- */
- public void onFaceDetection(Camera.Face[] faces, CameraProxy camera);
- }
-
- /**
- * Opens the camera of the specified ID synchronously.
- *
- * @param cameraId The camera ID to open.
- * @return An instance of {@link CameraProxy} on success. null on failure.
- */
- public CameraProxy cameraOpen(int cameraId);
-
- /**
- * An interface that takes camera operation requests and post messages to the
- * camera handler thread. All camera operations made through this interface is
- * asynchronous by default except those mentioned specifically.
- */
- public interface CameraProxy {
-
- /**
- * Returns the underlying {@link android.hardware.Camera} object used
- * by this proxy. This method should only be used when handing the
- * camera device over to {@link android.media.MediaRecorder} for
- * recording.
- */
- public android.hardware.Camera getCamera();
-
- /**
- * Releases the camera device synchronously.
- * This function must be synchronous so the caller knows exactly when the camera
- * is released and can continue on.
- */
- public void release();
-
- /**
- * Reconnects to the camera device.
- *
- * @see android.hardware.Camera#reconnect()
- */
- public void reconnect() throws IOException;
-
- /**
- * Unlocks the camera device.
- *
- * @see android.hardware.Camera#unlock()
- */
- public void unlock();
-
- /**
- * Locks the camera device.
- * @see android.hardware.Camera#lock()
- */
- public void lock();
-
- /**
- * Sets the {@link android.graphics.SurfaceTexture} for preview.
- *
- * @param surfaceTexture The {@link SurfaceTexture} for preview.
- */
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- public void setPreviewTexture(final SurfaceTexture surfaceTexture);
-
- /**
- * Sets the {@link android.view.SurfaceHolder} for preview.
- *
- * @param surfaceHolder The {@link SurfaceHolder} for preview.
- */
- public void setPreviewDisplay(final SurfaceHolder surfaceHolder);
-
- /**
- * Starts the camera preview.
- */
- public void startPreview();
-
- /**
- * Stops the camera preview synchronously.
- * {@code stopPreview()} must be synchronous to ensure that the caller can
- * continues to release resources related to camera preview.
- */
- public void stopPreview();
-
- /**
- * Sets the callback for preview data.
- *
- * @param handler handler in which the callback was handled.
- * @param cb The callback to be invoked when the preview data is available.
- * @see android.hardware.Camera#setPreviewCallback(android.hardware.Camera.PreviewCallback)
- */
- public void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb);
-
- /**
- * Sets the callback for preview data.
- *
- * @param handler The handler in which the callback will be invoked.
- * @param cb The callback to be invoked when the preview data is available.
- * @see android.hardware.Camera#setPreviewCallbackWithBuffer(android.hardware.Camera.PreviewCallback)
- */
- public void setPreviewDataCallbackWithBuffer(Handler handler, CameraPreviewDataCallback cb);
-
- /**
- * Adds buffer for the preview callback.
- *
- * @param callbackBuffer The buffer allocated for the preview data.
- */
- public void addCallbackBuffer(byte[] callbackBuffer);
-
- /**
- * Starts the auto-focus process. The result will be returned through the callback.
- *
- * @param handler The handler in which the callback will be invoked.
- * @param cb The auto-focus callback.
- */
- public void autoFocus(Handler handler, CameraAFCallback cb);
-
- /**
- * Cancels the auto-focus process.
- */
- public void cancelAutoFocus();
-
- /**
- * Sets the auto-focus callback
- *
- * @param handler The handler in which the callback will be invoked.
- * @param cb The callback to be invoked when the preview data is available.
- */
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- public void setAutoFocusMoveCallback(Handler handler, CameraAFMoveCallback cb);
-
- /**
- * Instrument the camera to take a picture.
- *
- * @param handler The handler in which the callback will be invoked.
- * @param shutter The callback for shutter action, may be null.
- * @param raw The callback for uncompressed data, may be null.
- * @param postview The callback for postview image data, may be null.
- * @param jpeg The callback for jpeg image data, may be null.
- * @see android.hardware.Camera#takePicture(
- * android.hardware.Camera.ShutterCallback,
- * android.hardware.Camera.PictureCallback,
- * android.hardware.Camera.PictureCallback)
- */
- public void takePicture(
- Handler handler,
- CameraShutterCallback shutter,
- CameraPictureCallback raw,
- CameraPictureCallback postview,
- CameraPictureCallback jpeg);
-
- /**
- * Sets the display orientation for camera to adjust the preview orientation.
- *
- * @param degrees The rotation in degrees. Should be 0, 90, 180 or 270.
- */
- public void setDisplayOrientation(int degrees);
-
- /**
- * Sets the listener for zoom change.
- *
- * @param listener The listener.
- */
- public void setZoomChangeListener(OnZoomChangeListener listener);
-
- /**
- * Sets the face detection listener.
- *
- * @param handler The handler in which the callback will be invoked.
- * @param callback The callback for face detection results.
- */
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- public void setFaceDetectionCallback(Handler handler, CameraFaceDetectionCallback callback);
-
- /**
- * Starts the face detection.
- */
- public void startFaceDetection();
-
- /**
- * Stops the face detection.
- */
- public void stopFaceDetection();
-
- /**
- * Registers an error callback.
- *
- * @param cb The error callback.
- * @see android.hardware.Camera#setErrorCallback(android.hardware.Camera.ErrorCallback)
- */
- public void setErrorCallback(ErrorCallback cb);
-
- /**
- * Sets the camera parameters.
- *
- * @param params The camera parameters to use.
- */
- public void setParameters(Parameters params);
-
- /**
- * Gets the current camera parameters synchronously. This method is
- * synchronous since the caller has to wait for the camera to return
- * the parameters. If the parameters are already cached, it returns
- * immediately.
- */
- public Parameters getParameters();
-
- /**
- * Forces {@code CameraProxy} to update the cached version of the camera
- * parameters regardless of the dirty bit.
- */
- public void refreshParameters();
-
- /**
- * Enables/Disables the camera shutter sound.
- *
- * @param enable {@code true} to enable the shutter sound,
- * {@code false} to disable it.
- */
- public void enableShutterSound(boolean enable);
- }
-}
diff --git a/src/com/android/camera/CameraManagerFactory.java b/src/com/android/camera/CameraManagerFactory.java
deleted file mode 100644
index 914ebb265..000000000
--- a/src/com/android/camera/CameraManagerFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-/**
- * A factory class for {@link CameraManager}.
- */
-public class CameraManagerFactory {
-
- private static AndroidCameraManagerImpl sAndroidCameraManager;
-
- /**
- * Returns the android camera implementation of {@link CameraManager}.
- *
- * @return The {@link CameraManager} to control the camera device.
- */
- public static synchronized CameraManager getAndroidCameraManager() {
- if (sAndroidCameraManager == null) {
- sAndroidCameraManager = new AndroidCameraManagerImpl();
- }
- return sAndroidCameraManager;
- }
-}
diff --git a/src/com/android/camera/CameraModule.java b/src/com/android/camera/CameraModule.java
deleted file mode 100644
index bcfe98d65..000000000
--- a/src/com/android/camera/CameraModule.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-
-public interface CameraModule {
-
- public void init(CameraActivity activity, View frame);
-
- public void onSwitchMode(boolean toCamera);
-
- public void onPauseBeforeSuper();
-
- public void onPauseAfterSuper();
-
- public void onResumeBeforeSuper();
-
- public void onResumeAfterSuper();
-
- public void onConfigurationChanged(Configuration config);
-
- public void onStop();
-
- public void installIntentFilter();
-
- public void onActivityResult(int requestCode, int resultCode, Intent data);
-
- public boolean onBackPressed();
-
- public boolean onKeyDown(int keyCode, KeyEvent event);
-
- public boolean onKeyUp(int keyCode, KeyEvent event);
-
- public void onSingleTapUp(View view, int x, int y);
-
- public void onPreviewTextureCopied();
-
- public void onCaptureTextureCopied();
-
- public void onUserInteraction();
-
- public boolean updateStorageHintOnResume();
-
- public void updateCameraAppView();
-
- public void onOrientationChanged(int orientation);
-
- public void onShowSwitcherPopup();
-
- public void onMediaSaveServiceConnected(MediaSaveService s);
-}
diff --git a/src/com/android/camera/CameraPreference.java b/src/com/android/camera/CameraPreference.java
deleted file mode 100644
index 5ddd86dbc..000000000
--- a/src/com/android/camera/CameraPreference.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import com.android.gallery3d.R;
-
-/**
- * The base class of all Preferences used in Camera. The preferences can be
- * loaded from XML resource by <code>PreferenceInflater</code>.
- */
-public abstract class CameraPreference {
-
- private final String mTitle;
- private SharedPreferences mSharedPreferences;
- private final Context mContext;
-
- static public interface OnPreferenceChangedListener {
- public void onSharedPreferenceChanged();
- public void onRestorePreferencesClicked();
- public void onOverriddenPreferencesClicked();
- public void onCameraPickerClicked(int cameraId);
- }
-
- public CameraPreference(Context context, AttributeSet attrs) {
- mContext = context;
- TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.CameraPreference, 0, 0);
- mTitle = a.getString(R.styleable.CameraPreference_title);
- a.recycle();
- }
-
- public String getTitle() {
- return mTitle;
- }
-
- public SharedPreferences getSharedPreferences() {
- if (mSharedPreferences == null) {
- mSharedPreferences = ComboPreferences.get(mContext);
- }
- return mSharedPreferences;
- }
-
- public abstract void reloadValue();
-}
diff --git a/src/com/android/camera/CameraScreenNail.java b/src/com/android/camera/CameraScreenNail.java
deleted file mode 100644
index 993a7d336..000000000
--- a/src/com/android/camera/CameraScreenNail.java
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.opengl.Matrix;
-import android.util.Log;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.glrenderer.RawTexture;
-import com.android.gallery3d.ui.SurfaceTextureScreenNail;
-
-/*
- * This is a ScreenNail which can display camera's preview.
- */
-@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
-public class CameraScreenNail extends SurfaceTextureScreenNail {
- private static final String TAG = "CAM_ScreenNail";
- private static final int ANIM_NONE = 0;
- // Capture animation is about to start.
- private static final int ANIM_CAPTURE_START = 1;
- // Capture animation is running.
- private static final int ANIM_CAPTURE_RUNNING = 2;
- // Switch camera animation needs to copy texture.
- private static final int ANIM_SWITCH_COPY_TEXTURE = 3;
- // Switch camera animation shows the initial feedback by darkening the
- // preview.
- private static final int ANIM_SWITCH_DARK_PREVIEW = 4;
- // Switch camera animation is waiting for the first frame.
- private static final int ANIM_SWITCH_WAITING_FIRST_FRAME = 5;
- // Switch camera animation is about to start.
- private static final int ANIM_SWITCH_START = 6;
- // Switch camera animation is running.
- private static final int ANIM_SWITCH_RUNNING = 7;
-
- private boolean mVisible;
- // True if first onFrameAvailable has been called. If screen nail is drawn
- // too early, it will be all white.
- private boolean mFirstFrameArrived;
- private Listener mListener;
- private final float[] mTextureTransformMatrix = new float[16];
-
- // Animation.
- private CaptureAnimManager mCaptureAnimManager;
- private SwitchAnimManager mSwitchAnimManager = new SwitchAnimManager();
- private int mAnimState = ANIM_NONE;
- private RawTexture mAnimTexture;
- // Some methods are called by GL thread and some are called by main thread.
- // This protects mAnimState, mVisible, and surface texture. This also makes
- // sure some code are atomic. For example, requestRender and setting
- // mAnimState.
- private Object mLock = new Object();
-
- private OnFrameDrawnListener mOneTimeFrameDrawnListener;
- private int mRenderWidth;
- private int mRenderHeight;
- // This represents the scaled, uncropped size of the texture
- // Needed for FaceView
- private int mUncroppedRenderWidth;
- private int mUncroppedRenderHeight;
- private float mScaleX = 1f, mScaleY = 1f;
- private boolean mFullScreen;
- private boolean mEnableAspectRatioClamping = false;
- private boolean mAcquireTexture = false;
- private final DrawClient mDefaultDraw = new DrawClient() {
- @Override
- public void onDraw(GLCanvas canvas, int x, int y, int width, int height) {
- CameraScreenNail.super.draw(canvas, x, y, width, height);
- }
-
- @Override
- public boolean requiresSurfaceTexture() {
- return true;
- }
-
- @Override
- public RawTexture copyToTexture(GLCanvas c, RawTexture texture, int w, int h) {
- // We shouldn't be here since requireSurfaceTexture() returns true.
- return null;
- }
- };
- private DrawClient mDraw = mDefaultDraw;
- private float mAlpha = 1f;
- private Runnable mOnFrameDrawnListener;
-
- public interface Listener {
- void requestRender();
- // Preview has been copied to a texture.
- void onPreviewTextureCopied();
-
- void onCaptureTextureCopied();
- }
-
- public interface OnFrameDrawnListener {
- void onFrameDrawn(CameraScreenNail c);
- }
-
- public interface DrawClient {
- void onDraw(GLCanvas canvas, int x, int y, int width, int height);
-
- boolean requiresSurfaceTexture();
- // The client should implement this if requiresSurfaceTexture() is false;
- RawTexture copyToTexture(GLCanvas c, RawTexture texture, int width, int height);
- }
-
- public CameraScreenNail(Listener listener, Context ctx) {
- mListener = listener;
- mCaptureAnimManager = new CaptureAnimManager(ctx);
- }
-
- public void setFullScreen(boolean full) {
- synchronized (mLock) {
- mFullScreen = full;
- }
- }
-
- /**
- * returns the uncropped, but scaled, width of the rendered texture
- */
- public int getUncroppedRenderWidth() {
- return mUncroppedRenderWidth;
- }
-
- /**
- * returns the uncropped, but scaled, width of the rendered texture
- */
- public int getUncroppedRenderHeight() {
- return mUncroppedRenderHeight;
- }
-
- @Override
- public int getWidth() {
- return mEnableAspectRatioClamping ? mRenderWidth : getTextureWidth();
- }
-
- @Override
- public int getHeight() {
- return mEnableAspectRatioClamping ? mRenderHeight : getTextureHeight();
- }
-
- private int getTextureWidth() {
- return super.getWidth();
- }
-
- private int getTextureHeight() {
- return super.getHeight();
- }
-
- @Override
- public void setSize(int w, int h) {
- super.setSize(w, h);
- mEnableAspectRatioClamping = false;
- if (mRenderWidth == 0) {
- mRenderWidth = w;
- mRenderHeight = h;
- }
- updateRenderSize();
- }
-
- /**
- * Tells the ScreenNail to override the default aspect ratio scaling
- * and instead perform custom scaling to basically do a centerCrop instead
- * of the default centerInside
- *
- * Note that calls to setSize will disable this
- */
- public void enableAspectRatioClamping() {
- mEnableAspectRatioClamping = true;
- updateRenderSize();
- }
-
- private void setPreviewLayoutSize(int w, int h) {
- Log.i(TAG, "preview layout size: "+w+"/"+h);
- mRenderWidth = w;
- mRenderHeight = h;
- updateRenderSize();
- }
-
- private void updateRenderSize() {
- if (!mEnableAspectRatioClamping) {
- mScaleX = mScaleY = 1f;
- mUncroppedRenderWidth = getTextureWidth();
- mUncroppedRenderHeight = getTextureHeight();
- Log.i(TAG, "aspect ratio clamping disabled");
- return;
- }
-
- float aspectRatio;
- if (getTextureWidth() > getTextureHeight()) {
- aspectRatio = (float) getTextureWidth() / (float) getTextureHeight();
- } else {
- aspectRatio = (float) getTextureHeight() / (float) getTextureWidth();
- }
- float scaledTextureWidth, scaledTextureHeight;
- if (mRenderWidth > mRenderHeight) {
- scaledTextureWidth = Math.max(mRenderWidth,
- (int) (mRenderHeight * aspectRatio));
- scaledTextureHeight = Math.max(mRenderHeight,
- (int)(mRenderWidth / aspectRatio));
- } else {
- scaledTextureWidth = Math.max(mRenderWidth,
- (int) (mRenderHeight / aspectRatio));
- scaledTextureHeight = Math.max(mRenderHeight,
- (int) (mRenderWidth * aspectRatio));
- }
- mScaleX = mRenderWidth / scaledTextureWidth;
- mScaleY = mRenderHeight / scaledTextureHeight;
- mUncroppedRenderWidth = Math.round(scaledTextureWidth);
- mUncroppedRenderHeight = Math.round(scaledTextureHeight);
- Log.i(TAG, "aspect ratio clamping enabled, surfaceTexture scale: " + mScaleX + ", " + mScaleY);
- }
-
- public void acquireSurfaceTexture() {
- synchronized (mLock) {
- mFirstFrameArrived = false;
- mAnimTexture = new RawTexture(getTextureWidth(), getTextureHeight(), true);
- mAcquireTexture = true;
- }
- mListener.requestRender();
- }
-
- @Override
- public void releaseSurfaceTexture() {
- synchronized (mLock) {
- if (mAcquireTexture) {
- mAcquireTexture = false;
- mLock.notifyAll();
- } else {
- if (super.getSurfaceTexture() != null) {
- super.releaseSurfaceTexture();
- }
- mAnimState = ANIM_NONE; // stop the animation
- }
- }
- }
-
- public void copyTexture() {
- synchronized (mLock) {
- mListener.requestRender();
- mAnimState = ANIM_SWITCH_COPY_TEXTURE;
- }
- }
-
- public void animateSwitchCamera() {
- Log.v(TAG, "animateSwitchCamera");
- synchronized (mLock) {
- if (mAnimState == ANIM_SWITCH_DARK_PREVIEW) {
- // Do not request render here because camera has been just
- // started. We do not want to draw black frames.
- mAnimState = ANIM_SWITCH_WAITING_FIRST_FRAME;
- }
- }
- }
-
- public void animateCapture(int displayRotation) {
- synchronized (mLock) {
- mCaptureAnimManager.setOrientation(displayRotation);
- mCaptureAnimManager.animateFlashAndSlide();
- mListener.requestRender();
- mAnimState = ANIM_CAPTURE_START;
- }
- }
-
- public RawTexture getAnimationTexture() {
- return mAnimTexture;
- }
-
- public void animateFlash(int displayRotation) {
- synchronized (mLock) {
- mCaptureAnimManager.setOrientation(displayRotation);
- mCaptureAnimManager.animateFlash();
- mListener.requestRender();
- mAnimState = ANIM_CAPTURE_START;
- }
- }
-
- public void animateSlide() {
- synchronized (mLock) {
- mCaptureAnimManager.animateSlide();
- mListener.requestRender();
- }
- }
-
- private void callbackIfNeeded() {
- if (mOneTimeFrameDrawnListener != null) {
- mOneTimeFrameDrawnListener.onFrameDrawn(this);
- mOneTimeFrameDrawnListener = null;
- }
- }
-
- @Override
- protected void updateTransformMatrix(float[] matrix) {
- super.updateTransformMatrix(matrix);
- Matrix.translateM(matrix, 0, .5f, .5f, 0);
- Matrix.scaleM(matrix, 0, mScaleX, mScaleY, 1f);
- Matrix.translateM(matrix, 0, -.5f, -.5f, 0);
- }
-
- public void directDraw(GLCanvas canvas, int x, int y, int width, int height) {
- DrawClient draw;
- synchronized (mLock) {
- draw = mDraw;
- }
- draw.onDraw(canvas, x, y, width, height);
- }
-
- public void setDraw(DrawClient draw) {
- synchronized (mLock) {
- if (draw == null) {
- mDraw = mDefaultDraw;
- } else {
- mDraw = draw;
- }
- }
- mListener.requestRender();
- }
-
- @Override
- public void draw(GLCanvas canvas, int x, int y, int width, int height) {
- synchronized (mLock) {
- allocateTextureIfRequested(canvas);
- if (!mVisible) mVisible = true;
- SurfaceTexture surfaceTexture = getSurfaceTexture();
- if (mDraw.requiresSurfaceTexture() && (surfaceTexture == null || !mFirstFrameArrived)) {
- return;
- }
- if (mOnFrameDrawnListener != null) {
- mOnFrameDrawnListener.run();
- mOnFrameDrawnListener = null;
- }
- float oldAlpha = canvas.getAlpha();
- canvas.setAlpha(mAlpha);
-
- switch (mAnimState) {
- case ANIM_NONE:
- directDraw(canvas, x, y, width, height);
- break;
- case ANIM_SWITCH_COPY_TEXTURE:
- copyPreviewTexture(canvas);
- mSwitchAnimManager.setReviewDrawingSize(width, height);
- mListener.onPreviewTextureCopied();
- mAnimState = ANIM_SWITCH_DARK_PREVIEW;
- // The texture is ready. Fall through to draw darkened
- // preview.
- case ANIM_SWITCH_DARK_PREVIEW:
- case ANIM_SWITCH_WAITING_FIRST_FRAME:
- // Consume the frame. If the buffers are full,
- // onFrameAvailable will not be called. Animation state
- // relies on onFrameAvailable.
- surfaceTexture.updateTexImage();
- mSwitchAnimManager.drawDarkPreview(canvas, x, y, width,
- height, mAnimTexture);
- break;
- case ANIM_SWITCH_START:
- mSwitchAnimManager.startAnimation();
- mAnimState = ANIM_SWITCH_RUNNING;
- break;
- case ANIM_CAPTURE_START:
- copyPreviewTexture(canvas);
- mListener.onCaptureTextureCopied();
- mCaptureAnimManager.startAnimation();
- mAnimState = ANIM_CAPTURE_RUNNING;
- break;
- }
-
- if (mAnimState == ANIM_CAPTURE_RUNNING || mAnimState == ANIM_SWITCH_RUNNING) {
- boolean drawn;
- if (mAnimState == ANIM_CAPTURE_RUNNING) {
- if (!mFullScreen) {
- // Skip the animation if no longer in full screen mode
- drawn = false;
- } else {
- drawn = mCaptureAnimManager.drawAnimation(canvas, this, mAnimTexture,
- x, y, width, height);
- }
- } else {
- drawn = mSwitchAnimManager.drawAnimation(canvas, x, y,
- width, height, this, mAnimTexture);
- }
- if (drawn) {
- mListener.requestRender();
- } else {
- // Continue to the normal draw procedure if the animation is
- // not drawn.
- mAnimState = ANIM_NONE;
- directDraw(canvas, x, y, width, height);
- }
- }
- canvas.setAlpha(oldAlpha);
- callbackIfNeeded();
- } // mLock
- }
-
- private void copyPreviewTexture(GLCanvas canvas) {
- if (!mDraw.requiresSurfaceTexture()) {
- mAnimTexture = mDraw.copyToTexture(
- canvas, mAnimTexture, getTextureWidth(), getTextureHeight());
- } else {
- int width = mAnimTexture.getWidth();
- int height = mAnimTexture.getHeight();
- canvas.beginRenderTarget(mAnimTexture);
- // Flip preview texture vertically. OpenGL uses bottom left point
- // as the origin (0, 0).
- canvas.translate(0, height);
- canvas.scale(1, -1, 1);
- getSurfaceTexture().getTransformMatrix(mTextureTransformMatrix);
- updateTransformMatrix(mTextureTransformMatrix);
- canvas.drawTexture(mExtTexture, mTextureTransformMatrix, 0, 0, width, height);
- canvas.endRenderTarget();
- }
- }
-
- @Override
- public void noDraw() {
- synchronized (mLock) {
- mVisible = false;
- }
- }
-
- @Override
- public void recycle() {
- synchronized (mLock) {
- mVisible = false;
- }
- }
-
- @Override
- public void onFrameAvailable(SurfaceTexture surfaceTexture) {
- synchronized (mLock) {
- if (getSurfaceTexture() != surfaceTexture) {
- return;
- }
- mFirstFrameArrived = true;
- if (mVisible) {
- if (mAnimState == ANIM_SWITCH_WAITING_FIRST_FRAME) {
- mAnimState = ANIM_SWITCH_START;
- }
- // We need to ask for re-render if the SurfaceTexture receives a new
- // frame.
- mListener.requestRender();
- }
- }
- }
-
- // We need to keep track of the size of preview frame on the screen because
- // it's needed when we do switch-camera animation. See comments in
- // SwitchAnimManager.java. This is based on the natural orientation, not the
- // view system orientation.
- public void setPreviewFrameLayoutSize(int width, int height) {
- synchronized (mLock) {
- mSwitchAnimManager.setPreviewFrameLayoutSize(width, height);
- setPreviewLayoutSize(width, height);
- }
- }
-
- public void setOneTimeOnFrameDrawnListener(OnFrameDrawnListener l) {
- synchronized (mLock) {
- mFirstFrameArrived = false;
- mOneTimeFrameDrawnListener = l;
- }
- }
-
- @Override
- public SurfaceTexture getSurfaceTexture() {
- synchronized (mLock) {
- SurfaceTexture surfaceTexture = super.getSurfaceTexture();
- if (surfaceTexture == null && mAcquireTexture) {
- try {
- mLock.wait();
- surfaceTexture = super.getSurfaceTexture();
- } catch (InterruptedException e) {
- Log.w(TAG, "unexpected interruption");
- }
- }
- return surfaceTexture;
- }
- }
-
- private void allocateTextureIfRequested(GLCanvas canvas) {
- synchronized (mLock) {
- if (mAcquireTexture) {
- super.acquireSurfaceTexture(canvas);
- mAcquireTexture = false;
- mLock.notifyAll();
- }
- }
- }
-
- public void setOnFrameDrawnOneShot(Runnable run) {
- synchronized (mLock) {
- mOnFrameDrawnListener = run;
- }
- }
-
- public float getAlpha() {
- synchronized (mLock) {
- return mAlpha;
- }
- }
-
- public void setAlpha(float alpha) {
- synchronized (mLock) {
- mAlpha = alpha;
- mListener.requestRender();
- }
- }
-}
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
deleted file mode 100644
index 3558014cc..000000000
--- a/src/com/android/camera/CameraSettings.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.media.CamcorderProfile;
-import android.util.FloatMath;
-import android.util.Log;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Provides utilities and keys for Camera settings.
- */
-public class CameraSettings {
- private static final int NOT_FOUND = -1;
-
- public static final String KEY_VERSION = "pref_version_key";
- public static final String KEY_LOCAL_VERSION = "pref_local_version_key";
- public static final String KEY_RECORD_LOCATION = "pref_camera_recordlocation_key";
- public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
- public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL = "pref_video_time_lapse_frame_interval_key";
- public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
- public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
- public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
- public static final String KEY_FLASH_MODE = "pref_camera_flashmode_key";
- public static final String KEY_VIDEOCAMERA_FLASH_MODE = "pref_camera_video_flashmode_key";
- public static final String KEY_WHITE_BALANCE = "pref_camera_whitebalance_key";
- public static final String KEY_SCENE_MODE = "pref_camera_scenemode_key";
- public static final String KEY_EXPOSURE = "pref_camera_exposure_key";
- public static final String KEY_TIMER = "pref_camera_timer_key";
- public static final String KEY_TIMER_SOUND_EFFECTS = "pref_camera_timer_sound_key";
- public static final String KEY_VIDEO_EFFECT = "pref_video_effect_key";
- public static final String KEY_CAMERA_ID = "pref_camera_id_key";
- public static final String KEY_CAMERA_HDR = "pref_camera_hdr_key";
- public static final String KEY_CAMERA_FIRST_USE_HINT_SHOWN = "pref_camera_first_use_hint_shown_key";
- public static final String KEY_VIDEO_FIRST_USE_HINT_SHOWN = "pref_video_first_use_hint_shown_key";
- public static final String KEY_PHOTOSPHERE_PICTURESIZE = "pref_photosphere_picturesize_key";
-
- public static final String EXPOSURE_DEFAULT_VALUE = "0";
-
- public static final int CURRENT_VERSION = 5;
- public static final int CURRENT_LOCAL_VERSION = 2;
-
- private static final String TAG = "CameraSettings";
-
- private final Context mContext;
- private final Parameters mParameters;
- private final CameraInfo[] mCameraInfo;
- private final int mCameraId;
-
- public CameraSettings(Activity activity, Parameters parameters,
- int cameraId, CameraInfo[] cameraInfo) {
- mContext = activity;
- mParameters = parameters;
- mCameraId = cameraId;
- mCameraInfo = cameraInfo;
- }
-
- public PreferenceGroup getPreferenceGroup(int preferenceRes) {
- PreferenceInflater inflater = new PreferenceInflater(mContext);
- PreferenceGroup group =
- (PreferenceGroup) inflater.inflate(preferenceRes);
- if (mParameters != null) initPreference(group);
- return group;
- }
-
- public static String getSupportedHighestVideoQuality(int cameraId,
- String defaultQuality) {
- // When launching the camera app first time, we will set the video quality
- // to the first one (i.e. highest quality) in the supported list
- List<String> supported = getSupportedVideoQuality(cameraId);
- if (supported == null) {
- Log.e(TAG, "No supported video quality is found");
- return defaultQuality;
- }
- return supported.get(0);
- }
-
- public static void initialCameraPictureSize(
- Context context, Parameters parameters) {
- // When launching the camera app first time, we will set the picture
- // size to the first one in the list defined in "arrays.xml" and is also
- // supported by the driver.
- List<Size> supported = parameters.getSupportedPictureSizes();
- if (supported == null) return;
- for (String candidate : context.getResources().getStringArray(
- R.array.pref_camera_picturesize_entryvalues)) {
- if (setCameraPictureSize(candidate, supported, parameters)) {
- SharedPreferences.Editor editor = ComboPreferences
- .get(context).edit();
- editor.putString(KEY_PICTURE_SIZE, candidate);
- editor.apply();
- return;
- }
- }
- Log.e(TAG, "No supported picture size found");
- }
-
- public static void removePreferenceFromScreen(
- PreferenceGroup group, String key) {
- removePreference(group, key);
- }
-
- public static boolean setCameraPictureSize(
- String candidate, List<Size> supported, Parameters parameters) {
- int index = candidate.indexOf('x');
- if (index == NOT_FOUND) return false;
- int width = Integer.parseInt(candidate.substring(0, index));
- int height = Integer.parseInt(candidate.substring(index + 1));
- for (Size size : supported) {
- if (size.width == width && size.height == height) {
- parameters.setPictureSize(width, height);
- return true;
- }
- }
- return false;
- }
-
- public static int getMaxVideoDuration(Context context) {
- int duration = 0; // in milliseconds, 0 means unlimited.
- try {
- duration = context.getResources().getInteger(R.integer.max_video_recording_length);
- } catch (Resources.NotFoundException ex) {
- }
- return duration;
- }
-
- private void initPreference(PreferenceGroup group) {
- ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY);
- ListPreference timeLapseInterval = group.findPreference(KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL);
- ListPreference pictureSize = group.findPreference(KEY_PICTURE_SIZE);
- ListPreference whiteBalance = group.findPreference(KEY_WHITE_BALANCE);
- ListPreference sceneMode = group.findPreference(KEY_SCENE_MODE);
- ListPreference flashMode = group.findPreference(KEY_FLASH_MODE);
- ListPreference focusMode = group.findPreference(KEY_FOCUS_MODE);
- IconListPreference exposure =
- (IconListPreference) group.findPreference(KEY_EXPOSURE);
- CountDownTimerPreference timer =
- (CountDownTimerPreference) group.findPreference(KEY_TIMER);
- ListPreference countDownSoundEffects = group.findPreference(KEY_TIMER_SOUND_EFFECTS);
- IconListPreference cameraIdPref =
- (IconListPreference) group.findPreference(KEY_CAMERA_ID);
- ListPreference videoFlashMode =
- group.findPreference(KEY_VIDEOCAMERA_FLASH_MODE);
- ListPreference videoEffect = group.findPreference(KEY_VIDEO_EFFECT);
- ListPreference cameraHdr = group.findPreference(KEY_CAMERA_HDR);
-
- // Since the screen could be loaded from different resources, we need
- // to check if the preference is available here
- if (videoQuality != null) {
- filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality(mCameraId));
- }
-
- if (pictureSize != null) {
- filterUnsupportedOptions(group, pictureSize, sizeListToStringList(
- mParameters.getSupportedPictureSizes()));
- filterSimilarPictureSize(group, pictureSize);
- }
- if (whiteBalance != null) {
- filterUnsupportedOptions(group,
- whiteBalance, mParameters.getSupportedWhiteBalance());
- }
- if (sceneMode != null) {
- filterUnsupportedOptions(group,
- sceneMode, mParameters.getSupportedSceneModes());
- }
- if (flashMode != null) {
- filterUnsupportedOptions(group,
- flashMode, mParameters.getSupportedFlashModes());
- }
- if (focusMode != null) {
- if (!Util.isFocusAreaSupported(mParameters)) {
- filterUnsupportedOptions(group,
- focusMode, mParameters.getSupportedFocusModes());
- } else {
- // Remove the focus mode if we can use tap-to-focus.
- removePreference(group, focusMode.getKey());
- }
- }
- if (videoFlashMode != null) {
- filterUnsupportedOptions(group,
- videoFlashMode, mParameters.getSupportedFlashModes());
- }
- if (exposure != null) buildExposureCompensation(group, exposure);
- if (cameraIdPref != null) buildCameraId(group, cameraIdPref);
-
- if (timeLapseInterval != null) {
- if (ApiHelper.HAS_TIME_LAPSE_RECORDING) {
- resetIfInvalid(timeLapseInterval);
- } else {
- removePreference(group, timeLapseInterval.getKey());
- }
- }
- if (videoEffect != null) {
- if (ApiHelper.HAS_EFFECTS_RECORDING) {
- initVideoEffect(group, videoEffect);
- resetIfInvalid(videoEffect);
- } else {
- filterUnsupportedOptions(group, videoEffect, null);
- }
- }
- if (cameraHdr != null && (!ApiHelper.HAS_CAMERA_HDR
- || !Util.isCameraHdrSupported(mParameters))) {
- removePreference(group, cameraHdr.getKey());
- }
- }
-
- private void buildExposureCompensation(
- PreferenceGroup group, IconListPreference exposure) {
- int max = mParameters.getMaxExposureCompensation();
- int min = mParameters.getMinExposureCompensation();
- if (max == 0 && min == 0) {
- removePreference(group, exposure.getKey());
- return;
- }
- float step = mParameters.getExposureCompensationStep();
-
- // show only integer values for exposure compensation
- int maxValue = Math.min(3, (int) FloatMath.floor(max * step));
- int minValue = Math.max(-3, (int) FloatMath.ceil(min * step));
- String explabel = mContext.getResources().getString(R.string.pref_exposure_label);
- CharSequence entries[] = new CharSequence[maxValue - minValue + 1];
- CharSequence entryValues[] = new CharSequence[maxValue - minValue + 1];
- CharSequence labels[] = new CharSequence[maxValue - minValue + 1];
- int[] icons = new int[maxValue - minValue + 1];
- TypedArray iconIds = mContext.getResources().obtainTypedArray(
- R.array.pref_camera_exposure_icons);
- for (int i = minValue; i <= maxValue; ++i) {
- entryValues[i - minValue] = Integer.toString(Math.round(i / step));
- StringBuilder builder = new StringBuilder();
- if (i > 0) builder.append('+');
- entries[i - minValue] = builder.append(i).toString();
- labels[i - minValue] = explabel + " " + builder.toString();
- icons[i - minValue] = iconIds.getResourceId(3 + i, 0);
- }
- exposure.setUseSingleIcon(true);
- exposure.setEntries(entries);
- exposure.setLabels(labels);
- exposure.setEntryValues(entryValues);
- exposure.setLargeIconIds(icons);
- }
-
- private void buildCameraId(
- PreferenceGroup group, IconListPreference preference) {
- int numOfCameras = mCameraInfo.length;
- if (numOfCameras < 2) {
- removePreference(group, preference.getKey());
- return;
- }
-
- CharSequence[] entryValues = new CharSequence[numOfCameras];
- for (int i = 0; i < numOfCameras; ++i) {
- entryValues[i] = "" + i;
- }
- preference.setEntryValues(entryValues);
- }
-
- private static boolean removePreference(PreferenceGroup group, String key) {
- for (int i = 0, n = group.size(); i < n; i++) {
- CameraPreference child = group.get(i);
- if (child instanceof PreferenceGroup) {
- if (removePreference((PreferenceGroup) child, key)) {
- return true;
- }
- }
- if (child instanceof ListPreference &&
- ((ListPreference) child).getKey().equals(key)) {
- group.removePreference(i);
- return true;
- }
- }
- return false;
- }
-
- private void filterUnsupportedOptions(PreferenceGroup group,
- ListPreference pref, List<String> supported) {
-
- // Remove the preference if the parameter is not supported or there is
- // only one options for the settings.
- if (supported == null || supported.size() <= 1) {
- removePreference(group, pref.getKey());
- return;
- }
-
- pref.filterUnsupported(supported);
- if (pref.getEntries().length <= 1) {
- removePreference(group, pref.getKey());
- return;
- }
-
- resetIfInvalid(pref);
- }
-
- private void filterSimilarPictureSize(PreferenceGroup group,
- ListPreference pref) {
- pref.filterDuplicated();
- if (pref.getEntries().length <= 1) {
- removePreference(group, pref.getKey());
- return;
- }
- resetIfInvalid(pref);
- }
-
- private void resetIfInvalid(ListPreference pref) {
- // Set the value to the first entry if it is invalid.
- String value = pref.getValue();
- if (pref.findIndexOfValue(value) == NOT_FOUND) {
- pref.setValueIndex(0);
- }
- }
-
- private static List<String> sizeListToStringList(List<Size> sizes) {
- ArrayList<String> list = new ArrayList<String>();
- for (Size size : sizes) {
- list.add(String.format(Locale.ENGLISH, "%dx%d", size.width, size.height));
- }
- return list;
- }
-
- public static void upgradeLocalPreferences(SharedPreferences pref) {
- int version;
- try {
- version = pref.getInt(KEY_LOCAL_VERSION, 0);
- } catch (Exception ex) {
- version = 0;
- }
- if (version == CURRENT_LOCAL_VERSION) return;
-
- SharedPreferences.Editor editor = pref.edit();
- if (version == 1) {
- // We use numbers to represent the quality now. The quality definition is identical to
- // that of CamcorderProfile.java.
- editor.remove("pref_video_quality_key");
- }
- editor.putInt(KEY_LOCAL_VERSION, CURRENT_LOCAL_VERSION);
- editor.apply();
- }
-
- public static void upgradeGlobalPreferences(SharedPreferences pref) {
- upgradeOldVersion(pref);
- upgradeCameraId(pref);
- }
-
- private static void upgradeOldVersion(SharedPreferences pref) {
- int version;
- try {
- version = pref.getInt(KEY_VERSION, 0);
- } catch (Exception ex) {
- version = 0;
- }
- if (version == CURRENT_VERSION) return;
-
- SharedPreferences.Editor editor = pref.edit();
- if (version == 0) {
- // We won't use the preference which change in version 1.
- // So, just upgrade to version 1 directly
- version = 1;
- }
- if (version == 1) {
- // Change jpeg quality {65,75,85} to {normal,fine,superfine}
- String quality = pref.getString(KEY_JPEG_QUALITY, "85");
- if (quality.equals("65")) {
- quality = "normal";
- } else if (quality.equals("75")) {
- quality = "fine";
- } else {
- quality = "superfine";
- }
- editor.putString(KEY_JPEG_QUALITY, quality);
- version = 2;
- }
- if (version == 2) {
- editor.putString(KEY_RECORD_LOCATION,
- pref.getBoolean(KEY_RECORD_LOCATION, false)
- ? RecordLocationPreference.VALUE_ON
- : RecordLocationPreference.VALUE_NONE);
- version = 3;
- }
- if (version == 3) {
- // Just use video quality to replace it and
- // ignore the current settings.
- editor.remove("pref_camera_videoquality_key");
- editor.remove("pref_camera_video_duration_key");
- }
-
- editor.putInt(KEY_VERSION, CURRENT_VERSION);
- editor.apply();
- }
-
- private static void upgradeCameraId(SharedPreferences pref) {
- // The id stored in the preference may be out of range if we are running
- // inside the emulator and a webcam is removed.
- // Note: This method accesses the global preferences directly, not the
- // combo preferences.
- int cameraId = readPreferredCameraId(pref);
- if (cameraId == 0) return; // fast path
-
- int n = CameraHolder.instance().getNumberOfCameras();
- if (cameraId < 0 || cameraId >= n) {
- writePreferredCameraId(pref, 0);
- }
- }
-
- public static int readPreferredCameraId(SharedPreferences pref) {
- return Integer.parseInt(pref.getString(KEY_CAMERA_ID, "0"));
- }
-
- public static void writePreferredCameraId(SharedPreferences pref,
- int cameraId) {
- Editor editor = pref.edit();
- editor.putString(KEY_CAMERA_ID, Integer.toString(cameraId));
- editor.apply();
- }
-
- public static int readExposure(ComboPreferences preferences) {
- String exposure = preferences.getString(
- CameraSettings.KEY_EXPOSURE,
- EXPOSURE_DEFAULT_VALUE);
- try {
- return Integer.parseInt(exposure);
- } catch (Exception ex) {
- Log.e(TAG, "Invalid exposure: " + exposure);
- }
- return 0;
- }
-
- public static int readEffectType(SharedPreferences pref) {
- String effectSelection = pref.getString(KEY_VIDEO_EFFECT, "none");
- if (effectSelection.equals("none")) {
- return EffectsRecorder.EFFECT_NONE;
- } else if (effectSelection.startsWith("goofy_face")) {
- return EffectsRecorder.EFFECT_GOOFY_FACE;
- } else if (effectSelection.startsWith("backdropper")) {
- return EffectsRecorder.EFFECT_BACKDROPPER;
- }
- Log.e(TAG, "Invalid effect selection: " + effectSelection);
- return EffectsRecorder.EFFECT_NONE;
- }
-
- public static Object readEffectParameter(SharedPreferences pref) {
- String effectSelection = pref.getString(KEY_VIDEO_EFFECT, "none");
- if (effectSelection.equals("none")) {
- return null;
- }
- int separatorIndex = effectSelection.indexOf('/');
- String effectParameter =
- effectSelection.substring(separatorIndex + 1);
- if (effectSelection.startsWith("goofy_face")) {
- if (effectParameter.equals("squeeze")) {
- return EffectsRecorder.EFFECT_GF_SQUEEZE;
- } else if (effectParameter.equals("big_eyes")) {
- return EffectsRecorder.EFFECT_GF_BIG_EYES;
- } else if (effectParameter.equals("big_mouth")) {
- return EffectsRecorder.EFFECT_GF_BIG_MOUTH;
- } else if (effectParameter.equals("small_mouth")) {
- return EffectsRecorder.EFFECT_GF_SMALL_MOUTH;
- } else if (effectParameter.equals("big_nose")) {
- return EffectsRecorder.EFFECT_GF_BIG_NOSE;
- } else if (effectParameter.equals("small_eyes")) {
- return EffectsRecorder.EFFECT_GF_SMALL_EYES;
- }
- } else if (effectSelection.startsWith("backdropper")) {
- // Parameter is a string that either encodes the URI to use,
- // or specifies 'gallery'.
- return effectParameter;
- }
-
- Log.e(TAG, "Invalid effect selection: " + effectSelection);
- return null;
- }
-
- public static void restorePreferences(Context context,
- ComboPreferences preferences, Parameters parameters) {
- int currentCameraId = readPreferredCameraId(preferences);
-
- // Clear the preferences of both cameras.
- int backCameraId = CameraHolder.instance().getBackCameraId();
- if (backCameraId != -1) {
- preferences.setLocalId(context, backCameraId);
- Editor editor = preferences.edit();
- editor.clear();
- editor.apply();
- }
- int frontCameraId = CameraHolder.instance().getFrontCameraId();
- if (frontCameraId != -1) {
- preferences.setLocalId(context, frontCameraId);
- Editor editor = preferences.edit();
- editor.clear();
- editor.apply();
- }
-
- // Switch back to the preferences of the current camera. Otherwise,
- // we may write the preference to wrong camera later.
- preferences.setLocalId(context, currentCameraId);
-
- upgradeGlobalPreferences(preferences.getGlobal());
- upgradeLocalPreferences(preferences.getLocal());
-
- // Write back the current camera id because parameters are related to
- // the camera. Otherwise, we may switch to the front camera but the
- // initial picture size is that of the back camera.
- initialCameraPictureSize(context, parameters);
- writePreferredCameraId(preferences, currentCameraId);
- }
-
- private static ArrayList<String> getSupportedVideoQuality(int cameraId) {
- ArrayList<String> supported = new ArrayList<String>();
- // Check for supported quality
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_1080P));
- }
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_720P));
- }
- if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) {
- supported.add(Integer.toString(CamcorderProfile.QUALITY_480P));
- }
- return supported;
- }
-
- private void initVideoEffect(PreferenceGroup group, ListPreference videoEffect) {
- CharSequence[] values = videoEffect.getEntryValues();
-
- boolean goofyFaceSupported =
- EffectsRecorder.isEffectSupported(EffectsRecorder.EFFECT_GOOFY_FACE);
- boolean backdropperSupported =
- EffectsRecorder.isEffectSupported(EffectsRecorder.EFFECT_BACKDROPPER) &&
- Util.isAutoExposureLockSupported(mParameters) &&
- Util.isAutoWhiteBalanceLockSupported(mParameters);
-
- ArrayList<String> supported = new ArrayList<String>();
- for (CharSequence value : values) {
- String effectSelection = value.toString();
- if (!goofyFaceSupported && effectSelection.startsWith("goofy_face")) continue;
- if (!backdropperSupported && effectSelection.startsWith("backdropper")) continue;
- supported.add(effectSelection);
- }
-
- filterUnsupportedOptions(group, videoEffect, supported);
- }
-}
diff --git a/src/com/android/camera/CaptureAnimManager.java b/src/com/android/camera/CaptureAnimManager.java
deleted file mode 100644
index 6e8092566..000000000
--- a/src/com/android/camera/CaptureAnimManager.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.os.SystemClock;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.glrenderer.NinePatchTexture;
-import com.android.gallery3d.glrenderer.RawTexture;
-
-/**
- * Class to handle the capture animation.
- */
-public class CaptureAnimManager {
- @SuppressWarnings("unused")
- private static final String TAG = "CAM_Capture";
- // times mark endpoint of animation phase
- private static final int TIME_FLASH = 200;
- private static final int TIME_HOLD = 400;
- private static final int TIME_SLIDE = 800;
- private static final int TIME_HOLD2 = 3300;
- private static final int TIME_SLIDE2 = 4100;
-
- private static final int ANIM_BOTH = 0;
- private static final int ANIM_FLASH = 1;
- private static final int ANIM_SLIDE = 2;
- private static final int ANIM_HOLD2 = 3;
- private static final int ANIM_SLIDE2 = 4;
-
- private final Interpolator mSlideInterpolator = new DecelerateInterpolator();
-
- private volatile int mAnimOrientation; // Could be 0, 90, 180 or 270 degrees.
- private long mAnimStartTime; // milliseconds.
- private float mX; // The center of the whole view including preview and review.
- private float mY;
- private int mDrawWidth;
- private int mDrawHeight;
- private int mAnimType;
-
- private int mHoldX;
- private int mHoldY;
- private int mHoldW;
- private int mHoldH;
-
- private int mOffset;
-
- private int mMarginRight;
- private int mMarginTop;
- private int mSize;
- private Resources mResources;
- private NinePatchTexture mBorder;
- private int mShadowSize;
-
- public static int getAnimationDuration() {
- return TIME_SLIDE2;
- }
-
- /* preview: camera preview view.
- * review: view of picture just taken.
- */
- public CaptureAnimManager(Context ctx) {
- mBorder = new NinePatchTexture(ctx, R.drawable.capture_thumbnail_shadow);
- mResources = ctx.getResources();
- }
-
- public void setOrientation(int displayRotation) {
- mAnimOrientation = (360 - displayRotation) % 360;
- }
-
- public void animateSlide() {
- if (mAnimType != ANIM_FLASH) {
- return;
- }
- mAnimType = ANIM_SLIDE;
- mAnimStartTime = SystemClock.uptimeMillis();
- }
-
- public void animateFlash() {
- mAnimType = ANIM_FLASH;
- }
-
- public void animateFlashAndSlide() {
- mAnimType = ANIM_BOTH;
- }
-
- public void startAnimation() {
- mAnimStartTime = SystemClock.uptimeMillis();
- }
-
- private void setAnimationGeometry(int x, int y, int w, int h) {
- mMarginRight = mResources.getDimensionPixelSize(R.dimen.capture_margin_right);
- mMarginTop = mResources.getDimensionPixelSize(R.dimen.capture_margin_top);
- mSize = mResources.getDimensionPixelSize(R.dimen.capture_size);
- mShadowSize = mResources.getDimensionPixelSize(R.dimen.capture_border);
- mOffset = mMarginRight + mSize;
- // Set the views to the initial positions.
- mDrawWidth = w;
- mDrawHeight = h;
- mX = x;
- mY = y;
- mHoldW = mSize;
- mHoldH = mSize;
- switch (mAnimOrientation) {
- case 0: // Preview is on the left.
- mHoldX = x + w - mMarginRight - mSize;
- mHoldY = y + mMarginTop;
- break;
- case 90: // Preview is below.
- mHoldX = x + mMarginTop;
- mHoldY = y + mMarginRight;
- break;
- case 180: // Preview on the right.
- mHoldX = x + mMarginRight;
- mHoldY = y + h - mMarginTop - mSize;
- break;
- case 270: // Preview is above.
- mHoldX = x + w - mMarginTop - mSize;
- mHoldY = y + h - mMarginRight - mSize;
- break;
- }
- }
-
- // Returns true if the animation has been drawn.
- public boolean drawAnimation(GLCanvas canvas, CameraScreenNail preview,
- RawTexture review, int lx, int ly, int lw, int lh) {
- setAnimationGeometry(lx, ly, lw, lh);
- long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime;
- // Check if the animation is over
- if (mAnimType == ANIM_SLIDE && timeDiff > TIME_SLIDE2 - TIME_HOLD) return false;
- if (mAnimType == ANIM_BOTH && timeDiff > TIME_SLIDE2) return false;
-
- // determine phase and time in phase
- int animStep = mAnimType;
- if (mAnimType == ANIM_SLIDE) {
- timeDiff += TIME_HOLD;
- }
- if (mAnimType == ANIM_SLIDE || mAnimType == ANIM_BOTH) {
- if (timeDiff < TIME_HOLD) {
- animStep = ANIM_FLASH;
- } else if (timeDiff < TIME_SLIDE) {
- animStep = ANIM_SLIDE;
- timeDiff -= TIME_HOLD;
- } else if (timeDiff < TIME_HOLD2) {
- animStep = ANIM_HOLD2;
- timeDiff -= TIME_SLIDE;
- } else {
- // SLIDE2
- animStep = ANIM_SLIDE2;
- timeDiff -= TIME_HOLD2;
- }
- }
-
- if (animStep == ANIM_FLASH) {
- review.draw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight);
- if (timeDiff < TIME_FLASH) {
- float f = 0.3f - 0.3f * timeDiff / TIME_FLASH;
- int color = Color.argb((int) (255 * f), 255, 255, 255);
- canvas.fillRect(mX, mY, mDrawWidth, mDrawHeight, color);
- }
- } else if (animStep == ANIM_SLIDE) {
- float fraction = mSlideInterpolator.getInterpolation((float) (timeDiff) / (TIME_SLIDE - TIME_HOLD));
- float x = mX;
- float y = mY;
- float w = 0;
- float h = 0;
- x = interpolate(mX, mHoldX, fraction);
- y = interpolate(mY, mHoldY, fraction);
- w = interpolate(mDrawWidth, mHoldW, fraction);
- h = interpolate(mDrawHeight, mHoldH, fraction);
- preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight);
- review.draw(canvas, (int) x, (int) y, (int) w, (int) h);
- } else if (animStep == ANIM_HOLD2) {
- preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight);
- review.draw(canvas, mHoldX, mHoldY, mHoldW, mHoldH);
- mBorder.draw(canvas, (int) mHoldX - mShadowSize, (int) mHoldY - mShadowSize,
- (int) mHoldW + 2 * mShadowSize, (int) mHoldH + 2 * mShadowSize);
- } else if (animStep == ANIM_SLIDE2) {
- float fraction = (float)(timeDiff) / (TIME_SLIDE2 - TIME_HOLD2);
- float x = mHoldX;
- float y = mHoldY;
- float d = mOffset * fraction;
- switch (mAnimOrientation) {
- case 0:
- x = mHoldX + d;
- break;
- case 180:
- x = mHoldX - d;
- break;
- case 90:
- y = mHoldY - d;
- break;
- case 270:
- y = mHoldY + d;
- break;
- }
- preview.directDraw(canvas, (int) mX, (int) mY, mDrawWidth, mDrawHeight);
- mBorder.draw(canvas, (int) x - mShadowSize, (int) y - mShadowSize,
- (int) mHoldW + 2 * mShadowSize, (int) mHoldH + 2 * mShadowSize);
- review.draw(canvas, (int) x, (int) y, mHoldW, mHoldH);
- }
- return true;
- }
-
- private static float interpolate(float start, float end, float fraction) {
- return start + (end - start) * fraction;
- }
-
-}
diff --git a/src/com/android/camera/ComboPreferences.java b/src/com/android/camera/ComboPreferences.java
deleted file mode 100644
index e17e47aa8..000000000
--- a/src/com/android/camera/ComboPreferences.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.app.backup.BackupManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.preference.PreferenceManager;
-
-import com.android.gallery3d.util.UsageStatistics;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-public class ComboPreferences implements
- SharedPreferences,
- OnSharedPreferenceChangeListener {
- private SharedPreferences mPrefGlobal; // global preferences
- private SharedPreferences mPrefLocal; // per-camera preferences
- private String mPackageName;
- private CopyOnWriteArrayList<OnSharedPreferenceChangeListener> mListeners;
- // TODO: Remove this WeakHashMap in the camera code refactoring
- private static WeakHashMap<Context, ComboPreferences> sMap =
- new WeakHashMap<Context, ComboPreferences>();
-
- public ComboPreferences(Context context) {
- mPackageName = context.getPackageName();
- mPrefGlobal = context.getSharedPreferences(
- getGlobalSharedPreferencesName(context), Context.MODE_PRIVATE);
- mPrefGlobal.registerOnSharedPreferenceChangeListener(this);
-
- synchronized (sMap) {
- sMap.put(context, this);
- }
- mListeners = new CopyOnWriteArrayList<OnSharedPreferenceChangeListener>();
-
- // The global preferences was previously stored in the default
- // shared preferences file. They should be stored in the camera-specific
- // shared preferences file so we can backup them solely.
- SharedPreferences oldprefs =
- PreferenceManager.getDefaultSharedPreferences(context);
- if (!mPrefGlobal.contains(CameraSettings.KEY_VERSION)
- && oldprefs.contains(CameraSettings.KEY_VERSION)) {
- moveGlobalPrefsFrom(oldprefs);
- }
- }
-
- public static ComboPreferences get(Context context) {
- synchronized (sMap) {
- return sMap.get(context);
- }
- }
-
- private static String getLocalSharedPreferencesName(
- Context context, int cameraId) {
- return context.getPackageName() + "_preferences_" + cameraId;
- }
-
- private static String getGlobalSharedPreferencesName(Context context) {
- return context.getPackageName() + "_preferences_camera";
- }
-
- private void movePrefFrom(
- Map<String, ?> m, String key, SharedPreferences src) {
- if (m.containsKey(key)) {
- Object v = m.get(key);
- if (v instanceof String) {
- mPrefGlobal.edit().putString(key, (String) v).apply();
- } else if (v instanceof Integer) {
- mPrefGlobal.edit().putInt(key, (Integer) v).apply();
- } else if (v instanceof Long) {
- mPrefGlobal.edit().putLong(key, (Long) v).apply();
- } else if (v instanceof Float) {
- mPrefGlobal.edit().putFloat(key, (Float) v).apply();
- } else if (v instanceof Boolean) {
- mPrefGlobal.edit().putBoolean(key, (Boolean) v).apply();
- }
- src.edit().remove(key).apply();
- }
- }
-
- private void moveGlobalPrefsFrom(SharedPreferences src) {
- Map<String, ?> prefMap = src.getAll();
- movePrefFrom(prefMap, CameraSettings.KEY_VERSION, src);
- movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, src);
- movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_ID, src);
- movePrefFrom(prefMap, CameraSettings.KEY_RECORD_LOCATION, src);
- movePrefFrom(prefMap, CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, src);
- movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, src);
- movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_EFFECT, src);
- }
-
- public static String[] getSharedPreferencesNames(Context context) {
- int numOfCameras = CameraHolder.instance().getNumberOfCameras();
- String prefNames[] = new String[numOfCameras + 1];
- prefNames[0] = getGlobalSharedPreferencesName(context);
- for (int i = 0; i < numOfCameras; i++) {
- prefNames[i + 1] = getLocalSharedPreferencesName(context, i);
- }
- return prefNames;
- }
-
- // Sets the camera id and reads its preferences. Each camera has its own
- // preferences.
- public void setLocalId(Context context, int cameraId) {
- String prefName = getLocalSharedPreferencesName(context, cameraId);
- if (mPrefLocal != null) {
- mPrefLocal.unregisterOnSharedPreferenceChangeListener(this);
- }
- mPrefLocal = context.getSharedPreferences(
- prefName, Context.MODE_PRIVATE);
- mPrefLocal.registerOnSharedPreferenceChangeListener(this);
- }
-
- public SharedPreferences getGlobal() {
- return mPrefGlobal;
- }
-
- public SharedPreferences getLocal() {
- return mPrefLocal;
- }
-
- @Override
- public Map<String, ?> getAll() {
- throw new UnsupportedOperationException(); // Can be implemented if needed.
- }
-
- private static boolean isGlobal(String key) {
- return key.equals(CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL)
- || key.equals(CameraSettings.KEY_CAMERA_ID)
- || key.equals(CameraSettings.KEY_RECORD_LOCATION)
- || key.equals(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN)
- || key.equals(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN)
- || key.equals(CameraSettings.KEY_VIDEO_EFFECT)
- || key.equals(CameraSettings.KEY_TIMER)
- || key.equals(CameraSettings.KEY_TIMER_SOUND_EFFECTS)
- || key.equals(CameraSettings.KEY_PHOTOSPHERE_PICTURESIZE);
- }
-
- @Override
- public String getString(String key, String defValue) {
- if (isGlobal(key) || !mPrefLocal.contains(key)) {
- return mPrefGlobal.getString(key, defValue);
- } else {
- return mPrefLocal.getString(key, defValue);
- }
- }
-
- @Override
- public int getInt(String key, int defValue) {
- if (isGlobal(key) || !mPrefLocal.contains(key)) {
- return mPrefGlobal.getInt(key, defValue);
- } else {
- return mPrefLocal.getInt(key, defValue);
- }
- }
-
- @Override
- public long getLong(String key, long defValue) {
- if (isGlobal(key) || !mPrefLocal.contains(key)) {
- return mPrefGlobal.getLong(key, defValue);
- } else {
- return mPrefLocal.getLong(key, defValue);
- }
- }
-
- @Override
- public float getFloat(String key, float defValue) {
- if (isGlobal(key) || !mPrefLocal.contains(key)) {
- return mPrefGlobal.getFloat(key, defValue);
- } else {
- return mPrefLocal.getFloat(key, defValue);
- }
- }
-
- @Override
- public boolean getBoolean(String key, boolean defValue) {
- if (isGlobal(key) || !mPrefLocal.contains(key)) {
- return mPrefGlobal.getBoolean(key, defValue);
- } else {
- return mPrefLocal.getBoolean(key, defValue);
- }
- }
-
- // This method is not used.
- @Override
- public Set<String> getStringSet(String key, Set<String> defValues) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean contains(String key) {
- return mPrefLocal.contains(key) || mPrefGlobal.contains(key);
- }
-
- private class MyEditor implements Editor {
- private Editor mEditorGlobal;
- private Editor mEditorLocal;
-
- MyEditor() {
- mEditorGlobal = mPrefGlobal.edit();
- mEditorLocal = mPrefLocal.edit();
- }
-
- @Override
- public boolean commit() {
- boolean result1 = mEditorGlobal.commit();
- boolean result2 = mEditorLocal.commit();
- return result1 && result2;
- }
-
- @Override
- public void apply() {
- mEditorGlobal.apply();
- mEditorLocal.apply();
- }
-
- // Note: clear() and remove() affects both local and global preferences.
- @Override
- public Editor clear() {
- mEditorGlobal.clear();
- mEditorLocal.clear();
- return this;
- }
-
- @Override
- public Editor remove(String key) {
- mEditorGlobal.remove(key);
- mEditorLocal.remove(key);
- return this;
- }
-
- @Override
- public Editor putString(String key, String value) {
- if (isGlobal(key)) {
- mEditorGlobal.putString(key, value);
- } else {
- mEditorLocal.putString(key, value);
- }
- return this;
- }
-
- @Override
- public Editor putInt(String key, int value) {
- if (isGlobal(key)) {
- mEditorGlobal.putInt(key, value);
- } else {
- mEditorLocal.putInt(key, value);
- }
- return this;
- }
-
- @Override
- public Editor putLong(String key, long value) {
- if (isGlobal(key)) {
- mEditorGlobal.putLong(key, value);
- } else {
- mEditorLocal.putLong(key, value);
- }
- return this;
- }
-
- @Override
- public Editor putFloat(String key, float value) {
- if (isGlobal(key)) {
- mEditorGlobal.putFloat(key, value);
- } else {
- mEditorLocal.putFloat(key, value);
- }
- return this;
- }
-
- @Override
- public Editor putBoolean(String key, boolean value) {
- if (isGlobal(key)) {
- mEditorGlobal.putBoolean(key, value);
- } else {
- mEditorLocal.putBoolean(key, value);
- }
- return this;
- }
-
- // This method is not used.
- @Override
- public Editor putStringSet(String key, Set<String> values) {
- throw new UnsupportedOperationException();
- }
- }
-
- // Note the remove() and clear() of the returned Editor may not work as
- // expected because it doesn't touch the global preferences at all.
- @Override
- public Editor edit() {
- return new MyEditor();
- }
-
- @Override
- public void registerOnSharedPreferenceChangeListener(
- OnSharedPreferenceChangeListener listener) {
- mListeners.add(listener);
- }
-
- @Override
- public void unregisterOnSharedPreferenceChangeListener(
- OnSharedPreferenceChangeListener listener) {
- mListeners.remove(listener);
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
- for (OnSharedPreferenceChangeListener listener : mListeners) {
- listener.onSharedPreferenceChanged(this, key);
- }
- BackupManager.dataChanged(mPackageName);
- UsageStatistics.onEvent("CameraSettingsChange", null, key);
- }
-}
diff --git a/src/com/android/camera/CountDownTimerPreference.java b/src/com/android/camera/CountDownTimerPreference.java
deleted file mode 100644
index 9c66dda8c..000000000
--- a/src/com/android/camera/CountDownTimerPreference.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.gallery3d.R;
-
-public class CountDownTimerPreference extends ListPreference {
- private static final int[] DURATIONS = {
- 0, 1, 2, 3, 4, 5, 10, 15, 20, 30, 60
- };
- public CountDownTimerPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- initCountDownDurationChoices(context);
- }
-
- private void initCountDownDurationChoices(Context context) {
- CharSequence[] entryValues = new CharSequence[DURATIONS.length];
- CharSequence[] entries = new CharSequence[DURATIONS.length];
- for (int i = 0; i < DURATIONS.length; i++) {
- entryValues[i] = Integer.toString(DURATIONS[i]);
- if (i == 0) {
- entries[0] = context.getString(R.string.setting_off); // Off
- } else {
- entries[i] = context.getResources()
- .getQuantityString(R.plurals.pref_camera_timer_entry, i, i);
- }
- }
- setEntries(entries);
- setEntryValues(entryValues);
- }
-}
diff --git a/src/com/android/camera/DisableCameraReceiver.java b/src/com/android/camera/DisableCameraReceiver.java
deleted file mode 100644
index 351740541..000000000
--- a/src/com/android/camera/DisableCameraReceiver.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.hardware.Camera.CameraInfo;
-import android.util.Log;
-
-// We want to disable camera-related activities if there is no camera. This
-// receiver runs when BOOT_COMPLETED intent is received. After running once
-// this receiver will be disabled, so it will not run again.
-public class DisableCameraReceiver extends BroadcastReceiver {
- private static final String TAG = "DisableCameraReceiver";
- private static final boolean CHECK_BACK_CAMERA_ONLY = true;
- private static final String ACTIVITIES[] = {
- "com.android.camera.CameraLauncher",
- };
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // Disable camera-related activities if there is no camera.
- boolean needCameraActivity = CHECK_BACK_CAMERA_ONLY
- ? hasBackCamera()
- : hasCamera();
-
- if (!needCameraActivity) {
- Log.i(TAG, "disable all camera activities");
- for (int i = 0; i < ACTIVITIES.length; i++) {
- disableComponent(context, ACTIVITIES[i]);
- }
- }
-
- // Disable this receiver so it won't run again.
- disableComponent(context, "com.android.camera.DisableCameraReceiver");
- }
-
- private boolean hasCamera() {
- int n = android.hardware.Camera.getNumberOfCameras();
- Log.i(TAG, "number of camera: " + n);
- return (n > 0);
- }
-
- private boolean hasBackCamera() {
- int n = android.hardware.Camera.getNumberOfCameras();
- CameraInfo info = new CameraInfo();
- for (int i = 0; i < n; i++) {
- android.hardware.Camera.getCameraInfo(i, info);
- if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
- Log.i(TAG, "back camera found: " + i);
- return true;
- }
- }
- Log.i(TAG, "no back camera");
- return false;
- }
-
- private void disableComponent(Context context, String klass) {
- ComponentName name = new ComponentName(context, klass);
- PackageManager pm = context.getPackageManager();
-
- // We need the DONT_KILL_APP flag, otherwise we will be killed
- // immediately because we are in the same app.
- pm.setComponentEnabledSetting(name,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
-}
diff --git a/src/com/android/camera/EffectsRecorder.java b/src/com/android/camera/EffectsRecorder.java
deleted file mode 100644
index 4bf8d411e..000000000
--- a/src/com/android/camera/EffectsRecorder.java
+++ /dev/null
@@ -1,1239 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.media.CamcorderProfile;
-import android.media.MediaRecorder;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.io.FileDescriptor;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-
-/**
- * Encapsulates the mobile filter framework components needed to record video
- * with effects applied. Modeled after MediaRecorder.
- */
-@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) // uses SurfaceTexture
-public class EffectsRecorder {
- private static final String TAG = "EffectsRecorder";
-
- private static Class<?> sClassFilter;
- private static Method sFilterIsAvailable;
- private static EffectsRecorder sEffectsRecorder;
- // The index of the current effects recorder.
- private static int sEffectsRecorderIndex;
-
- private static boolean sReflectionInited = false;
-
- private static Class<?> sClsLearningDoneListener;
- private static Class<?> sClsOnRunnerDoneListener;
- private static Class<?> sClsOnRecordingDoneListener;
- private static Class<?> sClsSurfaceTextureSourceListener;
-
- private static Method sFilterSetInputValue;
-
- private static Constructor<?> sCtPoint;
- private static Constructor<?> sCtQuad;
-
- private static Method sLearningDoneListenerOnLearningDone;
-
- private static Method sObjectEquals;
- private static Method sObjectToString;
-
- private static Class<?> sClsGraphRunner;
- private static Method sGraphRunnerGetGraph;
- private static Method sGraphRunnerSetDoneCallback;
- private static Method sGraphRunnerRun;
- private static Method sGraphRunnerGetError;
- private static Method sGraphRunnerStop;
-
- private static Method sFilterGraphGetFilter;
- private static Method sFilterGraphTearDown;
-
- private static Method sOnRunnerDoneListenerOnRunnerDone;
-
- private static Class<?> sClsGraphEnvironment;
- private static Constructor<?> sCtGraphEnvironment;
- private static Method sGraphEnvironmentCreateGLEnvironment;
- private static Method sGraphEnvironmentGetRunner;
- private static Method sGraphEnvironmentAddReferences;
- private static Method sGraphEnvironmentLoadGraph;
- private static Method sGraphEnvironmentGetContext;
-
- private static Method sFilterContextGetGLEnvironment;
- private static Method sGLEnvironmentIsActive;
- private static Method sGLEnvironmentActivate;
- private static Method sGLEnvironmentDeactivate;
- private static Method sSurfaceTextureTargetDisconnect;
- private static Method sOnRecordingDoneListenerOnRecordingDone;
- private static Method sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady;
-
- private Object mLearningDoneListener;
- private Object mRunnerDoneCallback;
- private Object mSourceReadyCallback;
- // A callback to finalize the media after the recording is done.
- private Object mRecordingDoneListener;
-
- static {
- try {
- sClassFilter = Class.forName("android.filterfw.core.Filter");
- sFilterIsAvailable = sClassFilter.getMethod("isAvailable",
- String.class);
- } catch (ClassNotFoundException ex) {
- Log.v(TAG, "Can't find the class android.filterfw.core.Filter");
- } catch (NoSuchMethodException e) {
- Log.v(TAG, "Can't find the method Filter.isAvailable");
- }
- }
-
- public static final int EFFECT_NONE = 0;
- public static final int EFFECT_GOOFY_FACE = 1;
- public static final int EFFECT_BACKDROPPER = 2;
-
- public static final int EFFECT_GF_SQUEEZE = 0;
- public static final int EFFECT_GF_BIG_EYES = 1;
- public static final int EFFECT_GF_BIG_MOUTH = 2;
- public static final int EFFECT_GF_SMALL_MOUTH = 3;
- public static final int EFFECT_GF_BIG_NOSE = 4;
- public static final int EFFECT_GF_SMALL_EYES = 5;
- public static final int NUM_OF_GF_EFFECTS = EFFECT_GF_SMALL_EYES + 1;
-
- public static final int EFFECT_MSG_STARTED_LEARNING = 0;
- public static final int EFFECT_MSG_DONE_LEARNING = 1;
- public static final int EFFECT_MSG_SWITCHING_EFFECT = 2;
- public static final int EFFECT_MSG_EFFECTS_STOPPED = 3;
- public static final int EFFECT_MSG_RECORDING_DONE = 4;
- public static final int EFFECT_MSG_PREVIEW_RUNNING = 5;
-
- private Context mContext;
- private Handler mHandler;
-
- private CameraManager.CameraProxy mCameraDevice;
- private CamcorderProfile mProfile;
- private double mCaptureRate = 0;
- private SurfaceTexture mPreviewSurfaceTexture;
- private int mPreviewWidth;
- private int mPreviewHeight;
- private MediaRecorder.OnInfoListener mInfoListener;
- private MediaRecorder.OnErrorListener mErrorListener;
-
- private String mOutputFile;
- private FileDescriptor mFd;
- private int mOrientationHint = 0;
- private long mMaxFileSize = 0;
- private int mMaxDurationMs = 0;
- private int mCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
- private int mCameraDisplayOrientation;
-
- private int mEffect = EFFECT_NONE;
- private int mCurrentEffect = EFFECT_NONE;
- private EffectsListener mEffectsListener;
-
- private Object mEffectParameter;
-
- private Object mGraphEnv;
- private int mGraphId;
- private Object mRunner = null;
- private Object mOldRunner = null;
-
- private SurfaceTexture mTextureSource;
-
- private static final int STATE_CONFIGURE = 0;
- private static final int STATE_WAITING_FOR_SURFACE = 1;
- private static final int STATE_STARTING_PREVIEW = 2;
- private static final int STATE_PREVIEW = 3;
- private static final int STATE_RECORD = 4;
- private static final int STATE_RELEASED = 5;
- private int mState = STATE_CONFIGURE;
-
- private boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE);
- private SoundClips.Player mSoundPlayer;
-
- /** Determine if a given effect is supported at runtime
- * Some effects require libraries not available on all devices
- */
- public static boolean isEffectSupported(int effectId) {
- if (sFilterIsAvailable == null) return false;
-
- try {
- switch (effectId) {
- case EFFECT_GOOFY_FACE:
- return (Boolean) sFilterIsAvailable.invoke(null,
- "com.google.android.filterpacks.facedetect.GoofyRenderFilter");
- case EFFECT_BACKDROPPER:
- return (Boolean) sFilterIsAvailable.invoke(null,
- "android.filterpacks.videoproc.BackDropperFilter");
- default:
- return false;
- }
- } catch (Exception ex) {
- Log.e(TAG, "Fail to check filter", ex);
- }
- return false;
- }
-
- public EffectsRecorder(Context context) {
- if (mLogVerbose) Log.v(TAG, "EffectsRecorder created (" + this + ")");
-
- if (!sReflectionInited) {
- try {
- sFilterSetInputValue = sClassFilter.getMethod("setInputValue",
- new Class[] {String.class, Object.class});
-
- Class<?> clsPoint = Class.forName("android.filterfw.geometry.Point");
- sCtPoint = clsPoint.getConstructor(new Class[] {float.class,
- float.class});
-
- Class<?> clsQuad = Class.forName("android.filterfw.geometry.Quad");
- sCtQuad = clsQuad.getConstructor(new Class[] {clsPoint, clsPoint,
- clsPoint, clsPoint});
-
- Class<?> clsBackDropperFilter = Class.forName(
- "android.filterpacks.videoproc.BackDropperFilter");
- sClsLearningDoneListener = Class.forName(
- "android.filterpacks.videoproc.BackDropperFilter$LearningDoneListener");
- sLearningDoneListenerOnLearningDone = sClsLearningDoneListener
- .getMethod("onLearningDone", new Class[] {clsBackDropperFilter});
-
- sObjectEquals = Object.class.getMethod("equals", new Class[] {Object.class});
- sObjectToString = Object.class.getMethod("toString");
-
- sClsOnRunnerDoneListener = Class.forName(
- "android.filterfw.core.GraphRunner$OnRunnerDoneListener");
- sOnRunnerDoneListenerOnRunnerDone = sClsOnRunnerDoneListener.getMethod(
- "onRunnerDone", new Class[] {int.class});
-
- sClsGraphRunner = Class.forName("android.filterfw.core.GraphRunner");
- sGraphRunnerGetGraph = sClsGraphRunner.getMethod("getGraph");
- sGraphRunnerSetDoneCallback = sClsGraphRunner.getMethod(
- "setDoneCallback", new Class[] {sClsOnRunnerDoneListener});
- sGraphRunnerRun = sClsGraphRunner.getMethod("run");
- sGraphRunnerGetError = sClsGraphRunner.getMethod("getError");
- sGraphRunnerStop = sClsGraphRunner.getMethod("stop");
-
- Class<?> clsFilterContext = Class.forName("android.filterfw.core.FilterContext");
- sFilterContextGetGLEnvironment = clsFilterContext.getMethod(
- "getGLEnvironment");
-
- Class<?> clsFilterGraph = Class.forName("android.filterfw.core.FilterGraph");
- sFilterGraphGetFilter = clsFilterGraph.getMethod("getFilter",
- new Class[] {String.class});
- sFilterGraphTearDown = clsFilterGraph.getMethod("tearDown",
- new Class[] {clsFilterContext});
-
- sClsGraphEnvironment = Class.forName("android.filterfw.GraphEnvironment");
- sCtGraphEnvironment = sClsGraphEnvironment.getConstructor();
- sGraphEnvironmentCreateGLEnvironment = sClsGraphEnvironment.getMethod(
- "createGLEnvironment");
- sGraphEnvironmentGetRunner = sClsGraphEnvironment.getMethod(
- "getRunner", new Class[] {int.class, int.class});
- sGraphEnvironmentAddReferences = sClsGraphEnvironment.getMethod(
- "addReferences", new Class[] {Object[].class});
- sGraphEnvironmentLoadGraph = sClsGraphEnvironment.getMethod(
- "loadGraph", new Class[] {Context.class, int.class});
- sGraphEnvironmentGetContext = sClsGraphEnvironment.getMethod(
- "getContext");
-
- Class<?> clsGLEnvironment = Class.forName("android.filterfw.core.GLEnvironment");
- sGLEnvironmentIsActive = clsGLEnvironment.getMethod("isActive");
- sGLEnvironmentActivate = clsGLEnvironment.getMethod("activate");
- sGLEnvironmentDeactivate = clsGLEnvironment.getMethod("deactivate");
-
- Class<?> clsSurfaceTextureTarget = Class.forName(
- "android.filterpacks.videosrc.SurfaceTextureTarget");
- sSurfaceTextureTargetDisconnect = clsSurfaceTextureTarget.getMethod(
- "disconnect", new Class[] {clsFilterContext});
-
- sClsOnRecordingDoneListener = Class.forName(
- "android.filterpacks.videosink.MediaEncoderFilter$OnRecordingDoneListener");
- sOnRecordingDoneListenerOnRecordingDone =
- sClsOnRecordingDoneListener.getMethod("onRecordingDone");
-
- sClsSurfaceTextureSourceListener = Class.forName(
- "android.filterpacks.videosrc.SurfaceTextureSource$SurfaceTextureSourceListener");
- sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady =
- sClsSurfaceTextureSourceListener.getMethod(
- "onSurfaceTextureSourceReady",
- new Class[] {SurfaceTexture.class});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
-
- sReflectionInited = true;
- }
-
- sEffectsRecorderIndex++;
- Log.v(TAG, "Current effects recorder index is " + sEffectsRecorderIndex);
- sEffectsRecorder = this;
- SerializableInvocationHandler sih = new SerializableInvocationHandler(
- sEffectsRecorderIndex);
- mLearningDoneListener = Proxy.newProxyInstance(
- sClsLearningDoneListener.getClassLoader(),
- new Class[] {sClsLearningDoneListener}, sih);
- mRunnerDoneCallback = Proxy.newProxyInstance(
- sClsOnRunnerDoneListener.getClassLoader(),
- new Class[] {sClsOnRunnerDoneListener}, sih);
- mSourceReadyCallback = Proxy.newProxyInstance(
- sClsSurfaceTextureSourceListener.getClassLoader(),
- new Class[] {sClsSurfaceTextureSourceListener}, sih);
- mRecordingDoneListener = Proxy.newProxyInstance(
- sClsOnRecordingDoneListener.getClassLoader(),
- new Class[] {sClsOnRecordingDoneListener}, sih);
-
- mContext = context;
- mHandler = new Handler(Looper.getMainLooper());
- mSoundPlayer = SoundClips.getPlayer(context);
- }
-
- public synchronized void setCamera(CameraManager.CameraProxy cameraDevice) {
- switch (mState) {
- case STATE_PREVIEW:
- throw new RuntimeException("setCamera cannot be called while previewing!");
- case STATE_RECORD:
- throw new RuntimeException("setCamera cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setCamera called on an already released recorder!");
- default:
- break;
- }
-
- mCameraDevice = cameraDevice;
- }
-
- public void setProfile(CamcorderProfile profile) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setProfile cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setProfile called on an already released recorder!");
- default:
- break;
- }
- mProfile = profile;
- }
-
- public void setOutputFile(String outputFile) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setOutputFile cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setOutputFile called on an already released recorder!");
- default:
- break;
- }
-
- mOutputFile = outputFile;
- mFd = null;
- }
-
- public void setOutputFile(FileDescriptor fd) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setOutputFile cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setOutputFile called on an already released recorder!");
- default:
- break;
- }
-
- mOutputFile = null;
- mFd = fd;
- }
-
- /**
- * Sets the maximum filesize (in bytes) of the recording session.
- * This will be passed on to the MediaEncoderFilter and then to the
- * MediaRecorder ultimately. If zero or negative, the MediaRecorder will
- * disable the limit
- */
- public synchronized void setMaxFileSize(long maxFileSize) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setMaxFileSize cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setMaxFileSize called on an already released recorder!");
- default:
- break;
- }
- mMaxFileSize = maxFileSize;
- }
-
- /**
- * Sets the maximum recording duration (in ms) for the next recording session
- * Setting it to zero (the default) disables the limit.
- */
- public synchronized void setMaxDuration(int maxDurationMs) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setMaxDuration cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setMaxDuration called on an already released recorder!");
- default:
- break;
- }
- mMaxDurationMs = maxDurationMs;
- }
-
-
- public void setCaptureRate(double fps) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setCaptureRate cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setCaptureRate called on an already released recorder!");
- default:
- break;
- }
-
- if (mLogVerbose) Log.v(TAG, "Setting time lapse capture rate to " + fps + " fps");
- mCaptureRate = fps;
- }
-
- public void setPreviewSurfaceTexture(SurfaceTexture previewSurfaceTexture,
- int previewWidth,
- int previewHeight) {
- if (mLogVerbose) Log.v(TAG, "setPreviewSurfaceTexture(" + this + ")");
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException(
- "setPreviewSurfaceTexture cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setPreviewSurfaceTexture called on an already released recorder!");
- default:
- break;
- }
-
- mPreviewSurfaceTexture = previewSurfaceTexture;
- mPreviewWidth = previewWidth;
- mPreviewHeight = previewHeight;
-
- switch (mState) {
- case STATE_WAITING_FOR_SURFACE:
- startPreview();
- break;
- case STATE_STARTING_PREVIEW:
- case STATE_PREVIEW:
- initializeEffect(true);
- break;
- }
- }
-
- public void setEffect(int effect, Object effectParameter) {
- if (mLogVerbose) Log.v(TAG,
- "setEffect: effect ID " + effect +
- ", parameter " + effectParameter.toString());
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setEffect cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setEffect called on an already released recorder!");
- default:
- break;
- }
-
- mEffect = effect;
- mEffectParameter = effectParameter;
-
- if (mState == STATE_PREVIEW ||
- mState == STATE_STARTING_PREVIEW) {
- initializeEffect(false);
- }
- }
-
- public interface EffectsListener {
- public void onEffectsUpdate(int effectId, int effectMsg);
- public void onEffectsError(Exception exception, String filePath);
- }
-
- public void setEffectsListener(EffectsListener listener) {
- mEffectsListener = listener;
- }
-
- private void setFaceDetectOrientation() {
- if (mCurrentEffect == EFFECT_GOOFY_FACE) {
- Object rotateFilter = getGraphFilter(mRunner, "rotate");
- Object metaRotateFilter = getGraphFilter(mRunner, "metarotate");
- setInputValue(rotateFilter, "rotation", mOrientationHint);
- int reverseDegrees = (360 - mOrientationHint) % 360;
- setInputValue(metaRotateFilter, "rotation", reverseDegrees);
- }
- }
-
- private void setRecordingOrientation() {
- if (mState != STATE_RECORD && mRunner != null) {
- Object bl = newInstance(sCtPoint, new Object[] {0, 0});
- Object br = newInstance(sCtPoint, new Object[] {1, 0});
- Object tl = newInstance(sCtPoint, new Object[] {0, 1});
- Object tr = newInstance(sCtPoint, new Object[] {1, 1});
- Object recordingRegion;
- if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
- // The back camera is not mirrored, so use a identity transform
- recordingRegion = newInstance(sCtQuad, new Object[] {bl, br, tl, tr});
- } else {
- // Recording region needs to be tweaked for front cameras, since they
- // mirror their preview
- if (mOrientationHint == 0 || mOrientationHint == 180) {
- // Horizontal flip in landscape
- recordingRegion = newInstance(sCtQuad, new Object[] {br, bl, tr, tl});
- } else {
- // Horizontal flip in portrait
- recordingRegion = newInstance(sCtQuad, new Object[] {tl, tr, bl, br});
- }
- }
- Object recorder = getGraphFilter(mRunner, "recorder");
- setInputValue(recorder, "inputRegion", recordingRegion);
- }
- }
- public void setOrientationHint(int degrees) {
- switch (mState) {
- case STATE_RELEASED:
- throw new RuntimeException(
- "setOrientationHint called on an already released recorder!");
- default:
- break;
- }
- if (mLogVerbose) Log.v(TAG, "Setting orientation hint to: " + degrees);
- mOrientationHint = degrees;
- setFaceDetectOrientation();
- setRecordingOrientation();
- }
-
- public void setCameraDisplayOrientation(int orientation) {
- if (mState != STATE_CONFIGURE) {
- throw new RuntimeException(
- "setCameraDisplayOrientation called after configuration!");
- }
- mCameraDisplayOrientation = orientation;
- }
-
- public void setCameraFacing(int facing) {
- switch (mState) {
- case STATE_RELEASED:
- throw new RuntimeException(
- "setCameraFacing called on alrady released recorder!");
- default:
- break;
- }
- mCameraFacing = facing;
- setRecordingOrientation();
- }
-
- public void setOnInfoListener(MediaRecorder.OnInfoListener infoListener) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setInfoListener cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setInfoListener called on an already released recorder!");
- default:
- break;
- }
- mInfoListener = infoListener;
- }
-
- public void setOnErrorListener(MediaRecorder.OnErrorListener errorListener) {
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("setErrorListener cannot be called while recording!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "setErrorListener called on an already released recorder!");
- default:
- break;
- }
- mErrorListener = errorListener;
- }
-
- private void initializeFilterFramework() {
- mGraphEnv = newInstance(sCtGraphEnvironment);
- invoke(mGraphEnv, sGraphEnvironmentCreateGLEnvironment);
-
- int videoFrameWidth = mProfile.videoFrameWidth;
- int videoFrameHeight = mProfile.videoFrameHeight;
- if (mCameraDisplayOrientation == 90 || mCameraDisplayOrientation == 270) {
- int tmp = videoFrameWidth;
- videoFrameWidth = videoFrameHeight;
- videoFrameHeight = tmp;
- }
-
- invoke(mGraphEnv, sGraphEnvironmentAddReferences,
- new Object[] {new Object[] {
- "textureSourceCallback", mSourceReadyCallback,
- "recordingWidth", videoFrameWidth,
- "recordingHeight", videoFrameHeight,
- "recordingProfile", mProfile,
- "learningDoneListener", mLearningDoneListener,
- "recordingDoneListener", mRecordingDoneListener}});
- mRunner = null;
- mGraphId = -1;
- mCurrentEffect = EFFECT_NONE;
- }
-
- private synchronized void initializeEffect(boolean forceReset) {
- if (forceReset ||
- mCurrentEffect != mEffect ||
- mCurrentEffect == EFFECT_BACKDROPPER) {
-
- invoke(mGraphEnv, sGraphEnvironmentAddReferences,
- new Object[] {new Object[] {
- "previewSurfaceTexture", mPreviewSurfaceTexture,
- "previewWidth", mPreviewWidth,
- "previewHeight", mPreviewHeight,
- "orientation", mOrientationHint}});
- if (mState == STATE_PREVIEW ||
- mState == STATE_STARTING_PREVIEW) {
- // Switching effects while running. Inform video camera.
- sendMessage(mCurrentEffect, EFFECT_MSG_SWITCHING_EFFECT);
- }
-
- switch (mEffect) {
- case EFFECT_GOOFY_FACE:
- mGraphId = (Integer) invoke(mGraphEnv,
- sGraphEnvironmentLoadGraph,
- new Object[] {mContext, R.raw.goofy_face});
- break;
- case EFFECT_BACKDROPPER:
- sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_STARTED_LEARNING);
- mGraphId = (Integer) invoke(mGraphEnv,
- sGraphEnvironmentLoadGraph,
- new Object[] {mContext, R.raw.backdropper});
- break;
- default:
- throw new RuntimeException("Unknown effect ID" + mEffect + "!");
- }
- mCurrentEffect = mEffect;
-
- mOldRunner = mRunner;
- mRunner = invoke(mGraphEnv, sGraphEnvironmentGetRunner,
- new Object[] {mGraphId,
- getConstant(sClsGraphEnvironment, "MODE_ASYNCHRONOUS")});
- invoke(mRunner, sGraphRunnerSetDoneCallback, new Object[] {mRunnerDoneCallback});
- if (mLogVerbose) {
- Log.v(TAG, "New runner: " + mRunner
- + ". Old runner: " + mOldRunner);
- }
- if (mState == STATE_PREVIEW ||
- mState == STATE_STARTING_PREVIEW) {
- // Switching effects while running. Stop existing runner.
- // The stop callback will take care of starting new runner.
- mCameraDevice.stopPreview();
- mCameraDevice.setPreviewTexture(null);
- invoke(mOldRunner, sGraphRunnerStop);
- }
- }
-
- switch (mCurrentEffect) {
- case EFFECT_GOOFY_FACE:
- tryEnableVideoStabilization(true);
- Object goofyFilter = getGraphFilter(mRunner, "goofyrenderer");
- setInputValue(goofyFilter, "currentEffect",
- ((Integer) mEffectParameter).intValue());
- break;
- case EFFECT_BACKDROPPER:
- tryEnableVideoStabilization(false);
- Object backgroundSrc = getGraphFilter(mRunner, "background");
- if (ApiHelper.HAS_EFFECTS_RECORDING_CONTEXT_INPUT) {
- // Set the context first before setting sourceUrl to
- // guarantee the content URI get resolved properly.
- setInputValue(backgroundSrc, "context", mContext);
- }
- setInputValue(backgroundSrc, "sourceUrl", mEffectParameter);
- // For front camera, the background video needs to be mirrored in the
- // backdropper filter
- if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
- Object replacer = getGraphFilter(mRunner, "replacer");
- setInputValue(replacer, "mirrorBg", true);
- if (mLogVerbose) Log.v(TAG, "Setting the background to be mirrored");
- }
- break;
- default:
- break;
- }
- setFaceDetectOrientation();
- setRecordingOrientation();
- }
-
- public synchronized void startPreview() {
- if (mLogVerbose) Log.v(TAG, "Starting preview (" + this + ")");
-
- switch (mState) {
- case STATE_STARTING_PREVIEW:
- case STATE_PREVIEW:
- // Already running preview
- Log.w(TAG, "startPreview called when already running preview");
- return;
- case STATE_RECORD:
- throw new RuntimeException("Cannot start preview when already recording!");
- case STATE_RELEASED:
- throw new RuntimeException("setEffect called on an already released recorder!");
- default:
- break;
- }
-
- if (mEffect == EFFECT_NONE) {
- throw new RuntimeException("No effect selected!");
- }
- if (mEffectParameter == null) {
- throw new RuntimeException("No effect parameter provided!");
- }
- if (mProfile == null) {
- throw new RuntimeException("No recording profile provided!");
- }
- if (mPreviewSurfaceTexture == null) {
- if (mLogVerbose) Log.v(TAG, "Passed a null surface; waiting for valid one");
- mState = STATE_WAITING_FOR_SURFACE;
- return;
- }
- if (mCameraDevice == null) {
- throw new RuntimeException("No camera to record from!");
- }
-
- if (mLogVerbose) Log.v(TAG, "Initializing filter framework and running the graph.");
- initializeFilterFramework();
-
- initializeEffect(true);
-
- mState = STATE_STARTING_PREVIEW;
- invoke(mRunner, sGraphRunnerRun);
- // Rest of preview startup handled in mSourceReadyCallback
- }
-
- private Object invokeObjectEquals(Object proxy, Object[] args) {
- return Boolean.valueOf(proxy == args[0]);
- }
-
- private Object invokeObjectToString() {
- return "Proxy-" + toString();
- }
-
- private void invokeOnLearningDone() {
- if (mLogVerbose) Log.v(TAG, "Learning done callback triggered");
- // Called in a processing thread, so have to post message back to UI
- // thread
- sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_DONE_LEARNING);
- enable3ALocks(true);
- }
-
- private void invokeOnRunnerDone(Object[] args) {
- int runnerDoneResult = (Integer) args[0];
- synchronized (EffectsRecorder.this) {
- if (mLogVerbose) {
- Log.v(TAG,
- "Graph runner done (" + EffectsRecorder.this
- + ", mRunner " + mRunner
- + ", mOldRunner " + mOldRunner + ")");
- }
- if (runnerDoneResult ==
- (Integer) getConstant(sClsGraphRunner, "RESULT_ERROR")) {
- // Handle error case
- Log.e(TAG, "Error running filter graph!");
- Exception e = null;
- if (mRunner != null) {
- e = (Exception) invoke(mRunner, sGraphRunnerGetError);
- } else if (mOldRunner != null) {
- e = (Exception) invoke(mOldRunner, sGraphRunnerGetError);
- }
- raiseError(e);
- }
- if (mOldRunner != null) {
- // Tear down old graph if available
- if (mLogVerbose) Log.v(TAG, "Tearing down old graph.");
- Object glEnv = getContextGLEnvironment(mGraphEnv);
- if (glEnv != null && !(Boolean) invoke(glEnv, sGLEnvironmentIsActive)) {
- invoke(glEnv, sGLEnvironmentActivate);
- }
- getGraphTearDown(mOldRunner,
- invoke(mGraphEnv, sGraphEnvironmentGetContext));
- if (glEnv != null && (Boolean) invoke(glEnv, sGLEnvironmentIsActive)) {
- invoke(glEnv, sGLEnvironmentDeactivate);
- }
- mOldRunner = null;
- }
- if (mState == STATE_PREVIEW ||
- mState == STATE_STARTING_PREVIEW) {
- // Switching effects, start up the new runner
- if (mLogVerbose) {
- Log.v(TAG, "Previous effect halted. Running graph again. state: "
- + mState);
- }
- tryEnable3ALocks(false);
- // In case of an error, the graph restarts from beginning and in case
- // of the BACKDROPPER effect, the learner re-learns the background.
- // Hence, we need to show the learning dialogue to the user
- // to avoid recording before the learning is done. Else, the user
- // could start recording before the learning is done and the new
- // background comes up later leading to an end result video
- // with a heterogeneous background.
- // For BACKDROPPER effect, this path is also executed sometimes at
- // the end of a normal recording session. In such a case, the graph
- // does not restart and hence the learner does not re-learn. So we
- // do not want to show the learning dialogue then.
- if (runnerDoneResult == (Integer) getConstant(
- sClsGraphRunner, "RESULT_ERROR")
- && mCurrentEffect == EFFECT_BACKDROPPER) {
- sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_STARTED_LEARNING);
- }
- invoke(mRunner, sGraphRunnerRun);
- } else if (mState != STATE_RELEASED) {
- // Shutting down effects
- if (mLogVerbose) Log.v(TAG, "Runner halted, restoring direct preview");
- tryEnable3ALocks(false);
- sendMessage(EFFECT_NONE, EFFECT_MSG_EFFECTS_STOPPED);
- } else {
- // STATE_RELEASED - camera will be/has been released as well, do nothing.
- }
- }
- }
-
- private void invokeOnSurfaceTextureSourceReady(Object[] args) {
- SurfaceTexture source = (SurfaceTexture) args[0];
- if (mLogVerbose) Log.v(TAG, "SurfaceTexture ready callback received");
- synchronized (EffectsRecorder.this) {
- mTextureSource = source;
-
- if (mState == STATE_CONFIGURE) {
- // Stop preview happened while the runner was doing startup tasks
- // Since we haven't started anything up, don't do anything
- // Rest of cleanup will happen in onRunnerDone
- if (mLogVerbose) Log.v(TAG, "Ready callback: Already stopped, skipping.");
- return;
- }
- if (mState == STATE_RELEASED) {
- // EffectsRecorder has been released, so don't touch the camera device
- // or anything else
- if (mLogVerbose) Log.v(TAG, "Ready callback: Already released, skipping.");
- return;
- }
- if (source == null) {
- if (mLogVerbose) {
- Log.v(TAG, "Ready callback: source null! Looks like graph was closed!");
- }
- if (mState == STATE_PREVIEW ||
- mState == STATE_STARTING_PREVIEW ||
- mState == STATE_RECORD) {
- // A null source here means the graph is shutting down
- // unexpectedly, so we need to turn off preview before
- // the surface texture goes away.
- if (mLogVerbose) {
- Log.v(TAG, "Ready callback: State: " + mState
- + ". stopCameraPreview");
- }
-
- stopCameraPreview();
- }
- return;
- }
-
- // Lock AE/AWB to reduce transition flicker
- tryEnable3ALocks(true);
-
- mCameraDevice.stopPreview();
- if (mLogVerbose) Log.v(TAG, "Runner active, connecting effects preview");
- mCameraDevice.setPreviewTexture(mTextureSource);
-
- mCameraDevice.startPreview();
-
- // Unlock AE/AWB after preview started
- tryEnable3ALocks(false);
-
- mState = STATE_PREVIEW;
-
- if (mLogVerbose) Log.v(TAG, "Start preview/effect switch complete");
-
- // Sending a message to listener that preview is complete
- sendMessage(mCurrentEffect, EFFECT_MSG_PREVIEW_RUNNING);
- }
- }
-
- private void invokeOnRecordingDone() {
- // Forward the callback to the VideoModule object (as an asynchronous event).
- if (mLogVerbose) Log.v(TAG, "Recording done callback triggered");
- sendMessage(EFFECT_NONE, EFFECT_MSG_RECORDING_DONE);
- }
-
- public synchronized void startRecording() {
- if (mLogVerbose) Log.v(TAG, "Starting recording (" + this + ")");
-
- switch (mState) {
- case STATE_RECORD:
- throw new RuntimeException("Already recording, cannot begin anew!");
- case STATE_RELEASED:
- throw new RuntimeException(
- "startRecording called on an already released recorder!");
- default:
- break;
- }
-
- if ((mOutputFile == null) && (mFd == null)) {
- throw new RuntimeException("No output file name or descriptor provided!");
- }
-
- if (mState == STATE_CONFIGURE) {
- startPreview();
- }
-
- Object recorder = getGraphFilter(mRunner, "recorder");
- if (mFd != null) {
- setInputValue(recorder, "outputFileDescriptor", mFd);
- } else {
- setInputValue(recorder, "outputFile", mOutputFile);
- }
- // It is ok to set the audiosource without checking for timelapse here
- // since that check will be done in the MediaEncoderFilter itself
- setInputValue(recorder, "audioSource", MediaRecorder.AudioSource.CAMCORDER);
- setInputValue(recorder, "recordingProfile", mProfile);
- setInputValue(recorder, "orientationHint", mOrientationHint);
- // Important to set the timelapseinterval to 0 if the capture rate is not >0
- // since the recorder does not get created every time the recording starts.
- // The recorder infers whether the capture is timelapsed based on the value of
- // this interval
- boolean captureTimeLapse = mCaptureRate > 0;
- if (captureTimeLapse) {
- double timeBetweenFrameCapture = 1 / mCaptureRate;
- setInputValue(recorder, "timelapseRecordingIntervalUs",
- (long) (1000000 * timeBetweenFrameCapture));
-
- } else {
- setInputValue(recorder, "timelapseRecordingIntervalUs", 0L);
- }
-
- if (mInfoListener != null) {
- setInputValue(recorder, "infoListener", mInfoListener);
- }
- if (mErrorListener != null) {
- setInputValue(recorder, "errorListener", mErrorListener);
- }
- setInputValue(recorder, "maxFileSize", mMaxFileSize);
- setInputValue(recorder, "maxDurationMs", mMaxDurationMs);
- setInputValue(recorder, "recording", true);
- mSoundPlayer.play(SoundClips.START_VIDEO_RECORDING);
- mState = STATE_RECORD;
- }
-
- public synchronized void stopRecording() {
- if (mLogVerbose) Log.v(TAG, "Stop recording (" + this + ")");
-
- switch (mState) {
- case STATE_CONFIGURE:
- case STATE_STARTING_PREVIEW:
- case STATE_PREVIEW:
- Log.w(TAG, "StopRecording called when recording not active!");
- return;
- case STATE_RELEASED:
- throw new RuntimeException("stopRecording called on released EffectsRecorder!");
- default:
- break;
- }
- Object recorder = getGraphFilter(mRunner, "recorder");
- setInputValue(recorder, "recording", false);
- mSoundPlayer.play(SoundClips.STOP_VIDEO_RECORDING);
- mState = STATE_PREVIEW;
- }
-
- // Called to tell the filter graph that the display surfacetexture is not valid anymore.
- // So the filter graph should not hold any reference to the surface created with that.
- public synchronized void disconnectDisplay() {
- if (mLogVerbose) Log.v(TAG, "Disconnecting the graph from the " +
- "SurfaceTexture");
- Object display = getGraphFilter(mRunner, "display");
- invoke(display, sSurfaceTextureTargetDisconnect, new Object[] {
- invoke(mGraphEnv, sGraphEnvironmentGetContext)});
- }
-
- // The VideoModule will call this to notify that the camera is being
- // released to the outside world. This call should happen after the
- // stopRecording call. Else, the effects may throw an exception.
- // With the recording stopped, the stopPreview call will not try to
- // release the camera again.
- // This must be called in onPause() if the effects are ON.
- public synchronized void disconnectCamera() {
- if (mLogVerbose) Log.v(TAG, "Disconnecting the effects from Camera");
- stopCameraPreview();
- mCameraDevice = null;
- }
-
- // In a normal case, when the disconnect is not called, we should not
- // set the camera device to null, since on return callback, we try to
- // enable 3A locks, which need the cameradevice.
- public synchronized void stopCameraPreview() {
- if (mLogVerbose) Log.v(TAG, "Stopping camera preview.");
- if (mCameraDevice == null) {
- Log.d(TAG, "Camera already null. Nothing to disconnect");
- return;
- }
- mCameraDevice.stopPreview();
- mCameraDevice.setPreviewTexture(null);
- }
-
- // Stop and release effect resources
- public synchronized void stopPreview() {
- if (mLogVerbose) Log.v(TAG, "Stopping preview (" + this + ")");
- switch (mState) {
- case STATE_CONFIGURE:
- Log.w(TAG, "StopPreview called when preview not active!");
- return;
- case STATE_RELEASED:
- throw new RuntimeException("stopPreview called on released EffectsRecorder!");
- default:
- break;
- }
-
- if (mState == STATE_RECORD) {
- stopRecording();
- }
-
- mCurrentEffect = EFFECT_NONE;
-
- // This will not do anything if the camera has already been disconnected.
- stopCameraPreview();
-
- mState = STATE_CONFIGURE;
- mOldRunner = mRunner;
- invoke(mRunner, sGraphRunnerStop);
- mRunner = null;
- // Rest of stop and release handled in mRunnerDoneCallback
- }
-
- // Try to enable/disable video stabilization if supported; otherwise return false
- // It is called from a synchronized block.
- boolean tryEnableVideoStabilization(boolean toggle) {
- if (mLogVerbose) Log.v(TAG, "tryEnableVideoStabilization.");
- if (mCameraDevice == null) {
- Log.d(TAG, "Camera already null. Not enabling video stabilization.");
- return false;
- }
- Camera.Parameters params = mCameraDevice.getParameters();
-
- String vstabSupported = params.get("video-stabilization-supported");
- if ("true".equals(vstabSupported)) {
- if (mLogVerbose) Log.v(TAG, "Setting video stabilization to " + toggle);
- params.set("video-stabilization", toggle ? "true" : "false");
- mCameraDevice.setParameters(params);
- return true;
- }
- if (mLogVerbose) Log.v(TAG, "Video stabilization not supported");
- return false;
- }
-
- // Try to enable/disable 3A locks if supported; otherwise return false
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- synchronized boolean tryEnable3ALocks(boolean toggle) {
- if (mLogVerbose) Log.v(TAG, "tryEnable3ALocks");
- if (mCameraDevice == null) {
- Log.d(TAG, "Camera already null. Not tryenabling 3A locks.");
- return false;
- }
- Camera.Parameters params = mCameraDevice.getParameters();
- if (Util.isAutoExposureLockSupported(params) &&
- Util.isAutoWhiteBalanceLockSupported(params)) {
- params.setAutoExposureLock(toggle);
- params.setAutoWhiteBalanceLock(toggle);
- mCameraDevice.setParameters(params);
- return true;
- }
- return false;
- }
-
- // Try to enable/disable 3A locks if supported; otherwise, throw error
- // Use this when locks are essential to success
- synchronized void enable3ALocks(boolean toggle) {
- if (mLogVerbose) Log.v(TAG, "Enable3ALocks");
- if (mCameraDevice == null) {
- Log.d(TAG, "Camera already null. Not enabling 3A locks.");
- return;
- }
- Camera.Parameters params = mCameraDevice.getParameters();
- if (!tryEnable3ALocks(toggle)) {
- throw new RuntimeException("Attempt to lock 3A on camera with no locking support!");
- }
- }
-
- static class SerializableInvocationHandler
- implements InvocationHandler, Serializable {
- private final int mEffectsRecorderIndex;
- public SerializableInvocationHandler(int index) {
- mEffectsRecorderIndex = index;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- if (sEffectsRecorder == null) return null;
- if (mEffectsRecorderIndex != sEffectsRecorderIndex) {
- Log.v(TAG, "Ignore old callback " + mEffectsRecorderIndex);
- return null;
- }
- if (method.equals(sObjectEquals)) {
- return sEffectsRecorder.invokeObjectEquals(proxy, args);
- } else if (method.equals(sObjectToString)) {
- return sEffectsRecorder.invokeObjectToString();
- } else if (method.equals(sLearningDoneListenerOnLearningDone)) {
- sEffectsRecorder.invokeOnLearningDone();
- } else if (method.equals(sOnRunnerDoneListenerOnRunnerDone)) {
- sEffectsRecorder.invokeOnRunnerDone(args);
- } else if (method.equals(
- sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady)) {
- sEffectsRecorder.invokeOnSurfaceTextureSourceReady(args);
- } else if (method.equals(sOnRecordingDoneListenerOnRecordingDone)) {
- sEffectsRecorder.invokeOnRecordingDone();
- }
- return null;
- }
- }
-
- // Indicates that all camera/recording activity needs to halt
- public synchronized void release() {
- if (mLogVerbose) Log.v(TAG, "Releasing (" + this + ")");
-
- switch (mState) {
- case STATE_RECORD:
- case STATE_STARTING_PREVIEW:
- case STATE_PREVIEW:
- stopPreview();
- // Fall-through
- default:
- if (mSoundPlayer != null) {
- mSoundPlayer.release();
- mSoundPlayer = null;
- }
- mState = STATE_RELEASED;
- break;
- }
- sEffectsRecorder = null;
- }
-
- private void sendMessage(final int effect, final int msg) {
- if (mEffectsListener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mEffectsListener.onEffectsUpdate(effect, msg);
- }
- });
- }
- }
-
- private void raiseError(final Exception exception) {
- if (mEffectsListener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mFd != null) {
- mEffectsListener.onEffectsError(exception, null);
- } else {
- mEffectsListener.onEffectsError(exception, mOutputFile);
- }
- }
- });
- }
- }
-
- // invoke method on receiver with no arguments
- private Object invoke(Object receiver, Method method) {
- try {
- return method.invoke(receiver);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- // invoke method on receiver with arguments
- private Object invoke(Object receiver, Method method, Object[] args) {
- try {
- return method.invoke(receiver, args);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private void setInputValue(Object receiver, String key, Object value) {
- try {
- sFilterSetInputValue.invoke(receiver, new Object[] {key, value});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private Object newInstance(Constructor<?> ct, Object[] initArgs) {
- try {
- return ct.newInstance(initArgs);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private Object newInstance(Constructor<?> ct) {
- try {
- return ct.newInstance();
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private Object getGraphFilter(Object receiver, String name) {
- try {
- return sFilterGraphGetFilter.invoke(sGraphRunnerGetGraph
- .invoke(receiver), new Object[] {name});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private Object getContextGLEnvironment(Object receiver) {
- try {
- return sFilterContextGetGLEnvironment
- .invoke(sGraphEnvironmentGetContext.invoke(receiver));
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private void getGraphTearDown(Object receiver, Object filterContext) {
- try {
- sFilterGraphTearDown.invoke(sGraphRunnerGetGraph.invoke(receiver),
- new Object[]{filterContext});
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- private Object getConstant(Class<?> cls, String name) {
- try {
- return cls.getDeclaredField(name).get(null);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-}
diff --git a/src/com/android/camera/Exif.java b/src/com/android/camera/Exif.java
deleted file mode 100644
index c6ec6af50..000000000
--- a/src/com/android/camera/Exif.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.util.Log;
-
-import com.android.gallery3d.exif.ExifInterface;
-
-import java.io.IOException;
-
-public class Exif {
- private static final String TAG = "CameraExif";
-
- public static ExifInterface getExif(byte[] jpegData) {
- ExifInterface exif = new ExifInterface();
- try {
- exif.readExif(jpegData);
- } catch (IOException e) {
- Log.w(TAG, "Failed to read EXIF data", e);
- }
- return exif;
- }
-
- // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
- public static int getOrientation(ExifInterface exif) {
- Integer val = exif.getTagIntValue(ExifInterface.TAG_ORIENTATION);
- if (val == null) {
- return 0;
- } else {
- return ExifInterface.getRotationForOrientationValue(val.shortValue());
- }
- }
-
- public static int getOrientation(byte[] jpegData) {
- if (jpegData == null) return 0;
-
- ExifInterface exif = getExif(jpegData);
- return getOrientation(exif);
- }
-}
diff --git a/src/com/android/camera/FocusOverlayManager.java b/src/com/android/camera/FocusOverlayManager.java
deleted file mode 100644
index 8bcb52fe5..000000000
--- a/src/com/android/camera/FocusOverlayManager.java
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.Camera.Area;
-import android.hardware.Camera.Parameters;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/* A class that handles everything about focus in still picture mode.
- * This also handles the metering area because it is the same as focus area.
- *
- * The test cases:
- * (1) The camera has continuous autofocus. Move the camera. Take a picture when
- * CAF is not in progress.
- * (2) The camera has continuous autofocus. Move the camera. Take a picture when
- * CAF is in progress.
- * (3) The camera has face detection. Point the camera at some faces. Hold the
- * shutter. Release to take a picture.
- * (4) The camera has face detection. Point the camera at some faces. Single tap
- * the shutter to take a picture.
- * (5) The camera has autofocus. Single tap the shutter to take a picture.
- * (6) The camera has autofocus. Hold the shutter. Release to take a picture.
- * (7) The camera has no autofocus. Single tap the shutter and take a picture.
- * (8) The camera has autofocus and supports focus area. Touch the screen to
- * trigger autofocus. Take a picture.
- * (9) The camera has autofocus and supports focus area. Touch the screen to
- * trigger autofocus. Wait until it times out.
- * (10) The camera has no autofocus and supports metering area. Touch the screen
- * to change metering area.
- */
-public class FocusOverlayManager {
- private static final String TAG = "CAM_FocusManager";
-
- private static final int RESET_TOUCH_FOCUS = 0;
- private static final int RESET_TOUCH_FOCUS_DELAY = 3000;
-
- private int mState = STATE_IDLE;
- private static final int STATE_IDLE = 0; // Focus is not active.
- private static final int STATE_FOCUSING = 1; // Focus is in progress.
- // Focus is in progress and the camera should take a picture after focus finishes.
- private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
- private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
- private static final int STATE_FAIL = 4; // Focus finishes and fails.
-
- private boolean mInitialized;
- private boolean mFocusAreaSupported;
- private boolean mMeteringAreaSupported;
- private boolean mLockAeAwbNeeded;
- private boolean mAeAwbLock;
- private Matrix mMatrix;
-
- private int mPreviewWidth; // The width of the preview frame layout.
- private int mPreviewHeight; // The height of the preview frame layout.
- private boolean mMirror; // true if the camera is front-facing.
- private int mDisplayOrientation;
- private List<Object> mFocusArea; // focus area in driver format
- private List<Object> mMeteringArea; // metering area in driver format
- private String mFocusMode;
- private String[] mDefaultFocusModes;
- private String mOverrideFocusMode;
- private Parameters mParameters;
- private ComboPreferences mPreferences;
- private Handler mHandler;
- Listener mListener;
- private boolean mPreviousMoving;
- private boolean mFocusDefault;
-
- private FocusUI mUI;
-
- public interface FocusUI {
- public boolean hasFaces();
- public void clearFocus();
- public void setFocusPosition(int x, int y);
- public void onFocusStarted();
- public void onFocusSucceeded(boolean timeOut);
- public void onFocusFailed(boolean timeOut);
- public void pauseFaceDetection();
- public void resumeFaceDetection();
- }
-
- public interface Listener {
- public void autoFocus();
- public void cancelAutoFocus();
- public boolean capture();
- public void startFaceDetection();
- public void stopFaceDetection();
- public void setFocusParameters();
- }
-
- private class MainHandler extends Handler {
- public MainHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case RESET_TOUCH_FOCUS: {
- cancelAutoFocus();
- mListener.startFaceDetection();
- break;
- }
- }
- }
- }
-
- public FocusOverlayManager(ComboPreferences preferences, String[] defaultFocusModes,
- Parameters parameters, Listener listener,
- boolean mirror, Looper looper, FocusUI ui) {
- mHandler = new MainHandler(looper);
- mMatrix = new Matrix();
- mPreferences = preferences;
- mDefaultFocusModes = defaultFocusModes;
- setParameters(parameters);
- mListener = listener;
- setMirror(mirror);
- mFocusDefault = true;
- mUI = ui;
- }
-
- public void setParameters(Parameters parameters) {
- // parameters can only be null when onConfigurationChanged is called
- // before camera is open. We will just return in this case, because
- // parameters will be set again later with the right parameters after
- // camera is open.
- if (parameters == null) return;
- mParameters = parameters;
- mFocusAreaSupported = Util.isFocusAreaSupported(parameters);
- mMeteringAreaSupported = Util.isMeteringAreaSupported(parameters);
- mLockAeAwbNeeded = (Util.isAutoExposureLockSupported(mParameters) ||
- Util.isAutoWhiteBalanceLockSupported(mParameters));
- }
-
- public void setPreviewSize(int previewWidth, int previewHeight) {
- if (mPreviewWidth != previewWidth || mPreviewHeight != previewHeight) {
- mPreviewWidth = previewWidth;
- mPreviewHeight = previewHeight;
- setMatrix();
- }
- }
-
- public void setMirror(boolean mirror) {
- mMirror = mirror;
- setMatrix();
- }
-
- public void setDisplayOrientation(int displayOrientation) {
- mDisplayOrientation = displayOrientation;
- setMatrix();
- }
-
- private void setMatrix() {
- if (mPreviewWidth != 0 && mPreviewHeight != 0) {
- Matrix matrix = new Matrix();
- Util.prepareMatrix(matrix, mMirror, mDisplayOrientation,
- mPreviewWidth, mPreviewHeight);
- // In face detection, the matrix converts the driver coordinates to UI
- // coordinates. In tap focus, the inverted matrix converts the UI
- // coordinates to driver coordinates.
- matrix.invert(mMatrix);
- mInitialized = true;
- }
- }
-
- private void lockAeAwbIfNeeded() {
- if (mLockAeAwbNeeded && !mAeAwbLock) {
- mAeAwbLock = true;
- mListener.setFocusParameters();
- }
- }
-
- private void unlockAeAwbIfNeeded() {
- if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) {
- mAeAwbLock = false;
- mListener.setFocusParameters();
- }
- }
-
- public void onShutterDown() {
- if (!mInitialized) return;
-
- boolean autoFocusCalled = false;
- if (needAutoFocusCall()) {
- // Do not focus if touch focus has been triggered.
- if (mState != STATE_SUCCESS && mState != STATE_FAIL) {
- autoFocus();
- autoFocusCalled = true;
- }
- }
-
- if (!autoFocusCalled) lockAeAwbIfNeeded();
- }
-
- public void onShutterUp() {
- if (!mInitialized) return;
-
- if (needAutoFocusCall()) {
- // User releases half-pressed focus key.
- if (mState == STATE_FOCUSING || mState == STATE_SUCCESS
- || mState == STATE_FAIL) {
- cancelAutoFocus();
- }
- }
-
- // Unlock AE and AWB after cancelAutoFocus. Camera API does not
- // guarantee setParameters can be called during autofocus.
- unlockAeAwbIfNeeded();
- }
-
- public void doSnap() {
- if (!mInitialized) return;
-
- // If the user has half-pressed the shutter and focus is completed, we
- // can take the photo right away. If the focus mode is infinity, we can
- // also take the photo.
- if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) {
- capture();
- } else if (mState == STATE_FOCUSING) {
- // Half pressing the shutter (i.e. the focus button event) will
- // already have requested AF for us, so just request capture on
- // focus here.
- mState = STATE_FOCUSING_SNAP_ON_FINISH;
- } else if (mState == STATE_IDLE) {
- // We didn't do focus. This can happen if the user press focus key
- // while the snapshot is still in progress. The user probably wants
- // the next snapshot as soon as possible, so we just do a snapshot
- // without focusing again.
- capture();
- }
- }
-
- public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
- if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
- // Take the picture no matter focus succeeds or fails. No need
- // to play the AF sound if we're about to play the shutter
- // sound.
- if (focused) {
- mState = STATE_SUCCESS;
- } else {
- mState = STATE_FAIL;
- }
- updateFocusUI();
- capture();
- } else if (mState == STATE_FOCUSING) {
- // This happens when (1) user is half-pressing the focus key or
- // (2) touch focus is triggered. Play the focus tone. Do not
- // take the picture now.
- if (focused) {
- mState = STATE_SUCCESS;
- } else {
- mState = STATE_FAIL;
- }
- updateFocusUI();
- // If this is triggered by touch focus, cancel focus after a
- // while.
- if (!mFocusDefault) {
- mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
- }
- if (shutterButtonPressed) {
- // Lock AE & AWB so users can half-press shutter and recompose.
- lockAeAwbIfNeeded();
- }
- } else if (mState == STATE_IDLE) {
- // User has released the focus key before focus completes.
- // Do nothing.
- }
- }
-
- public void onAutoFocusMoving(boolean moving) {
- if (!mInitialized) return;
-
-
- // Ignore if the camera has detected some faces.
- if (mUI.hasFaces()) {
- mUI.clearFocus();
- return;
- }
-
- // Ignore if we have requested autofocus. This method only handles
- // continuous autofocus.
- if (mState != STATE_IDLE) return;
-
- // animate on false->true trasition only b/8219520
- if (moving && !mPreviousMoving) {
- mUI.onFocusStarted();
- } else if (!moving) {
- mUI.onFocusSucceeded(true);
- }
- mPreviousMoving = moving;
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void initializeFocusAreas(int x, int y) {
- if (mFocusArea == null) {
- mFocusArea = new ArrayList<Object>();
- mFocusArea.add(new Area(new Rect(), 1));
- }
-
- // Convert the coordinates to driver format.
- calculateTapArea(x, y, 1f, ((Area) mFocusArea.get(0)).rect);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void initializeMeteringAreas(int x, int y) {
- if (mMeteringArea == null) {
- mMeteringArea = new ArrayList<Object>();
- mMeteringArea.add(new Area(new Rect(), 1));
- }
-
- // Convert the coordinates to driver format.
- // AE area is bigger because exposure is sensitive and
- // easy to over- or underexposure if area is too small.
- calculateTapArea(x, y, 1.5f, ((Area) mMeteringArea.get(0)).rect);
- }
-
- public void onSingleTapUp(int x, int y) {
- if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return;
-
- // Let users be able to cancel previous touch focus.
- if ((!mFocusDefault) && (mState == STATE_FOCUSING ||
- mState == STATE_SUCCESS || mState == STATE_FAIL)) {
- cancelAutoFocus();
- }
- if (mPreviewWidth == 0 || mPreviewHeight == 0) return;
- mFocusDefault = false;
- // Initialize mFocusArea.
- if (mFocusAreaSupported) {
- initializeFocusAreas(x, y);
- }
- // Initialize mMeteringArea.
- if (mMeteringAreaSupported) {
- initializeMeteringAreas(x, y);
- }
-
- // Use margin to set the focus indicator to the touched area.
- mUI.setFocusPosition(x, y);
-
- // Stop face detection because we want to specify focus and metering area.
- mListener.stopFaceDetection();
-
- // Set the focus area and metering area.
- mListener.setFocusParameters();
- if (mFocusAreaSupported) {
- autoFocus();
- } else { // Just show the indicator in all other cases.
- updateFocusUI();
- // Reset the metering area in 3 seconds.
- mHandler.removeMessages(RESET_TOUCH_FOCUS);
- mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
- }
- }
-
- public void onPreviewStarted() {
- mState = STATE_IDLE;
- }
-
- public void onPreviewStopped() {
- // If auto focus was in progress, it would have been stopped.
- mState = STATE_IDLE;
- resetTouchFocus();
- updateFocusUI();
- }
-
- public void onCameraReleased() {
- onPreviewStopped();
- }
-
- private void autoFocus() {
- Log.v(TAG, "Start autofocus.");
- mListener.autoFocus();
- mState = STATE_FOCUSING;
- // Pause the face view because the driver will keep sending face
- // callbacks after the focus completes.
- mUI.pauseFaceDetection();
- updateFocusUI();
- mHandler.removeMessages(RESET_TOUCH_FOCUS);
- }
-
- private void cancelAutoFocus() {
- Log.v(TAG, "Cancel autofocus.");
-
- // Reset the tap area before calling mListener.cancelAutofocus.
- // Otherwise, focus mode stays at auto and the tap area passed to the
- // driver is not reset.
- resetTouchFocus();
- mListener.cancelAutoFocus();
- mUI.resumeFaceDetection();
- mState = STATE_IDLE;
- updateFocusUI();
- mHandler.removeMessages(RESET_TOUCH_FOCUS);
- }
-
- private void capture() {
- if (mListener.capture()) {
- mState = STATE_IDLE;
- mHandler.removeMessages(RESET_TOUCH_FOCUS);
- }
- }
-
- public String getFocusMode() {
- if (mOverrideFocusMode != null) return mOverrideFocusMode;
- if (mParameters == null) return Parameters.FOCUS_MODE_AUTO;
- List<String> supportedFocusModes = mParameters.getSupportedFocusModes();
-
- if (mFocusAreaSupported && !mFocusDefault) {
- // Always use autofocus in tap-to-focus.
- mFocusMode = Parameters.FOCUS_MODE_AUTO;
- } else {
- // The default is continuous autofocus.
- mFocusMode = mPreferences.getString(
- CameraSettings.KEY_FOCUS_MODE, null);
-
- // Try to find a supported focus mode from the default list.
- if (mFocusMode == null) {
- for (int i = 0; i < mDefaultFocusModes.length; i++) {
- String mode = mDefaultFocusModes[i];
- if (Util.isSupported(mode, supportedFocusModes)) {
- mFocusMode = mode;
- break;
- }
- }
- }
- }
- if (!Util.isSupported(mFocusMode, supportedFocusModes)) {
- // For some reasons, the driver does not support the current
- // focus mode. Fall back to auto.
- if (Util.isSupported(Parameters.FOCUS_MODE_AUTO,
- mParameters.getSupportedFocusModes())) {
- mFocusMode = Parameters.FOCUS_MODE_AUTO;
- } else {
- mFocusMode = mParameters.getFocusMode();
- }
- }
- return mFocusMode;
- }
-
- public List getFocusAreas() {
- return mFocusArea;
- }
-
- public List getMeteringAreas() {
- return mMeteringArea;
- }
-
- public void updateFocusUI() {
- if (!mInitialized) return;
- // Show only focus indicator or face indicator.
-
- if (mState == STATE_IDLE) {
- if (mFocusDefault) {
- mUI.clearFocus();
- } else {
- // Users touch on the preview and the indicator represents the
- // metering area. Either focus area is not supported or
- // autoFocus call is not required.
- mUI.onFocusStarted();
- }
- } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
- mUI.onFocusStarted();
- } else {
- if (Util.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) {
- // TODO: check HAL behavior and decide if this can be removed.
- mUI.onFocusSucceeded(false);
- } else if (mState == STATE_SUCCESS) {
- mUI.onFocusSucceeded(false);
- } else if (mState == STATE_FAIL) {
- mUI.onFocusFailed(false);
- }
- }
- }
-
- public void resetTouchFocus() {
- if (!mInitialized) return;
-
- // Put focus indicator to the center. clear reset position
- mUI.clearFocus();
- // Initialize mFocusArea.
- if (mFocusAreaSupported) {
- initializeFocusAreas(mPreviewWidth / 2, mPreviewHeight / 2);
- }
- // Initialize mMeteringArea.
- if (mMeteringAreaSupported) {
- initializeMeteringAreas(mPreviewWidth / 2, mPreviewHeight / 2);
- }
- mFocusDefault = true;
- }
-
- private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) {
- int areaSize = (int) (Math.min(mPreviewWidth, mPreviewHeight) * areaMultiple / 20);
- int left = Util.clamp(x - areaSize, 0, mPreviewWidth - 2 * areaSize);
- int top = Util.clamp(y - areaSize, 0, mPreviewHeight - 2 * areaSize);
-
- RectF rectF = new RectF(left, top, left + 2 * areaSize, top + 2 * areaSize);
- mMatrix.mapRect(rectF);
- Util.rectFToRect(rectF, rect);
- }
-
- /* package */ int getFocusState() {
- return mState;
- }
-
- public boolean isFocusCompleted() {
- return mState == STATE_SUCCESS || mState == STATE_FAIL;
- }
-
- public boolean isFocusingSnapOnFinish() {
- return mState == STATE_FOCUSING_SNAP_ON_FINISH;
- }
-
- public void removeMessages() {
- mHandler.removeMessages(RESET_TOUCH_FOCUS);
- }
-
- public void overrideFocusMode(String focusMode) {
- mOverrideFocusMode = focusMode;
- }
-
- public void setAeAwbLock(boolean lock) {
- mAeAwbLock = lock;
- }
-
- public boolean getAeAwbLock() {
- return mAeAwbLock;
- }
-
- private boolean needAutoFocusCall() {
- String focusMode = getFocusMode();
- return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY)
- || focusMode.equals(Parameters.FOCUS_MODE_FIXED)
- || focusMode.equals(Parameters.FOCUS_MODE_EDOF));
- }
-}
diff --git a/src/com/android/camera/IconListPreference.java b/src/com/android/camera/IconListPreference.java
deleted file mode 100644
index e5f75d3a5..000000000
--- a/src/com/android/camera/IconListPreference.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-
-import com.android.gallery3d.R;
-
-import java.util.List;
-
-/** A {@code ListPreference} where each entry has a corresponding icon. */
-public class IconListPreference extends ListPreference {
- private int mSingleIconId;
- private int mIconIds[];
- private int mLargeIconIds[];
- private int mImageIds[];
- private boolean mUseSingleIcon;
-
- public IconListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.IconListPreference, 0, 0);
- Resources res = context.getResources();
- mSingleIconId = a.getResourceId(
- R.styleable.IconListPreference_singleIcon, 0);
- mIconIds = getIds(res, a.getResourceId(
- R.styleable.IconListPreference_icons, 0));
- mLargeIconIds = getIds(res, a.getResourceId(
- R.styleable.IconListPreference_largeIcons, 0));
- mImageIds = getIds(res, a.getResourceId(
- R.styleable.IconListPreference_images, 0));
- a.recycle();
- }
-
- public int getSingleIcon() {
- return mSingleIconId;
- }
-
- public int[] getIconIds() {
- return mIconIds;
- }
-
- public int[] getLargeIconIds() {
- return mLargeIconIds;
- }
-
- public int[] getImageIds() {
- return mImageIds;
- }
-
- public boolean getUseSingleIcon() {
- return mUseSingleIcon;
- }
-
- public void setIconIds(int[] iconIds) {
- mIconIds = iconIds;
- }
-
- public void setLargeIconIds(int[] largeIconIds) {
- mLargeIconIds = largeIconIds;
- }
-
- public void setUseSingleIcon(boolean useSingle) {
- mUseSingleIcon = useSingle;
- }
-
- private int[] getIds(Resources res, int iconsRes) {
- if (iconsRes == 0) return null;
- TypedArray array = res.obtainTypedArray(iconsRes);
- int n = array.length();
- int ids[] = new int[n];
- for (int i = 0; i < n; ++i) {
- ids[i] = array.getResourceId(i, 0);
- }
- array.recycle();
- return ids;
- }
-
- @Override
- public void filterUnsupported(List<String> supported) {
- CharSequence entryValues[] = getEntryValues();
- IntArray iconIds = new IntArray();
- IntArray largeIconIds = new IntArray();
- IntArray imageIds = new IntArray();
-
- for (int i = 0, len = entryValues.length; i < len; i++) {
- if (supported.indexOf(entryValues[i].toString()) >= 0) {
- if (mIconIds != null) iconIds.add(mIconIds[i]);
- if (mLargeIconIds != null) largeIconIds.add(mLargeIconIds[i]);
- if (mImageIds != null) imageIds.add(mImageIds[i]);
- }
- }
- if (mIconIds != null) mIconIds = iconIds.toArray(new int[iconIds.size()]);
- if (mLargeIconIds != null) {
- mLargeIconIds = largeIconIds.toArray(new int[largeIconIds.size()]);
- }
- if (mImageIds != null) mImageIds = imageIds.toArray(new int[imageIds.size()]);
- super.filterUnsupported(supported);
- }
-}
diff --git a/src/com/android/camera/ImageTaskManager.java b/src/com/android/camera/ImageTaskManager.java
deleted file mode 100644
index 601de4c50..000000000
--- a/src/com/android/camera/ImageTaskManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.net.Uri;
-
-/**
- * The interface for background image processing task manager.
- */
-public interface ImageTaskManager {
-
- /**
- * Callback interface for task events.
- */
- public interface TaskListener {
- public void onTaskQueued(String filePath, Uri imageUri);
- public void onTaskDone(String filePath, Uri imageUri);
- public void onTaskProgress(
- String filePath, Uri imageUri, int progress);
- }
-
- public void addTaskListener(TaskListener l);
-
- public void removeTaskListener(TaskListener l);
-
- /**
- * Get task progress by Uri.
- *
- * @param uri The Uri of the final image file to identify the task.
- * @return Integer from 0 to 100, or -1. The percentage of the task done
- * so far. -1 means not found.
- */
- public int getTaskProgress(Uri uri);
-}
diff --git a/src/com/android/camera/IntArray.java b/src/com/android/camera/IntArray.java
deleted file mode 100644
index a2550dbd8..000000000
--- a/src/com/android/camera/IntArray.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-public class IntArray {
- private static final int INIT_CAPACITY = 8;
-
- private int mData[] = new int[INIT_CAPACITY];
- private int mSize = 0;
-
- public void add(int value) {
- if (mData.length == mSize) {
- int temp[] = new int[mSize + mSize];
- System.arraycopy(mData, 0, temp, 0, mSize);
- mData = temp;
- }
- mData[mSize++] = value;
- }
-
- public int size() {
- return mSize;
- }
-
- public int[] toArray(int[] result) {
- if (result == null || result.length < mSize) {
- result = new int[mSize];
- }
- System.arraycopy(mData, 0, result, 0, mSize);
- return result;
- }
-}
diff --git a/src/com/android/camera/ListPreference.java b/src/com/android/camera/ListPreference.java
deleted file mode 100644
index 38866de9d..000000000
--- a/src/com/android/camera/ListPreference.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A type of <code>CameraPreference</code> whose number of possible values
- * is limited.
- */
-public class ListPreference extends CameraPreference {
- private static final String TAG = "ListPreference";
- private final String mKey;
- private String mValue;
- private final CharSequence[] mDefaultValues;
-
- private CharSequence[] mEntries;
- private CharSequence[] mEntryValues;
- private CharSequence[] mLabels;
- private boolean mLoaded = false;
-
- public ListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.ListPreference, 0, 0);
-
- mKey = Util.checkNotNull(
- a.getString(R.styleable.ListPreference_key));
-
- // We allow the defaultValue attribute to be a string or an array of
- // strings. The reason we need multiple default values is that some
- // of them may be unsupported on a specific platform (for example,
- // continuous auto-focus). In that case the first supported value
- // in the array will be used.
- int attrDefaultValue = R.styleable.ListPreference_defaultValue;
- TypedValue tv = a.peekValue(attrDefaultValue);
- if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) {
- mDefaultValues = a.getTextArray(attrDefaultValue);
- } else {
- mDefaultValues = new CharSequence[1];
- mDefaultValues[0] = a.getString(attrDefaultValue);
- }
-
- setEntries(a.getTextArray(R.styleable.ListPreference_entries));
- setEntryValues(a.getTextArray(
- R.styleable.ListPreference_entryValues));
- setLabels(a.getTextArray(
- R.styleable.ListPreference_labelList));
- a.recycle();
- }
-
- public String getKey() {
- return mKey;
- }
-
- public CharSequence[] getEntries() {
- return mEntries;
- }
-
- public CharSequence[] getEntryValues() {
- return mEntryValues;
- }
-
- public CharSequence[] getLabels() {
- return mLabels;
- }
-
- public void setEntries(CharSequence entries[]) {
- mEntries = entries == null ? new CharSequence[0] : entries;
- }
-
- public void setEntryValues(CharSequence values[]) {
- mEntryValues = values == null ? new CharSequence[0] : values;
- }
-
- public void setLabels(CharSequence labels[]) {
- mLabels = labels == null ? new CharSequence[0] : labels;
- }
-
- public String getValue() {
- if (!mLoaded) {
- mValue = getSharedPreferences().getString(mKey,
- findSupportedDefaultValue());
- mLoaded = true;
- }
- return mValue;
- }
-
- // Find the first value in mDefaultValues which is supported.
- private String findSupportedDefaultValue() {
- for (int i = 0; i < mDefaultValues.length; i++) {
- for (int j = 0; j < mEntryValues.length; j++) {
- // Note that mDefaultValues[i] may be null (if unspecified
- // in the xml file).
- if (mEntryValues[j].equals(mDefaultValues[i])) {
- return mDefaultValues[i].toString();
- }
- }
- }
- return null;
- }
-
- public void setValue(String value) {
- if (findIndexOfValue(value) < 0) throw new IllegalArgumentException();
- mValue = value;
- persistStringValue(value);
- }
-
- public void setValueIndex(int index) {
- setValue(mEntryValues[index].toString());
- }
-
- public int findIndexOfValue(String value) {
- for (int i = 0, n = mEntryValues.length; i < n; ++i) {
- if (Util.equals(mEntryValues[i], value)) return i;
- }
- return -1;
- }
-
- public int getCurrentIndex() {
- return findIndexOfValue(getValue());
- }
-
- public String getEntry() {
- return mEntries[findIndexOfValue(getValue())].toString();
- }
-
- public String getLabel() {
- return mLabels[findIndexOfValue(getValue())].toString();
- }
-
- protected void persistStringValue(String value) {
- SharedPreferences.Editor editor = getSharedPreferences().edit();
- editor.putString(mKey, value);
- editor.apply();
- }
-
- @Override
- public void reloadValue() {
- this.mLoaded = false;
- }
-
- public void filterUnsupported(List<String> supported) {
- ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
- ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
- for (int i = 0, len = mEntryValues.length; i < len; i++) {
- if (supported.indexOf(mEntryValues[i].toString()) >= 0) {
- entries.add(mEntries[i]);
- entryValues.add(mEntryValues[i]);
- }
- }
- int size = entries.size();
- mEntries = entries.toArray(new CharSequence[size]);
- mEntryValues = entryValues.toArray(new CharSequence[size]);
- }
-
- public void filterDuplicated() {
- ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
- ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
- for (int i = 0, len = mEntryValues.length; i < len; i++) {
- if (!entries.contains(mEntries[i])) {
- entries.add(mEntries[i]);
- entryValues.add(mEntryValues[i]);
- }
- }
- int size = entries.size();
- mEntries = entries.toArray(new CharSequence[size]);
- mEntryValues = entryValues.toArray(new CharSequence[size]);
- }
-
- public void print() {
- Log.v(TAG, "Preference key=" + getKey() + ". value=" + getValue());
- for (int i = 0; i < mEntryValues.length; i++) {
- Log.v(TAG, "entryValues[" + i + "]=" + mEntryValues[i]);
- }
- }
-}
diff --git a/src/com/android/camera/LocationManager.java b/src/com/android/camera/LocationManager.java
deleted file mode 100644
index fcf21b60f..000000000
--- a/src/com/android/camera/LocationManager.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.content.Context;
-import android.location.Location;
-import android.location.LocationProvider;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- * A class that handles everything about location.
- */
-public class LocationManager {
- private static final String TAG = "LocationManager";
-
- private Context mContext;
- private Listener mListener;
- private android.location.LocationManager mLocationManager;
- private boolean mRecordLocation;
-
- LocationListener [] mLocationListeners = new LocationListener[] {
- new LocationListener(android.location.LocationManager.GPS_PROVIDER),
- new LocationListener(android.location.LocationManager.NETWORK_PROVIDER)
- };
-
- public interface Listener {
- public void showGpsOnScreenIndicator(boolean hasSignal);
- public void hideGpsOnScreenIndicator();
- }
-
- public LocationManager(Context context, Listener listener) {
- mContext = context;
- mListener = listener;
- }
-
- public Location getCurrentLocation() {
- if (!mRecordLocation) return null;
-
- // go in best to worst order
- for (int i = 0; i < mLocationListeners.length; i++) {
- Location l = mLocationListeners[i].current();
- if (l != null) return l;
- }
- Log.d(TAG, "No location received yet.");
- return null;
- }
-
- public void recordLocation(boolean recordLocation) {
- if (mRecordLocation != recordLocation) {
- mRecordLocation = recordLocation;
- if (recordLocation) {
- startReceivingLocationUpdates();
- } else {
- stopReceivingLocationUpdates();
- }
- }
- }
-
- private void startReceivingLocationUpdates() {
- if (mLocationManager == null) {
- mLocationManager = (android.location.LocationManager)
- mContext.getSystemService(Context.LOCATION_SERVICE);
- }
- if (mLocationManager != null) {
- try {
- mLocationManager.requestLocationUpdates(
- android.location.LocationManager.NETWORK_PROVIDER,
- 1000,
- 0F,
- mLocationListeners[1]);
- } catch (SecurityException ex) {
- Log.i(TAG, "fail to request location update, ignore", ex);
- } catch (IllegalArgumentException ex) {
- Log.d(TAG, "provider does not exist " + ex.getMessage());
- }
- try {
- mLocationManager.requestLocationUpdates(
- android.location.LocationManager.GPS_PROVIDER,
- 1000,
- 0F,
- mLocationListeners[0]);
- if (mListener != null) mListener.showGpsOnScreenIndicator(false);
- } catch (SecurityException ex) {
- Log.i(TAG, "fail to request location update, ignore", ex);
- } catch (IllegalArgumentException ex) {
- Log.d(TAG, "provider does not exist " + ex.getMessage());
- }
- Log.d(TAG, "startReceivingLocationUpdates");
- }
- }
-
- private void stopReceivingLocationUpdates() {
- if (mLocationManager != null) {
- for (int i = 0; i < mLocationListeners.length; i++) {
- try {
- mLocationManager.removeUpdates(mLocationListeners[i]);
- } catch (Exception ex) {
- Log.i(TAG, "fail to remove location listners, ignore", ex);
- }
- }
- Log.d(TAG, "stopReceivingLocationUpdates");
- }
- if (mListener != null) mListener.hideGpsOnScreenIndicator();
- }
-
- private class LocationListener
- implements android.location.LocationListener {
- Location mLastLocation;
- boolean mValid = false;
- String mProvider;
-
- public LocationListener(String provider) {
- mProvider = provider;
- mLastLocation = new Location(mProvider);
- }
-
- @Override
- public void onLocationChanged(Location newLocation) {
- if (newLocation.getLatitude() == 0.0
- && newLocation.getLongitude() == 0.0) {
- // Hack to filter out 0.0,0.0 locations
- return;
- }
- // If GPS is available before start camera, we won't get status
- // update so update GPS indicator when we receive data.
- if (mListener != null && mRecordLocation &&
- android.location.LocationManager.GPS_PROVIDER.equals(mProvider)) {
- mListener.showGpsOnScreenIndicator(true);
- }
- if (!mValid) {
- Log.d(TAG, "Got first location.");
- }
- mLastLocation.set(newLocation);
- mValid = true;
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- mValid = false;
- }
-
- @Override
- public void onStatusChanged(
- String provider, int status, Bundle extras) {
- switch(status) {
- case LocationProvider.OUT_OF_SERVICE:
- case LocationProvider.TEMPORARILY_UNAVAILABLE: {
- mValid = false;
- if (mListener != null && mRecordLocation &&
- android.location.LocationManager.GPS_PROVIDER.equals(provider)) {
- mListener.showGpsOnScreenIndicator(false);
- }
- break;
- }
- }
- }
-
- public Location current() {
- return mValid ? mLastLocation : null;
- }
- }
-}
diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java
deleted file mode 100644
index 40675b8c0..000000000
--- a/src/com/android/camera/MediaSaveService.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.app.Service;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.location.Location;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Binder;
-import android.os.IBinder;
-import android.provider.MediaStore.Video;
-import android.util.Log;
-
-import com.android.gallery3d.exif.ExifInterface;
-
-import java.io.File;
-
-/*
- * Service for saving images in the background thread.
- */
-public class MediaSaveService extends Service {
- // The memory limit for unsaved image is 20MB.
- private static final int SAVE_TASK_MEMORY_LIMIT = 20 * 1024 * 1024;
- private static final String TAG = "CAM_" + MediaSaveService.class.getSimpleName();
-
- private final IBinder mBinder = new LocalBinder();
- private Listener mListener;
- // Memory used by the total queued save request, in bytes.
- private long mMemoryUse;
-
- interface Listener {
- public void onQueueStatus(boolean full);
- }
-
- interface OnMediaSavedListener {
- public void onMediaSaved(Uri uri);
- }
-
- class LocalBinder extends Binder {
- public MediaSaveService getService() {
- return MediaSaveService.this;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flag, int startId) {
- return START_STICKY;
- }
-
- @Override
- public void onDestroy() {
- }
-
- @Override
- public void onCreate() {
- mMemoryUse = 0;
- }
-
- public boolean isQueueFull() {
- return (mMemoryUse >= SAVE_TASK_MEMORY_LIMIT);
- }
-
- public void addImage(final byte[] data, String title, long date, Location loc,
- int width, int height, int orientation, ExifInterface exif,
- OnMediaSavedListener l, ContentResolver resolver) {
- if (isQueueFull()) {
- Log.e(TAG, "Cannot add image when the queue is full");
- return;
- }
- ImageSaveTask t = new ImageSaveTask(data, title, date,
- (loc == null) ? null : new Location(loc),
- width, height, orientation, exif, resolver, l);
-
- mMemoryUse += data.length;
- if (isQueueFull()) {
- onQueueFull();
- }
- t.execute();
- }
-
- public void addImage(final byte[] data, String title, Location loc,
- int width, int height, int orientation, ExifInterface exif,
- OnMediaSavedListener l, ContentResolver resolver) {
- addImage(data, title, System.currentTimeMillis(), loc, width, height,
- orientation, exif, l, resolver);
- }
-
- public void addVideo(String path, long duration, ContentValues values,
- OnMediaSavedListener l, ContentResolver resolver) {
- // We don't set a queue limit for video saving because the file
- // is already in the storage. Only updating the database.
- new VideoSaveTask(path, duration, values, l, resolver).execute();
- }
-
- public void setListener(Listener l) {
- mListener = l;
- if (l == null) return;
- l.onQueueStatus(isQueueFull());
- }
-
- private void onQueueFull() {
- if (mListener != null) mListener.onQueueStatus(true);
- }
-
- private void onQueueAvailable() {
- if (mListener != null) mListener.onQueueStatus(false);
- }
-
- private class ImageSaveTask extends AsyncTask <Void, Void, Uri> {
- private byte[] data;
- private String title;
- private long date;
- private Location loc;
- private int width, height;
- private int orientation;
- private ExifInterface exif;
- private ContentResolver resolver;
- private OnMediaSavedListener listener;
-
- public ImageSaveTask(byte[] data, String title, long date, Location loc,
- int width, int height, int orientation, ExifInterface exif,
- ContentResolver resolver, OnMediaSavedListener listener) {
- this.data = data;
- this.title = title;
- this.date = date;
- this.loc = loc;
- this.width = width;
- this.height = height;
- this.orientation = orientation;
- this.exif = exif;
- this.resolver = resolver;
- this.listener = listener;
- }
-
- @Override
- protected void onPreExecute() {
- // do nothing.
- }
-
- @Override
- protected Uri doInBackground(Void... v) {
- return Storage.addImage(
- resolver, title, date, loc, orientation, exif, data, width, height);
- }
-
- @Override
- protected void onPostExecute(Uri uri) {
- if (listener != null) listener.onMediaSaved(uri);
- boolean previouslyFull = isQueueFull();
- mMemoryUse -= data.length;
- if (isQueueFull() != previouslyFull) onQueueAvailable();
- }
- }
-
- private class VideoSaveTask extends AsyncTask <Void, Void, Uri> {
- private String path;
- private long duration;
- private ContentValues values;
- private OnMediaSavedListener listener;
- private ContentResolver resolver;
-
- public VideoSaveTask(String path, long duration, ContentValues values,
- OnMediaSavedListener l, ContentResolver r) {
- this.path = path;
- this.duration = duration;
- this.values = new ContentValues(values);
- this.listener = l;
- this.resolver = r;
- }
-
- @Override
- protected void onPreExecute() {
- // do nothing.
- }
-
- @Override
- protected Uri doInBackground(Void... v) {
- values.put(Video.Media.SIZE, new File(path).length());
- values.put(Video.Media.DURATION, duration);
- Uri uri = null;
- try {
- Uri videoTable = Uri.parse("content://media/external/video/media");
- uri = resolver.insert(videoTable, values);
-
- // Rename the video file to the final name. This avoids other
- // apps reading incomplete data. We need to do it after we are
- // certain that the previous insert to MediaProvider is completed.
- String finalName = values.getAsString(
- Video.Media.DATA);
- if (new File(path).renameTo(new File(finalName))) {
- path = finalName;
- }
-
- resolver.update(uri, values, null, null);
- } catch (Exception e) {
- // We failed to insert into the database. This can happen if
- // the SD card is unmounted.
- Log.e(TAG, "failed to add video to media store", e);
- uri = null;
- } finally {
- Log.v(TAG, "Current video URI: " + uri);
- }
- return uri;
- }
-
- @Override
- protected void onPostExecute(Uri uri) {
- if (listener != null) listener.onMediaSaved(uri);
- }
- }
-}
diff --git a/src/com/android/camera/OnClickAttr.java b/src/com/android/camera/OnClickAttr.java
deleted file mode 100644
index 07a10635b..000000000
--- a/src/com/android/camera/OnClickAttr.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-
-/**
- * Interface for OnClickAttr annotation.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface OnClickAttr {
-}
diff --git a/src/com/android/camera/OnScreenHint.java b/src/com/android/camera/OnScreenHint.java
deleted file mode 100644
index 4d7fa7088..000000000
--- a/src/com/android/camera/OnScreenHint.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.os.Handler;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView;
-
-import com.android.gallery3d.R;
-
-/**
- * A on-screen hint is a view containing a little message for the user and will
- * be shown on the screen continuously. This class helps you create and show
- * those.
- *
- * <p>
- * When the view is shown to the user, appears as a floating view over the
- * application.
- * <p>
- * The easiest way to use this class is to call one of the static methods that
- * constructs everything you need and returns a new {@code OnScreenHint} object.
- */
-public class OnScreenHint {
- static final String TAG = "OnScreenHint";
-
- int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- int mX, mY;
- float mHorizontalMargin;
- float mVerticalMargin;
- View mView;
- View mNextView;
-
- private final WindowManager.LayoutParams mParams =
- new WindowManager.LayoutParams();
- private final WindowManager mWM;
- private final Handler mHandler = new Handler();
-
- /**
- * Construct an empty OnScreenHint object.
- *
- * @param context The context to use. Usually your
- * {@link android.app.Application} or
- * {@link android.app.Activity} object.
- */
- private OnScreenHint(Context context) {
- mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- mY = context.getResources().getDimensionPixelSize(
- R.dimen.hint_y_offset);
-
- mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
- mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
- mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
- mParams.format = PixelFormat.TRANSLUCENT;
- mParams.windowAnimations = R.style.Animation_OnScreenHint;
- mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
- mParams.setTitle("OnScreenHint");
- }
-
- /**
- * Show the view on the screen.
- */
- public void show() {
- if (mNextView == null) {
- throw new RuntimeException("View is not initialized");
- }
- mHandler.post(mShow);
- }
-
- /**
- * Close the view if it's showing.
- */
- public void cancel() {
- mHandler.post(mHide);
- }
-
- /**
- * Make a standard hint that just contains a text view.
- *
- * @param context The context to use. Usually your
- * {@link android.app.Application} or
- * {@link android.app.Activity} object.
- * @param text The text to show. Can be formatted text.
- *
- */
- public static OnScreenHint makeText(Context context, CharSequence text) {
- OnScreenHint result = new OnScreenHint(context);
-
- LayoutInflater inflate =
- (LayoutInflater) context.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View v = inflate.inflate(R.layout.on_screen_hint, null);
- TextView tv = (TextView) v.findViewById(R.id.message);
- tv.setText(text);
-
- result.mNextView = v;
-
- return result;
- }
-
- /**
- * Update the text in a OnScreenHint that was previously created using one
- * of the makeText() methods.
- * @param s The new text for the OnScreenHint.
- */
- public void setText(CharSequence s) {
- if (mNextView == null) {
- throw new RuntimeException("This OnScreenHint was not "
- + "created with OnScreenHint.makeText()");
- }
- TextView tv = (TextView) mNextView.findViewById(R.id.message);
- if (tv == null) {
- throw new RuntimeException("This OnScreenHint was not "
- + "created with OnScreenHint.makeText()");
- }
- tv.setText(s);
- }
-
- private synchronized void handleShow() {
- if (mView != mNextView) {
- // remove the old view if necessary
- handleHide();
- mView = mNextView;
- final int gravity = mGravity;
- mParams.gravity = gravity;
- if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK)
- == Gravity.FILL_HORIZONTAL) {
- mParams.horizontalWeight = 1.0f;
- }
- if ((gravity & Gravity.VERTICAL_GRAVITY_MASK)
- == Gravity.FILL_VERTICAL) {
- mParams.verticalWeight = 1.0f;
- }
- mParams.x = mX;
- mParams.y = mY;
- mParams.verticalMargin = mVerticalMargin;
- mParams.horizontalMargin = mHorizontalMargin;
- if (mView.getParent() != null) {
- mWM.removeView(mView);
- }
- mWM.addView(mView, mParams);
- }
- }
-
- private synchronized void handleHide() {
- if (mView != null) {
- // note: checking parent() just to make sure the view has
- // been added... i have seen cases where we get here when
- // the view isn't yet added, so let's try not to crash.
- if (mView.getParent() != null) {
- mWM.removeView(mView);
- }
- mView = null;
- }
- }
-
- private final Runnable mShow = new Runnable() {
- @Override
- public void run() {
- handleShow();
- }
- };
-
- private final Runnable mHide = new Runnable() {
- @Override
- public void run() {
- handleHide();
- }
- };
-}
-
diff --git a/src/com/android/camera/OnScreenIndicators.java b/src/com/android/camera/OnScreenIndicators.java
deleted file mode 100644
index 77c8fafc0..000000000
--- a/src/com/android/camera/OnScreenIndicators.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.gallery3d.R;
-
-/**
- * The on-screen indicators of the pie menu button. They show the camera
- * settings in the viewfinder.
- */
-public class OnScreenIndicators {
- private final int[] mWBArray;
- private final View mOnScreenIndicators;
- private final ImageView mExposureIndicator;
- private final ImageView mFlashIndicator;
- private final ImageView mSceneIndicator;
- private final ImageView mLocationIndicator;
- private final ImageView mTimerIndicator;
- private final ImageView mWBIndicator;
-
- public OnScreenIndicators(Context ctx, View onScreenIndicatorsView) {
- TypedArray iconIds = ctx.getResources().obtainTypedArray(
- R.array.camera_wb_indicators);
- final int n = iconIds.length();
- mWBArray = new int[n];
- for (int i = 0; i < n; i++) {
- mWBArray[i] = iconIds.getResourceId(i, R.drawable.ic_indicator_wb_off);
- }
- mOnScreenIndicators = onScreenIndicatorsView;
- mExposureIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_exposure_indicator);
- mFlashIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_flash_indicator);
- mSceneIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_scenemode_indicator);
- mLocationIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_location_indicator);
- mTimerIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_timer_indicator);
- mWBIndicator = (ImageView) onScreenIndicatorsView.findViewById(
- R.id.menu_wb_indicator);
- }
-
- /**
- * Resets all indicators to show the default values.
- */
- public void resetToDefault() {
- updateExposureOnScreenIndicator(0);
- updateFlashOnScreenIndicator(Parameters.FLASH_MODE_OFF);
- updateSceneOnScreenIndicator(Parameters.SCENE_MODE_AUTO);
- updateWBIndicator(2);
- updateTimerIndicator(false);
- updateLocationIndicator(false);
- }
-
- /**
- * Sets the exposure indicator using exposure compensations step rounding.
- */
- public void updateExposureOnScreenIndicator(Camera.Parameters params, int value) {
- if (mExposureIndicator == null) {
- return;
- }
- float step = params.getExposureCompensationStep();
- value = Math.round(value * step);
- updateExposureOnScreenIndicator(value);
- }
-
- /**
- * Set the exposure indicator to the given value.
- *
- * @param value Value between -3 and 3. If outside this range, 0 is used by
- * default.
- */
- public void updateExposureOnScreenIndicator(int value) {
- int id = 0;
- switch(value) {
- case -3:
- id = R.drawable.ic_indicator_ev_n3;
- break;
- case -2:
- id = R.drawable.ic_indicator_ev_n2;
- break;
- case -1:
- id = R.drawable.ic_indicator_ev_n1;
- break;
- case 0:
- id = R.drawable.ic_indicator_ev_0;
- break;
- case 1:
- id = R.drawable.ic_indicator_ev_p1;
- break;
- case 2:
- id = R.drawable.ic_indicator_ev_p2;
- break;
- case 3:
- id = R.drawable.ic_indicator_ev_p3;
- break;
- }
- mExposureIndicator.setImageResource(id);
- }
-
- public void updateWBIndicator(int wbIndex) {
- if (mWBIndicator == null) return;
- mWBIndicator.setImageResource(mWBArray[wbIndex]);
- }
-
- public void updateTimerIndicator(boolean on) {
- if (mTimerIndicator == null) return;
- mTimerIndicator.setImageResource(on ? R.drawable.ic_indicator_timer_on
- : R.drawable.ic_indicator_timer_off);
- }
-
- public void updateLocationIndicator(boolean on) {
- if (mLocationIndicator == null) return;
- mLocationIndicator.setImageResource(on ? R.drawable.ic_indicator_loc_on
- : R.drawable.ic_indicator_loc_off);
- }
-
- /**
- * Set the flash indicator to the given value.
- *
- * @param value One of Parameters.FLASH_MODE_OFF,
- * Parameters.FLASH_MODE_AUTO, Parameters.FLASH_MODE_ON.
- */
- public void updateFlashOnScreenIndicator(String value) {
- if (mFlashIndicator == null) {
- return;
- }
- if (value == null || Parameters.FLASH_MODE_OFF.equals(value)) {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_off);
- } else {
- if (Parameters.FLASH_MODE_AUTO.equals(value)) {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_auto);
- } else if (Parameters.FLASH_MODE_ON.equals(value)
- || Parameters.FLASH_MODE_TORCH.equals(value)) {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_on);
- } else {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_off);
- }
- }
- }
-
- /**
- * Set the scene indicator depending on the given scene mode.
- *
- * @param value the current Parameters.SCENE_MODE_* value.
- */
- public void updateSceneOnScreenIndicator(String value) {
- if (mSceneIndicator == null) {
- return;
- }
- if ((value == null) || Parameters.SCENE_MODE_AUTO.equals(value)) {
- mSceneIndicator.setImageResource(R.drawable.ic_indicator_sce_off);
- } else if (Parameters.SCENE_MODE_HDR.equals(value)) {
- mSceneIndicator.setImageResource(R.drawable.ic_indicator_sce_hdr);
- } else {
- mSceneIndicator.setImageResource(R.drawable.ic_indicator_sce_on);
- }
- }
-
- /**
- * Sets the visibility of all indicators.
- *
- * @param visibility View.VISIBLE, View.GONE etc.
- */
- public void setVisibility(int visibility) {
- mOnScreenIndicators.setVisibility(visibility);
- }
-}
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
deleted file mode 100644
index bc824d917..000000000
--- a/src/com/android/camera/PhotoController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.view.SurfaceHolder;
-import android.view.View;
-
-import com.android.camera.ShutterButton.OnShutterButtonListener;
-
-
-public interface PhotoController extends OnShutterButtonListener {
-
- public static final int PREVIEW_STOPPED = 0;
- public static final int IDLE = 1; // preview is active
- // Focus is in progress. The exact focus state is in Focus.java.
- public static final int FOCUSING = 2;
- public static final int SNAPSHOT_IN_PROGRESS = 3;
- // Switching between cameras.
- public static final int SWITCHING_CAMERA = 4;
-
- // returns the actual set zoom value
- public int onZoomChanged(int requestedZoom);
-
- public boolean isImageCaptureIntent();
-
- public boolean isCameraIdle();
-
- public void onCaptureDone();
-
- public void onCaptureCancelled();
-
- public void onCaptureRetake();
-
- public void cancelAutoFocus();
-
- public void stopPreview();
-
- public int getCameraState();
-
- public void onSingleTapUp(View view, int x, int y);
-
- public void onSurfaceCreated(SurfaceHolder holder);
-
- public void onCountDownFinished();
-
- public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight);
-
- public void updateCameraOrientation();
-
- public void enableRecordingLocation(boolean enable);
-}
diff --git a/src/com/android/camera/PhotoMenu.java b/src/com/android/camera/PhotoMenu.java
deleted file mode 100644
index 6c1e2d085..000000000
--- a/src/com/android/camera/PhotoMenu.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.content.res.Resources;
-import android.hardware.Camera.Parameters;
-
-import com.android.camera.ui.AbstractSettingPopup;
-import com.android.camera.ui.CountdownTimerPopup;
-import com.android.camera.ui.ListPrefSettingPopup;
-import com.android.camera.ui.PieItem;
-import com.android.camera.ui.PieItem.OnClickListener;
-import com.android.camera.ui.PieRenderer;
-import com.android.gallery3d.R;
-
-import java.util.Locale;
-
-public class PhotoMenu extends PieController
- implements CountdownTimerPopup.Listener,
- ListPrefSettingPopup.Listener {
- private static String TAG = "CAM_photomenu";
-
- private final String mSettingOff;
-
- private PhotoUI mUI;
- private AbstractSettingPopup mPopup;
- private CameraActivity mActivity;
-
- public PhotoMenu(CameraActivity activity, PhotoUI ui, PieRenderer pie) {
- super(activity, pie);
- mUI = ui;
- mSettingOff = activity.getString(R.string.setting_off_value);
- mActivity = activity;
- }
-
- public void initialize(PreferenceGroup group) {
- super.initialize(group);
- mPopup = null;
- PieItem item = null;
- final Resources res = mActivity.getResources();
- Locale locale = res.getConfiguration().locale;
- // the order is from left to right in the menu
-
- // hdr
- if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) {
- item = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR, true);
- mRenderer.addItem(item);
- }
- // exposure compensation
- if (group.findPreference(CameraSettings.KEY_EXPOSURE) != null) {
- item = makeItem(CameraSettings.KEY_EXPOSURE);
- item.setLabel(res.getString(R.string.pref_exposure_label));
- mRenderer.addItem(item);
- }
- // more settings
- PieItem more = makeItem(R.drawable.ic_settings_holo_light);
- more.setLabel(res.getString(R.string.camera_menu_more_label));
- mRenderer.addItem(more);
- // flash
- if (group.findPreference(CameraSettings.KEY_FLASH_MODE) != null) {
- item = makeItem(CameraSettings.KEY_FLASH_MODE);
- item.setLabel(res.getString(R.string.pref_camera_flashmode_label));
- mRenderer.addItem(item);
- }
- // camera switcher
- if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) {
- item = makeSwitchItem(CameraSettings.KEY_CAMERA_ID, false);
- final PieItem fitem = item;
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- // Find the index of next camera.
- ListPreference pref = mPreferenceGroup
- .findPreference(CameraSettings.KEY_CAMERA_ID);
- if (pref != null) {
- int index = pref.findIndexOfValue(pref.getValue());
- CharSequence[] values = pref.getEntryValues();
- index = (index + 1) % values.length;
- pref.setValueIndex(index);
- mListener.onCameraPickerClicked(index);
- }
- updateItem(fitem, CameraSettings.KEY_CAMERA_ID);
- }
- });
- mRenderer.addItem(item);
- }
- // location
- if (group.findPreference(CameraSettings.KEY_RECORD_LOCATION) != null) {
- item = makeSwitchItem(CameraSettings.KEY_RECORD_LOCATION, true);
- more.addItem(item);
- if (mActivity.isSecureCamera()) {
- // Prevent location preference from getting changed in secure camera mode
- item.setEnabled(false);
- }
- }
- // countdown timer
- final ListPreference ctpref = group.findPreference(CameraSettings.KEY_TIMER);
- final ListPreference beeppref = group.findPreference(CameraSettings.KEY_TIMER_SOUND_EFFECTS);
- item = makeItem(R.drawable.ic_timer);
- item.setLabel(res.getString(R.string.pref_camera_timer_title).toUpperCase(locale));
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- CountdownTimerPopup timerPopup = (CountdownTimerPopup) mActivity.getLayoutInflater().inflate(
- R.layout.countdown_setting_popup, null, false);
- timerPopup.initialize(ctpref, beeppref);
- timerPopup.setSettingChangedListener(PhotoMenu.this);
- mUI.dismissPopup();
- mPopup = timerPopup;
- mUI.showPopup(mPopup);
- }
- });
- more.addItem(item);
- // image size
- item = makeItem(R.drawable.ic_imagesize);
- final ListPreference sizePref = group.findPreference(CameraSettings.KEY_PICTURE_SIZE);
- item.setLabel(res.getString(R.string.pref_camera_picturesize_title).toUpperCase(locale));
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- ListPrefSettingPopup popup = (ListPrefSettingPopup) mActivity.getLayoutInflater().inflate(
- R.layout.list_pref_setting_popup, null, false);
- popup.initialize(sizePref);
- popup.setSettingChangedListener(PhotoMenu.this);
- mUI.dismissPopup();
- mPopup = popup;
- mUI.showPopup(mPopup);
- }
- });
- more.addItem(item);
- // white balance
- if (group.findPreference(CameraSettings.KEY_WHITE_BALANCE) != null) {
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE);
- item.setLabel(res.getString(R.string.pref_camera_whitebalance_label));
- more.addItem(item);
- }
- // scene mode
- if (group.findPreference(CameraSettings.KEY_SCENE_MODE) != null) {
- IconListPreference pref = (IconListPreference) group.findPreference(
- CameraSettings.KEY_SCENE_MODE);
- pref.setUseSingleIcon(true);
- item = makeItem(CameraSettings.KEY_SCENE_MODE);
- more.addItem(item);
- }
- }
-
- @Override
- // Hit when an item in a popup gets selected
- public void onListPrefChanged(ListPreference pref) {
- if (mPopup != null) {
- mUI.dismissPopup();
- }
- onSettingChanged(pref);
- }
-
- public void popupDismissed() {
- if (mPopup != null) {
- mPopup = null;
- }
- }
-
- // Return true if the preference has the specified key but not the value.
- private static boolean notSame(ListPreference pref, String key, String value) {
- return (key.equals(pref.getKey()) && !value.equals(pref.getValue()));
- }
-
- private void setPreference(String key, String value) {
- ListPreference pref = mPreferenceGroup.findPreference(key);
- if (pref != null && !value.equals(pref.getValue())) {
- pref.setValue(value);
- reloadPreferences();
- }
- }
-
- @Override
- public void onSettingChanged(ListPreference pref) {
- // Reset the scene mode if HDR is set to on. Reset HDR if scene mode is
- // set to non-auto.
- if (notSame(pref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) {
- setPreference(CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO);
- } else if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) {
- setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff);
- }
- super.onSettingChanged(pref);
- }
-}
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
deleted file mode 100644
index d09c081a1..000000000
--- a/src/com/android/camera/PhotoModule.java
+++ /dev/null
@@ -1,1985 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences.Editor;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.location.Location;
-import android.media.CameraProfile;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.MessageQueue;
-import android.os.SystemClock;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.OrientationEventListener;
-import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.camera.CameraManager.CameraAFCallback;
-import com.android.camera.CameraManager.CameraAFMoveCallback;
-import com.android.camera.CameraManager.CameraPictureCallback;
-import com.android.camera.CameraManager.CameraProxy;
-import com.android.camera.CameraManager.CameraShutterCallback;
-import com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
-import com.android.camera.ui.PopupManager;
-import com.android.camera.ui.RotateTextToast;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.exif.ExifInterface;
-import com.android.gallery3d.exif.ExifTag;
-import com.android.gallery3d.exif.Rational;
-import com.android.gallery3d.filtershow.crop.CropActivity;
-import com.android.gallery3d.filtershow.crop.CropExtras;
-import com.android.gallery3d.util.UsageStatistics;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Formatter;
-import java.util.List;
-
-public class PhotoModule
- implements CameraModule,
- PhotoController,
- FocusOverlayManager.Listener,
- CameraPreference.OnPreferenceChangedListener,
- ShutterButton.OnShutterButtonListener,
- MediaSaveService.Listener,
- OnCountDownFinishedListener,
- SensorEventListener {
-
- private static final String TAG = "CAM_PhotoModule";
-
- // We number the request code from 1000 to avoid collision with Gallery.
- private static final int REQUEST_CROP = 1000;
-
- private static final int SETUP_PREVIEW = 1;
- private static final int FIRST_TIME_INIT = 2;
- private static final int CLEAR_SCREEN_DELAY = 3;
- private static final int SET_CAMERA_PARAMETERS_WHEN_IDLE = 4;
- private static final int CHECK_DISPLAY_ROTATION = 5;
- private static final int SHOW_TAP_TO_FOCUS_TOAST = 6;
- private static final int SWITCH_CAMERA = 7;
- private static final int SWITCH_CAMERA_START_ANIMATION = 8;
- private static final int CAMERA_OPEN_DONE = 9;
- private static final int START_PREVIEW_DONE = 10;
- private static final int OPEN_CAMERA_FAIL = 11;
- private static final int CAMERA_DISABLED = 12;
-
- // The subset of parameters we need to update in setCameraParameters().
- private static final int UPDATE_PARAM_INITIALIZE = 1;
- private static final int UPDATE_PARAM_ZOOM = 2;
- private static final int UPDATE_PARAM_PREFERENCE = 4;
- private static final int UPDATE_PARAM_ALL = -1;
-
- // This is the timeout to keep the camera in onPause for the first time
- // after screen on if the activity is started from secure lock screen.
- private static final int KEEP_CAMERA_TIMEOUT = 1000; // ms
-
- // copied from Camera hierarchy
- private CameraActivity mActivity;
- private CameraProxy mCameraDevice;
- private int mCameraId;
- private Parameters mParameters;
- private boolean mPaused;
-
- private PhotoUI mUI;
-
- // The activity is going to switch to the specified camera id. This is
- // needed because texture copy is done in GL thread. -1 means camera is not
- // switching.
- protected int mPendingSwitchCameraId = -1;
- private boolean mOpenCameraFail;
- private boolean mCameraDisabled;
-
- // When setCameraParametersWhenIdle() is called, we accumulate the subsets
- // needed to be updated in mUpdateSet.
- private int mUpdateSet;
-
- private static final int SCREEN_DELAY = 2 * 60 * 1000;
-
- private int mZoomValue; // The current zoom value.
-
- private Parameters mInitialParams;
- private boolean mFocusAreaSupported;
- private boolean mMeteringAreaSupported;
- private boolean mAeLockSupported;
- private boolean mAwbLockSupported;
- private boolean mContinousFocusSupported;
-
- // The degrees of the device rotated clockwise from its natural orientation.
- private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
- private ComboPreferences mPreferences;
-
- private static final String sTempCropFilename = "crop-temp";
-
- private ContentProviderClient mMediaProviderClient;
- private boolean mFaceDetectionStarted = false;
-
- // mCropValue and mSaveUri are used only if isImageCaptureIntent() is true.
- private String mCropValue;
- private Uri mSaveUri;
-
- // We use a queue to generated names of the images to be used later
- // when the image is ready to be saved.
- private NamedImages mNamedImages;
-
- private Runnable mDoSnapRunnable = new Runnable() {
- @Override
- public void run() {
- onShutterButtonClick();
- }
- };
-
- private final StringBuilder mBuilder = new StringBuilder();
- private final Formatter mFormatter = new Formatter(mBuilder);
- private final Object[] mFormatterArgs = new Object[1];
-
- /**
- * An unpublished intent flag requesting to return as soon as capturing
- * is completed.
- *
- * TODO: consider publishing by moving into MediaStore.
- */
- private static final String EXTRA_QUICK_CAPTURE =
- "android.intent.extra.quickCapture";
-
- // The display rotation in degrees. This is only valid when mCameraState is
- // not PREVIEW_STOPPED.
- private int mDisplayRotation;
- // The value for android.hardware.Camera.setDisplayOrientation.
- private int mCameraDisplayOrientation;
- // The value for UI components like indicators.
- private int mDisplayOrientation;
- // The value for android.hardware.Camera.Parameters.setRotation.
- private int mJpegRotation;
- private boolean mFirstTimeInitialized;
- private boolean mIsImageCaptureIntent;
-
- private int mCameraState = PREVIEW_STOPPED;
- private boolean mSnapshotOnIdle = false;
-
- private ContentResolver mContentResolver;
-
- private LocationManager mLocationManager;
-
- private final PostViewPictureCallback mPostViewPictureCallback =
- new PostViewPictureCallback();
- private final RawPictureCallback mRawPictureCallback =
- new RawPictureCallback();
- private final AutoFocusCallback mAutoFocusCallback =
- new AutoFocusCallback();
- private final Object mAutoFocusMoveCallback =
- ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK
- ? new AutoFocusMoveCallback()
- : null;
-
- private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
-
- private long mFocusStartTime;
- private long mShutterCallbackTime;
- private long mPostViewPictureCallbackTime;
- private long mRawPictureCallbackTime;
- private long mJpegPictureCallbackTime;
- private long mOnResumeTime;
- private byte[] mJpegImageData;
-
- // These latency time are for the CameraLatency test.
- public long mAutoFocusTime;
- public long mShutterLag;
- public long mShutterToPictureDisplayedTime;
- public long mPictureDisplayedToJpegCallbackTime;
- public long mJpegCallbackFinishTime;
- public long mCaptureStartTime;
-
- // This handles everything about focus.
- private FocusOverlayManager mFocusManager;
-
- private String mSceneMode;
-
- private final Handler mHandler = new MainHandler();
- private PreferenceGroup mPreferenceGroup;
-
- private boolean mQuickCapture;
- private SensorManager mSensorManager;
- private float[] mGData = new float[3];
- private float[] mMData = new float[3];
- private float[] mR = new float[16];
- private int mHeading = -1;
-
- CameraStartUpThread mCameraStartUpThread;
- ConditionVariable mStartPreviewPrerequisiteReady = new ConditionVariable();
-
- private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
- new MediaSaveService.OnMediaSavedListener() {
- @Override
- public void onMediaSaved(Uri uri) {
- if (uri != null) {
- mActivity.notifyNewMedia(uri);
- }
- }
- };
-
- // The purpose is not to block the main thread in onCreate and onResume.
- private class CameraStartUpThread extends Thread {
- private volatile boolean mCancelled;
-
- public void cancel() {
- mCancelled = true;
- interrupt();
- }
-
- public boolean isCanceled() {
- return mCancelled;
- }
-
- @Override
- public void run() {
- try {
- // We need to check whether the activity is paused before long
- // operations to ensure that onPause() can be done ASAP.
- if (mCancelled) return;
- mCameraDevice = Util.openCamera(mActivity, mCameraId);
- mParameters = mCameraDevice.getParameters();
- // Wait until all the initialization needed by startPreview are
- // done.
- mStartPreviewPrerequisiteReady.block();
-
- initializeCapabilities();
- if (mFocusManager == null) initializeFocusManager();
- if (mCancelled) return;
- setCameraParameters(UPDATE_PARAM_ALL);
- mHandler.sendEmptyMessage(CAMERA_OPEN_DONE);
- if (mCancelled) return;
- startPreview();
- mHandler.sendEmptyMessage(START_PREVIEW_DONE);
- mOnResumeTime = SystemClock.uptimeMillis();
- mHandler.sendEmptyMessage(CHECK_DISPLAY_ROTATION);
- } catch (CameraHardwareException e) {
- mHandler.sendEmptyMessage(OPEN_CAMERA_FAIL);
- } catch (CameraDisabledException e) {
- mHandler.sendEmptyMessage(CAMERA_DISABLED);
- }
- }
- }
-
- /**
- * This Handler is used to post message back onto the main thread of the
- * application
- */
- private class MainHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case SETUP_PREVIEW: {
- setupPreview();
- break;
- }
-
- case CLEAR_SCREEN_DELAY: {
- mActivity.getWindow().clearFlags(
- WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- break;
- }
-
- case FIRST_TIME_INIT: {
- initializeFirstTime();
- break;
- }
-
- case SET_CAMERA_PARAMETERS_WHEN_IDLE: {
- setCameraParametersWhenIdle(0);
- break;
- }
-
- case CHECK_DISPLAY_ROTATION: {
- // Set the display orientation if display rotation has changed.
- // Sometimes this happens when the device is held upside
- // down and camera app is opened. Rotation animation will
- // take some time and the rotation value we have got may be
- // wrong. Framework does not have a callback for this now.
- if (Util.getDisplayRotation(mActivity) != mDisplayRotation) {
- setDisplayOrientation();
- }
- if (SystemClock.uptimeMillis() - mOnResumeTime < 5000) {
- mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION, 100);
- }
- break;
- }
-
- case SHOW_TAP_TO_FOCUS_TOAST: {
- showTapToFocusToast();
- break;
- }
-
- case SWITCH_CAMERA: {
- switchCamera();
- break;
- }
-
- case SWITCH_CAMERA_START_ANIMATION: {
- // TODO: Need to revisit
- // ((CameraScreenNail) mActivity.mCameraScreenNail).animateSwitchCamera();
- break;
- }
-
- case CAMERA_OPEN_DONE: {
- onCameraOpened();
- break;
- }
-
- case START_PREVIEW_DONE: {
- onPreviewStarted();
- break;
- }
-
- case OPEN_CAMERA_FAIL: {
- mCameraStartUpThread = null;
- mOpenCameraFail = true;
- Util.showErrorAndFinish(mActivity,
- R.string.cannot_connect_camera);
- break;
- }
-
- case CAMERA_DISABLED: {
- mCameraStartUpThread = null;
- mCameraDisabled = true;
- Util.showErrorAndFinish(mActivity,
- R.string.camera_disabled);
- break;
- }
- }
- }
- }
-
- @Override
- public void init(CameraActivity activity, View parent) {
- mActivity = activity;
- mUI = new PhotoUI(activity, this, parent);
- mPreferences = new ComboPreferences(mActivity);
- CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal());
- mCameraId = getPreferredCameraId(mPreferences);
-
- mContentResolver = mActivity.getContentResolver();
-
- // To reduce startup time, open the camera and start the preview in
- // another thread.
- mCameraStartUpThread = new CameraStartUpThread();
- mCameraStartUpThread.start();
-
- // Surface texture is from camera screen nail and startPreview needs it.
- // This must be done before startPreview.
- mIsImageCaptureIntent = isImageCaptureIntent();
-
- mPreferences.setLocalId(mActivity, mCameraId);
- CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
- // we need to reset exposure for the preview
- resetExposureCompensation();
- // Starting the preview needs preferences, camera screen nail, and
- // focus area indicator.
- mStartPreviewPrerequisiteReady.open();
-
- initializeControlByIntent();
- mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
- mLocationManager = new LocationManager(mActivity, mUI);
- mSensorManager = (SensorManager)(mActivity.getSystemService(Context.SENSOR_SERVICE));
- }
-
- private void initializeControlByIntent() {
- mUI.initializeControlByIntent();
- if (mIsImageCaptureIntent) {
- setupCaptureParams();
- }
- }
-
- private void onPreviewStarted() {
- mCameraStartUpThread = null;
- setCameraState(IDLE);
- startFaceDetection();
- locationFirstRun();
- }
-
- // Prompt the user to pick to record location for the very first run of
- // camera only
- private void locationFirstRun() {
- if (RecordLocationPreference.isSet(mPreferences)) {
- return;
- }
- if (mActivity.isSecureCamera()) return;
- // Check if the back camera exists
- int backCameraId = CameraHolder.instance().getBackCameraId();
- if (backCameraId == -1) {
- // If there is no back camera, do not show the prompt.
- return;
- }
- mUI.showLocationDialog();
- }
-
- public void enableRecordingLocation(boolean enable) {
- setLocationPreference(enable ? RecordLocationPreference.VALUE_ON
- : RecordLocationPreference.VALUE_OFF);
- }
-
- private void setLocationPreference(String value) {
- mPreferences.edit()
- .putString(CameraSettings.KEY_RECORD_LOCATION, value)
- .apply();
- // TODO: Fix this to use the actual onSharedPreferencesChanged listener
- // instead of invoking manually
- onSharedPreferenceChanged();
- }
-
- private void onCameraOpened() {
- View root = mUI.getRootView();
- // These depend on camera parameters.
-
- int width = root.getWidth();
- int height = root.getHeight();
- mFocusManager.setPreviewSize(width, height);
- openCameraCommon();
- }
-
- private void switchCamera() {
- if (mPaused) return;
-
- Log.v(TAG, "Start to switch camera. id=" + mPendingSwitchCameraId);
- mCameraId = mPendingSwitchCameraId;
- mPendingSwitchCameraId = -1;
- setCameraId(mCameraId);
-
- // from onPause
- closeCamera();
- mUI.collapseCameraControls();
- mUI.clearFaces();
- if (mFocusManager != null) mFocusManager.removeMessages();
-
- // Restart the camera and initialize the UI. From onCreate.
- mPreferences.setLocalId(mActivity, mCameraId);
- CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
- try {
- mCameraDevice = Util.openCamera(mActivity, mCameraId);
- mParameters = mCameraDevice.getParameters();
- } catch (CameraHardwareException e) {
- Util.showErrorAndFinish(mActivity, R.string.cannot_connect_camera);
- return;
- } catch (CameraDisabledException e) {
- Util.showErrorAndFinish(mActivity, R.string.camera_disabled);
- return;
- }
- initializeCapabilities();
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
- boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
- mFocusManager.setMirror(mirror);
- mFocusManager.setParameters(mInitialParams);
- setupPreview();
-
- // reset zoom value index
- mZoomValue = 0;
- openCameraCommon();
-
- if (ApiHelper.HAS_SURFACE_TEXTURE) {
- // Start switch camera animation. Post a message because
- // onFrameAvailable from the old camera may already exist.
- mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION);
- }
- }
-
- protected void setCameraId(int cameraId) {
- ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID);
- pref.setValue("" + cameraId);
- }
-
- // either open a new camera or switch cameras
- private void openCameraCommon() {
- loadCameraPreferences();
-
- mUI.onCameraOpened(mPreferenceGroup, mPreferences, mParameters, this);
- updateSceneMode();
- showTapToFocusToastIfNeeded();
-
-
- }
-
- public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) {
- if (mFocusManager != null) mFocusManager.setPreviewSize(width, height);
- }
-
- private void resetExposureCompensation() {
- String value = mPreferences.getString(CameraSettings.KEY_EXPOSURE,
- CameraSettings.EXPOSURE_DEFAULT_VALUE);
- if (!CameraSettings.EXPOSURE_DEFAULT_VALUE.equals(value)) {
- Editor editor = mPreferences.edit();
- editor.putString(CameraSettings.KEY_EXPOSURE, "0");
- editor.apply();
- }
- }
-
- private void keepMediaProviderInstance() {
- // We want to keep a reference to MediaProvider in camera's lifecycle.
- // TODO: Utilize mMediaProviderClient instance to replace
- // ContentResolver calls.
- if (mMediaProviderClient == null) {
- mMediaProviderClient = mContentResolver
- .acquireContentProviderClient(MediaStore.AUTHORITY);
- }
- }
-
- // Snapshots can only be taken after this is called. It should be called
- // once only. We could have done these things in onCreate() but we want to
- // make preview screen appear as soon as possible.
- private void initializeFirstTime() {
- if (mFirstTimeInitialized) return;
-
- // Initialize location service.
- boolean recordLocation = RecordLocationPreference.get(
- mPreferences, mContentResolver);
- mLocationManager.recordLocation(recordLocation);
-
- keepMediaProviderInstance();
-
- mUI.initializeFirstTime();
- MediaSaveService s = mActivity.getMediaSaveService();
- // We set the listener only when both service and shutterbutton
- // are initialized.
- if (s != null) {
- s.setListener(this);
- }
-
- mNamedImages = new NamedImages();
-
- mFirstTimeInitialized = true;
- addIdleHandler();
-
- mActivity.updateStorageSpaceAndHint();
- }
-
- // If the activity is paused and resumed, this method will be called in
- // onResume.
- private void initializeSecondTime() {
- // Start location update if needed.
- boolean recordLocation = RecordLocationPreference.get(
- mPreferences, mContentResolver);
- mLocationManager.recordLocation(recordLocation);
- MediaSaveService s = mActivity.getMediaSaveService();
- if (s != null) {
- s.setListener(this);
- }
- mNamedImages = new NamedImages();
- mUI.initializeSecondTime(mParameters);
- keepMediaProviderInstance();
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- // Do not access the camera if camera start up thread is not finished.
- if (mCameraDevice == null || mCameraStartUpThread != null)
- return;
-
- mCameraDevice.setPreviewDisplay(holder);
- // This happens when onConfigurationChanged arrives, surface has been
- // destroyed, and there is no onFullScreenChanged.
- if (mCameraState == PREVIEW_STOPPED) {
- setupPreview();
- }
- }
-
- private void showTapToFocusToastIfNeeded() {
- // Show the tap to focus toast if this is the first start.
- if (mFocusAreaSupported &&
- mPreferences.getBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, true)) {
- // Delay the toast for one second to wait for orientation.
- mHandler.sendEmptyMessageDelayed(SHOW_TAP_TO_FOCUS_TOAST, 1000);
- }
- }
-
- private void addIdleHandler() {
- MessageQueue queue = Looper.myQueue();
- queue.addIdleHandler(new MessageQueue.IdleHandler() {
- @Override
- public boolean queueIdle() {
- Storage.ensureOSXCompatible();
- return false;
- }
- });
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public void startFaceDetection() {
- if (!ApiHelper.HAS_FACE_DETECTION) return;
- if (mFaceDetectionStarted) return;
- if (mParameters.getMaxNumDetectedFaces() > 0) {
- mFaceDetectionStarted = true;
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
- mUI.onStartFaceDetection(mDisplayOrientation,
- (info.facing == CameraInfo.CAMERA_FACING_FRONT));
- mCameraDevice.setFaceDetectionCallback(mHandler, mUI);
- mCameraDevice.startFaceDetection();
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public void stopFaceDetection() {
- if (!ApiHelper.HAS_FACE_DETECTION) return;
- if (!mFaceDetectionStarted) return;
- if (mParameters.getMaxNumDetectedFaces() > 0) {
- mFaceDetectionStarted = false;
- mCameraDevice.setFaceDetectionCallback(null, null);
- mCameraDevice.stopFaceDetection();
- mUI.clearFaces();
- }
- }
-
- private final class ShutterCallback
- implements CameraShutterCallback {
-
- private boolean mNeedsAnimation;
-
- public ShutterCallback(boolean needsAnimation) {
- mNeedsAnimation = needsAnimation;
- }
-
- @Override
- public void onShutter(CameraProxy camera) {
- mShutterCallbackTime = System.currentTimeMillis();
- mShutterLag = mShutterCallbackTime - mCaptureStartTime;
- Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
- if (mNeedsAnimation) {
- mActivity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- animateAfterShutter();
- }
- });
- }
- }
- }
-
- private final class PostViewPictureCallback
- implements CameraPictureCallback {
- @Override
- public void onPictureTaken(byte [] data, CameraProxy camera) {
- mPostViewPictureCallbackTime = System.currentTimeMillis();
- Log.v(TAG, "mShutterToPostViewCallbackTime = "
- + (mPostViewPictureCallbackTime - mShutterCallbackTime)
- + "ms");
- }
- }
-
- private final class RawPictureCallback
- implements CameraPictureCallback {
- @Override
- public void onPictureTaken(byte [] rawData, CameraProxy camera) {
- mRawPictureCallbackTime = System.currentTimeMillis();
- Log.v(TAG, "mShutterToRawCallbackTime = "
- + (mRawPictureCallbackTime - mShutterCallbackTime) + "ms");
- }
- }
-
- private final class JpegPictureCallback
- implements CameraPictureCallback {
- Location mLocation;
-
- public JpegPictureCallback(Location loc) {
- mLocation = loc;
- }
-
- @Override
- public void onPictureTaken(final byte [] jpegData, CameraProxy camera) {
- if (mPaused) {
- return;
- }
- if (mIsImageCaptureIntent) {
- stopPreview();
- } else {
- // Animate capture with real jpeg data instead of a preview frame.
- mUI.animateCapture(jpegData);
- }
- if (mSceneMode == Util.SCENE_MODE_HDR) {
- mUI.showSwitcher();
- mUI.setSwipingEnabled(true);
- }
-
- mJpegPictureCallbackTime = System.currentTimeMillis();
- // If postview callback has arrived, the captured image is displayed
- // in postview callback. If not, the captured image is displayed in
- // raw picture callback.
- if (mPostViewPictureCallbackTime != 0) {
- mShutterToPictureDisplayedTime =
- mPostViewPictureCallbackTime - mShutterCallbackTime;
- mPictureDisplayedToJpegCallbackTime =
- mJpegPictureCallbackTime - mPostViewPictureCallbackTime;
- } else {
- mShutterToPictureDisplayedTime =
- mRawPictureCallbackTime - mShutterCallbackTime;
- mPictureDisplayedToJpegCallbackTime =
- mJpegPictureCallbackTime - mRawPictureCallbackTime;
- }
- Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = "
- + mPictureDisplayedToJpegCallbackTime + "ms");
-
- mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
- if (!mIsImageCaptureIntent) {
- if (ApiHelper.CAN_START_PREVIEW_IN_JPEG_CALLBACK) {
- setupPreview();
- } else {
- // Camera HAL of some devices have a bug. Starting preview
- // immediately after taking a picture will fail. Wait some
- // time before starting the preview.
- mHandler.sendEmptyMessageDelayed(SETUP_PREVIEW, 300);
- }
- }
-
- if (!mIsImageCaptureIntent) {
- // Calculate the width and the height of the jpeg.
- Size s = mParameters.getPictureSize();
- ExifInterface exif = Exif.getExif(jpegData);
- int orientation = Exif.getOrientation(exif);
- int width, height;
- if ((mJpegRotation + orientation) % 180 == 0) {
- width = s.width;
- height = s.height;
- } else {
- width = s.height;
- height = s.width;
- }
- String title = mNamedImages.getTitle();
- long date = mNamedImages.getDate();
- if (title == null) {
- Log.e(TAG, "Unbalanced name/data pair");
- } else {
- if (date == -1) date = mCaptureStartTime;
- if (mHeading >= 0) {
- // heading direction has been updated by the sensor.
- ExifTag directionRefTag = exif.buildTag(
- ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
- ExifInterface.GpsTrackRef.MAGNETIC_DIRECTION);
- ExifTag directionTag = exif.buildTag(
- ExifInterface.TAG_GPS_IMG_DIRECTION,
- new Rational(mHeading, 1));
- exif.setTag(directionRefTag);
- exif.setTag(directionTag);
- }
- mActivity.getMediaSaveService().addImage(
- jpegData, title, date, mLocation, width, height,
- orientation, exif, mOnMediaSavedListener, mContentResolver);
- }
- } else {
- mJpegImageData = jpegData;
- if (!mQuickCapture) {
- mUI.showPostCaptureAlert();
- } else {
- onCaptureDone();
- }
- }
-
- // Check this in advance of each shot so we don't add to shutter
- // latency. It's true that someone else could write to the SD card in
- // the mean time and fill it, but that could have happened between the
- // shutter press and saving the JPEG too.
- mActivity.updateStorageSpaceAndHint();
-
- long now = System.currentTimeMillis();
- mJpegCallbackFinishTime = now - mJpegPictureCallbackTime;
- Log.v(TAG, "mJpegCallbackFinishTime = "
- + mJpegCallbackFinishTime + "ms");
- mJpegPictureCallbackTime = 0;
- }
- }
-
- private final class AutoFocusCallback implements CameraAFCallback {
- @Override
- public void onAutoFocus(
- boolean focused, CameraProxy camera) {
- if (mPaused) return;
-
- mAutoFocusTime = System.currentTimeMillis() - mFocusStartTime;
- Log.v(TAG, "mAutoFocusTime = " + mAutoFocusTime + "ms");
- setCameraState(IDLE);
- mFocusManager.onAutoFocus(focused, mUI.isShutterPressed());
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private final class AutoFocusMoveCallback
- implements CameraAFMoveCallback {
- @Override
- public void onAutoFocusMoving(
- boolean moving, CameraProxy camera) {
- mFocusManager.onAutoFocusMoving(moving);
- }
- }
-
- private static class NamedImages {
- private ArrayList<NamedEntity> mQueue;
- private boolean mStop;
- private NamedEntity mNamedEntity;
-
- public NamedImages() {
- mQueue = new ArrayList<NamedEntity>();
- }
-
- public void nameNewImage(ContentResolver resolver, long date) {
- NamedEntity r = new NamedEntity();
- r.title = Util.createJpegName(date);
- r.date = date;
- mQueue.add(r);
- }
-
- public String getTitle() {
- if (mQueue.isEmpty()) {
- mNamedEntity = null;
- return null;
- }
- mNamedEntity = mQueue.get(0);
- mQueue.remove(0);
-
- return mNamedEntity.title;
- }
-
- // Must be called after getTitle().
- public long getDate() {
- if (mNamedEntity == null) return -1;
- return mNamedEntity.date;
- }
-
- private static class NamedEntity {
- String title;
- long date;
- }
- }
-
- private void setCameraState(int state) {
- mCameraState = state;
- switch (state) {
- case PhotoController.PREVIEW_STOPPED:
- case PhotoController.SNAPSHOT_IN_PROGRESS:
- case PhotoController.SWITCHING_CAMERA:
- mUI.enableGestures(false);
- break;
- case PhotoController.IDLE:
- mUI.enableGestures(true);
- break;
- }
- }
-
- private void animateAfterShutter() {
- // Only animate when in full screen capture mode
- // i.e. If monkey/a user swipes to the gallery during picture taking,
- // don't show animation
- if (!mIsImageCaptureIntent) {
- mUI.animateFlash();
- }
- }
-
- @Override
- public boolean capture() {
- // If we are already in the middle of taking a snapshot or the image save request
- // is full then ignore.
- if (mCameraDevice == null || mCameraState == SNAPSHOT_IN_PROGRESS
- || mCameraState == SWITCHING_CAMERA
- || mActivity.getMediaSaveService().isQueueFull()) {
- return false;
- }
- mCaptureStartTime = System.currentTimeMillis();
- mPostViewPictureCallbackTime = 0;
- mJpegImageData = null;
-
- final boolean animateBefore = (mSceneMode == Util.SCENE_MODE_HDR);
-
- if (animateBefore) {
- animateAfterShutter();
- }
-
- // Set rotation and gps data.
- int orientation;
- // We need to be consistent with the framework orientation (i.e. the
- // orientation of the UI.) when the auto-rotate screen setting is on.
- if (mActivity.isAutoRotateScreen()) {
- orientation = (360 - mDisplayRotation) % 360;
- } else {
- orientation = mOrientation;
- }
- mJpegRotation = Util.getJpegRotation(mCameraId, orientation);
- mParameters.setRotation(mJpegRotation);
- Location loc = mLocationManager.getCurrentLocation();
- Util.setGpsParameters(mParameters, loc);
- mCameraDevice.setParameters(mParameters);
-
- mCameraDevice.takePicture(mHandler,
- new ShutterCallback(!animateBefore),
- mRawPictureCallback, mPostViewPictureCallback,
- new JpegPictureCallback(loc));
-
- mNamedImages.nameNewImage(mContentResolver, mCaptureStartTime);
-
- mFaceDetectionStarted = false;
- setCameraState(SNAPSHOT_IN_PROGRESS);
- UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
- UsageStatistics.ACTION_CAPTURE_DONE, "Photo");
- return true;
- }
-
- @Override
- public void setFocusParameters() {
- setCameraParameters(UPDATE_PARAM_PREFERENCE);
- }
-
- private int getPreferredCameraId(ComboPreferences preferences) {
- int intentCameraId = Util.getCameraFacingIntentExtras(mActivity);
- if (intentCameraId != -1) {
- // Testing purpose. Launch a specific camera through the intent
- // extras.
- return intentCameraId;
- } else {
- return CameraSettings.readPreferredCameraId(preferences);
- }
- }
-
- private void updateSceneMode() {
- // If scene mode is set, we cannot set flash mode, white balance, and
- // focus mode, instead, we read it from driver
- if (!Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
- overrideCameraSettings(mParameters.getFlashMode(),
- mParameters.getWhiteBalance(), mParameters.getFocusMode());
- } else {
- overrideCameraSettings(null, null, null);
- }
- }
-
- private void overrideCameraSettings(final String flashMode,
- final String whiteBalance, final String focusMode) {
- mUI.overrideSettings(
- CameraSettings.KEY_FLASH_MODE, flashMode,
- CameraSettings.KEY_WHITE_BALANCE, whiteBalance,
- CameraSettings.KEY_FOCUS_MODE, focusMode);
- }
-
- private void loadCameraPreferences() {
- CameraSettings settings = new CameraSettings(mActivity, mInitialParams,
- mCameraId, CameraHolder.instance().getCameraInfo());
- mPreferenceGroup = settings.getPreferenceGroup(R.xml.camera_preferences);
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- // We keep the last known orientation. So if the user first orient
- // the camera then point the camera to floor or sky, we still have
- // the correct orientation.
- if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return;
- mOrientation = Util.roundOrientation(orientation, mOrientation);
-
- // Show the toast after getting the first orientation changed.
- if (mHandler.hasMessages(SHOW_TAP_TO_FOCUS_TOAST)) {
- mHandler.removeMessages(SHOW_TAP_TO_FOCUS_TOAST);
- showTapToFocusToast();
- }
- }
-
- @Override
- public void onStop() {
- if (mMediaProviderClient != null) {
- mMediaProviderClient.release();
- mMediaProviderClient = null;
- }
- }
-
- @Override
- public void onCaptureCancelled() {
- mActivity.setResultEx(Activity.RESULT_CANCELED, new Intent());
- mActivity.finish();
- }
-
- @Override
- public void onCaptureRetake() {
- if (mPaused)
- return;
- mUI.hidePostCaptureAlert();
- setupPreview();
- }
-
- @Override
- public void onCaptureDone() {
- if (mPaused) {
- return;
- }
-
- byte[] data = mJpegImageData;
-
- if (mCropValue == null) {
- // First handle the no crop case -- just return the value. If the
- // caller specifies a "save uri" then write the data to its
- // stream. Otherwise, pass back a scaled down version of the bitmap
- // directly in the extras.
- if (mSaveUri != null) {
- OutputStream outputStream = null;
- try {
- outputStream = mContentResolver.openOutputStream(mSaveUri);
- outputStream.write(data);
- outputStream.close();
-
- mActivity.setResultEx(Activity.RESULT_OK);
- mActivity.finish();
- } catch (IOException ex) {
- // ignore exception
- } finally {
- Util.closeSilently(outputStream);
- }
- } else {
- ExifInterface exif = Exif.getExif(data);
- int orientation = Exif.getOrientation(exif);
- Bitmap bitmap = Util.makeBitmap(data, 50 * 1024);
- bitmap = Util.rotate(bitmap, orientation);
- mActivity.setResultEx(Activity.RESULT_OK,
- new Intent("inline-data").putExtra("data", bitmap));
- mActivity.finish();
- }
- } else {
- // Save the image to a temp file and invoke the cropper
- Uri tempUri = null;
- FileOutputStream tempStream = null;
- try {
- File path = mActivity.getFileStreamPath(sTempCropFilename);
- path.delete();
- tempStream = mActivity.openFileOutput(sTempCropFilename, 0);
- tempStream.write(data);
- tempStream.close();
- tempUri = Uri.fromFile(path);
- } catch (FileNotFoundException ex) {
- mActivity.setResultEx(Activity.RESULT_CANCELED);
- mActivity.finish();
- return;
- } catch (IOException ex) {
- mActivity.setResultEx(Activity.RESULT_CANCELED);
- mActivity.finish();
- return;
- } finally {
- Util.closeSilently(tempStream);
- }
-
- Bundle newExtras = new Bundle();
- if (mCropValue.equals("circle")) {
- newExtras.putString("circleCrop", "true");
- }
- if (mSaveUri != null) {
- newExtras.putParcelable(MediaStore.EXTRA_OUTPUT, mSaveUri);
- } else {
- newExtras.putBoolean(CropExtras.KEY_RETURN_DATA, true);
- }
- if (mActivity.isSecureCamera()) {
- newExtras.putBoolean(CropExtras.KEY_SHOW_WHEN_LOCKED, true);
- }
-
- Intent cropIntent = new Intent(CropActivity.CROP_ACTION);
-
- cropIntent.setData(tempUri);
- cropIntent.putExtras(newExtras);
-
- mActivity.startActivityForResult(cropIntent, REQUEST_CROP);
- }
- }
-
- @Override
- public void onShutterButtonFocus(boolean pressed) {
- if (mPaused || mUI.collapseCameraControls()
- || (mCameraState == SNAPSHOT_IN_PROGRESS)
- || (mCameraState == PREVIEW_STOPPED)) return;
-
- // Do not do focus if there is not enough storage.
- if (pressed && !canTakePicture()) return;
-
- if (pressed) {
- mFocusManager.onShutterDown();
- } else {
- // for countdown mode, we need to postpone the shutter release
- // i.e. lock the focus during countdown.
- if (!mUI.isCountingDown()) {
- mFocusManager.onShutterUp();
- }
- }
- }
-
- @Override
- public void onShutterButtonClick() {
- if (mPaused || mUI.collapseCameraControls()
- || (mCameraState == SWITCHING_CAMERA)
- || (mCameraState == PREVIEW_STOPPED)) return;
-
- // Do not take the picture if there is not enough storage.
- if (mActivity.getStorageSpace() <= Storage.LOW_STORAGE_THRESHOLD) {
- Log.i(TAG, "Not enough space or storage not ready. remaining="
- + mActivity.getStorageSpace());
- return;
- }
- Log.v(TAG, "onShutterButtonClick: mCameraState=" + mCameraState);
-
- if (mSceneMode == Util.SCENE_MODE_HDR) {
- mUI.hideSwitcher();
- mUI.setSwipingEnabled(false);
- }
- // If the user wants to do a snapshot while the previous one is still
- // in progress, remember the fact and do it after we finish the previous
- // one and re-start the preview. Snapshot in progress also includes the
- // state that autofocus is focusing and a picture will be taken when
- // focus callback arrives.
- if ((mFocusManager.isFocusingSnapOnFinish() || mCameraState == SNAPSHOT_IN_PROGRESS)
- && !mIsImageCaptureIntent) {
- mSnapshotOnIdle = true;
- return;
- }
-
- String timer = mPreferences.getString(
- CameraSettings.KEY_TIMER,
- mActivity.getString(R.string.pref_camera_timer_default));
- boolean playSound = mPreferences.getString(CameraSettings.KEY_TIMER_SOUND_EFFECTS,
- mActivity.getString(R.string.pref_camera_timer_sound_default))
- .equals(mActivity.getString(R.string.setting_on_value));
-
- int seconds = Integer.parseInt(timer);
- // When shutter button is pressed, check whether the previous countdown is
- // finished. If not, cancel the previous countdown and start a new one.
- if (mUI.isCountingDown()) {
- mUI.cancelCountDown();
- }
- if (seconds > 0) {
- mUI.startCountDown(seconds, playSound);
- } else {
- mSnapshotOnIdle = false;
- mFocusManager.doSnap();
- }
- }
-
- @Override
- public void installIntentFilter() {
- }
-
- @Override
- public boolean updateStorageHintOnResume() {
- return mFirstTimeInitialized;
- }
-
- @Override
- public void updateCameraAppView() {
- }
-
- @Override
- public void onResumeBeforeSuper() {
- mPaused = false;
- }
-
- @Override
- public void onResumeAfterSuper() {
- if (mOpenCameraFail || mCameraDisabled) return;
-
- mJpegPictureCallbackTime = 0;
- mZoomValue = 0;
- // Start the preview if it is not started.
- if (mCameraState == PREVIEW_STOPPED && mCameraStartUpThread == null) {
- resetExposureCompensation();
- mCameraStartUpThread = new CameraStartUpThread();
- mCameraStartUpThread.start();
- }
-
- // If first time initialization is not finished, put it in the
- // message queue.
- if (!mFirstTimeInitialized) {
- mHandler.sendEmptyMessage(FIRST_TIME_INIT);
- } else {
- initializeSecondTime();
- }
- keepScreenOnAwhile();
-
- // Dismiss open menu if exists.
- PopupManager.getInstance(mActivity).notifyShowPopup(null);
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_CAMERA, "PhotoModule");
-
- Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- if (gsensor != null) {
- mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_NORMAL);
- }
-
- Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
- if (msensor != null) {
- mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_NORMAL);
- }
- }
-
- void waitCameraStartUpThread() {
- try {
- if (mCameraStartUpThread != null) {
- mCameraStartUpThread.cancel();
- mCameraStartUpThread.join();
- mCameraStartUpThread = null;
- setCameraState(IDLE);
- }
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- @Override
- public void onPauseBeforeSuper() {
- mPaused = true;
- Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- if (gsensor != null) {
- mSensorManager.unregisterListener(this, gsensor);
- }
-
- Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
- if (msensor != null) {
- mSensorManager.unregisterListener(this, msensor);
- }
- }
-
- @Override
- public void onPauseAfterSuper() {
- // Wait the camera start up thread to finish.
- waitCameraStartUpThread();
-
- // When camera is started from secure lock screen for the first time
- // after screen on, the activity gets onCreate->onResume->onPause->onResume.
- // To reduce the latency, keep the camera for a short time so it does
- // not need to be opened again.
- if (mCameraDevice != null && mActivity.isSecureCamera()
- && CameraActivity.isFirstStartAfterScreenOn()) {
- CameraActivity.resetFirstStartAfterScreenOn();
- CameraHolder.instance().keep(KEEP_CAMERA_TIMEOUT);
- }
- // Reset the focus first. Camera CTS does not guarantee that
- // cancelAutoFocus is allowed after preview stops.
- if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
- mCameraDevice.cancelAutoFocus();
- }
- stopPreview();
-
- mNamedImages = null;
-
- if (mLocationManager != null) mLocationManager.recordLocation(false);
-
- // If we are in an image capture intent and has taken
- // a picture, we just clear it in onPause.
- mJpegImageData = null;
-
- // Remove the messages in the event queue.
- mHandler.removeMessages(SETUP_PREVIEW);
- mHandler.removeMessages(FIRST_TIME_INIT);
- mHandler.removeMessages(CHECK_DISPLAY_ROTATION);
- mHandler.removeMessages(SWITCH_CAMERA);
- mHandler.removeMessages(SWITCH_CAMERA_START_ANIMATION);
- mHandler.removeMessages(CAMERA_OPEN_DONE);
- mHandler.removeMessages(START_PREVIEW_DONE);
- mHandler.removeMessages(OPEN_CAMERA_FAIL);
- mHandler.removeMessages(CAMERA_DISABLED);
-
- closeCamera();
-
- resetScreenOn();
- mUI.onPause();
-
- mPendingSwitchCameraId = -1;
- if (mFocusManager != null) mFocusManager.removeMessages();
- MediaSaveService s = mActivity.getMediaSaveService();
- if (s != null) {
- s.setListener(null);
- }
- }
-
- /**
- * The focus manager is the first UI related element to get initialized,
- * and it requires the RenderOverlay, so initialize it here
- */
- private void initializeFocusManager() {
- // Create FocusManager object. startPreview needs it.
- // if mFocusManager not null, reuse it
- // otherwise create a new instance
- if (mFocusManager != null) {
- mFocusManager.removeMessages();
- } else {
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
- boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
- String[] defaultFocusModes = mActivity.getResources().getStringArray(
- R.array.pref_camera_focusmode_default_array);
- mFocusManager = new FocusOverlayManager(mPreferences, defaultFocusModes,
- mInitialParams, this, mirror,
- mActivity.getMainLooper(), mUI);
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- Log.v(TAG, "onConfigurationChanged");
- setDisplayOrientation();
- }
-
- @Override
- public void updateCameraOrientation() {
- if (mDisplayRotation != Util.getDisplayRotation(mActivity)) {
- setDisplayOrientation();
- }
- }
-
- @Override
- public void onActivityResult(
- int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_CROP: {
- Intent intent = new Intent();
- if (data != null) {
- Bundle extras = data.getExtras();
- if (extras != null) {
- intent.putExtras(extras);
- }
- }
- mActivity.setResultEx(resultCode, intent);
- mActivity.finish();
-
- File path = mActivity.getFileStreamPath(sTempCropFilename);
- path.delete();
-
- break;
- }
- }
- }
-
- private boolean canTakePicture() {
- return isCameraIdle() && (mActivity.getStorageSpace() > Storage.LOW_STORAGE_THRESHOLD);
- }
-
- @Override
- public void autoFocus() {
- mFocusStartTime = System.currentTimeMillis();
- mCameraDevice.autoFocus(mHandler, mAutoFocusCallback);
- setCameraState(FOCUSING);
- }
-
- @Override
- public void cancelAutoFocus() {
- mCameraDevice.cancelAutoFocus();
- setCameraState(IDLE);
- setCameraParameters(UPDATE_PARAM_PREFERENCE);
- }
-
- // Preview area is touched. Handle touch focus.
- @Override
- public void onSingleTapUp(View view, int x, int y) {
- if (mPaused || mCameraDevice == null || !mFirstTimeInitialized
- || mCameraState == SNAPSHOT_IN_PROGRESS
- || mCameraState == SWITCHING_CAMERA
- || mCameraState == PREVIEW_STOPPED) {
- return;
- }
-
- // Do not trigger touch focus if popup window is opened.
- if (mUI.removeTopLevelPopup()) return;
-
- // Check if metering area or focus area is supported.
- if (!mFocusAreaSupported && !mMeteringAreaSupported) return;
- mFocusManager.onSingleTapUp(x, y);
- }
-
- @Override
- public boolean onBackPressed() {
- return mUI.onBackPressed();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_FOCUS:
- if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized) {
- if (event.getRepeatCount() == 0) {
- onShutterButtonFocus(true);
- }
- return true;
- }
- return false;
- case KeyEvent.KEYCODE_CAMERA:
- if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
- onShutterButtonClick();
- }
- return true;
- case KeyEvent.KEYCODE_DPAD_CENTER:
- // If we get a dpad center event without any focused view, move
- // the focus to the shutter button and press it.
- if (mFirstTimeInitialized && event.getRepeatCount() == 0) {
- // Start auto-focus immediately to reduce shutter lag. After
- // the shutter button gets the focus, onShutterButtonFocus()
- // will be called again but it is fine.
- if (mUI.removeTopLevelPopup()) return true;
- onShutterButtonFocus(true);
- mUI.pressShutterButton();
- }
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_VOLUME_UP:
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- if (/*mActivity.isInCameraApp() && */ mFirstTimeInitialized) {
- onShutterButtonClick();
- return true;
- }
- return false;
- case KeyEvent.KEYCODE_FOCUS:
- if (mFirstTimeInitialized) {
- onShutterButtonFocus(false);
- }
- return true;
- }
- return false;
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void closeCamera() {
- if (mCameraDevice != null) {
- mCameraDevice.setZoomChangeListener(null);
- if(ApiHelper.HAS_FACE_DETECTION) {
- mCameraDevice.setFaceDetectionCallback(null, null);
- }
- mCameraDevice.setErrorCallback(null);
- CameraHolder.instance().release();
- mFaceDetectionStarted = false;
- mCameraDevice = null;
- setCameraState(PREVIEW_STOPPED);
- mFocusManager.onCameraReleased();
- }
- }
-
- private void setDisplayOrientation() {
- mDisplayRotation = Util.getDisplayRotation(mActivity);
- mDisplayOrientation = Util.getDisplayOrientation(mDisplayRotation, mCameraId);
- mCameraDisplayOrientation = mDisplayOrientation;
- mUI.setDisplayOrientation(mDisplayOrientation);
- if (mFocusManager != null) {
- mFocusManager.setDisplayOrientation(mDisplayOrientation);
- }
- // Change the camera display orientation
- if (mCameraDevice != null) {
- mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation);
- }
- }
-
- // Only called by UI thread.
- private void setupPreview() {
- mFocusManager.resetTouchFocus();
- startPreview();
- setCameraState(IDLE);
- startFaceDetection();
- }
-
- // This can be called by UI Thread or CameraStartUpThread. So this should
- // not modify the views.
- private void startPreview() {
- mCameraDevice.setErrorCallback(mErrorCallback);
-
- // ICS camera frameworks has a bug. Face detection state is not cleared
- // after taking a picture. Stop the preview to work around it. The bug
- // was fixed in JB.
- if (mCameraState != PREVIEW_STOPPED) stopPreview();
-
- setDisplayOrientation();
-
- if (!mSnapshotOnIdle) {
- // If the focus mode is continuous autofocus, call cancelAutoFocus to
- // resume it because it may have been paused by autoFocus call.
- if (Util.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) {
- mCameraDevice.cancelAutoFocus();
- }
- mFocusManager.setAeAwbLock(false); // Unlock AE and AWB.
- }
- setCameraParameters(UPDATE_PARAM_ALL);
- // Let UI set its expected aspect ratio
- mUI.setPreviewSize(mParameters.getPreviewSize());
- Object st = mUI.getSurfaceTexture();
- if (st != null) {
- mCameraDevice.setPreviewTexture((SurfaceTexture) st);
- }
-
- Log.v(TAG, "startPreview");
- mCameraDevice.startPreview();
- mFocusManager.onPreviewStarted();
-
- if (mSnapshotOnIdle) {
- mHandler.post(mDoSnapRunnable);
- }
- }
-
- @Override
- public void stopPreview() {
- if (mCameraDevice != null && mCameraState != PREVIEW_STOPPED) {
- Log.v(TAG, "stopPreview");
- mCameraDevice.stopPreview();
- mFaceDetectionStarted = false;
- }
- setCameraState(PREVIEW_STOPPED);
- if (mFocusManager != null) mFocusManager.onPreviewStopped();
- }
-
- @SuppressWarnings("deprecation")
- private void updateCameraParametersInitialize() {
- // Reset preview frame rate to the maximum because it may be lowered by
- // video camera application.
- int[] fpsRange = Util.getMaxPreviewFpsRange(mParameters);
- if (fpsRange.length > 0) {
- mParameters.setPreviewFpsRange(
- fpsRange[Parameters.PREVIEW_FPS_MIN_INDEX],
- fpsRange[Parameters.PREVIEW_FPS_MAX_INDEX]);
- }
-
- mParameters.set(Util.RECORDING_HINT, Util.FALSE);
-
- // Disable video stabilization. Convenience methods not available in API
- // level <= 14
- String vstabSupported = mParameters.get("video-stabilization-supported");
- if ("true".equals(vstabSupported)) {
- mParameters.set("video-stabilization", "false");
- }
- }
-
- private void updateCameraParametersZoom() {
- // Set zoom.
- if (mParameters.isZoomSupported()) {
- mParameters.setZoom(mZoomValue);
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void setAutoExposureLockIfSupported() {
- if (mAeLockSupported) {
- mParameters.setAutoExposureLock(mFocusManager.getAeAwbLock());
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void setAutoWhiteBalanceLockIfSupported() {
- if (mAwbLockSupported) {
- mParameters.setAutoWhiteBalanceLock(mFocusManager.getAeAwbLock());
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void setFocusAreasIfSupported() {
- if (mFocusAreaSupported) {
- mParameters.setFocusAreas(mFocusManager.getFocusAreas());
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void setMeteringAreasIfSupported() {
- if (mMeteringAreaSupported) {
- // Use the same area for focus and metering.
- mParameters.setMeteringAreas(mFocusManager.getMeteringAreas());
- }
- }
-
- private void updateCameraParametersPreference() {
- setAutoExposureLockIfSupported();
- setAutoWhiteBalanceLockIfSupported();
- setFocusAreasIfSupported();
- setMeteringAreasIfSupported();
-
- // Set picture size.
- String pictureSize = mPreferences.getString(
- CameraSettings.KEY_PICTURE_SIZE, null);
- if (pictureSize == null) {
- CameraSettings.initialCameraPictureSize(mActivity, mParameters);
- } else {
- List<Size> supported = mParameters.getSupportedPictureSizes();
- CameraSettings.setCameraPictureSize(
- pictureSize, supported, mParameters);
- }
- Size size = mParameters.getPictureSize();
-
- // Set a preview size that is closest to the viewfinder height and has
- // the right aspect ratio.
- List<Size> sizes = mParameters.getSupportedPreviewSizes();
- Size optimalSize = Util.getOptimalPreviewSize(mActivity, sizes,
- (double) size.width / size.height);
- Size original = mParameters.getPreviewSize();
- if (!original.equals(optimalSize)) {
- mParameters.setPreviewSize(optimalSize.width, optimalSize.height);
-
- // Zoom related settings will be changed for different preview
- // sizes, so set and read the parameters to get latest values
- if (mHandler.getLooper() == Looper.myLooper()) {
- // On UI thread only, not when camera starts up
- setupPreview();
- } else {
- mCameraDevice.setParameters(mParameters);
- }
- mParameters = mCameraDevice.getParameters();
- }
- Log.v(TAG, "Preview size is " + optimalSize.width + "x" + optimalSize.height);
-
- // Since changing scene mode may change supported values, set scene mode
- // first. HDR is a scene mode. To promote it in UI, it is stored in a
- // separate preference.
- String hdr = mPreferences.getString(CameraSettings.KEY_CAMERA_HDR,
- mActivity.getString(R.string.pref_camera_hdr_default));
- if (mActivity.getString(R.string.setting_on_value).equals(hdr)) {
- mSceneMode = Util.SCENE_MODE_HDR;
- } else {
- mSceneMode = mPreferences.getString(
- CameraSettings.KEY_SCENE_MODE,
- mActivity.getString(R.string.pref_camera_scenemode_default));
- }
- if (Util.isSupported(mSceneMode, mParameters.getSupportedSceneModes())) {
- if (!mParameters.getSceneMode().equals(mSceneMode)) {
- mParameters.setSceneMode(mSceneMode);
-
- // Setting scene mode will change the settings of flash mode,
- // white balance, and focus mode. Here we read back the
- // parameters, so we can know those settings.
- mCameraDevice.setParameters(mParameters);
- mParameters = mCameraDevice.getParameters();
- }
- } else {
- mSceneMode = mParameters.getSceneMode();
- if (mSceneMode == null) {
- mSceneMode = Parameters.SCENE_MODE_AUTO;
- }
- }
-
- // Set JPEG quality.
- int jpegQuality = CameraProfile.getJpegEncodingQualityParameter(mCameraId,
- CameraProfile.QUALITY_HIGH);
- mParameters.setJpegQuality(jpegQuality);
-
- // For the following settings, we need to check if the settings are
- // still supported by latest driver, if not, ignore the settings.
-
- // Set exposure compensation
- int value = CameraSettings.readExposure(mPreferences);
- int max = mParameters.getMaxExposureCompensation();
- int min = mParameters.getMinExposureCompensation();
- if (value >= min && value <= max) {
- mParameters.setExposureCompensation(value);
- } else {
- Log.w(TAG, "invalid exposure range: " + value);
- }
-
- if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
- // Set flash mode.
- String flashMode = mPreferences.getString(
- CameraSettings.KEY_FLASH_MODE,
- mActivity.getString(R.string.pref_camera_flashmode_default));
- List<String> supportedFlash = mParameters.getSupportedFlashModes();
- if (Util.isSupported(flashMode, supportedFlash)) {
- mParameters.setFlashMode(flashMode);
- } else {
- flashMode = mParameters.getFlashMode();
- if (flashMode == null) {
- flashMode = mActivity.getString(
- R.string.pref_camera_flashmode_no_flash);
- }
- }
-
- // Set white balance parameter.
- String whiteBalance = mPreferences.getString(
- CameraSettings.KEY_WHITE_BALANCE,
- mActivity.getString(R.string.pref_camera_whitebalance_default));
- if (Util.isSupported(whiteBalance,
- mParameters.getSupportedWhiteBalance())) {
- mParameters.setWhiteBalance(whiteBalance);
- } else {
- whiteBalance = mParameters.getWhiteBalance();
- if (whiteBalance == null) {
- whiteBalance = Parameters.WHITE_BALANCE_AUTO;
- }
- }
-
- // Set focus mode.
- mFocusManager.overrideFocusMode(null);
- mParameters.setFocusMode(mFocusManager.getFocusMode());
- } else {
- mFocusManager.overrideFocusMode(mParameters.getFocusMode());
- }
-
- if (mContinousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
- updateAutoFocusMoveCallback();
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private void updateAutoFocusMoveCallback() {
- if (mParameters.getFocusMode().equals(Util.FOCUS_MODE_CONTINUOUS_PICTURE)) {
- mCameraDevice.setAutoFocusMoveCallback(mHandler,
- (CameraManager.CameraAFMoveCallback) mAutoFocusMoveCallback);
- } else {
- mCameraDevice.setAutoFocusMoveCallback(null, null);
- }
- }
-
- // We separate the parameters into several subsets, so we can update only
- // the subsets actually need updating. The PREFERENCE set needs extra
- // locking because the preference can be changed from GLThread as well.
- private void setCameraParameters(int updateSet) {
- if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) {
- updateCameraParametersInitialize();
- }
-
- if ((updateSet & UPDATE_PARAM_ZOOM) != 0) {
- updateCameraParametersZoom();
- }
-
- if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
- updateCameraParametersPreference();
- }
-
- mCameraDevice.setParameters(mParameters);
- }
-
- // If the Camera is idle, update the parameters immediately, otherwise
- // accumulate them in mUpdateSet and update later.
- private void setCameraParametersWhenIdle(int additionalUpdateSet) {
- mUpdateSet |= additionalUpdateSet;
- if (mCameraDevice == null) {
- // We will update all the parameters when we open the device, so
- // we don't need to do anything now.
- mUpdateSet = 0;
- return;
- } else if (isCameraIdle()) {
- setCameraParameters(mUpdateSet);
- updateSceneMode();
- mUpdateSet = 0;
- } else {
- if (!mHandler.hasMessages(SET_CAMERA_PARAMETERS_WHEN_IDLE)) {
- mHandler.sendEmptyMessageDelayed(
- SET_CAMERA_PARAMETERS_WHEN_IDLE, 1000);
- }
- }
- }
-
- public boolean isCameraIdle() {
- return (mCameraState == IDLE) ||
- (mCameraState == PREVIEW_STOPPED) ||
- ((mFocusManager != null) && mFocusManager.isFocusCompleted()
- && (mCameraState != SWITCHING_CAMERA));
- }
-
- public boolean isImageCaptureIntent() {
- String action = mActivity.getIntent().getAction();
- return (MediaStore.ACTION_IMAGE_CAPTURE.equals(action)
- || CameraActivity.ACTION_IMAGE_CAPTURE_SECURE.equals(action));
- }
-
- private void setupCaptureParams() {
- Bundle myExtras = mActivity.getIntent().getExtras();
- if (myExtras != null) {
- mSaveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
- mCropValue = myExtras.getString("crop");
- }
- }
-
- @Override
- public void onSharedPreferenceChanged() {
- // ignore the events after "onPause()"
- if (mPaused) return;
-
- boolean recordLocation = RecordLocationPreference.get(
- mPreferences, mContentResolver);
- mLocationManager.recordLocation(recordLocation);
-
- setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
- mUI.updateOnScreenIndicators(mParameters, mPreferenceGroup, mPreferences);
- }
-
- @Override
- public void onCameraPickerClicked(int cameraId) {
- if (mPaused || mPendingSwitchCameraId != -1) return;
-
- mPendingSwitchCameraId = cameraId;
-
- Log.v(TAG, "Start to switch camera. cameraId=" + cameraId);
- // We need to keep a preview frame for the animation before
- // releasing the camera. This will trigger onPreviewTextureCopied.
- //TODO: Need to animate the camera switch
- switchCamera();
- }
-
- // Preview texture has been copied. Now camera can be released and the
- // animation can be started.
- @Override
- public void onPreviewTextureCopied() {
- mHandler.sendEmptyMessage(SWITCH_CAMERA);
- }
-
- @Override
- public void onCaptureTextureCopied() {
- }
-
- @Override
- public void onUserInteraction() {
- if (!mActivity.isFinishing()) keepScreenOnAwhile();
- }
-
- private void resetScreenOn() {
- mHandler.removeMessages(CLEAR_SCREEN_DELAY);
- mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
-
- private void keepScreenOnAwhile() {
- mHandler.removeMessages(CLEAR_SCREEN_DELAY);
- mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
- }
-
- @Override
- public void onOverriddenPreferencesClicked() {
- if (mPaused) return;
- mUI.showPreferencesToast();
- }
-
- private void showTapToFocusToast() {
- // TODO: Use a toast?
- new RotateTextToast(mActivity, R.string.tap_to_focus, 0).show();
- // Clear the preference.
- Editor editor = mPreferences.edit();
- editor.putBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, false);
- editor.apply();
- }
-
- private void initializeCapabilities() {
- mInitialParams = mCameraDevice.getParameters();
- mFocusAreaSupported = Util.isFocusAreaSupported(mInitialParams);
- mMeteringAreaSupported = Util.isMeteringAreaSupported(mInitialParams);
- mAeLockSupported = Util.isAutoExposureLockSupported(mInitialParams);
- mAwbLockSupported = Util.isAutoWhiteBalanceLockSupported(mInitialParams);
- mContinousFocusSupported = mInitialParams.getSupportedFocusModes().contains(
- Util.FOCUS_MODE_CONTINUOUS_PICTURE);
- }
-
- @Override
- public void onCountDownFinished() {
- mSnapshotOnIdle = false;
- mFocusManager.doSnap();
- mFocusManager.onShutterUp();
- }
-
- @Override
- public void onShowSwitcherPopup() {
- mUI.onShowSwitcherPopup();
- }
-
- @Override
- public int onZoomChanged(int index) {
- // Not useful to change zoom value when the activity is paused.
- if (mPaused) return index;
- mZoomValue = index;
- if (mParameters == null || mCameraDevice == null) return index;
- // Set zoom parameters asynchronously
- mParameters.setZoom(mZoomValue);
- mCameraDevice.setParameters(mParameters);
- Parameters p = mCameraDevice.getParameters();
- if (p != null) return p.getZoom();
- return index;
- }
-
- @Override
- public int getCameraState() {
- return mCameraState;
- }
-
- @Override
- public void onQueueStatus(boolean full) {
- mUI.enableShutter(!full);
- }
-
- @Override
- public void onMediaSaveServiceConnected(MediaSaveService s) {
- // We set the listener only when both service and shutterbutton
- // are initialized.
- if (mFirstTimeInitialized) {
- s.setListener(this);
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
- int type = event.sensor.getType();
- float[] data;
- if (type == Sensor.TYPE_ACCELEROMETER) {
- data = mGData;
- } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
- data = mMData;
- } else {
- // we should not be here.
- return;
- }
- for (int i = 0; i < 3 ; i++) {
- data[i] = event.values[i];
- }
- float[] orientation = new float[3];
- SensorManager.getRotationMatrix(mR, null, mGData, mMData);
- SensorManager.getOrientation(mR, orientation);
- mHeading = (int) (orientation[0] * 180f / Math.PI) % 360;
- if (mHeading < 0) {
- mHeading += 360;
- }
- }
-
- @Override
- public void onSwitchMode(boolean toCamera) {
- mUI.onSwitchMode(toCamera);
- }
-
-/* Below is no longer needed, except to get rid of compile error
- * TODO: Remove these
- */
-
- // TODO: Delete this function after old camera code is removed
- @Override
- public void onRestorePreferencesClicked() {}
-
-}
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
deleted file mode 100644
index ef2722438..000000000
--- a/src/com/android/camera/PhotoUI.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.Camera.Face;
-import android.hardware.Camera.Size;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.TextureView;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLayoutChangeListener;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.widget.FrameLayout;
-import android.widget.FrameLayout.LayoutParams;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.android.camera.CameraPreference.OnPreferenceChangedListener;
-import com.android.camera.FocusOverlayManager.FocusUI;
-import com.android.camera.ui.AbstractSettingPopup;
-import com.android.camera.ui.CameraControls;
-import com.android.camera.ui.CameraRootView;
-import com.android.camera.ui.CameraSwitcher;
-import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
-import com.android.camera.ui.CountDownView;
-import com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
-import com.android.camera.ui.FaceView;
-import com.android.camera.ui.FocusIndicator;
-import com.android.camera.ui.PieRenderer;
-import com.android.camera.ui.PieRenderer.PieListener;
-import com.android.camera.ui.RenderOverlay;
-import com.android.camera.ui.ZoomRenderer;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.List;
-
-public class PhotoUI implements PieListener,
- PreviewGestures.SingleTapListener,
- FocusUI, TextureView.SurfaceTextureListener,
- LocationManager.Listener, CameraRootView.MyDisplayListener,
- CameraManager.CameraFaceDetectionCallback {
-
- private static final String TAG = "CAM_UI";
- private static final int UPDATE_TRANSFORM_MATRIX = 1;
- private static final int DOWN_SAMPLE_FACTOR = 4;
- private final AnimationManager mAnimationManager;
- private CameraActivity mActivity;
- private PhotoController mController;
- private PreviewGestures mGestures;
-
- private View mRootView;
- private Object mSurfaceTexture;
-
- private AbstractSettingPopup mPopup;
- private ShutterButton mShutterButton;
- private CountDownView mCountDownView;
-
- private FaceView mFaceView;
- private RenderOverlay mRenderOverlay;
- private View mReviewCancelButton;
- private View mReviewDoneButton;
- private View mReviewRetakeButton;
-
- private View mMenuButton;
- private View mBlocker;
- private PhotoMenu mMenu;
- private CameraSwitcher mSwitcher;
- private CameraControls mCameraControls;
- private AlertDialog mLocationDialog;
-
- // Small indicators which show the camera settings in the viewfinder.
- private OnScreenIndicators mOnScreenIndicators;
-
- private PieRenderer mPieRenderer;
- private ZoomRenderer mZoomRenderer;
- private Toast mNotSelectableToast;
-
- private int mZoomMax;
- private List<Integer> mZoomRatios;
-
- private int mPreviewWidth = 0;
- private int mPreviewHeight = 0;
- private float mSurfaceTextureUncroppedWidth;
- private float mSurfaceTextureUncroppedHeight;
-
- private ImageView mPreviewThumb;
- private View mFlashOverlay;
-
- private SurfaceTextureSizeChangedListener mSurfaceTextureSizeListener;
- private TextureView mTextureView;
- private Matrix mMatrix = null;
- private float mAspectRatio = 4f / 3f;
- private final Object mLock = new Object();
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case UPDATE_TRANSFORM_MATRIX:
- setTransformMatrix(mPreviewWidth, mPreviewHeight);
- break;
- default:
- break;
- }
- }
- };
-
- public interface SurfaceTextureSizeChangedListener {
- public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight);
- }
-
- private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
- int width = right - left;
- int height = bottom - top;
- // Full-screen screennail
- int w = width;
- int h = height;
- if (Util.getDisplayRotation(mActivity) % 180 != 0) {
- w = height;
- h = width;
- }
- if (mPreviewWidth != width || mPreviewHeight != height) {
- mPreviewWidth = width;
- mPreviewHeight = height;
- onScreenSizeChanged(width, height, w, h);
- mController.onScreenSizeChanged(width, height, w, h);
- }
- }
- };
-
- private class DecodeTask extends AsyncTask<Integer, Void, Bitmap> {
- private final byte [] mData;
-
- public DecodeTask(byte[] data) {
- mData = data;
- }
-
- @Override
- protected Bitmap doInBackground(Integer... params) {
- // Decode image in background.
- return Util.downSample(mData, DOWN_SAMPLE_FACTOR);
- }
-
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- mPreviewThumb.setImageBitmap(bitmap);
- mAnimationManager.startCaptureAnimation(mPreviewThumb);
- }
- }
-
- public PhotoUI(CameraActivity activity, PhotoController controller, View parent) {
- mActivity = activity;
- mController = controller;
- mRootView = parent;
-
- mActivity.getLayoutInflater().inflate(R.layout.photo_module,
- (ViewGroup) mRootView, true);
- mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);
- mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);
- // display the view
- mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
- mTextureView.setSurfaceTextureListener(this);
- mTextureView.addOnLayoutChangeListener(mLayoutListener);
- initIndicators();
-
- mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
- mSwitcher = (CameraSwitcher) mRootView.findViewById(R.id.camera_switcher);
- mSwitcher.setCurrentIndex(CameraSwitcher.PHOTO_MODULE_INDEX);
- mSwitcher.setSwitchListener((CameraSwitchListener) mActivity);
- mMenuButton = mRootView.findViewById(R.id.menu);
- if (ApiHelper.HAS_FACE_DETECTION) {
- ViewStub faceViewStub = (ViewStub) mRootView
- .findViewById(R.id.face_view_stub);
- if (faceViewStub != null) {
- faceViewStub.inflate();
- mFaceView = (FaceView) mRootView.findViewById(R.id.face_view);
- setSurfaceTextureSizeChangedListener(
- (SurfaceTextureSizeChangedListener) mFaceView);
- }
- }
- mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
- ((CameraRootView) mRootView).setDisplayChangeListener(this);
- mAnimationManager = new AnimationManager();
- }
-
- public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) {
- setTransformMatrix(width, height);
- }
-
- public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {
- mSurfaceTextureSizeListener = listener;
- }
-
- public void setPreviewSize(Size size) {
- int width = size.width;
- int height = size.height;
- if (width == 0 || height == 0) {
- Log.w(TAG, "Preview size should not be 0.");
- return;
- }
- if (width > height) {
- mAspectRatio = (float) width / height;
- } else {
- mAspectRatio = (float) height / width;
- }
- mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
- }
-
- private void setTransformMatrix(int width, int height) {
- mMatrix = mTextureView.getTransform(mMatrix);
- int orientation = Util.getDisplayRotation(mActivity);
- float scaleX = 1f, scaleY = 1f;
- float scaledTextureWidth, scaledTextureHeight;
- if (width > height) {
- scaledTextureWidth = Math.max(width,
- (int) (height * mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int)(width / mAspectRatio));
- } else {
- scaledTextureWidth = Math.max(width,
- (int) (height / mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int) (width * mAspectRatio));
- }
-
- if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
- mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
- mSurfaceTextureUncroppedWidth = scaledTextureWidth;
- mSurfaceTextureUncroppedHeight = scaledTextureHeight;
- if (mSurfaceTextureSizeListener != null) {
- mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
- (int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight);
- }
- }
- scaleX = scaledTextureWidth / width;
- scaleY = scaledTextureHeight / height;
- mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2);
- mTextureView.setTransform(mMatrix);
- }
-
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- synchronized (mLock) {
- mSurfaceTexture = surface;
- mLock.notifyAll();
- }
- }
-
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- // Ignored, Camera does all the work for us
- }
-
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- mSurfaceTexture = null;
- mController.stopPreview();
- Log.w(TAG, "surfaceTexture is destroyed");
- return true;
- }
-
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- // Invoked every time there's a new Camera preview frame
- }
-
- public View getRootView() {
- return mRootView;
- }
-
- private void initIndicators() {
- mOnScreenIndicators = new OnScreenIndicators(mActivity,
- mRootView.findViewById(R.id.on_screen_indicators));
- }
-
- public void onCameraOpened(PreferenceGroup prefGroup, ComboPreferences prefs,
- Camera.Parameters params, OnPreferenceChangedListener listener) {
- if (mPieRenderer == null) {
- mPieRenderer = new PieRenderer(mActivity);
- mPieRenderer.setPieListener(this);
- mRenderOverlay.addRenderer(mPieRenderer);
- }
-
- if (mMenu == null) {
- mMenu = new PhotoMenu(mActivity, this, mPieRenderer);
- mMenu.setListener(listener);
- }
- mMenu.initialize(prefGroup);
-
- if (mZoomRenderer == null) {
- mZoomRenderer = new ZoomRenderer(mActivity);
- mRenderOverlay.addRenderer(mZoomRenderer);
- }
-
- if (mGestures == null) {
- // this will handle gesture disambiguation and dispatching
- mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer);
- mRenderOverlay.setGestures(mGestures);
- }
- mGestures.setZoomEnabled(params.isZoomSupported());
- mGestures.setRenderOverlay(mRenderOverlay);
- mRenderOverlay.requestLayout();
-
- initializeZoom(params);
- updateOnScreenIndicators(params, prefGroup, prefs);
- }
-
- public void animateCapture(final byte[] jpegData) {
- // Decode jpeg byte array and then animate the jpeg
- DecodeTask task = new DecodeTask(jpegData);
- task.execute();
- }
-
- private void openMenu() {
- if (mPieRenderer != null) {
- // If autofocus is not finished, cancel autofocus so that the
- // subsequent touch can be handled by PreviewGestures
- if (mController.getCameraState() == PhotoController.FOCUSING) {
- mController.cancelAutoFocus();
- }
- mPieRenderer.showInCenter();
- }
- }
-
- public void initializeControlByIntent() {
- mBlocker = mRootView.findViewById(R.id.blocker);
- mPreviewThumb = (ImageView) mRootView.findViewById(R.id.preview_thumb);
- mPreviewThumb.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO: go to filmstrip
- // mActivity.gotoGallery();
- }
- });
- mMenuButton = mRootView.findViewById(R.id.menu);
- mMenuButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- openMenu();
- }
- });
- if (mController.isImageCaptureIntent()) {
- hideSwitcher();
- ViewGroup cameraControls = (ViewGroup) mRootView.findViewById(R.id.camera_controls);
- mActivity.getLayoutInflater().inflate(R.layout.review_module_control, cameraControls);
-
- mReviewDoneButton = mRootView.findViewById(R.id.btn_done);
- mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel);
- mReviewRetakeButton = mRootView.findViewById(R.id.btn_retake);
- mReviewCancelButton.setVisibility(View.VISIBLE);
-
- mReviewDoneButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onCaptureDone();
- }
- });
- mReviewCancelButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onCaptureCancelled();
- }
- });
-
- mReviewRetakeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onCaptureRetake();
- }
- });
- }
- }
-
- public void hideUI() {
- mCameraControls.setVisibility(View.INVISIBLE);
- mSwitcher.closePopup();
- }
-
- public void showUI() {
- mCameraControls.setVisibility(View.VISIBLE);
- }
-
- public void hideSwitcher() {
- mSwitcher.closePopup();
- mSwitcher.setVisibility(View.INVISIBLE);
- }
-
- public void showSwitcher() {
- mSwitcher.setVisibility(View.VISIBLE);
- }
- // called from onResume but only the first time
- public void initializeFirstTime() {
- // Initialize shutter button.
- mShutterButton.setImageResource(R.drawable.btn_new_shutter);
- mShutterButton.setOnShutterButtonListener(mController);
- mShutterButton.setVisibility(View.VISIBLE);
- }
-
- // called from onResume every other time
- public void initializeSecondTime(Camera.Parameters params) {
- initializeZoom(params);
- if (mController.isImageCaptureIntent()) {
- hidePostCaptureAlert();
- }
- if (mMenu != null) {
- mMenu.reloadPreferences();
- }
- }
-
- public void showLocationDialog() {
- mLocationDialog = new AlertDialog.Builder(mActivity)
- .setTitle(R.string.remember_location_title)
- .setMessage(R.string.remember_location_prompt)
- .setPositiveButton(R.string.remember_location_yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int arg1) {
- mController.enableRecordingLocation(true);
- mLocationDialog = null;
- }
- })
- .setNegativeButton(R.string.remember_location_no,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int arg1) {
- dialog.cancel();
- }
- })
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- mController.enableRecordingLocation(false);
- mLocationDialog = null;
- }
- })
- .show();
- }
-
- public void initializeZoom(Camera.Parameters params) {
- if ((params == null) || !params.isZoomSupported()
- || (mZoomRenderer == null)) return;
- mZoomMax = params.getMaxZoom();
- mZoomRatios = params.getZoomRatios();
- // Currently we use immediate zoom for fast zooming to get better UX and
- // there is no plan to take advantage of the smooth zoom.
- if (mZoomRenderer != null) {
- mZoomRenderer.setZoomMax(mZoomMax);
- mZoomRenderer.setZoom(params.getZoom());
- mZoomRenderer.setZoomValue(mZoomRatios.get(params.getZoom()));
- mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener());
- }
- }
-
- public void showGpsOnScreenIndicator(boolean hasSignal) { }
-
- public void hideGpsOnScreenIndicator() { }
-
- public void overrideSettings(final String ... keyvalues) {
- mMenu.overrideSettings(keyvalues);
- }
-
- public void updateOnScreenIndicators(Camera.Parameters params,
- PreferenceGroup group, ComboPreferences prefs) {
- if (params == null) return;
- mOnScreenIndicators.updateSceneOnScreenIndicator(params.getSceneMode());
- mOnScreenIndicators.updateExposureOnScreenIndicator(params,
- CameraSettings.readExposure(prefs));
- mOnScreenIndicators.updateFlashOnScreenIndicator(params.getFlashMode());
- int wbIndex = 2;
- ListPreference pref = group.findPreference(CameraSettings.KEY_WHITE_BALANCE);
- if (pref != null) {
- wbIndex = pref.getCurrentIndex();
- }
- mOnScreenIndicators.updateWBIndicator(wbIndex);
- boolean location = RecordLocationPreference.get(
- prefs, mActivity.getContentResolver());
- mOnScreenIndicators.updateLocationIndicator(location);
- }
-
- public void setCameraState(int state) {
- }
-
- public void animateFlash() {
- mAnimationManager.startFlashAnimation(mFlashOverlay);
- }
-
- public void enableGestures(boolean enable) {
- if (mGestures != null) {
- mGestures.setEnabled(enable);
- }
- }
-
- // forward from preview gestures to controller
- @Override
- public void onSingleTapUp(View view, int x, int y) {
- mController.onSingleTapUp(view, x, y);
- }
-
- public boolean onBackPressed() {
- if (mPieRenderer != null && mPieRenderer.showsItems()) {
- mPieRenderer.hide();
- return true;
- }
- // In image capture mode, back button should:
- // 1) if there is any popup, dismiss them, 2) otherwise, get out of
- // image capture
- if (mController.isImageCaptureIntent()) {
- if (!removeTopLevelPopup()) {
- // no popup to dismiss, cancel image capture
- mController.onCaptureCancelled();
- }
- return true;
- } else if (!mController.isCameraIdle()) {
- // ignore backs while we're taking a picture
- return true;
- } else {
- return removeTopLevelPopup();
- }
- }
-
- public void onSwitchMode(boolean toCamera) {
- if (toCamera) {
- showUI();
- } else {
- hideUI();
- }
- if (mFaceView != null) {
- mFaceView.setBlockDraw(!toCamera);
- }
- if (mPopup != null) {
- dismissPopup(toCamera);
- }
- if (mGestures != null) {
- mGestures.setEnabled(toCamera);
- }
- if (mRenderOverlay != null) {
- // this can not happen in capture mode
- mRenderOverlay.setVisibility(toCamera ? View.VISIBLE : View.GONE);
- }
- if (mPieRenderer != null) {
- mPieRenderer.setBlockFocus(!toCamera);
- }
- setShowMenu(toCamera);
- if (!toCamera && mCountDownView != null) mCountDownView.cancelCountDown();
- }
-
- public boolean removeTopLevelPopup() {
- // Remove the top level popup or dialog box and return true if there's any
- if (mPopup != null) {
- dismissPopup();
- return true;
- }
- return false;
- }
-
- public void showPopup(AbstractSettingPopup popup) {
- hideUI();
- mBlocker.setVisibility(View.INVISIBLE);
- setShowMenu(false);
- mPopup = popup;
- mPopup.setVisibility(View.VISIBLE);
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER;
- ((FrameLayout) mRootView).addView(mPopup, lp);
- }
-
- public void dismissPopup() {
- dismissPopup(true);
- }
-
- private void dismissPopup(boolean fullScreen) {
- if (fullScreen) {
- showUI();
- mBlocker.setVisibility(View.VISIBLE);
- }
- setShowMenu(fullScreen);
- if (mPopup != null) {
- ((FrameLayout) mRootView).removeView(mPopup);
- mPopup = null;
- }
- mMenu.popupDismissed();
- }
-
- public void onShowSwitcherPopup() {
- if (mPieRenderer != null && mPieRenderer.showsItems()) {
- mPieRenderer.hide();
- }
- }
-
- private void setShowMenu(boolean show) {
- if (mOnScreenIndicators != null) {
- mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- if (mMenuButton != null) {
- mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- }
-
- public boolean collapseCameraControls() {
- // Remove all the popups/dialog boxes
- boolean ret = false;
- if (mPopup != null) {
- dismissPopup();
- ret = true;
- }
- onShowSwitcherPopup();
- return ret;
- }
-
- protected void showPostCaptureAlert() {
- mOnScreenIndicators.setVisibility(View.GONE);
- mMenuButton.setVisibility(View.GONE);
- Util.fadeIn(mReviewDoneButton);
- mShutterButton.setVisibility(View.INVISIBLE);
- Util.fadeIn(mReviewRetakeButton);
- pauseFaceDetection();
- }
-
- protected void hidePostCaptureAlert() {
- mOnScreenIndicators.setVisibility(View.VISIBLE);
- mMenuButton.setVisibility(View.VISIBLE);
- Util.fadeOut(mReviewDoneButton);
- mShutterButton.setVisibility(View.VISIBLE);
- Util.fadeOut(mReviewRetakeButton);
- resumeFaceDetection();
- }
-
- public void setDisplayOrientation(int orientation) {
- if (mFaceView != null) {
- mFaceView.setDisplayOrientation(orientation);
- }
- }
-
- // shutter button handling
-
- public boolean isShutterPressed() {
- return mShutterButton.isPressed();
- }
-
- public void enableShutter(boolean enabled) {
- if (mShutterButton != null) {
- mShutterButton.setEnabled(enabled);
- }
- }
-
- public void pressShutterButton() {
- if (mShutterButton.isInTouchMode()) {
- mShutterButton.requestFocusFromTouch();
- } else {
- mShutterButton.requestFocus();
- }
- mShutterButton.setPressed(true);
- }
-
- private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener {
- @Override
- public void onZoomValueChanged(int index) {
- int newZoom = mController.onZoomChanged(index);
- if (mZoomRenderer != null) {
- mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom));
- }
- }
-
- @Override
- public void onZoomStart() {
- if (mPieRenderer != null) {
- mPieRenderer.setBlockFocus(true);
- }
- }
-
- @Override
- public void onZoomEnd() {
- if (mPieRenderer != null) {
- mPieRenderer.setBlockFocus(false);
- }
- }
- }
-
- @Override
- public void onPieOpened(int centerX, int centerY) {
- setSwipingEnabled(false);
- dismissPopup();
- if (mFaceView != null) {
- mFaceView.setBlockDraw(true);
- }
- }
-
- @Override
- public void onPieClosed() {
- setSwipingEnabled(true);
- if (mFaceView != null) {
- mFaceView.setBlockDraw(false);
- }
- }
-
- public void setSwipingEnabled(boolean enable) {
- mActivity.setSwipingEnabled(enable);
- }
-
- public Object getSurfaceTexture() {
- synchronized (mLock) {
- if (mSurfaceTexture == null) {
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- Log.w(TAG, "Unexpected interruption when waiting to get surface texture");
- }
- }
- }
- return mSurfaceTexture;
- }
-
- // Countdown timer
-
- private void initializeCountDown() {
- mActivity.getLayoutInflater().inflate(R.layout.count_down_to_capture,
- (ViewGroup) mRootView, true);
- mCountDownView = (CountDownView) (mRootView.findViewById(R.id.count_down_to_capture));
- mCountDownView.setCountDownFinishedListener((OnCountDownFinishedListener) mController);
- }
-
- public boolean isCountingDown() {
- return mCountDownView != null && mCountDownView.isCountingDown();
- }
-
- public void cancelCountDown() {
- if (mCountDownView == null) return;
- mCountDownView.cancelCountDown();
- }
-
- public void startCountDown(int sec, boolean playSound) {
- if (mCountDownView == null) initializeCountDown();
- mCountDownView.startCountDown(sec, playSound);
- }
-
- public void showPreferencesToast() {
- if (mNotSelectableToast == null) {
- String str = mActivity.getResources().getString(R.string.not_selectable_in_scene_mode);
- mNotSelectableToast = Toast.makeText(mActivity, str, Toast.LENGTH_SHORT);
- }
- mNotSelectableToast.show();
- }
-
- public void onPause() {
- cancelCountDown();
-
- // Clear UI.
- collapseCameraControls();
- if (mFaceView != null) mFaceView.clear();
-
- if (mLocationDialog != null && mLocationDialog.isShowing()) {
- mLocationDialog.dismiss();
- }
- mLocationDialog = null;
- mPreviewWidth = 0;
- mPreviewHeight = 0;
- }
-
- // focus UI implementation
-
- private FocusIndicator getFocusIndicator() {
- return (mFaceView != null && mFaceView.faceExists()) ? mFaceView : mPieRenderer;
- }
-
- @Override
- public boolean hasFaces() {
- return (mFaceView != null && mFaceView.faceExists());
- }
-
- public void clearFaces() {
- if (mFaceView != null) mFaceView.clear();
- }
-
- @Override
- public void clearFocus() {
- FocusIndicator indicator = getFocusIndicator();
- if (indicator != null) indicator.clear();
- }
-
- @Override
- public void setFocusPosition(int x, int y) {
- mPieRenderer.setFocus(x, y);
- }
-
- @Override
- public void onFocusStarted() {
- getFocusIndicator().showStart();
- }
-
- @Override
- public void onFocusSucceeded(boolean timeout) {
- getFocusIndicator().showSuccess(timeout);
- }
-
- @Override
- public void onFocusFailed(boolean timeout) {
- getFocusIndicator().showFail(timeout);
- }
-
- @Override
- public void pauseFaceDetection() {
- if (mFaceView != null) mFaceView.pause();
- }
-
- @Override
- public void resumeFaceDetection() {
- if (mFaceView != null) mFaceView.resume();
- }
-
- public void onStartFaceDetection(int orientation, boolean mirror) {
- mFaceView.clear();
- mFaceView.setVisibility(View.VISIBLE);
- mFaceView.setDisplayOrientation(orientation);
- mFaceView.setMirror(mirror);
- mFaceView.resume();
- }
-
- @Override
- public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) {
- mFaceView.setFaces(faces);
- }
-
- public void onDisplayChanged() {
- mCameraControls.checkLayoutFlip();
- mController.updateCameraOrientation();
- }
-
-}
diff --git a/src/com/android/camera/PieController.java b/src/com/android/camera/PieController.java
deleted file mode 100644
index 3cbcb4bf5..000000000
--- a/src/com/android/camera/PieController.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.Activity;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-
-import com.android.camera.CameraPreference.OnPreferenceChangedListener;
-import com.android.camera.drawable.TextDrawable;
-import com.android.camera.ui.PieItem;
-import com.android.camera.ui.PieItem.OnClickListener;
-import com.android.camera.ui.PieRenderer;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PieController {
-
- private static String TAG = "CAM_piecontrol";
-
- protected static final int MODE_PHOTO = 0;
- protected static final int MODE_VIDEO = 1;
-
- protected static float CENTER = (float) Math.PI / 2;
- protected static final float SWEEP = 0.06f;
-
- protected Activity mActivity;
- protected PreferenceGroup mPreferenceGroup;
- protected OnPreferenceChangedListener mListener;
- protected PieRenderer mRenderer;
- private List<IconListPreference> mPreferences;
- private Map<IconListPreference, PieItem> mPreferenceMap;
- private Map<IconListPreference, String> mOverrides;
-
- public void setListener(OnPreferenceChangedListener listener) {
- mListener = listener;
- }
-
- public PieController(Activity activity, PieRenderer pie) {
- mActivity = activity;
- mRenderer = pie;
- mPreferences = new ArrayList<IconListPreference>();
- mPreferenceMap = new HashMap<IconListPreference, PieItem>();
- mOverrides = new HashMap<IconListPreference, String>();
- }
-
- public void initialize(PreferenceGroup group) {
- mRenderer.clearItems();
- mPreferenceMap.clear();
- setPreferenceGroup(group);
- }
-
- public void onSettingChanged(ListPreference pref) {
- if (mListener != null) {
- mListener.onSharedPreferenceChanged();
- }
- }
-
- protected void setCameraId(int cameraId) {
- ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID);
- pref.setValue("" + cameraId);
- }
-
- protected PieItem makeItem(int resId) {
- // We need a mutable version as we change the alpha
- Drawable d = mActivity.getResources().getDrawable(resId).mutate();
- return new PieItem(d, 0);
- }
-
- protected PieItem makeItem(CharSequence value) {
- TextDrawable drawable = new TextDrawable(mActivity.getResources(), value);
- return new PieItem(drawable, 0);
- }
-
- public PieItem makeItem(String prefKey) {
- final IconListPreference pref =
- (IconListPreference) mPreferenceGroup.findPreference(prefKey);
- if (pref == null) return null;
- int[] iconIds = pref.getLargeIconIds();
- int resid = -1;
- if (!pref.getUseSingleIcon() && iconIds != null) {
- // Each entry has a corresponding icon.
- int index = pref.findIndexOfValue(pref.getValue());
- resid = iconIds[index];
- } else {
- // The preference only has a single icon to represent it.
- resid = pref.getSingleIcon();
- }
- PieItem item = makeItem(resid);
- item.setLabel(pref.getTitle().toUpperCase());
- mPreferences.add(pref);
- mPreferenceMap.put(pref, item);
- int nOfEntries = pref.getEntries().length;
- if (nOfEntries > 1) {
- for (int i = 0; i < nOfEntries; i++) {
- PieItem inner = null;
- if (iconIds != null) {
- inner = makeItem(iconIds[i]);
- } else {
- inner = makeItem(pref.getEntries()[i]);
- }
- inner.setLabel(pref.getLabels()[i]);
- item.addItem(inner);
- final int index = i;
- inner.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- pref.setValueIndex(index);
- reloadPreference(pref);
- onSettingChanged(pref);
- }
- });
- }
- }
- return item;
- }
-
- public PieItem makeSwitchItem(final String prefKey, boolean addListener) {
- final IconListPreference pref =
- (IconListPreference) mPreferenceGroup.findPreference(prefKey);
- if (pref == null) return null;
- int[] iconIds = pref.getLargeIconIds();
- int resid = -1;
- int index = pref.findIndexOfValue(pref.getValue());
- if (!pref.getUseSingleIcon() && iconIds != null) {
- // Each entry has a corresponding icon.
- resid = iconIds[index];
- } else {
- // The preference only has a single icon to represent it.
- resid = pref.getSingleIcon();
- }
- PieItem item = makeItem(resid);
- item.setLabel(pref.getLabels()[index]);
- item.setImageResource(mActivity, resid);
- mPreferences.add(pref);
- mPreferenceMap.put(pref, item);
- if (addListener) {
- final PieItem fitem = item;
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- IconListPreference pref = (IconListPreference) mPreferenceGroup
- .findPreference(prefKey);
- int index = pref.findIndexOfValue(pref.getValue());
- CharSequence[] values = pref.getEntryValues();
- index = (index + 1) % values.length;
- pref.setValueIndex(index);
- fitem.setLabel(pref.getLabels()[index]);
- fitem.setImageResource(mActivity,
- ((IconListPreference) pref).getLargeIconIds()[index]);
- reloadPreference(pref);
- onSettingChanged(pref);
- }
- });
- }
- return item;
- }
-
-
- public PieItem makeDialItem(ListPreference pref, int iconId, float center, float sweep) {
- PieItem item = makeItem(iconId);
- return item;
- }
-
- public void addItem(String prefKey) {
- PieItem item = makeItem(prefKey);
- mRenderer.addItem(item);
- }
-
- public void updateItem(PieItem item, String prefKey) {
- IconListPreference pref = (IconListPreference) mPreferenceGroup
- .findPreference(prefKey);
- if (pref != null) {
- int index = pref.findIndexOfValue(pref.getValue());
- item.setLabel(pref.getLabels()[index]);
- item.setImageResource(mActivity,
- ((IconListPreference) pref).getLargeIconIds()[index]);
- }
- }
-
- public void setPreferenceGroup(PreferenceGroup group) {
- mPreferenceGroup = group;
- }
-
- public void reloadPreferences() {
- mPreferenceGroup.reloadValue();
- for (IconListPreference pref : mPreferenceMap.keySet()) {
- reloadPreference(pref);
- }
- }
-
- private void reloadPreference(IconListPreference pref) {
- if (pref.getUseSingleIcon()) return;
- PieItem item = mPreferenceMap.get(pref);
- String overrideValue = mOverrides.get(pref);
- int[] iconIds = pref.getLargeIconIds();
- if (iconIds != null) {
- // Each entry has a corresponding icon.
- int index;
- if (overrideValue == null) {
- index = pref.findIndexOfValue(pref.getValue());
- } else {
- index = pref.findIndexOfValue(overrideValue);
- if (index == -1) {
- // Avoid the crash if camera driver has bugs.
- Log.e(TAG, "Fail to find override value=" + overrideValue);
- pref.print();
- return;
- }
- }
- item.setImageResource(mActivity, iconIds[index]);
- } else {
- // The preference only has a single icon to represent it.
- item.setImageResource(mActivity, pref.getSingleIcon());
- }
- }
-
- // Scene mode may override other camera settings (ex: flash mode).
- public void overrideSettings(final String ... keyvalues) {
- if (keyvalues.length % 2 != 0) {
- throw new IllegalArgumentException();
- }
- for (IconListPreference pref : mPreferenceMap.keySet()) {
- override(pref, keyvalues);
- }
- }
-
- private void override(IconListPreference pref, final String ... keyvalues) {
- mOverrides.remove(pref);
- for (int i = 0; i < keyvalues.length; i += 2) {
- String key = keyvalues[i];
- String value = keyvalues[i + 1];
- if (key.equals(pref.getKey())) {
- mOverrides.put(pref, value);
- PieItem item = mPreferenceMap.get(pref);
- item.setEnabled(value == null);
- break;
- }
- }
- reloadPreference(pref);
- }
-}
diff --git a/src/com/android/camera/PreferenceGroup.java b/src/com/android/camera/PreferenceGroup.java
deleted file mode 100644
index 4d0519f4e..000000000
--- a/src/com/android/camera/PreferenceGroup.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import java.util.ArrayList;
-
-/**
- * A collection of <code>CameraPreference</code>s. It may contain other
- * <code>PreferenceGroup</code> and form a tree structure.
- */
-public class PreferenceGroup extends CameraPreference {
- private ArrayList<CameraPreference> list =
- new ArrayList<CameraPreference>();
-
- public PreferenceGroup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void addChild(CameraPreference child) {
- list.add(child);
- }
-
- public void removePreference(int index) {
- list.remove(index);
- }
-
- public CameraPreference get(int index) {
- return list.get(index);
- }
-
- public int size() {
- return list.size();
- }
-
- @Override
- public void reloadValue() {
- for (CameraPreference pref : list) {
- pref.reloadValue();
- }
- }
-
- /**
- * Finds the preference with the given key recursively. Returns
- * <code>null</code> if cannot find.
- */
- public ListPreference findPreference(String key) {
- // Find a leaf preference with the given key. Currently, the base
- // type of all "leaf" preference is "ListPreference". If we add some
- // other types later, we need to change the code.
- for (CameraPreference pref : list) {
- if (pref instanceof ListPreference) {
- ListPreference listPref = (ListPreference) pref;
- if(listPref.getKey().equals(key)) return listPref;
- } else if(pref instanceof PreferenceGroup) {
- ListPreference listPref =
- ((PreferenceGroup) pref).findPreference(key);
- if (listPref != null) return listPref;
- }
- }
- return null;
- }
-}
diff --git a/src/com/android/camera/PreferenceInflater.java b/src/com/android/camera/PreferenceInflater.java
deleted file mode 100644
index 231c9833b..000000000
--- a/src/com/android/camera/PreferenceInflater.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Xml;
-import android.view.InflateException;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Inflate <code>CameraPreference</code> from XML resource.
- */
-public class PreferenceInflater {
- private static final String PACKAGE_NAME =
- PreferenceInflater.class.getPackage().getName();
-
- private static final Class<?>[] CTOR_SIGNATURE =
- new Class[] {Context.class, AttributeSet.class};
- private static final HashMap<String, Constructor<?>> sConstructorMap =
- new HashMap<String, Constructor<?>>();
-
- private Context mContext;
-
- public PreferenceInflater(Context context) {
- mContext = context;
- }
-
- public CameraPreference inflate(int resId) {
- return inflate(mContext.getResources().getXml(resId));
- }
-
- private CameraPreference newPreference(String tagName, Object[] args) {
- String name = PACKAGE_NAME + "." + tagName;
- Constructor<?> constructor = sConstructorMap.get(name);
- try {
- if (constructor == null) {
- // Class not found in the cache, see if it's real, and try to
- // add it
- Class<?> clazz = mContext.getClassLoader().loadClass(name);
- constructor = clazz.getConstructor(CTOR_SIGNATURE);
- sConstructorMap.put(name, constructor);
- }
- return (CameraPreference) constructor.newInstance(args);
- } catch (NoSuchMethodException e) {
- throw new InflateException("Error inflating class " + name, e);
- } catch (ClassNotFoundException e) {
- throw new InflateException("No such class: " + name, e);
- } catch (Exception e) {
- throw new InflateException("While create instance of" + name, e);
- }
- }
-
- private CameraPreference inflate(XmlPullParser parser) {
-
- AttributeSet attrs = Xml.asAttributeSet(parser);
- ArrayList<CameraPreference> list = new ArrayList<CameraPreference>();
- Object args[] = new Object[]{mContext, attrs};
-
- try {
- for (int type = parser.next();
- type != XmlPullParser.END_DOCUMENT; type = parser.next()) {
- if (type != XmlPullParser.START_TAG) continue;
- CameraPreference pref = newPreference(parser.getName(), args);
-
- int depth = parser.getDepth();
- if (depth > list.size()) {
- list.add(pref);
- } else {
- list.set(depth - 1, pref);
- }
- if (depth > 1) {
- ((PreferenceGroup) list.get(depth - 2)).addChild(pref);
- }
- }
-
- if (list.size() == 0) {
- throw new InflateException("No root element found");
- }
- return list.get(0);
- } catch (XmlPullParserException e) {
- throw new InflateException(e);
- } catch (IOException e) {
- throw new InflateException(parser.getPositionDescription(), e);
- }
- }
-}
diff --git a/src/com/android/camera/PreviewFrameLayout.java b/src/com/android/camera/PreviewFrameLayout.java
deleted file mode 100644
index 03ef91c60..000000000
--- a/src/com/android/camera/PreviewFrameLayout.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewStub;
-import android.widget.RelativeLayout;
-
-import com.android.camera.ui.LayoutChangeHelper;
-import com.android.camera.ui.LayoutChangeNotifier;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-/**
- * A layout which handles the preview aspect ratio.
- */
-public class PreviewFrameLayout extends RelativeLayout implements LayoutChangeNotifier {
-
- private static final String TAG = "CAM_preview";
-
- /** A callback to be invoked when the preview frame's size changes. */
- public interface OnSizeChangedListener {
- public void onSizeChanged(int width, int height);
- }
-
- private double mAspectRatio;
- private View mBorder;
- private OnSizeChangedListener mListener;
- private LayoutChangeHelper mLayoutChangeHelper;
-
- public PreviewFrameLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- setAspectRatio(4.0 / 3.0);
- mLayoutChangeHelper = new LayoutChangeHelper(this);
- }
-
- @Override
- protected void onFinishInflate() {
- mBorder = findViewById(R.id.preview_border);
- }
-
- public void setAspectRatio(double ratio) {
- if (ratio <= 0.0) throw new IllegalArgumentException();
-
- if (mAspectRatio != ratio) {
- mAspectRatio = ratio;
- requestLayout();
- }
- }
-
- public void showBorder(boolean enabled) {
- mBorder.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
- }
-
- public void fadeOutBorder() {
- Util.fadeOut(mBorder);
- }
-
- @Override
- protected void onMeasure(int widthSpec, int heightSpec) {
- int previewWidth = MeasureSpec.getSize(widthSpec);
- int previewHeight = MeasureSpec.getSize(heightSpec);
-
- if (!ApiHelper.HAS_SURFACE_TEXTURE) {
- // Get the padding of the border background.
- int hPadding = getPaddingLeft() + getPaddingRight();
- int vPadding = getPaddingTop() + getPaddingBottom();
-
- // Resize the preview frame with correct aspect ratio.
- previewWidth -= hPadding;
- previewHeight -= vPadding;
-
- boolean widthLonger = previewWidth > previewHeight;
- int longSide = (widthLonger ? previewWidth : previewHeight);
- int shortSide = (widthLonger ? previewHeight : previewWidth);
- if (longSide > shortSide * mAspectRatio) {
- longSide = (int) ((double) shortSide * mAspectRatio);
- } else {
- shortSide = (int) ((double) longSide / mAspectRatio);
- }
- if (widthLonger) {
- previewWidth = longSide;
- previewHeight = shortSide;
- } else {
- previewWidth = shortSide;
- previewHeight = longSide;
- }
-
- // Add the padding of the border.
- previewWidth += hPadding;
- previewHeight += vPadding;
- }
-
- // Ask children to follow the new preview dimension.
- super.onMeasure(MeasureSpec.makeMeasureSpec(previewWidth, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(previewHeight, MeasureSpec.EXACTLY));
- }
-
- public void setOnSizeChangedListener(OnSizeChangedListener listener) {
- mListener = listener;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (mListener != null) mListener.onSizeChanged(w, h);
- }
-
- @Override
- public void setOnLayoutChangeListener(
- LayoutChangeNotifier.Listener listener) {
- mLayoutChangeHelper.setOnLayoutChangeListener(listener);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- mLayoutChangeHelper.onLayout(changed, l, t, r, b);
- }
-}
diff --git a/src/com/android/camera/PreviewGestures.java b/src/com/android/camera/PreviewGestures.java
deleted file mode 100644
index 466172b7c..000000000
--- a/src/com/android/camera/PreviewGestures.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.View;
-
-import com.android.camera.ui.PieRenderer;
-import com.android.camera.ui.RenderOverlay;
-import com.android.camera.ui.ZoomRenderer;
-
-/* PreviewGestures disambiguates touch events received on RenderOverlay
- * and dispatch them to the proper recipient (i.e. zoom renderer or pie renderer).
- * Touch events on CameraControls will be handled by framework.
- * */
-public class PreviewGestures
- implements ScaleGestureDetector.OnScaleGestureListener {
-
- private static final String TAG = "CAM_gestures";
-
- private static final int MODE_NONE = 0;
- private static final int MODE_ZOOM = 2;
-
- public static final int DIR_UP = 0;
- public static final int DIR_DOWN = 1;
- public static final int DIR_LEFT = 2;
- public static final int DIR_RIGHT = 3;
-
- private SingleTapListener mTapListener;
- private RenderOverlay mOverlay;
- private PieRenderer mPie;
- private ZoomRenderer mZoom;
- private MotionEvent mDown;
- private MotionEvent mCurrent;
- private ScaleGestureDetector mScale;
- private int mMode;
- private boolean mZoomEnabled;
- private boolean mEnabled;
- private boolean mZoomOnly;
- private GestureDetector mGestureDetector;
-
- private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() {
- @Override
- public void onLongPress (MotionEvent e) {
- // Open pie
- if (!mZoomOnly && mPie != null && !mPie.showsItems()) {
- openPie();
- }
- }
-
- @Override
- public boolean onSingleTapUp (MotionEvent e) {
- // Tap to focus when pie is not open
- if (mPie == null || !mPie.showsItems()) {
- mTapListener.onSingleTapUp(null, (int) e.getX(), (int) e.getY());
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- if (mZoomOnly || mMode == MODE_ZOOM) return false;
- int deltaX = (int) (e1.getX() - e2.getX());
- int deltaY = (int) (e1.getY() - e2.getY());
- if (deltaY > 2 * deltaX && deltaY > -2 * deltaX) {
- // Open pie on swipe up
- if (mPie != null && !mPie.showsItems()) {
- openPie();
- return true;
- }
- }
- return false;
- }
- };
-
- public interface SingleTapListener {
- public void onSingleTapUp(View v, int x, int y);
- }
-
- public PreviewGestures(CameraActivity ctx, SingleTapListener tapListener,
- ZoomRenderer zoom, PieRenderer pie) {
- mTapListener = tapListener;
- mPie = pie;
- mZoom = zoom;
- mMode = MODE_NONE;
- mScale = new ScaleGestureDetector(ctx, this);
- mEnabled = true;
- mGestureDetector = new GestureDetector(mGestureListener);
- }
-
- public void setRenderOverlay(RenderOverlay overlay) {
- mOverlay = overlay;
- }
-
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
- public void setZoomEnabled(boolean enable) {
- mZoomEnabled = enable;
- }
-
- public void setZoomOnly(boolean zoom) {
- mZoomOnly = zoom;
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
-
- public boolean dispatchTouch(MotionEvent m) {
- if (!mEnabled) {
- return false;
- }
- mCurrent = m;
- if (MotionEvent.ACTION_DOWN == m.getActionMasked()) {
- mMode = MODE_NONE;
- mDown = MotionEvent.obtain(m);
- }
-
- // If pie is open, redirects all the touch events to pie.
- if (mPie != null && mPie.isOpen()) {
- return sendToPie(m);
- }
-
- // If pie is not open, send touch events to gesture detector and scale
- // listener to recognize the gesture.
- mGestureDetector.onTouchEvent(m);
- if (mZoom != null) {
- mScale.onTouchEvent(m);
- if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) {
- mMode = MODE_ZOOM;
- if (mZoomEnabled) {
- // Start showing zoom UI as soon as there is a second finger down
- mZoom.onScaleBegin(mScale);
- }
- } else if (MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) {
- mZoom.onScaleEnd(mScale);
- }
- }
- return true;
- }
-
- private MotionEvent makeCancelEvent(MotionEvent m) {
- MotionEvent c = MotionEvent.obtain(m);
- c.setAction(MotionEvent.ACTION_CANCEL);
- return c;
- }
-
- private void openPie() {
- mGestureDetector.onTouchEvent(makeCancelEvent(mDown));
- mScale.onTouchEvent(makeCancelEvent(mDown));
- mOverlay.directDispatchTouch(mDown, mPie);
- }
-
- private boolean sendToPie(MotionEvent m) {
- return mOverlay.directDispatchTouch(m, mPie);
- }
-
- // OnScaleGestureListener implementation
- @Override
- public boolean onScale(ScaleGestureDetector detector) {
- return mZoom.onScale(detector);
- }
-
- @Override
- public boolean onScaleBegin(ScaleGestureDetector detector) {
- if (mPie == null || !mPie.isOpen()) {
- mMode = MODE_ZOOM;
- mGestureDetector.onTouchEvent(makeCancelEvent(mCurrent));
- if (!mZoomEnabled) return false;
- return mZoom.onScaleBegin(detector);
- }
- return false;
- }
-
- @Override
- public void onScaleEnd(ScaleGestureDetector detector) {
- mZoom.onScaleEnd(detector);
- }
-}
-
diff --git a/src/com/android/camera/ProxyLauncher.java b/src/com/android/camera/ProxyLauncher.java
deleted file mode 100644
index 8c566214c..000000000
--- a/src/com/android/camera/ProxyLauncher.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class ProxyLauncher extends Activity {
-
- public static final int RESULT_USER_CANCELED = -2;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (savedInstanceState == null) {
- Intent intent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
- startActivityForResult(intent, 0);
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (resultCode == RESULT_CANCELED) {
- resultCode = RESULT_USER_CANCELED;
- }
- setResult(resultCode, data);
- finish();
- }
-
-}
diff --git a/src/com/android/camera/RecordLocationPreference.java b/src/com/android/camera/RecordLocationPreference.java
deleted file mode 100644
index 9992afabb..000000000
--- a/src/com/android/camera/RecordLocationPreference.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.AttributeSet;
-
-/**
- * {@code RecordLocationPreference} is used to keep the "store locaiton"
- * option in {@code SharedPreference}.
- */
-public class RecordLocationPreference extends IconListPreference {
-
- public static final String VALUE_NONE = "none";
- public static final String VALUE_ON = "on";
- public static final String VALUE_OFF = "off";
-
- private final ContentResolver mResolver;
-
- public RecordLocationPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- mResolver = context.getContentResolver();
- }
-
- @Override
- public String getValue() {
- return get(getSharedPreferences(), mResolver) ? VALUE_ON : VALUE_OFF;
- }
-
- public static boolean get(
- SharedPreferences pref, ContentResolver resolver) {
- String value = pref.getString(
- CameraSettings.KEY_RECORD_LOCATION, VALUE_NONE);
- return VALUE_ON.equals(value);
- }
-
- public static boolean isSet(SharedPreferences pref) {
- String value = pref.getString(
- CameraSettings.KEY_RECORD_LOCATION, VALUE_NONE);
- return !VALUE_NONE.equals(value);
- }
-}
diff --git a/src/com/android/camera/RotateDialogController.java b/src/com/android/camera/RotateDialogController.java
deleted file mode 100644
index 5d5e5e70f..000000000
--- a/src/com/android/camera/RotateDialogController.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.app.Activity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.Button;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.camera.ui.Rotatable;
-import com.android.camera.ui.RotateLayout;
-import com.android.gallery3d.R;
-
-public class RotateDialogController implements Rotatable {
-
- @SuppressWarnings("unused")
- private static final String TAG = "RotateDialogController";
- private static final long ANIM_DURATION = 150; // millis
-
- private Activity mActivity;
- private int mLayoutResourceID;
- private View mDialogRootLayout;
- private RotateLayout mRotateDialog;
- private View mRotateDialogTitleLayout;
- private View mRotateDialogButtonLayout;
- private TextView mRotateDialogTitle;
- private ProgressBar mRotateDialogSpinner;
- private TextView mRotateDialogText;
- private TextView mRotateDialogButton1;
- private TextView mRotateDialogButton2;
-
- private Animation mFadeInAnim, mFadeOutAnim;
-
- public RotateDialogController(Activity a, int layoutResource) {
- mActivity = a;
- mLayoutResourceID = layoutResource;
- }
-
- private void inflateDialogLayout() {
- if (mDialogRootLayout == null) {
- ViewGroup layoutRoot = (ViewGroup) mActivity.getWindow().getDecorView();
- LayoutInflater inflater = mActivity.getLayoutInflater();
- View v = inflater.inflate(mLayoutResourceID, layoutRoot);
- mDialogRootLayout = v.findViewById(R.id.rotate_dialog_root_layout);
- mRotateDialog = (RotateLayout) v.findViewById(R.id.rotate_dialog_layout);
- mRotateDialogTitleLayout = v.findViewById(R.id.rotate_dialog_title_layout);
- mRotateDialogButtonLayout = v.findViewById(R.id.rotate_dialog_button_layout);
- mRotateDialogTitle = (TextView) v.findViewById(R.id.rotate_dialog_title);
- mRotateDialogSpinner = (ProgressBar) v.findViewById(R.id.rotate_dialog_spinner);
- mRotateDialogText = (TextView) v.findViewById(R.id.rotate_dialog_text);
- mRotateDialogButton1 = (Button) v.findViewById(R.id.rotate_dialog_button1);
- mRotateDialogButton2 = (Button) v.findViewById(R.id.rotate_dialog_button2);
-
- mFadeInAnim = AnimationUtils.loadAnimation(
- mActivity, android.R.anim.fade_in);
- mFadeOutAnim = AnimationUtils.loadAnimation(
- mActivity, android.R.anim.fade_out);
- mFadeInAnim.setDuration(ANIM_DURATION);
- mFadeOutAnim.setDuration(ANIM_DURATION);
- }
- }
-
- @Override
- public void setOrientation(int orientation, boolean animation) {
- inflateDialogLayout();
- mRotateDialog.setOrientation(orientation, animation);
- }
-
- public void resetRotateDialog() {
- inflateDialogLayout();
- mRotateDialogTitleLayout.setVisibility(View.GONE);
- mRotateDialogSpinner.setVisibility(View.GONE);
- mRotateDialogButton1.setVisibility(View.GONE);
- mRotateDialogButton2.setVisibility(View.GONE);
- mRotateDialogButtonLayout.setVisibility(View.GONE);
- }
-
- private void fadeOutDialog() {
- mDialogRootLayout.startAnimation(mFadeOutAnim);
- mDialogRootLayout.setVisibility(View.GONE);
- }
-
- private void fadeInDialog() {
- mDialogRootLayout.startAnimation(mFadeInAnim);
- mDialogRootLayout.setVisibility(View.VISIBLE);
- }
-
- public void dismissDialog() {
- if (mDialogRootLayout != null && mDialogRootLayout.getVisibility() != View.GONE) {
- fadeOutDialog();
- }
- }
-
- public void showAlertDialog(String title, String msg, String button1Text,
- final Runnable r1, String button2Text, final Runnable r2) {
- resetRotateDialog();
-
- if (title != null) {
- mRotateDialogTitle.setText(title);
- mRotateDialogTitleLayout.setVisibility(View.VISIBLE);
- }
-
- mRotateDialogText.setText(msg);
-
- if (button1Text != null) {
- mRotateDialogButton1.setText(button1Text);
- mRotateDialogButton1.setContentDescription(button1Text);
- mRotateDialogButton1.setVisibility(View.VISIBLE);
- mRotateDialogButton1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (r1 != null) r1.run();
- dismissDialog();
- }
- });
- mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
- }
- if (button2Text != null) {
- mRotateDialogButton2.setText(button2Text);
- mRotateDialogButton2.setContentDescription(button2Text);
- mRotateDialogButton2.setVisibility(View.VISIBLE);
- mRotateDialogButton2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (r2 != null) r2.run();
- dismissDialog();
- }
- });
- mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
- }
-
- fadeInDialog();
- }
-
- public void showWaitingDialog(String msg) {
- resetRotateDialog();
-
- mRotateDialogText.setText(msg);
- mRotateDialogSpinner.setVisibility(View.VISIBLE);
-
- fadeInDialog();
- }
-
- public int getVisibility() {
- if (mDialogRootLayout != null) {
- return mDialogRootLayout.getVisibility();
- }
- return View.INVISIBLE;
- }
-}
diff --git a/src/com/android/camera/SecureCameraActivity.java b/src/com/android/camera/SecureCameraActivity.java
deleted file mode 100644
index 2fa68f8e6..000000000
--- a/src/com/android/camera/SecureCameraActivity.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-// Use a different activity for secure camera only. So it can have a different
-// task affinity from others. This makes sure non-secure camera activity is not
-// started in secure lock screen.
-public class SecureCameraActivity extends CameraActivity {
-}
diff --git a/src/com/android/camera/ShutterButton.java b/src/com/android/camera/ShutterButton.java
deleted file mode 100755
index a1bbb1a0d..000000000
--- a/src/com/android/camera/ShutterButton.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-
-/**
- * A button designed to be used for the on-screen shutter button.
- * It's currently an {@code ImageView} that can call a delegate when the
- * pressed state changes.
- */
-public class ShutterButton extends ImageView {
-
- private boolean mTouchEnabled = true;
-
- /**
- * A callback to be invoked when a ShutterButton's pressed state changes.
- */
- public interface OnShutterButtonListener {
- /**
- * Called when a ShutterButton has been pressed.
- *
- * @param pressed The ShutterButton that was pressed.
- */
- void onShutterButtonFocus(boolean pressed);
- void onShutterButtonClick();
- }
-
- private OnShutterButtonListener mListener;
- private boolean mOldPressed;
-
- public ShutterButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void setOnShutterButtonListener(OnShutterButtonListener listener) {
- mListener = listener;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mTouchEnabled) {
- return super.dispatchTouchEvent(m);
- } else {
- return false;
- }
- }
-
- public void enableTouch(boolean enable) {
- mTouchEnabled = enable;
- }
-
- /**
- * Hook into the drawable state changing to get changes to isPressed -- the
- * onPressed listener doesn't always get called when the pressed state
- * changes.
- */
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- final boolean pressed = isPressed();
- if (pressed != mOldPressed) {
- if (!pressed) {
- // When pressing the physical camera button the sequence of
- // events is:
- // focus pressed, optional camera pressed, focus released.
- // We want to emulate this sequence of events with the shutter
- // button. When clicking using a trackball button, the view
- // system changes the drawable state before posting click
- // notification, so the sequence of events is:
- // pressed(true), optional click, pressed(false)
- // When clicking using touch events, the view system changes the
- // drawable state after posting click notification, so the
- // sequence of events is:
- // pressed(true), pressed(false), optional click
- // Since we're emulating the physical camera button, we want to
- // have the same order of events. So we want the optional click
- // callback to be delivered before the pressed(false) callback.
- //
- // To do this, we delay the posting of the pressed(false) event
- // slightly by pushing it on the event queue. This moves it
- // after the optional click notification, so our client always
- // sees events in this sequence:
- // pressed(true), optional click, pressed(false)
- post(new Runnable() {
- @Override
- public void run() {
- callShutterButtonFocus(pressed);
- }
- });
- } else {
- callShutterButtonFocus(pressed);
- }
- mOldPressed = pressed;
- }
- }
-
- private void callShutterButtonFocus(boolean pressed) {
- if (mListener != null) {
- mListener.onShutterButtonFocus(pressed);
- }
- }
-
- @Override
- public boolean performClick() {
- boolean result = super.performClick();
- if (mListener != null && getVisibility() == View.VISIBLE) {
- mListener.onShutterButtonClick();
- }
- return result;
- }
-}
diff --git a/src/com/android/camera/SoundClips.java b/src/com/android/camera/SoundClips.java
deleted file mode 100644
index 8155c03dc..000000000
--- a/src/com/android/camera/SoundClips.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.MediaActionSound;
-import android.media.SoundPool;
-import android.util.Log;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-/*
- * This class controls the sound playback according to the API level.
- */
-public class SoundClips {
- // Sound actions.
- public static final int FOCUS_COMPLETE = 0;
- public static final int START_VIDEO_RECORDING = 1;
- public static final int STOP_VIDEO_RECORDING = 2;
-
- public interface Player {
- public void release();
- public void play(int action);
- }
-
- public static Player getPlayer(Context context) {
- if (ApiHelper.HAS_MEDIA_ACTION_SOUND) {
- return new MediaActionSoundPlayer();
- } else {
- return new SoundPoolPlayer(context);
- }
- }
-
- public static int getAudioTypeForSoundPool() {
- return ApiHelper.getIntFieldIfExists(AudioManager.class,
- "STREAM_SYSTEM_ENFORCED", null, AudioManager.STREAM_RING);
- }
-
- /**
- * This class implements SoundClips.Player using MediaActionSound,
- * which exists since API level 16.
- */
- @TargetApi(ApiHelper.VERSION_CODES.JELLY_BEAN)
- private static class MediaActionSoundPlayer implements Player {
- private static final String TAG = "MediaActionSoundPlayer";
- private MediaActionSound mSound;
-
- @Override
- public void release() {
- if (mSound != null) {
- mSound.release();
- mSound = null;
- }
- }
-
- public MediaActionSoundPlayer() {
- mSound = new MediaActionSound();
- mSound.load(MediaActionSound.START_VIDEO_RECORDING);
- mSound.load(MediaActionSound.STOP_VIDEO_RECORDING);
- mSound.load(MediaActionSound.FOCUS_COMPLETE);
- }
-
- @Override
- public synchronized void play(int action) {
- switch(action) {
- case FOCUS_COMPLETE:
- mSound.play(MediaActionSound.FOCUS_COMPLETE);
- break;
- case START_VIDEO_RECORDING:
- mSound.play(MediaActionSound.START_VIDEO_RECORDING);
- break;
- case STOP_VIDEO_RECORDING:
- mSound.play(MediaActionSound.STOP_VIDEO_RECORDING);
- break;
- default:
- Log.w(TAG, "Unrecognized action:" + action);
- }
- }
- }
-
- /**
- * This class implements SoundClips.Player using SoundPool, which
- * exists since API level 1.
- */
- private static class SoundPoolPlayer implements
- Player, SoundPool.OnLoadCompleteListener {
-
- private static final String TAG = "SoundPoolPlayer";
- private static final int NUM_SOUND_STREAMS = 1;
- private static final int[] SOUND_RES = { // Soundtrack res IDs.
- R.raw.focus_complete,
- R.raw.video_record
- };
-
- // ID returned by load() should be non-zero.
- private static final int ID_NOT_LOADED = 0;
-
- // Maps a sound action to the id;
- private final int[] mSoundRes = {0, 1, 1};
- // Store the context for lazy loading.
- private Context mContext;
- // mSoundPool is created every time load() is called and cleared every
- // time release() is called.
- private SoundPool mSoundPool;
- // Sound ID of each sound resources. Given when the sound is loaded.
- private final int[] mSoundIDs;
- private final boolean[] mSoundIDReady;
- private int mSoundIDToPlay;
-
- public SoundPoolPlayer(Context context) {
- mContext = context;
-
- mSoundIDToPlay = ID_NOT_LOADED;
-
- mSoundPool = new SoundPool(NUM_SOUND_STREAMS, getAudioTypeForSoundPool(), 0);
- mSoundPool.setOnLoadCompleteListener(this);
-
- mSoundIDs = new int[SOUND_RES.length];
- mSoundIDReady = new boolean[SOUND_RES.length];
- for (int i = 0; i < SOUND_RES.length; i++) {
- mSoundIDs[i] = mSoundPool.load(mContext, SOUND_RES[i], 1);
- mSoundIDReady[i] = false;
- }
- }
-
- @Override
- public synchronized void release() {
- if (mSoundPool != null) {
- mSoundPool.release();
- mSoundPool = null;
- }
- }
-
- @Override
- public synchronized void play(int action) {
- if (action < 0 || action >= mSoundRes.length) {
- Log.e(TAG, "Resource ID not found for action:" + action + " in play().");
- return;
- }
-
- int index = mSoundRes[action];
- if (mSoundIDs[index] == ID_NOT_LOADED) {
- // Not loaded yet, load first and then play when the loading is complete.
- mSoundIDs[index] = mSoundPool.load(mContext, SOUND_RES[index], 1);
- mSoundIDToPlay = mSoundIDs[index];
- } else if (!mSoundIDReady[index]) {
- // Loading and not ready yet.
- mSoundIDToPlay = mSoundIDs[index];
- } else {
- mSoundPool.play(mSoundIDs[index], 1f, 1f, 0, 0, 1f);
- }
- }
-
- @Override
- public void onLoadComplete(SoundPool pool, int soundID, int status) {
- if (status != 0) {
- Log.e(TAG, "loading sound tracks failed (status=" + status + ")");
- for (int i = 0; i < mSoundIDs.length; i++ ) {
- if (mSoundIDs[i] == soundID) {
- mSoundIDs[i] = ID_NOT_LOADED;
- break;
- }
- }
- return;
- }
-
- for (int i = 0; i < mSoundIDs.length; i++ ) {
- if (mSoundIDs[i] == soundID) {
- mSoundIDReady[i] = true;
- break;
- }
- }
-
- if (soundID == mSoundIDToPlay) {
- mSoundIDToPlay = ID_NOT_LOADED;
- mSoundPool.play(soundID, 1f, 1f, 0, 0, 1f);
- }
- }
- }
-}
diff --git a/src/com/android/camera/StaticBitmapScreenNail.java b/src/com/android/camera/StaticBitmapScreenNail.java
deleted file mode 100644
index 10788c0fb..000000000
--- a/src/com/android/camera/StaticBitmapScreenNail.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.graphics.Bitmap;
-
-import com.android.gallery3d.ui.BitmapScreenNail;
-
-public class StaticBitmapScreenNail extends BitmapScreenNail {
- public StaticBitmapScreenNail(Bitmap bitmap) {
- super(bitmap);
- }
-
- @Override
- public void recycle() {
- // Always keep the bitmap in memory.
- }
-}
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
deleted file mode 100644
index ba995edef..000000000
--- a/src/com/android/camera/Storage.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2010 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;
-
-import android.annotation.TargetApi;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.location.Location;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Environment;
-import android.os.StatFs;
-import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.provider.MediaStore.MediaColumns;
-import android.util.Log;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.exif.ExifInterface;
-
-import java.io.File;
-import java.io.FileOutputStream;
-
-public class Storage {
- private static final String TAG = "CameraStorage";
-
- public static final String DCIM =
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
-
- public static final String DIRECTORY = DCIM + "/Camera";
-
- // Match the code in MediaProvider.computeBucketValues().
- public static final String BUCKET_ID =
- String.valueOf(DIRECTORY.toLowerCase().hashCode());
-
- public static final long UNAVAILABLE = -1L;
- public static final long PREPARING = -2L;
- public static final long UNKNOWN_SIZE = -3L;
- public static final long LOW_STORAGE_THRESHOLD = 50000000;
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private static void setImageSize(ContentValues values, int width, int height) {
- // The two fields are available since ICS but got published in JB
- if (ApiHelper.HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT) {
- values.put(MediaColumns.WIDTH, width);
- values.put(MediaColumns.HEIGHT, height);
- }
- }
-
- public static void writeFile(String path, byte[] data) {
- FileOutputStream out = null;
- try {
- out = new FileOutputStream(path);
- out.write(data);
- } catch (Exception e) {
- Log.e(TAG, "Failed to write data", e);
- } finally {
- try {
- out.close();
- } catch (Exception e) {
- }
- }
- }
-
- // Save the image and add it to media store.
- public static Uri addImage(ContentResolver resolver, String title,
- long date, Location location, int orientation, ExifInterface exif,
- byte[] jpeg, int width, int height) {
- // Save the image.
- String path = generateFilepath(title);
- if (exif != null) {
- try {
- exif.writeExif(jpeg, path);
- } catch (Exception e) {
- Log.e(TAG, "Failed to write data", e);
- }
- } else {
- writeFile(path, jpeg);
- }
- return addImage(resolver, title, date, location, orientation,
- jpeg.length, path, width, height);
- }
-
- // Add the image to media store.
- public static Uri addImage(ContentResolver resolver, String title,
- long date, Location location, int orientation, int jpegLength,
- String path, int width, int height) {
- // Insert into MediaStore.
- ContentValues values = new ContentValues(9);
- values.put(ImageColumns.TITLE, title);
- values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
- values.put(ImageColumns.DATE_TAKEN, date);
- values.put(ImageColumns.MIME_TYPE, "image/jpeg");
- // Clockwise rotation in degrees. 0, 90, 180, or 270.
- values.put(ImageColumns.ORIENTATION, orientation);
- values.put(ImageColumns.DATA, path);
- values.put(ImageColumns.SIZE, jpegLength);
-
- setImageSize(values, width, height);
-
- if (location != null) {
- values.put(ImageColumns.LATITUDE, location.getLatitude());
- values.put(ImageColumns.LONGITUDE, location.getLongitude());
- }
-
- Uri uri = null;
- try {
- uri = resolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values);
- } catch (Throwable th) {
- // This can happen when the external volume is already mounted, but
- // MediaScanner has not notify MediaProvider to add that volume.
- // The picture is still safe and MediaScanner will find it and
- // insert it into MediaProvider. The only problem is that the user
- // cannot click the thumbnail to review the picture.
- Log.e(TAG, "Failed to write MediaStore" + th);
- }
- return uri;
- }
-
- public static void deleteImage(ContentResolver resolver, Uri uri) {
- try {
- resolver.delete(uri, null, null);
- } catch (Throwable th) {
- Log.e(TAG, "Failed to delete image: " + uri);
- }
- }
-
- public static String generateFilepath(String title) {
- return DIRECTORY + '/' + title + ".jpg";
- }
-
- public static long getAvailableSpace() {
- String state = Environment.getExternalStorageState();
- Log.d(TAG, "External storage state=" + state);
- if (Environment.MEDIA_CHECKING.equals(state)) {
- return PREPARING;
- }
- if (!Environment.MEDIA_MOUNTED.equals(state)) {
- return UNAVAILABLE;
- }
-
- File dir = new File(DIRECTORY);
- dir.mkdirs();
- if (!dir.isDirectory() || !dir.canWrite()) {
- return UNAVAILABLE;
- }
-
- try {
- StatFs stat = new StatFs(DIRECTORY);
- return stat.getAvailableBlocks() * (long) stat.getBlockSize();
- } catch (Exception e) {
- Log.i(TAG, "Fail to access external storage", e);
- }
- return UNKNOWN_SIZE;
- }
-
- /**
- * OSX requires plugged-in USB storage to have path /DCIM/NNNAAAAA to be
- * imported. This is a temporary fix for bug#1655552.
- */
- public static void ensureOSXCompatible() {
- File nnnAAAAA = new File(DCIM, "100ANDRO");
- if (!(nnnAAAAA.exists() || nnnAAAAA.mkdirs())) {
- Log.e(TAG, "Failed to create " + nnnAAAAA.getPath());
- }
- }
-}
diff --git a/src/com/android/camera/SurfaceTextureRenderer.java b/src/com/android/camera/SurfaceTextureRenderer.java
deleted file mode 100644
index 66f7aa219..000000000
--- a/src/com/android/camera/SurfaceTextureRenderer.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import android.util.Log;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL10;
-
-public class SurfaceTextureRenderer {
-
- public interface FrameDrawer {
- public void onDrawFrame(GL10 gl);
- }
-
- private static final String TAG = "CAM_" + SurfaceTextureRenderer.class.getSimpleName();
- private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
-
- private EGLConfig mEglConfig;
- private EGLDisplay mEglDisplay;
- private EGLContext mEglContext;
- private EGLSurface mEglSurface;
- private EGL10 mEgl;
- private GL10 mGl;
-
- private Handler mEglHandler;
- private FrameDrawer mFrameDrawer;
-
- private Object mRenderLock = new Object();
- private Runnable mRenderTask = new Runnable() {
- @Override
- public void run() {
- synchronized (mRenderLock) {
- mFrameDrawer.onDrawFrame(mGl);
- mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
- mRenderLock.notifyAll();
- }
- }
- };
-
- public class RenderThread extends Thread {
- private Boolean mRenderStopped = false;
-
- @Override
- public void run() {
- while (true) {
- synchronized (mRenderStopped) {
- if (mRenderStopped) return;
- }
- draw(true);
- }
- }
-
- public void stopRender() {
- synchronized (mRenderStopped) {
- mRenderStopped = true;
- }
- }
- }
-
- public SurfaceTextureRenderer(SurfaceTexture tex,
- Handler handler, FrameDrawer renderer) {
- mEglHandler = handler;
- mFrameDrawer = renderer;
-
- initialize(tex);
- }
-
- public RenderThread createRenderThread() {
- return new RenderThread();
- }
-
- public void release() {
- mEglHandler.post(new Runnable() {
- @Override
- public void run() {
- mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
- mEgl.eglDestroyContext(mEglDisplay, mEglContext);
- mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
- EGL10.EGL_NO_CONTEXT);
- mEgl.eglTerminate(mEglDisplay);
- mEglSurface = null;
- mEglContext = null;
- mEglDisplay = null;
- }
- });
- }
-
- /**
- * Posts a render request to the GL thread.
- * @param sync set <code>true</code> if the caller needs it to be
- * a synchronous call.
- */
- public void draw(boolean sync) {
- synchronized (mRenderLock) {
- mEglHandler.post(mRenderTask);
- if (sync) {
- try {
- mRenderLock.wait();
- } catch (InterruptedException ex) {
- Log.v(TAG, "RenderLock.wait() interrupted");
- }
- }
- }
- }
-
- private void initialize(final SurfaceTexture target) {
- mEglHandler.post(new Runnable() {
- @Override
- public void run() {
- mEgl = (EGL10) EGLContext.getEGL();
- mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
- throw new RuntimeException("eglGetDisplay failed");
- }
- int[] version = new int[2];
- if (!mEgl.eglInitialize(mEglDisplay, version)) {
- throw new RuntimeException("eglInitialize failed");
- } else {
- Log.v(TAG, "EGL version: " + version[0] + '.' + version[1]);
- }
- int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
- mEglConfig = chooseConfig(mEgl, mEglDisplay);
- mEglContext = mEgl.eglCreateContext(
- mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, attribList);
-
- if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
- throw new RuntimeException("failed to createContext");
- }
- mEglSurface = mEgl.eglCreateWindowSurface(
- mEglDisplay, mEglConfig, target, null);
- if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
- throw new RuntimeException("failed to createWindowSurface");
- }
-
- if (!mEgl.eglMakeCurrent(
- mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
- throw new RuntimeException("failed to eglMakeCurrent");
- }
-
- mGl = (GL10) mEglContext.getGL();
- }
- });
- waitDone();
- }
-
- private void waitDone() {
- final Object lock = new Object();
- synchronized (lock) {
- mEglHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (lock) {
- lock.notifyAll();
- }
- }
- });
- try {
- lock.wait();
- } catch (InterruptedException ex) {
- Log.v(TAG, "waitDone() interrupted");
- }
- }
- }
-
- private static void checkEglError(String prompt, EGL10 egl) {
- int error;
- while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
- Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
- }
- }
-
- private static final int EGL_OPENGL_ES2_BIT = 4;
- private static final int[] CONFIG_SPEC = new int[] {
- EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL10.EGL_RED_SIZE, 8,
- EGL10.EGL_GREEN_SIZE, 8,
- EGL10.EGL_BLUE_SIZE, 8,
- EGL10.EGL_ALPHA_SIZE, 0,
- EGL10.EGL_DEPTH_SIZE, 0,
- EGL10.EGL_STENCIL_SIZE, 0,
- EGL10.EGL_NONE
- };
-
- private static EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
- int[] numConfig = new int[1];
- if (!egl.eglChooseConfig(display, CONFIG_SPEC, null, 0, numConfig)) {
- throw new IllegalArgumentException("eglChooseConfig failed");
- }
-
- int numConfigs = numConfig[0];
- if (numConfigs <= 0) {
- throw new IllegalArgumentException("No configs match configSpec");
- }
-
- EGLConfig[] configs = new EGLConfig[numConfigs];
- if (!egl.eglChooseConfig(
- display, CONFIG_SPEC, configs, numConfigs, numConfig)) {
- throw new IllegalArgumentException("eglChooseConfig#2 failed");
- }
-
- return configs[0];
- }
-}
diff --git a/src/com/android/camera/SwitchAnimManager.java b/src/com/android/camera/SwitchAnimManager.java
deleted file mode 100644
index 6ec88223e..000000000
--- a/src/com/android/camera/SwitchAnimManager.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.gallery3d.glrenderer.GLCanvas;
-import com.android.gallery3d.glrenderer.RawTexture;
-
-/**
- * Class to handle the animation when switching between back and front cameras.
- * An image of the previous camera zooms in and fades out. The preview of the
- * new camera zooms in and fades in. The image of the previous camera is called
- * review in this class.
- */
-public class SwitchAnimManager {
- private static final String TAG = "SwitchAnimManager";
- // The amount of change for zooming in and out.
- private static final float ZOOM_DELTA_PREVIEW = 0.2f;
- private static final float ZOOM_DELTA_REVIEW = 0.5f;
- private static final float ANIMATION_DURATION = 400; // ms
- public static final float INITIAL_DARKEN_ALPHA = 0.8f;
-
- private long mAnimStartTime; // milliseconds.
- // The drawing width and height of the review image. This is saved when the
- // texture is copied.
- private int mReviewDrawingWidth;
- private int mReviewDrawingHeight;
- // The maximum width of the camera screen nail width from onDraw. We need to
- // know how much the preview is scaled and scale the review the same amount.
- // For example, the preview is not full screen in film strip mode.
- private int mPreviewFrameLayoutWidth;
-
- public SwitchAnimManager() {
- }
-
- public void setReviewDrawingSize(int width, int height) {
- mReviewDrawingWidth = width;
- mReviewDrawingHeight = height;
- }
-
- // width: the width of PreviewFrameLayout view.
- // height: the height of PreviewFrameLayout view. Not used. Kept for
- // consistency.
- public void setPreviewFrameLayoutSize(int width, int height) {
- mPreviewFrameLayoutWidth = width;
- }
-
- // w and h: the rectangle area where the animation takes place.
- public void startAnimation() {
- mAnimStartTime = SystemClock.uptimeMillis();
- }
-
- // Returns true if the animation has been drawn.
- // preview: camera preview view.
- // review: snapshot of the preview before switching the camera.
- public boolean drawAnimation(GLCanvas canvas, int x, int y, int width,
- int height, CameraScreenNail preview, RawTexture review) {
- long timeDiff = SystemClock.uptimeMillis() - mAnimStartTime;
- if (timeDiff > ANIMATION_DURATION) return false;
- float fraction = timeDiff / ANIMATION_DURATION;
-
- // Calculate the position and the size of the preview.
- float centerX = x + width / 2f;
- float centerY = y + height / 2f;
- float previewAnimScale = 1 - ZOOM_DELTA_PREVIEW * (1 - fraction);
- float previewWidth = width * previewAnimScale;
- float previewHeight = height * previewAnimScale;
- int previewX = Math.round(centerX - previewWidth / 2);
- int previewY = Math.round(centerY - previewHeight / 2);
-
- // Calculate the position and the size of the review.
- float reviewAnimScale = 1 + ZOOM_DELTA_REVIEW * fraction;
-
- // Calculate how much preview is scaled.
- // The scaling is done by PhotoView in Gallery so we don't have the
- // scaling information but only the width and the height passed to this
- // method. The inference of the scale ratio is done by matching the
- // current width and the original width we have at first when the camera
- // layout is inflated.
- float scaleRatio = 1;
- if (mPreviewFrameLayoutWidth != 0) {
- scaleRatio = (float) width / mPreviewFrameLayoutWidth;
- } else {
- Log.e(TAG, "mPreviewFrameLayoutWidth is 0.");
- }
- float reviewWidth = mReviewDrawingWidth * reviewAnimScale * scaleRatio;
- float reviewHeight = mReviewDrawingHeight * reviewAnimScale * scaleRatio;
- int reviewX = Math.round(centerX - reviewWidth / 2);
- int reviewY = Math.round(centerY - reviewHeight / 2);
-
- // Draw the preview.
- float alpha = canvas.getAlpha();
- canvas.setAlpha(fraction); // fade in
- preview.directDraw(canvas, previewX, previewY, Math.round(previewWidth),
- Math.round(previewHeight));
-
- // Draw the review.
- canvas.setAlpha((1f - fraction) * INITIAL_DARKEN_ALPHA); // fade out
- review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth),
- Math.round(reviewHeight));
- canvas.setAlpha(alpha);
- return true;
- }
-
- public boolean drawDarkPreview(GLCanvas canvas, int x, int y, int width,
- int height, RawTexture review) {
- // Calculate the position and the size.
- float centerX = x + width / 2f;
- float centerY = y + height / 2f;
- float scaleRatio = 1;
- if (mPreviewFrameLayoutWidth != 0) {
- scaleRatio = (float) width / mPreviewFrameLayoutWidth;
- } else {
- Log.e(TAG, "mPreviewFrameLayoutWidth is 0.");
- }
- float reviewWidth = mReviewDrawingWidth * scaleRatio;
- float reviewHeight = mReviewDrawingHeight * scaleRatio;
- int reviewX = Math.round(centerX - reviewWidth / 2);
- int reviewY = Math.round(centerY - reviewHeight / 2);
-
- // Draw the review.
- float alpha = canvas.getAlpha();
- canvas.setAlpha(INITIAL_DARKEN_ALPHA);
- review.draw(canvas, reviewX, reviewY, Math.round(reviewWidth),
- Math.round(reviewHeight));
- canvas.setAlpha(alpha);
- return true;
- }
-
-}
diff --git a/src/com/android/camera/Thumbnail.java b/src/com/android/camera/Thumbnail.java
deleted file mode 100644
index 5f8483d6c..000000000
--- a/src/com/android/camera/Thumbnail.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.graphics.Bitmap;
-import android.media.MediaMetadataRetriever;
-
-import java.io.FileDescriptor;
-
-public class Thumbnail {
- public static Bitmap createVideoThumbnailBitmap(FileDescriptor fd, int targetWidth) {
- return createVideoThumbnailBitmap(null, fd, targetWidth);
- }
-
- public static Bitmap createVideoThumbnailBitmap(String filePath, int targetWidth) {
- return createVideoThumbnailBitmap(filePath, null, targetWidth);
- }
-
- private static Bitmap createVideoThumbnailBitmap(String filePath, FileDescriptor fd,
- int targetWidth) {
- Bitmap bitmap = null;
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- try {
- if (filePath != null) {
- retriever.setDataSource(filePath);
- } else {
- retriever.setDataSource(fd);
- }
- bitmap = retriever.getFrameAtTime(-1);
- } catch (IllegalArgumentException ex) {
- // Assume this is a corrupt video file
- } catch (RuntimeException ex) {
- // Assume this is a corrupt video file.
- } finally {
- try {
- retriever.release();
- } catch (RuntimeException ex) {
- // Ignore failures while cleaning up.
- }
- }
- if (bitmap == null) return null;
-
- // Scale down the bitmap if it is bigger than we need.
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
- if (width > targetWidth) {
- float scale = (float) targetWidth / width;
- int w = Math.round(scale * width);
- int h = Math.round(scale * height);
- bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
- }
- return bitmap;
- }
-}
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
deleted file mode 100644
index 2c5aa9eab..000000000
--- a/src/com/android/camera/Util.java
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.admin.DevicePolicyManager;
-import android.content.ActivityNotFoundException;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.location.Location;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.ParcelFileDescriptor;
-import android.telephony.TelephonyManager;
-import android.util.DisplayMetrics;
-import android.util.FloatMath;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Display;
-import android.view.OrientationEventListener;
-import android.view.Surface;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.app.MovieActivity;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * Collection of utility functions used in this package.
- */
-public class Util {
- private static final String TAG = "Util";
-
- // Orientation hysteresis amount used in rounding, in degrees
- public static final int ORIENTATION_HYSTERESIS = 5;
-
- public static final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
- // See android.hardware.Camera.ACTION_NEW_PICTURE.
- public static final String ACTION_NEW_PICTURE = "android.hardware.action.NEW_PICTURE";
- // See android.hardware.Camera.ACTION_NEW_VIDEO.
- public static final String ACTION_NEW_VIDEO = "android.hardware.action.NEW_VIDEO";
-
- // Fields from android.hardware.Camera.Parameters
- public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture";
- public static final String RECORDING_HINT = "recording-hint";
- private static final String AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
- private static final String AUTO_WHITE_BALANCE_LOCK_SUPPORTED = "auto-whitebalance-lock-supported";
- private static final String VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
- public static final String SCENE_MODE_HDR = "hdr";
- public static final String TRUE = "true";
- public static final String FALSE = "false";
-
- public static boolean isSupported(String value, List<String> supported) {
- return supported == null ? false : supported.indexOf(value) >= 0;
- }
-
- public static boolean isAutoExposureLockSupported(Parameters params) {
- return TRUE.equals(params.get(AUTO_EXPOSURE_LOCK_SUPPORTED));
- }
-
- public static boolean isAutoWhiteBalanceLockSupported(Parameters params) {
- return TRUE.equals(params.get(AUTO_WHITE_BALANCE_LOCK_SUPPORTED));
- }
-
- public static boolean isVideoSnapshotSupported(Parameters params) {
- return TRUE.equals(params.get(VIDEO_SNAPSHOT_SUPPORTED));
- }
-
- public static boolean isCameraHdrSupported(Parameters params) {
- List<String> supported = params.getSupportedSceneModes();
- return (supported != null) && supported.contains(SCENE_MODE_HDR);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- public static boolean isMeteringAreaSupported(Parameters params) {
- if (ApiHelper.HAS_CAMERA_METERING_AREA) {
- return params.getMaxNumMeteringAreas() > 0;
- }
- return false;
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- public static boolean isFocusAreaSupported(Parameters params) {
- if (ApiHelper.HAS_CAMERA_FOCUS_AREA) {
- return (params.getMaxNumFocusAreas() > 0
- && isSupported(Parameters.FOCUS_MODE_AUTO,
- params.getSupportedFocusModes()));
- }
- return false;
- }
-
- // Private intent extras. Test only.
- private static final String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
-
- private static float sPixelDensity = 1;
- private static ImageFileNamer sImageFileNamer;
-
- private Util() {
- }
-
- public static void initialize(Context context) {
- DisplayMetrics metrics = new DisplayMetrics();
- WindowManager wm = (WindowManager)
- context.getSystemService(Context.WINDOW_SERVICE);
- wm.getDefaultDisplay().getMetrics(metrics);
- sPixelDensity = metrics.density;
- sImageFileNamer = new ImageFileNamer(
- context.getString(R.string.image_file_name_format));
- }
-
- public static int dpToPixel(int dp) {
- return Math.round(sPixelDensity * dp);
- }
-
- // Rotates the bitmap by the specified degree.
- // If a new bitmap is created, the original bitmap is recycled.
- public static Bitmap rotate(Bitmap b, int degrees) {
- return rotateAndMirror(b, degrees, false);
- }
-
- // Rotates and/or mirrors the bitmap. If a new bitmap is created, the
- // original bitmap is recycled.
- public static Bitmap rotateAndMirror(Bitmap b, int degrees, boolean mirror) {
- if ((degrees != 0 || mirror) && b != null) {
- Matrix m = new Matrix();
- // Mirror first.
- // horizontal flip + rotation = -rotation + horizontal flip
- if (mirror) {
- m.postScale(-1, 1);
- degrees = (degrees + 360) % 360;
- if (degrees == 0 || degrees == 180) {
- m.postTranslate(b.getWidth(), 0);
- } else if (degrees == 90 || degrees == 270) {
- m.postTranslate(b.getHeight(), 0);
- } else {
- throw new IllegalArgumentException("Invalid degrees=" + degrees);
- }
- }
- if (degrees != 0) {
- // clockwise
- m.postRotate(degrees,
- (float) b.getWidth() / 2, (float) b.getHeight() / 2);
- }
-
- try {
- Bitmap b2 = Bitmap.createBitmap(
- b, 0, 0, b.getWidth(), b.getHeight(), m, true);
- if (b != b2) {
- b.recycle();
- b = b2;
- }
- } catch (OutOfMemoryError ex) {
- // We have no memory to rotate. Return the original bitmap.
- }
- }
- return b;
- }
-
- /*
- * Compute the sample size as a function of minSideLength
- * and maxNumOfPixels.
- * minSideLength is used to specify that minimal width or height of a
- * bitmap.
- * maxNumOfPixels is used to specify the maximal size in pixels that is
- * tolerable in terms of memory usage.
- *
- * The function returns a sample size based on the constraints.
- * Both size and minSideLength can be passed in as -1
- * which indicates no care of the corresponding constraint.
- * The functions prefers returning a sample size that
- * generates a smaller bitmap, unless minSideLength = -1.
- *
- * Also, the function rounds up the sample size to a power of 2 or multiple
- * of 8 because BitmapFactory only honors sample size this way.
- * For example, BitmapFactory downsamples an image by 2 even though the
- * request is 3. So we round up the sample size to avoid OOM.
- */
- public static int computeSampleSize(BitmapFactory.Options options,
- int minSideLength, int maxNumOfPixels) {
- int initialSize = computeInitialSampleSize(options, minSideLength,
- maxNumOfPixels);
-
- int roundedSize;
- if (initialSize <= 8) {
- roundedSize = 1;
- while (roundedSize < initialSize) {
- roundedSize <<= 1;
- }
- } else {
- roundedSize = (initialSize + 7) / 8 * 8;
- }
-
- return roundedSize;
- }
-
- private static int computeInitialSampleSize(BitmapFactory.Options options,
- int minSideLength, int maxNumOfPixels) {
- double w = options.outWidth;
- double h = options.outHeight;
-
- int lowerBound = (maxNumOfPixels < 0) ? 1 :
- (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
- int upperBound = (minSideLength < 0) ? 128 :
- (int) Math.min(Math.floor(w / minSideLength),
- Math.floor(h / minSideLength));
-
- if (upperBound < lowerBound) {
- // return the larger one when there is no overlapping zone.
- return lowerBound;
- }
-
- if (maxNumOfPixels < 0 && minSideLength < 0) {
- return 1;
- } else if (minSideLength < 0) {
- return lowerBound;
- } else {
- return upperBound;
- }
- }
-
- public static Bitmap makeBitmap(byte[] jpegData, int maxNumOfPixels) {
- try {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length,
- options);
- if (options.mCancel || options.outWidth == -1
- || options.outHeight == -1) {
- return null;
- }
- options.inSampleSize = computeSampleSize(
- options, -1, maxNumOfPixels);
- options.inJustDecodeBounds = false;
-
- options.inDither = false;
- options.inPreferredConfig = Bitmap.Config.ARGB_8888;
- return BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length,
- options);
- } catch (OutOfMemoryError ex) {
- Log.e(TAG, "Got oom exception ", ex);
- return null;
- }
- }
-
- public static void closeSilently(Closeable c) {
- if (c == null) return;
- try {
- c.close();
- } catch (Throwable t) {
- // do nothing
- }
- }
-
- public static void Assert(boolean cond) {
- if (!cond) {
- throw new AssertionError();
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private static void throwIfCameraDisabled(Activity activity) throws CameraDisabledException {
- // Check if device policy has disabled the camera.
- if (ApiHelper.HAS_GET_CAMERA_DISABLED) {
- DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (dpm.getCameraDisabled(null)) {
- throw new CameraDisabledException();
- }
- }
- }
-
- public static CameraManager.CameraProxy openCamera(
- Activity activity, int cameraId)
- throws CameraHardwareException, CameraDisabledException {
- throwIfCameraDisabled(activity);
-
- try {
- return CameraHolder.instance().open(cameraId);
- } catch (CameraHardwareException e) {
- // In eng build, we throw the exception so that test tool
- // can detect it and report it
- if ("eng".equals(Build.TYPE)) {
- throw new RuntimeException("openCamera failed", e);
- } else {
- throw e;
- }
- }
- }
-
- public static void showErrorAndFinish(final Activity activity, int msgId) {
- DialogInterface.OnClickListener buttonListener =
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- activity.finish();
- }
- };
- TypedValue out = new TypedValue();
- activity.getTheme().resolveAttribute(android.R.attr.alertDialogIcon, out, true);
- new AlertDialog.Builder(activity)
- .setCancelable(false)
- .setTitle(R.string.camera_error_title)
- .setMessage(msgId)
- .setNeutralButton(R.string.dialog_ok, buttonListener)
- .setIcon(out.resourceId)
- .show();
- }
-
- public static <T> T checkNotNull(T object) {
- if (object == null) throw new NullPointerException();
- return object;
- }
-
- public static boolean equals(Object a, Object b) {
- return (a == b) || (a == null ? false : a.equals(b));
- }
-
- public static int nextPowerOf2(int n) {
- n -= 1;
- n |= n >>> 16;
- n |= n >>> 8;
- n |= n >>> 4;
- n |= n >>> 2;
- n |= n >>> 1;
- return n + 1;
- }
-
- public static float distance(float x, float y, float sx, float sy) {
- float dx = x - sx;
- float dy = y - sy;
- return FloatMath.sqrt(dx * dx + dy * dy);
- }
-
- public static int clamp(int x, int min, int max) {
- if (x > max) return max;
- if (x < min) return min;
- return x;
- }
-
- public static int getDisplayRotation(Activity activity) {
- int rotation = activity.getWindowManager().getDefaultDisplay()
- .getRotation();
- switch (rotation) {
- case Surface.ROTATION_0: return 0;
- case Surface.ROTATION_90: return 90;
- case Surface.ROTATION_180: return 180;
- case Surface.ROTATION_270: return 270;
- }
- return 0;
- }
-
- public static int getDisplayOrientation(int degrees, int cameraId) {
- // See android.hardware.Camera.setDisplayOrientation for
- // documentation.
- Camera.CameraInfo info = new Camera.CameraInfo();
- Camera.getCameraInfo(cameraId, info);
- int result;
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
- result = (info.orientation + degrees) % 360;
- result = (360 - result) % 360; // compensate the mirror
- } else { // back-facing
- result = (info.orientation - degrees + 360) % 360;
- }
- return result;
- }
-
- public static int getCameraOrientation(int cameraId) {
- Camera.CameraInfo info = new Camera.CameraInfo();
- Camera.getCameraInfo(cameraId, info);
- return info.orientation;
- }
-
- public static int roundOrientation(int orientation, int orientationHistory) {
- boolean changeOrientation = false;
- if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) {
- changeOrientation = true;
- } else {
- int dist = Math.abs(orientation - orientationHistory);
- dist = Math.min( dist, 360 - dist );
- changeOrientation = ( dist >= 45 + ORIENTATION_HYSTERESIS );
- }
- if (changeOrientation) {
- return ((orientation + 45) / 90 * 90) % 360;
- }
- return orientationHistory;
- }
-
- @SuppressWarnings("deprecation")
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
- private static Point getDefaultDisplaySize(Activity activity, Point size) {
- Display d = activity.getWindowManager().getDefaultDisplay();
- if (Build.VERSION.SDK_INT >= ApiHelper.VERSION_CODES.HONEYCOMB_MR2) {
- d.getSize(size);
- } else {
- size.set(d.getWidth(), d.getHeight());
- }
- return size;
- }
-
- public static Size getOptimalPreviewSize(Activity currentActivity,
- List<Size> sizes, double targetRatio) {
- // Use a very small tolerance because we want an exact match.
- final double ASPECT_TOLERANCE = 0.001;
- if (sizes == null) return null;
-
- Size optimalSize = null;
- double minDiff = Double.MAX_VALUE;
-
- // Because of bugs of overlay and layout, we sometimes will try to
- // layout the viewfinder in the portrait orientation and thus get the
- // wrong size of preview surface. When we change the preview size, the
- // new overlay will be created before the old one closed, which causes
- // an exception. For now, just get the screen size.
- Point point = getDefaultDisplaySize(currentActivity, new Point());
- int targetHeight = Math.min(point.x, point.y);
- // Try to find an size match aspect ratio and size
- for (Size size : sizes) {
- double ratio = (double) size.width / size.height;
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
- // Cannot find the one match the aspect ratio. This should not happen.
- // Ignore the requirement.
- if (optimalSize == null) {
- Log.w(TAG, "No preview size match the aspect ratio");
- minDiff = Double.MAX_VALUE;
- for (Size size : sizes) {
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
- }
- return optimalSize;
- }
-
- // Returns the largest picture size which matches the given aspect ratio.
- public static Size getOptimalVideoSnapshotPictureSize(
- List<Size> sizes, double targetRatio) {
- // Use a very small tolerance because we want an exact match.
- final double ASPECT_TOLERANCE = 0.001;
- if (sizes == null) return null;
-
- Size optimalSize = null;
-
- // Try to find a size matches aspect ratio and has the largest width
- for (Size size : sizes) {
- double ratio = (double) size.width / size.height;
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
- if (optimalSize == null || size.width > optimalSize.width) {
- optimalSize = size;
- }
- }
-
- // Cannot find one that matches the aspect ratio. This should not happen.
- // Ignore the requirement.
- if (optimalSize == null) {
- Log.w(TAG, "No picture size match the aspect ratio");
- for (Size size : sizes) {
- if (optimalSize == null || size.width > optimalSize.width) {
- optimalSize = size;
- }
- }
- }
- return optimalSize;
- }
-
- public static void dumpParameters(Parameters parameters) {
- String flattened = parameters.flatten();
- StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
- Log.d(TAG, "Dump all camera parameters:");
- while (tokenizer.hasMoreElements()) {
- Log.d(TAG, tokenizer.nextToken());
- }
- }
-
- /**
- * Returns whether the device is voice-capable (meaning, it can do MMS).
- */
- public static boolean isMmsCapable(Context context) {
- TelephonyManager telephonyManager = (TelephonyManager)
- context.getSystemService(Context.TELEPHONY_SERVICE);
- if (telephonyManager == null) {
- return false;
- }
-
- try {
- Class<?> partypes[] = new Class[0];
- Method sIsVoiceCapable = TelephonyManager.class.getMethod(
- "isVoiceCapable", partypes);
-
- Object arglist[] = new Object[0];
- Object retobj = sIsVoiceCapable.invoke(telephonyManager, arglist);
- return (Boolean) retobj;
- } catch (java.lang.reflect.InvocationTargetException ite) {
- // Failure, must be another device.
- // Assume that it is voice capable.
- } catch (IllegalAccessException iae) {
- // Failure, must be an other device.
- // Assume that it is voice capable.
- } catch (NoSuchMethodException nsme) {
- }
- return true;
- }
-
- // This is for test only. Allow the camera to launch the specific camera.
- public static int getCameraFacingIntentExtras(Activity currentActivity) {
- int cameraId = -1;
-
- int intentCameraId =
- currentActivity.getIntent().getIntExtra(Util.EXTRAS_CAMERA_FACING, -1);
-
- if (isFrontCameraIntent(intentCameraId)) {
- // Check if the front camera exist
- int frontCameraId = CameraHolder.instance().getFrontCameraId();
- if (frontCameraId != -1) {
- cameraId = frontCameraId;
- }
- } else if (isBackCameraIntent(intentCameraId)) {
- // Check if the back camera exist
- int backCameraId = CameraHolder.instance().getBackCameraId();
- if (backCameraId != -1) {
- cameraId = backCameraId;
- }
- }
- return cameraId;
- }
-
- private static boolean isFrontCameraIntent(int intentCameraId) {
- return (intentCameraId == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
- }
-
- private static boolean isBackCameraIntent(int intentCameraId) {
- return (intentCameraId == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
- }
-
- private static int sLocation[] = new int[2];
-
- // This method is not thread-safe.
- public static boolean pointInView(float x, float y, View v) {
- v.getLocationInWindow(sLocation);
- return x >= sLocation[0] && x < (sLocation[0] + v.getWidth())
- && y >= sLocation[1] && y < (sLocation[1] + v.getHeight());
- }
-
- public static int[] getRelativeLocation(View reference, View view) {
- reference.getLocationInWindow(sLocation);
- int referenceX = sLocation[0];
- int referenceY = sLocation[1];
- view.getLocationInWindow(sLocation);
- sLocation[0] -= referenceX;
- sLocation[1] -= referenceY;
- return sLocation;
- }
-
- public static boolean isUriValid(Uri uri, ContentResolver resolver) {
- if (uri == null) return false;
-
- try {
- ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
- if (pfd == null) {
- Log.e(TAG, "Fail to open URI. URI=" + uri);
- return false;
- }
- pfd.close();
- } catch (IOException ex) {
- return false;
- }
- return true;
- }
-
- public static void viewUri(Uri uri, Context context) {
- if (!isUriValid(uri, context.getContentResolver())) {
- Log.e(TAG, "Uri invalid. uri=" + uri);
- return;
- }
-
- try {
- context.startActivity(new Intent(Util.REVIEW_ACTION, uri));
- } catch (ActivityNotFoundException ex) {
- try {
- context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "review image fail. uri=" + uri, e);
- }
- }
- }
-
- public static void dumpRect(RectF rect, String msg) {
- Log.v(TAG, msg + "=(" + rect.left + "," + rect.top
- + "," + rect.right + "," + rect.bottom + ")");
- }
-
- public static void rectFToRect(RectF rectF, Rect rect) {
- rect.left = Math.round(rectF.left);
- rect.top = Math.round(rectF.top);
- rect.right = Math.round(rectF.right);
- rect.bottom = Math.round(rectF.bottom);
- }
-
- public static void prepareMatrix(Matrix matrix, boolean mirror, int displayOrientation,
- int viewWidth, int viewHeight) {
- // Need mirror for front camera.
- matrix.setScale(mirror ? -1 : 1, 1);
- // This is the value for android.hardware.Camera.setDisplayOrientation.
- matrix.postRotate(displayOrientation);
- // Camera driver coordinates range from (-1000, -1000) to (1000, 1000).
- // UI coordinates range from (0, 0) to (width, height).
- matrix.postScale(viewWidth / 2000f, viewHeight / 2000f);
- matrix.postTranslate(viewWidth / 2f, viewHeight / 2f);
- }
-
- public static String createJpegName(long dateTaken) {
- synchronized (sImageFileNamer) {
- return sImageFileNamer.generateName(dateTaken);
- }
- }
-
- public static void broadcastNewPicture(Context context, Uri uri) {
- context.sendBroadcast(new Intent(ACTION_NEW_PICTURE, uri));
- // Keep compatibility
- context.sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));
- }
-
- public static void fadeIn(View view, float startAlpha, float endAlpha, long duration) {
- if (view.getVisibility() == View.VISIBLE) return;
-
- view.setVisibility(View.VISIBLE);
- Animation animation = new AlphaAnimation(startAlpha, endAlpha);
- animation.setDuration(duration);
- view.startAnimation(animation);
- }
-
- public static void fadeIn(View view) {
- fadeIn(view, 0F, 1F, 400);
-
- // We disabled the button in fadeOut(), so enable it here.
- view.setEnabled(true);
- }
-
- public static void fadeOut(View view) {
- if (view.getVisibility() != View.VISIBLE) return;
-
- // Since the button is still clickable before fade-out animation
- // ends, we disable the button first to block click.
- view.setEnabled(false);
- Animation animation = new AlphaAnimation(1F, 0F);
- animation.setDuration(400);
- view.startAnimation(animation);
- view.setVisibility(View.GONE);
- }
-
- public static int getJpegRotation(int cameraId, int orientation) {
- // See android.hardware.Camera.Parameters.setRotation for
- // documentation.
- int rotation = 0;
- if (orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
- CameraInfo info = CameraHolder.instance().getCameraInfo()[cameraId];
- if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
- rotation = (info.orientation - orientation + 360) % 360;
- } else { // back-facing camera
- rotation = (info.orientation + orientation) % 360;
- }
- }
- return rotation;
- }
-
- /**
- * Down-samples a jpeg byte array.
- * @param data a byte array of jpeg data
- * @param downSampleFactor down-sample factor
- * @return decoded and down-sampled bitmap
- */
- public static Bitmap downSample(final byte[] data, int downSampleFactor) {
- final BitmapFactory.Options opts = new BitmapFactory.Options();
- // Downsample the image
- opts.inSampleSize = downSampleFactor;
- return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
- }
-
- public static void setGpsParameters(Parameters parameters, Location loc) {
- // Clear previous GPS location from the parameters.
- parameters.removeGpsData();
-
- // We always encode GpsTimeStamp
- parameters.setGpsTimestamp(System.currentTimeMillis() / 1000);
-
- // Set GPS location.
- if (loc != null) {
- double lat = loc.getLatitude();
- double lon = loc.getLongitude();
- boolean hasLatLon = (lat != 0.0d) || (lon != 0.0d);
-
- if (hasLatLon) {
- Log.d(TAG, "Set gps location");
- parameters.setGpsLatitude(lat);
- parameters.setGpsLongitude(lon);
- parameters.setGpsProcessingMethod(loc.getProvider().toUpperCase());
- if (loc.hasAltitude()) {
- parameters.setGpsAltitude(loc.getAltitude());
- } else {
- // for NETWORK_PROVIDER location provider, we may have
- // no altitude information, but the driver needs it, so
- // we fake one.
- parameters.setGpsAltitude(0);
- }
- if (loc.getTime() != 0) {
- // Location.getTime() is UTC in milliseconds.
- // gps-timestamp is UTC in seconds.
- long utcTimeSeconds = loc.getTime() / 1000;
- parameters.setGpsTimestamp(utcTimeSeconds);
- }
- } else {
- loc = null;
- }
- }
- }
-
-
- public static int[] getMaxPreviewFpsRange(Parameters params) {
- List<int[]> frameRates = params.getSupportedPreviewFpsRange();
- if (frameRates != null && frameRates.size() > 0) {
- // The list is sorted. Return the last element.
- return frameRates.get(frameRates.size() - 1);
- }
- return new int[0];
- }
-
- private static class ImageFileNamer {
- private SimpleDateFormat mFormat;
-
- // The date (in milliseconds) used to generate the last name.
- private long mLastDate;
-
- // Number of names generated for the same second.
- private int mSameSecondCount;
-
- public ImageFileNamer(String format) {
- mFormat = new SimpleDateFormat(format);
- }
-
- public String generateName(long dateTaken) {
- Date date = new Date(dateTaken);
- String result = mFormat.format(date);
-
- // If the last name was generated for the same second,
- // we append _1, _2, etc to the name.
- if (dateTaken / 1000 == mLastDate / 1000) {
- mSameSecondCount++;
- result += "_" + mSameSecondCount;
- } else {
- mLastDate = dateTaken;
- mSameSecondCount = 0;
- }
-
- return result;
- }
- }
-
- public static void playVideo(Context context, Uri uri, String title) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW)
- .setDataAndType(uri, "video/*")
- .putExtra(Intent.EXTRA_TITLE, title)
- .putExtra(MovieActivity.KEY_TREAT_UP_AS_BACK, true);
- context.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(context, context.getString(R.string.video_err),
- Toast.LENGTH_SHORT).show();
- }
- }
-}
diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java
deleted file mode 100644
index e84654821..000000000
--- a/src/com/android/camera/VideoController.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.view.View;
-
-import com.android.camera.ShutterButton.OnShutterButtonListener;
-
-public interface VideoController extends OnShutterButtonListener {
-
- public void onReviewDoneClicked(View view);
- public void onReviewCancelClicked(View viwe);
- public void onReviewPlayClicked(View view);
-
- public boolean isVideoCaptureIntent();
- public boolean isInReviewMode();
- public int onZoomChanged(int index);
-
- public void onSingleTapUp(View view, int x, int y);
-
- public void stopPreview();
-
- public void updateCameraOrientation();
-
- // Callbacks for camera preview UI events.
- public void onPreviewUIReady();
- public void onPreviewUIDestroyed();
-}
diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java
deleted file mode 100644
index da0bde10e..000000000
--- a/src/com/android/camera/VideoMenu.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.app.Activity;
-import android.content.Context;
-import android.view.LayoutInflater;
-
-import com.android.camera.ui.AbstractSettingPopup;
-import com.android.camera.ui.ListPrefSettingPopup;
-import com.android.camera.ui.MoreSettingPopup;
-import com.android.camera.ui.PieItem;
-import com.android.camera.ui.PieItem.OnClickListener;
-import com.android.camera.ui.PieRenderer;
-import com.android.camera.ui.TimeIntervalPopup;
-import com.android.gallery3d.R;
-
-public class VideoMenu extends PieController
- implements MoreSettingPopup.Listener,
- ListPrefSettingPopup.Listener,
- TimeIntervalPopup.Listener {
-
- private static String TAG = "CAM_VideoMenu";
-
- private VideoUI mUI;
- private String[] mOtherKeys;
- private AbstractSettingPopup mPopup;
-
- private static final int POPUP_NONE = 0;
- private static final int POPUP_FIRST_LEVEL = 1;
- private static final int POPUP_SECOND_LEVEL = 2;
- private int mPopupStatus;
- private CameraActivity mActivity;
-
- public VideoMenu(CameraActivity activity, VideoUI ui, PieRenderer pie) {
- super(activity, pie);
- mUI = ui;
- mActivity = activity;
- }
-
-
- public void initialize(PreferenceGroup group) {
- super.initialize(group);
- mPopup = null;
- mPopupStatus = POPUP_NONE;
- PieItem item = null;
- // white balance
- if (group.findPreference(CameraSettings.KEY_WHITE_BALANCE) != null) {
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE);
- mRenderer.addItem(item);
- }
- // settings popup
- mOtherKeys = new String[] {
- CameraSettings.KEY_VIDEO_EFFECT,
- CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
- CameraSettings.KEY_VIDEO_QUALITY,
- CameraSettings.KEY_RECORD_LOCATION
- };
- item = makeItem(R.drawable.ic_settings_holo_light);
- item.setLabel(mActivity.getResources().getString(R.string.camera_menu_settings_label));
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- if (mPopup == null || mPopupStatus != POPUP_FIRST_LEVEL) {
- initializePopup();
- mPopupStatus = POPUP_FIRST_LEVEL;
- }
- mUI.showPopup(mPopup);
- }
- });
- mRenderer.addItem(item);
- // camera switcher
- if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) {
- item = makeItem(R.drawable.ic_switch_back);
- IconListPreference lpref = (IconListPreference) group.findPreference(
- CameraSettings.KEY_CAMERA_ID);
- item.setLabel(lpref.getLabel());
- item.setImageResource(mActivity,
- ((IconListPreference) lpref).getIconIds()
- [lpref.findIndexOfValue(lpref.getValue())]);
-
- final PieItem fitem = item;
- item.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(PieItem item) {
- // Find the index of next camera.
- ListPreference pref =
- mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID);
- if (pref != null) {
- int index = pref.findIndexOfValue(pref.getValue());
- CharSequence[] values = pref.getEntryValues();
- index = (index + 1) % values.length;
- int newCameraId = Integer.parseInt((String) values[index]);
- fitem.setImageResource(mActivity,
- ((IconListPreference) pref).getIconIds()[index]);
- fitem.setLabel(pref.getLabel());
- mListener.onCameraPickerClicked(newCameraId);
- }
- }
- });
- mRenderer.addItem(item);
- }
- // flash
- if (group.findPreference(CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE) != null) {
- item = makeItem(CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);
- mRenderer.addItem(item);
- }
- }
-
- @Override
- public void reloadPreferences() {
- super.reloadPreferences();
- if (mPopup != null) {
- mPopup.reloadPreference();
- }
- }
-
- @Override
- public void overrideSettings(final String ... keyvalues) {
- super.overrideSettings(keyvalues);
- if (mPopup == null || mPopupStatus != POPUP_FIRST_LEVEL) {
- mPopupStatus = POPUP_FIRST_LEVEL;
- initializePopup();
- }
- ((MoreSettingPopup) mPopup).overrideSettings(keyvalues);
- }
-
- @Override
- // Hit when an item in the second-level popup gets selected
- public void onListPrefChanged(ListPreference pref) {
- if (mPopup != null) {
- if (mPopupStatus == POPUP_SECOND_LEVEL) {
- mUI.dismissPopup(true);
- }
- }
- super.onSettingChanged(pref);
- }
-
- protected void initializePopup() {
- LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- MoreSettingPopup popup = (MoreSettingPopup) inflater.inflate(
- R.layout.more_setting_popup, null, false);
- popup.setSettingChangedListener(this);
- popup.initialize(mPreferenceGroup, mOtherKeys);
- if (mActivity.isSecureCamera()) {
- // Prevent location preference from getting changed in secure camera mode
- popup.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false);
- }
- mPopup = popup;
- }
-
- public void popupDismissed(boolean topPopupOnly) {
- // if the 2nd level popup gets dismissed
- if (mPopupStatus == POPUP_SECOND_LEVEL) {
- initializePopup();
- mPopupStatus = POPUP_FIRST_LEVEL;
- if (topPopupOnly) mUI.showPopup(mPopup);
- }
- }
-
- @Override
- // Hit when an item in the first-level popup gets selected, then bring up
- // the second-level popup
- public void onPreferenceClicked(ListPreference pref) {
- if (mPopupStatus != POPUP_FIRST_LEVEL) return;
-
- LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- if (CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL.equals(pref.getKey())) {
- TimeIntervalPopup timeInterval = (TimeIntervalPopup) inflater.inflate(
- R.layout.time_interval_popup, null, false);
- timeInterval.initialize((IconListPreference) pref);
- timeInterval.setSettingChangedListener(this);
- mUI.dismissPopup(true);
- mPopup = timeInterval;
- } else {
- ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate(
- R.layout.list_pref_setting_popup, null, false);
- basic.initialize(pref);
- basic.setSettingChangedListener(this);
- mUI.dismissPopup(true);
- mPopup = basic;
- }
- mUI.showPopup(mPopup);
- mPopupStatus = POPUP_SECOND_LEVEL;
- }
-}
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
deleted file mode 100644
index 3c4d1e57b..000000000
--- a/src/com/android/camera/VideoModule.java
+++ /dev/null
@@ -1,2225 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences.Editor;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.location.Location;
-import android.media.CamcorderProfile;
-import android.media.CameraProfile;
-import android.media.MediaRecorder;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
-import android.provider.MediaStore;
-import android.provider.MediaStore.MediaColumns;
-import android.provider.MediaStore.Video;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.OrientationEventListener;
-import android.view.Surface;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.Toast;
-
-import com.android.camera.CameraManager.CameraPictureCallback;
-import com.android.camera.CameraManager.CameraProxy;
-import com.android.camera.ui.PopupManager;
-import com.android.camera.ui.RotateTextToast;
-import com.android.gallery3d.R;
-import com.android.gallery3d.app.OrientationManager;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.exif.ExifInterface;
-import com.android.gallery3d.util.AccessibilityUtils;
-import com.android.gallery3d.util.UsageStatistics;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-public class VideoModule implements CameraModule,
- VideoController,
- CameraPreference.OnPreferenceChangedListener,
- ShutterButton.OnShutterButtonListener,
- MediaRecorder.OnErrorListener,
- MediaRecorder.OnInfoListener,
- EffectsRecorder.EffectsListener {
-
- private static final String TAG = "CAM_VideoModule";
-
- // We number the request code from 1000 to avoid collision with Gallery.
- private static final int REQUEST_EFFECT_BACKDROPPER = 1000;
-
- private static final int CHECK_DISPLAY_ROTATION = 3;
- private static final int CLEAR_SCREEN_DELAY = 4;
- private static final int UPDATE_RECORD_TIME = 5;
- private static final int ENABLE_SHUTTER_BUTTON = 6;
- private static final int SHOW_TAP_TO_SNAPSHOT_TOAST = 7;
- private static final int SWITCH_CAMERA = 8;
- private static final int SWITCH_CAMERA_START_ANIMATION = 9;
-
- private static final int SCREEN_DELAY = 2 * 60 * 1000;
-
- private static final long SHUTTER_BUTTON_TIMEOUT = 500L; // 500ms
-
- /**
- * An unpublished intent flag requesting to start recording straight away
- * and return as soon as recording is stopped.
- * TODO: consider publishing by moving into MediaStore.
- */
- private static final String EXTRA_QUICK_CAPTURE =
- "android.intent.extra.quickCapture";
-
- // module fields
- private CameraActivity mActivity;
- private boolean mPaused;
- private int mCameraId;
- private Parameters mParameters;
-
- private boolean mIsInReviewMode;
- private boolean mSnapshotInProgress = false;
-
- private static final String EFFECT_BG_FROM_GALLERY = "gallery";
-
- private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
-
- private ComboPreferences mPreferences;
- private PreferenceGroup mPreferenceGroup;
- // Preference must be read before starting preview. We check this before starting
- // preview.
- private boolean mPreferenceRead;
-
- private boolean mIsVideoCaptureIntent;
- private boolean mQuickCapture;
-
- private MediaRecorder mMediaRecorder;
- private EffectsRecorder mEffectsRecorder;
- private boolean mEffectsDisplayResult;
-
- private int mEffectType = EffectsRecorder.EFFECT_NONE;
- private Object mEffectParameter = null;
- private String mEffectUriFromGallery = null;
- private String mPrefVideoEffectDefault;
- private boolean mResetEffect = true;
-
- private boolean mSwitchingCamera;
- private boolean mMediaRecorderRecording = false;
- private long mRecordingStartTime;
- private boolean mRecordingTimeCountsDown = false;
- private long mOnResumeTime;
- // The video file that the hardware camera is about to record into
- // (or is recording into.)
- private String mVideoFilename;
- private ParcelFileDescriptor mVideoFileDescriptor;
-
- // The video file that has already been recorded, and that is being
- // examined by the user.
- private String mCurrentVideoFilename;
- private Uri mCurrentVideoUri;
- private ContentValues mCurrentVideoValues;
-
- private CamcorderProfile mProfile;
-
- // The video duration limit. 0 menas no limit.
- private int mMaxVideoDurationInMs;
-
- // Time Lapse parameters.
- private boolean mCaptureTimeLapse = false;
- // Default 0. If it is larger than 0, the camcorder is in time lapse mode.
- private int mTimeBetweenTimeLapseFrameCaptureMs = 0;
-
- boolean mPreviewing = false; // True if preview is started.
- // The display rotation in degrees. This is only valid when mPreviewing is
- // true.
- private int mDisplayRotation;
- private int mCameraDisplayOrientation;
-
- private int mDesiredPreviewWidth;
- private int mDesiredPreviewHeight;
- private ContentResolver mContentResolver;
-
- private LocationManager mLocationManager;
- private OrientationManager mOrientationManager;
-
- private Surface mSurface;
- private int mPendingSwitchCameraId;
- private boolean mOpenCameraFail;
- private boolean mCameraDisabled;
- private final Handler mHandler = new MainHandler();
- private VideoUI mUI;
- private CameraProxy mCameraDevice;
-
- // The degrees of the device rotated clockwise from its natural orientation.
- private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
-
- private int mZoomValue; // The current zoom value.
-
- private boolean mRestoreFlash; // This is used to check if we need to restore the flash
- // status when going back from gallery.
-
- private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener =
- new MediaSaveService.OnMediaSavedListener() {
- @Override
- public void onMediaSaved(Uri uri) {
- if (uri != null) {
- mActivity.notifyNewMedia(uri);
- }
- }
- };
-
- private final MediaSaveService.OnMediaSavedListener mOnPhotoSavedListener =
- new MediaSaveService.OnMediaSavedListener() {
- @Override
- public void onMediaSaved(Uri uri) {
- if (uri != null) {
- mActivity.notifyNewMedia(uri);
- }
- }
- };
-
-
- protected class CameraOpenThread extends Thread {
- @Override
- public void run() {
- openCamera();
- }
- }
-
- private void openCamera() {
- try {
- if (mCameraDevice == null) {
- mCameraDevice = Util.openCamera(mActivity, mCameraId);
- }
- mParameters = mCameraDevice.getParameters();
- } catch (CameraHardwareException e) {
- mOpenCameraFail = true;
- } catch (CameraDisabledException e) {
- mCameraDisabled = true;
- }
- }
-
- // This Handler is used to post message back onto the main thread of the
- // application
- private class MainHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
-
- case ENABLE_SHUTTER_BUTTON:
- mUI.enableShutter(true);
- break;
-
- case CLEAR_SCREEN_DELAY: {
- mActivity.getWindow().clearFlags(
- WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- break;
- }
-
- case UPDATE_RECORD_TIME: {
- updateRecordingTime();
- break;
- }
-
- case CHECK_DISPLAY_ROTATION: {
- // Restart the preview if display rotation has changed.
- // Sometimes this happens when the device is held upside
- // down and camera app is opened. Rotation animation will
- // take some time and the rotation value we have got may be
- // wrong. Framework does not have a callback for this now.
- if ((Util.getDisplayRotation(mActivity) != mDisplayRotation)
- && !mMediaRecorderRecording && !mSwitchingCamera) {
- startPreview();
- }
- if (SystemClock.uptimeMillis() - mOnResumeTime < 5000) {
- mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION, 100);
- }
- break;
- }
-
- case SHOW_TAP_TO_SNAPSHOT_TOAST: {
- showTapToSnapshotToast();
- break;
- }
-
- case SWITCH_CAMERA: {
- switchCamera();
- break;
- }
-
- case SWITCH_CAMERA_START_ANIMATION: {
- //TODO:
- //((CameraScreenNail) mActivity.mCameraScreenNail).animateSwitchCamera();
-
- // Enable all camera controls.
- mSwitchingCamera = false;
- break;
- }
-
- default:
- Log.v(TAG, "Unhandled message: " + msg.what);
- break;
- }
- }
- }
-
- private BroadcastReceiver mReceiver = null;
-
- private class MyBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
- stopVideoRecording();
- } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
- Toast.makeText(mActivity,
- mActivity.getResources().getString(R.string.wait), Toast.LENGTH_LONG).show();
- }
- }
- }
-
- private String createName(long dateTaken) {
- Date date = new Date(dateTaken);
- SimpleDateFormat dateFormat = new SimpleDateFormat(
- mActivity.getString(R.string.video_file_name_format));
-
- return dateFormat.format(date);
- }
-
- private int getPreferredCameraId(ComboPreferences preferences) {
- int intentCameraId = Util.getCameraFacingIntentExtras(mActivity);
- if (intentCameraId != -1) {
- // Testing purpose. Launch a specific camera through the intent
- // extras.
- return intentCameraId;
- } else {
- return CameraSettings.readPreferredCameraId(preferences);
- }
- }
-
- private void initializeSurfaceView() {
- if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) { // API level < 16
- mUI.initializeSurfaceView();
- }
- }
-
- @Override
- public void init(CameraActivity activity, View root) {
- mActivity = activity;
- mUI = new VideoUI(activity, this, root);
- mPreferences = new ComboPreferences(mActivity);
- CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal());
- mCameraId = getPreferredCameraId(mPreferences);
-
- mPreferences.setLocalId(mActivity, mCameraId);
- CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
-
- mPrefVideoEffectDefault = mActivity.getString(R.string.pref_video_effect_default);
- resetEffect();
- mOrientationManager = new OrientationManager(mActivity);
-
- /*
- * To reduce startup time, we start the preview in another thread.
- * We make sure the preview is started at the end of onCreate.
- */
- CameraOpenThread cameraOpenThread = new CameraOpenThread();
- cameraOpenThread.start();
-
- mContentResolver = mActivity.getContentResolver();
-
- // Surface texture is from camera screen nail and startPreview needs it.
- // This must be done before startPreview.
- mIsVideoCaptureIntent = isVideoCaptureIntent();
- initializeSurfaceView();
-
- // Make sure camera device is opened.
- try {
- cameraOpenThread.join();
- if (mOpenCameraFail) {
- Util.showErrorAndFinish(mActivity, R.string.cannot_connect_camera);
- return;
- } else if (mCameraDisabled) {
- Util.showErrorAndFinish(mActivity, R.string.camera_disabled);
- return;
- }
- } catch (InterruptedException ex) {
- // ignore
- }
-
- readVideoPreferences();
- mUI.setPrefChangedListener(this);
-
- mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
- mLocationManager = new LocationManager(mActivity, null);
-
- mUI.setOrientationIndicator(0, false);
- setDisplayOrientation();
-
- mUI.showTimeLapseUI(mCaptureTimeLapse);
- initializeVideoSnapshot();
- resizeForPreviewAspectRatio();
-
- initializeVideoControl();
- mPendingSwitchCameraId = -1;
- mUI.updateOnScreenIndicators(mParameters, mPreferences);
-
- // Disable the shutter button if effects are ON since it might take
- // a little more time for the effects preview to be ready. We do not
- // want to allow recording before that happens. The shutter button
- // will be enabled when we get the message from effectsrecorder that
- // the preview is running. This becomes critical when the camera is
- // swapped.
- if (effectsActive()) {
- mUI.enableShutter(false);
- }
- }
-
- // SingleTapListener
- // Preview area is touched. Take a picture.
- @Override
- public void onSingleTapUp(View view, int x, int y) {
- if (mMediaRecorderRecording && effectsActive()) {
- new RotateTextToast(mActivity, R.string.disable_video_snapshot_hint,
- mOrientation).show();
- return;
- }
-
- MediaSaveService s = mActivity.getMediaSaveService();
- if (mPaused || mSnapshotInProgress || effectsActive() || s == null || s.isQueueFull()) {
- return;
- }
-
- if (!mMediaRecorderRecording) {
- // check for dismissing popup
- mUI.dismissPopup(true);
- return;
- }
-
- // Set rotation and gps data.
- int rotation = Util.getJpegRotation(mCameraId, mOrientation);
- mParameters.setRotation(rotation);
- Location loc = mLocationManager.getCurrentLocation();
- Util.setGpsParameters(mParameters, loc);
- mCameraDevice.setParameters(mParameters);
-
- Log.v(TAG, "Video snapshot start");
- mCameraDevice.takePicture(mHandler,
- null, null, null, new JpegPictureCallback(loc));
- showVideoSnapshotUI(true);
- mSnapshotInProgress = true;
- UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
- UsageStatistics.ACTION_CAPTURE_DONE, "VideoSnapshot");
- }
-
- @Override
- public void onStop() {}
-
- private void loadCameraPreferences() {
- CameraSettings settings = new CameraSettings(mActivity, mParameters,
- mCameraId, CameraHolder.instance().getCameraInfo());
- // Remove the video quality preference setting when the quality is given in the intent.
- mPreferenceGroup = filterPreferenceScreenByIntent(
- settings.getPreferenceGroup(R.xml.video_preferences));
- }
-
- private void initializeVideoControl() {
- loadCameraPreferences();
- mUI.initializePopup(mPreferenceGroup);
- if (effectsActive()) {
- mUI.overrideSettings(
- CameraSettings.KEY_VIDEO_QUALITY,
- Integer.toString(CamcorderProfile.QUALITY_480P));
- }
- }
-
- @Override
- public void onOrientationChanged(int orientation) {
- // We keep the last known orientation. So if the user first orient
- // the camera then point the camera to floor or sky, we still have
- // the correct orientation.
- if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) return;
- int newOrientation = Util.roundOrientation(orientation, mOrientation);
-
- if (mOrientation != newOrientation) {
- mOrientation = newOrientation;
- // The input of effects recorder is affected by
- // android.hardware.Camera.setDisplayOrientation. Its value only
- // compensates the camera orientation (no Display.getRotation).
- // So the orientation hint here should only consider sensor
- // orientation.
- if (effectsActive()) {
- mEffectsRecorder.setOrientationHint(mOrientation);
- }
- }
-
- // Show the toast after getting the first orientation changed.
- if (mHandler.hasMessages(SHOW_TAP_TO_SNAPSHOT_TOAST)) {
- mHandler.removeMessages(SHOW_TAP_TO_SNAPSHOT_TOAST);
- showTapToSnapshotToast();
- }
- }
-
- private void startPlayVideoActivity() {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setDataAndType(mCurrentVideoUri, convertOutputFormatToMimeType(mProfile.fileFormat));
- try {
- mActivity.startActivity(intent);
- } catch (ActivityNotFoundException ex) {
- Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
- }
- }
-
- @OnClickAttr
- public void onReviewPlayClicked(View v) {
- startPlayVideoActivity();
- }
-
- @OnClickAttr
- public void onReviewDoneClicked(View v) {
- mIsInReviewMode = false;
- doReturnToCaller(true);
- }
-
- @OnClickAttr
- public void onReviewCancelClicked(View v) {
- mIsInReviewMode = false;
- stopVideoRecording();
- doReturnToCaller(false);
- }
-
- @Override
- public boolean isInReviewMode() {
- return mIsInReviewMode;
- }
-
- private void onStopVideoRecording() {
- mEffectsDisplayResult = true;
- boolean recordFail = stopVideoRecording();
- if (mIsVideoCaptureIntent) {
- if (!effectsActive()) {
- if (mQuickCapture) {
- doReturnToCaller(!recordFail);
- } else if (!recordFail) {
- showCaptureResult();
- }
- }
- } else if (!recordFail){
- // Start capture animation.
- if (!mPaused && ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
- // The capture animation is disabled on ICS because we use SurfaceView
- // for preview during recording. When the recording is done, we switch
- // back to use SurfaceTexture for preview and we need to stop then start
- // the preview. This will cause the preview flicker since the preview
- // will not be continuous for a short period of time.
-
- mUI.animateFlash();
- Bitmap bitmap = getVideoThumbnail();
- if (bitmap != null) {
- mUI.animateCapture(bitmap);
- }
- }
- }
- }
-
- public void onProtectiveCurtainClick(View v) {
- // Consume clicks
- }
-
- @Override
- public void onShutterButtonClick() {
- if (mUI.collapseCameraControls() || mSwitchingCamera) return;
-
- boolean stop = mMediaRecorderRecording;
-
- if (stop) {
- onStopVideoRecording();
- } else {
- startVideoRecording();
- }
- mUI.enableShutter(false);
-
- // Keep the shutter button disabled when in video capture intent
- // mode and recording is stopped. It'll be re-enabled when
- // re-take button is clicked.
- if (!(mIsVideoCaptureIntent && stop)) {
- mHandler.sendEmptyMessageDelayed(
- ENABLE_SHUTTER_BUTTON, SHUTTER_BUTTON_TIMEOUT);
- }
- }
-
- @Override
- public void onShutterButtonFocus(boolean pressed) {
- mUI.setShutterPressed(pressed);
- }
-
- private void readVideoPreferences() {
- // The preference stores values from ListPreference and is thus string type for all values.
- // We need to convert it to int manually.
- String videoQuality = mPreferences.getString(CameraSettings.KEY_VIDEO_QUALITY,
- null);
- if (videoQuality == null) {
- // check for highest quality before setting default value
- videoQuality = CameraSettings.getSupportedHighestVideoQuality(mCameraId,
- mActivity.getResources().getString(R.string.pref_video_quality_default));
- mPreferences.edit().putString(CameraSettings.KEY_VIDEO_QUALITY, videoQuality);
- }
- int quality = Integer.valueOf(videoQuality);
-
- // Set video quality.
- Intent intent = mActivity.getIntent();
- if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
- int extraVideoQuality =
- intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
- if (extraVideoQuality > 0) {
- quality = CamcorderProfile.QUALITY_HIGH;
- } else { // 0 is mms.
- quality = CamcorderProfile.QUALITY_LOW;
- }
- }
-
- // Set video duration limit. The limit is read from the preference,
- // unless it is specified in the intent.
- if (intent.hasExtra(MediaStore.EXTRA_DURATION_LIMIT)) {
- int seconds =
- intent.getIntExtra(MediaStore.EXTRA_DURATION_LIMIT, 0);
- mMaxVideoDurationInMs = 1000 * seconds;
- } else {
- mMaxVideoDurationInMs = CameraSettings.getMaxVideoDuration(mActivity);
- }
-
- // Set effect
- mEffectType = CameraSettings.readEffectType(mPreferences);
- if (mEffectType != EffectsRecorder.EFFECT_NONE) {
- mEffectParameter = CameraSettings.readEffectParameter(mPreferences);
- // Set quality to be no higher than 480p.
- CamcorderProfile profile = CamcorderProfile.get(mCameraId, quality);
- if (profile.videoFrameHeight > 480) {
- quality = CamcorderProfile.QUALITY_480P;
- }
- } else {
- mEffectParameter = null;
- }
- // Read time lapse recording interval.
- if (ApiHelper.HAS_TIME_LAPSE_RECORDING) {
- String frameIntervalStr = mPreferences.getString(
- CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
- mActivity.getString(R.string.pref_video_time_lapse_frame_interval_default));
- mTimeBetweenTimeLapseFrameCaptureMs = Integer.parseInt(frameIntervalStr);
- mCaptureTimeLapse = (mTimeBetweenTimeLapseFrameCaptureMs != 0);
- }
- // TODO: This should be checked instead directly +1000.
- if (mCaptureTimeLapse) quality += 1000;
- mProfile = CamcorderProfile.get(mCameraId, quality);
- getDesiredPreviewSize();
- mPreferenceRead = true;
- }
-
- private void writeDefaultEffectToPrefs() {
- ComboPreferences.Editor editor = mPreferences.edit();
- editor.putString(CameraSettings.KEY_VIDEO_EFFECT,
- mActivity.getString(R.string.pref_video_effect_default));
- editor.apply();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- private void getDesiredPreviewSize() {
- mParameters = mCameraDevice.getParameters();
- if (ApiHelper.HAS_GET_SUPPORTED_VIDEO_SIZE) {
- if (mParameters.getSupportedVideoSizes() == null || effectsActive()) {
- mDesiredPreviewWidth = mProfile.videoFrameWidth;
- mDesiredPreviewHeight = mProfile.videoFrameHeight;
- } else { // Driver supports separates outputs for preview and video.
- List<Size> sizes = mParameters.getSupportedPreviewSizes();
- Size preferred = mParameters.getPreferredPreviewSizeForVideo();
- int product = preferred.width * preferred.height;
- Iterator<Size> it = sizes.iterator();
- // Remove the preview sizes that are not preferred.
- while (it.hasNext()) {
- Size size = it.next();
- if (size.width * size.height > product) {
- it.remove();
- }
- }
- Size optimalSize = Util.getOptimalPreviewSize(mActivity, sizes,
- (double) mProfile.videoFrameWidth / mProfile.videoFrameHeight);
- mDesiredPreviewWidth = optimalSize.width;
- mDesiredPreviewHeight = optimalSize.height;
- }
- } else {
- mDesiredPreviewWidth = mProfile.videoFrameWidth;
- mDesiredPreviewHeight = mProfile.videoFrameHeight;
- }
- mUI.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
- Log.v(TAG, "mDesiredPreviewWidth=" + mDesiredPreviewWidth +
- ". mDesiredPreviewHeight=" + mDesiredPreviewHeight);
- }
-
- private void resizeForPreviewAspectRatio() {
- mUI.setAspectRatio(
- (double) mProfile.videoFrameWidth / mProfile.videoFrameHeight);
- }
-
- @Override
- public void installIntentFilter() {
- // install an intent filter to receive SD card related events.
- IntentFilter intentFilter =
- new IntentFilter(Intent.ACTION_MEDIA_EJECT);
- intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
- intentFilter.addDataScheme("file");
- mReceiver = new MyBroadcastReceiver();
- mActivity.registerReceiver(mReceiver, intentFilter);
- }
-
- @Override
- public void onResumeBeforeSuper() {
- mPaused = false;
- }
-
- @Override
- public void onResumeAfterSuper() {
- if (mOpenCameraFail || mCameraDisabled)
- return;
- mUI.enableShutter(false);
- mZoomValue = 0;
-
- showVideoSnapshotUI(false);
-
- if (!mPreviewing) {
- resetEffect();
- openCamera();
- if (mOpenCameraFail) {
- Util.showErrorAndFinish(mActivity,
- R.string.cannot_connect_camera);
- return;
- } else if (mCameraDisabled) {
- Util.showErrorAndFinish(mActivity, R.string.camera_disabled);
- return;
- }
- readVideoPreferences();
- resizeForPreviewAspectRatio();
- startPreview();
- } else {
- // preview already started
- mUI.enableShutter(true);
- }
-
- // Initializing it here after the preview is started.
- mUI.initializeZoom(mParameters);
-
- keepScreenOnAwhile();
-
- // Initialize location service.
- boolean recordLocation = RecordLocationPreference.get(mPreferences,
- mContentResolver);
- mLocationManager.recordLocation(recordLocation);
-
- if (mPreviewing) {
- mOnResumeTime = SystemClock.uptimeMillis();
- mHandler.sendEmptyMessageDelayed(CHECK_DISPLAY_ROTATION, 100);
- }
- // Dismiss open menu if exists.
- PopupManager.getInstance(mActivity).notifyShowPopup(null);
-
- UsageStatistics.onContentViewChanged(
- UsageStatistics.COMPONENT_CAMERA, "VideoModule");
- }
-
- private void setDisplayOrientation() {
- mDisplayRotation = Util.getDisplayRotation(mActivity);
- mCameraDisplayOrientation = Util.getDisplayOrientation(mDisplayRotation, mCameraId);
- // Change the camera display orientation
- if (mCameraDevice != null) {
- mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation);
- }
- }
-
- @Override
- public void updateCameraOrientation() {
- if (mMediaRecorderRecording) return;
- if (mDisplayRotation != Util.getDisplayRotation(mActivity)) {
- setDisplayOrientation();
- }
- }
-
- @Override
- public int onZoomChanged(int index) {
- // Not useful to change zoom value when the activity is paused.
- if (mPaused) return index;
- mZoomValue = index;
- if (mParameters == null || mCameraDevice == null) return index;
- // Set zoom parameters asynchronously
- mParameters.setZoom(mZoomValue);
- mCameraDevice.setParameters(mParameters);
- Parameters p = mCameraDevice.getParameters();
- if (p != null) return p.getZoom();
- return index;
- }
-
- private void startPreview() {
- Log.v(TAG, "startPreview");
-
- SurfaceTexture surfaceTexture = mUI.getSurfaceTexture();
- if (!mPreferenceRead || surfaceTexture == null || mPaused == true) return;
-
- mCameraDevice.setErrorCallback(mErrorCallback);
- if (mPreviewing == true) {
- stopPreview();
- if (effectsActive() && mEffectsRecorder != null) {
- mEffectsRecorder.release();
- mEffectsRecorder = null;
- }
- }
-
- setDisplayOrientation();
- mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation);
- setCameraParameters();
-
- try {
- if (!effectsActive()) {
- mCameraDevice.setPreviewTexture(surfaceTexture);
- mCameraDevice.startPreview();
- mPreviewing = true;
- onPreviewStarted();
- } else {
- initializeEffectsPreview();
- mEffectsRecorder.startPreview();
- mPreviewing = true;
- onPreviewStarted();
- }
- } catch (Throwable ex) {
- closeCamera();
- throw new RuntimeException("startPreview failed", ex);
- } finally {
- if (mOpenCameraFail) {
- Util.showErrorAndFinish(mActivity, R.string.cannot_connect_camera);
- } else if (mCameraDisabled) {
- Util.showErrorAndFinish(mActivity, R.string.camera_disabled);
- }
- }
-
- }
-
- private void onPreviewStarted() {
- mUI.enableShutter(true);
- }
-
- @Override
- public void stopPreview() {
- if (!mPreviewing) return;
- mCameraDevice.stopPreview();
- mPreviewing = false;
- }
-
- // Closing the effects out. Will shut down the effects graph.
- private void closeEffects() {
- Log.v(TAG, "Closing effects");
- mEffectType = EffectsRecorder.EFFECT_NONE;
- if (mEffectsRecorder == null) {
- Log.d(TAG, "Effects are already closed. Nothing to do");
- return;
- }
- // This call can handle the case where the camera is already released
- // after the recording has been stopped.
- mEffectsRecorder.release();
- mEffectsRecorder = null;
- }
-
- // By default, we want to close the effects as well with the camera.
- private void closeCamera() {
- closeCamera(true);
- }
-
- // In certain cases, when the effects are active, we may want to shutdown
- // only the camera related parts, and handle closing the effects in the
- // effectsUpdate callback.
- // For example, in onPause, we want to make the camera available to
- // outside world immediately, however, want to wait till the effects
- // callback to shut down the effects. In such a case, we just disconnect
- // the effects from the camera by calling disconnectCamera. That way
- // the effects can handle that when shutting down.
- //
- // @param closeEffectsAlso - indicates whether we want to close the
- // effects also along with the camera.
- private void closeCamera(boolean closeEffectsAlso) {
- Log.v(TAG, "closeCamera");
- if (mCameraDevice == null) {
- Log.d(TAG, "already stopped.");
- return;
- }
-
- if (mEffectsRecorder != null) {
- // Disconnect the camera from effects so that camera is ready to
- // be released to the outside world.
- mEffectsRecorder.disconnectCamera();
- }
- if (closeEffectsAlso) closeEffects();
- mCameraDevice.setZoomChangeListener(null);
- mCameraDevice.setErrorCallback(null);
- CameraHolder.instance().release();
- mCameraDevice = null;
- mPreviewing = false;
- mSnapshotInProgress = false;
- }
-
- private void releasePreviewResources() {
- if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
- mUI.hideSurfaceView();
- }
- }
-
- @Override
- public void onPauseBeforeSuper() {
- mPaused = true;
-
- if (mMediaRecorderRecording) {
- // Camera will be released in onStopVideoRecording.
- onStopVideoRecording();
- } else {
- closeCamera();
- if (!effectsActive()) releaseMediaRecorder();
- }
- if (effectsActive()) {
- // If the effects are active, make sure we tell the graph that the
- // surfacetexture is not valid anymore. Disconnect the graph from
- // the display. This should be done before releasing the surface
- // texture.
- mEffectsRecorder.disconnectDisplay();
- } else {
- // Close the file descriptor and clear the video namer only if the
- // effects are not active. If effects are active, we need to wait
- // till we get the callback from the Effects that the graph is done
- // recording. That also needs a change in the stopVideoRecording()
- // call to not call closeCamera if the effects are active, because
- // that will close down the effects are well, thus making this if
- // condition invalid.
- closeVideoFileDescriptor();
- }
-
- releasePreviewResources();
-
- if (mReceiver != null) {
- mActivity.unregisterReceiver(mReceiver);
- mReceiver = null;
- }
- resetScreenOn();
-
- if (mLocationManager != null) mLocationManager.recordLocation(false);
-
- mHandler.removeMessages(CHECK_DISPLAY_ROTATION);
- mHandler.removeMessages(SWITCH_CAMERA);
- mHandler.removeMessages(SWITCH_CAMERA_START_ANIMATION);
- mPendingSwitchCameraId = -1;
- mSwitchingCamera = false;
- mPreferenceRead = false;
- // Call onPause after stopping video recording. So the camera can be
- // released as soon as possible.
- }
-
- @Override
- public void onPauseAfterSuper() {
- }
-
- @Override
- public void onUserInteraction() {
- if (!mMediaRecorderRecording && !mActivity.isFinishing()) {
- keepScreenOnAwhile();
- }
- }
-
- @Override
- public boolean onBackPressed() {
- if (mPaused) return true;
- if (mMediaRecorderRecording) {
- onStopVideoRecording();
- return true;
- } else if (mUI.hidePieRenderer()) {
- return true;
- } else {
- return mUI.removeTopLevelPopup();
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- // Do not handle any key if the activity is paused.
- if (mPaused) {
- return true;
- }
-
- switch (keyCode) {
- case KeyEvent.KEYCODE_CAMERA:
- if (event.getRepeatCount() == 0) {
- mUI.clickShutter();
- return true;
- }
- break;
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (event.getRepeatCount() == 0) {
- mUI.clickShutter();
- return true;
- }
- break;
- case KeyEvent.KEYCODE_MENU:
- if (mMediaRecorderRecording) return true;
- break;
- }
- return false;
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_CAMERA:
- mUI.pressShutter(false);
- return true;
- }
- return false;
- }
-
- @Override
- public boolean isVideoCaptureIntent() {
- String action = mActivity.getIntent().getAction();
- return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
- }
-
- private void doReturnToCaller(boolean valid) {
- Intent resultIntent = new Intent();
- int resultCode;
- if (valid) {
- resultCode = Activity.RESULT_OK;
- resultIntent.setData(mCurrentVideoUri);
- } else {
- resultCode = Activity.RESULT_CANCELED;
- }
- mActivity.setResultEx(resultCode, resultIntent);
- mActivity.finish();
- }
-
- private void cleanupEmptyFile() {
- if (mVideoFilename != null) {
- File f = new File(mVideoFilename);
- if (f.length() == 0 && f.delete()) {
- Log.v(TAG, "Empty video file deleted: " + mVideoFilename);
- mVideoFilename = null;
- }
- }
- }
-
- private void setupMediaRecorderPreviewDisplay() {
- // Nothing to do here if using SurfaceTexture.
- if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
- // We stop the preview here before unlocking the device because we
- // need to change the SurfaceTexture to SurfaceView for preview.
- stopPreview();
- mCameraDevice.setPreviewDisplay(mUI.getSurfaceHolder());
- // The orientation for SurfaceTexture is different from that for
- // SurfaceView. For SurfaceTexture we don't need to consider the
- // display rotation. Just consider the sensor's orientation and we
- // will set the orientation correctly when showing the texture.
- // Gallery will handle the orientation for the preview. For
- // SurfaceView we will have to take everything into account so the
- // display rotation is considered.
- mCameraDevice.setDisplayOrientation(
- Util.getDisplayOrientation(mDisplayRotation, mCameraId));
- mCameraDevice.startPreview();
- mPreviewing = true;
- mMediaRecorder.setPreviewDisplay(mUI.getSurfaceHolder().getSurface());
- }
- }
-
- // Prepares media recorder.
- private void initializeRecorder() {
- Log.v(TAG, "initializeRecorder");
- // If the mCameraDevice is null, then this activity is going to finish
- if (mCameraDevice == null) return;
-
- if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
- // Set the SurfaceView to visible so the surface gets created.
- // surfaceCreated() is called immediately when the visibility is
- // changed to visible. Thus, mSurfaceViewReady should become true
- // right after calling setVisibility().
- mUI.showSurfaceView();
- }
-
- Intent intent = mActivity.getIntent();
- Bundle myExtras = intent.getExtras();
-
- long requestedSizeLimit = 0;
- closeVideoFileDescriptor();
- if (mIsVideoCaptureIntent && myExtras != null) {
- Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
- if (saveUri != null) {
- try {
- mVideoFileDescriptor =
- mContentResolver.openFileDescriptor(saveUri, "rw");
- mCurrentVideoUri = saveUri;
- } catch (java.io.FileNotFoundException ex) {
- // invalid uri
- Log.e(TAG, ex.toString());
- }
- }
- requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
- }
- mMediaRecorder = new MediaRecorder();
-
- setupMediaRecorderPreviewDisplay();
- // Unlock the camera object before passing it to media recorder.
- mCameraDevice.unlock();
- mMediaRecorder.setCamera(mCameraDevice.getCamera());
- if (!mCaptureTimeLapse) {
- mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
- }
- mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
- mMediaRecorder.setProfile(mProfile);
- mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
- if (mCaptureTimeLapse) {
- double fps = 1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs;
- setCaptureRate(mMediaRecorder, fps);
- }
-
- setRecordLocation();
-
- // Set output file.
- // Try Uri in the intent first. If it doesn't exist, use our own
- // instead.
- if (mVideoFileDescriptor != null) {
- mMediaRecorder.setOutputFile(mVideoFileDescriptor.getFileDescriptor());
- } else {
- generateVideoFilename(mProfile.fileFormat);
- mMediaRecorder.setOutputFile(mVideoFilename);
- }
-
- // Set maximum file size.
- long maxFileSize = mActivity.getStorageSpace() - Storage.LOW_STORAGE_THRESHOLD;
- if (requestedSizeLimit > 0 && requestedSizeLimit < maxFileSize) {
- maxFileSize = requestedSizeLimit;
- }
-
- try {
- mMediaRecorder.setMaxFileSize(maxFileSize);
- } catch (RuntimeException exception) {
- // We are going to ignore failure of setMaxFileSize here, as
- // a) The composer selected may simply not support it, or
- // b) The underlying media framework may not handle 64-bit range
- // on the size restriction.
- }
-
- // See android.hardware.Camera.Parameters.setRotation for
- // documentation.
- // Note that mOrientation here is the device orientation, which is the opposite of
- // what activity.getWindowManager().getDefaultDisplay().getRotation() would return,
- // which is the orientation the graphics need to rotate in order to render correctly.
- int rotation = 0;
- if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
- if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
- rotation = (info.orientation - mOrientation + 360) % 360;
- } else { // back-facing camera
- rotation = (info.orientation + mOrientation) % 360;
- }
- }
- mMediaRecorder.setOrientationHint(rotation);
-
- try {
- mMediaRecorder.prepare();
- } catch (IOException e) {
- Log.e(TAG, "prepare failed for " + mVideoFilename, e);
- releaseMediaRecorder();
- throw new RuntimeException(e);
- }
-
- mMediaRecorder.setOnErrorListener(this);
- mMediaRecorder.setOnInfoListener(this);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- private static void setCaptureRate(MediaRecorder recorder, double fps) {
- recorder.setCaptureRate(fps);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- private void setRecordLocation() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Location loc = mLocationManager.getCurrentLocation();
- if (loc != null) {
- mMediaRecorder.setLocation((float) loc.getLatitude(),
- (float) loc.getLongitude());
- }
- }
- }
-
- private void initializeEffectsPreview() {
- Log.v(TAG, "initializeEffectsPreview");
- // If the mCameraDevice is null, then this activity is going to finish
- if (mCameraDevice == null) return;
-
- boolean inLandscape = (mActivity.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE);
-
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
-
- mEffectsDisplayResult = false;
- mEffectsRecorder = new EffectsRecorder(mActivity);
-
- // TODO: Confirm none of the following need to go to initializeEffectsRecording()
- // and none of these change even when the preview is not refreshed.
- mEffectsRecorder.setCameraDisplayOrientation(mCameraDisplayOrientation);
- mEffectsRecorder.setCamera(mCameraDevice);
- mEffectsRecorder.setCameraFacing(info.facing);
- mEffectsRecorder.setProfile(mProfile);
- mEffectsRecorder.setEffectsListener(this);
- mEffectsRecorder.setOnInfoListener(this);
- mEffectsRecorder.setOnErrorListener(this);
-
- // The input of effects recorder is affected by
- // android.hardware.Camera.setDisplayOrientation. Its value only
- // compensates the camera orientation (no Display.getRotation). So the
- // orientation hint here should only consider sensor orientation.
- int orientation = 0;
- if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
- orientation = mOrientation;
- }
- mEffectsRecorder.setOrientationHint(orientation);
-
- mEffectsRecorder.setPreviewSurfaceTexture(mUI.getSurfaceTexture(),
- mUI.getPreviewWidth(), mUI.getPreviewHeight());
-
- if (mEffectType == EffectsRecorder.EFFECT_BACKDROPPER &&
- ((String) mEffectParameter).equals(EFFECT_BG_FROM_GALLERY)) {
- mEffectsRecorder.setEffect(mEffectType, mEffectUriFromGallery);
- } else {
- mEffectsRecorder.setEffect(mEffectType, mEffectParameter);
- }
- }
-
- private void initializeEffectsRecording() {
- Log.v(TAG, "initializeEffectsRecording");
-
- Intent intent = mActivity.getIntent();
- Bundle myExtras = intent.getExtras();
-
- long requestedSizeLimit = 0;
- closeVideoFileDescriptor();
- if (mIsVideoCaptureIntent && myExtras != null) {
- Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
- if (saveUri != null) {
- try {
- mVideoFileDescriptor =
- mContentResolver.openFileDescriptor(saveUri, "rw");
- mCurrentVideoUri = saveUri;
- } catch (java.io.FileNotFoundException ex) {
- // invalid uri
- Log.e(TAG, ex.toString());
- }
- }
- requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
- }
-
- mEffectsRecorder.setProfile(mProfile);
- // important to set the capture rate to zero if not timelapsed, since the
- // effectsrecorder object does not get created again for each recording
- // session
- if (mCaptureTimeLapse) {
- mEffectsRecorder.setCaptureRate((1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs));
- } else {
- mEffectsRecorder.setCaptureRate(0);
- }
-
- // Set output file
- if (mVideoFileDescriptor != null) {
- mEffectsRecorder.setOutputFile(mVideoFileDescriptor.getFileDescriptor());
- } else {
- generateVideoFilename(mProfile.fileFormat);
- mEffectsRecorder.setOutputFile(mVideoFilename);
- }
-
- // Set maximum file size.
- long maxFileSize = mActivity.getStorageSpace() - Storage.LOW_STORAGE_THRESHOLD;
- if (requestedSizeLimit > 0 && requestedSizeLimit < maxFileSize) {
- maxFileSize = requestedSizeLimit;
- }
- mEffectsRecorder.setMaxFileSize(maxFileSize);
- mEffectsRecorder.setMaxDuration(mMaxVideoDurationInMs);
- }
-
-
- private void releaseMediaRecorder() {
- Log.v(TAG, "Releasing media recorder.");
- if (mMediaRecorder != null) {
- cleanupEmptyFile();
- mMediaRecorder.reset();
- mMediaRecorder.release();
- mMediaRecorder = null;
- }
- mVideoFilename = null;
- }
-
- private void releaseEffectsRecorder() {
- Log.v(TAG, "Releasing effects recorder.");
- if (mEffectsRecorder != null) {
- cleanupEmptyFile();
- mEffectsRecorder.release();
- mEffectsRecorder = null;
- }
- mEffectType = EffectsRecorder.EFFECT_NONE;
- mVideoFilename = null;
- }
-
- private void generateVideoFilename(int outputFileFormat) {
- long dateTaken = System.currentTimeMillis();
- String title = createName(dateTaken);
- // Used when emailing.
- String filename = title + convertOutputFormatToFileExt(outputFileFormat);
- String mime = convertOutputFormatToMimeType(outputFileFormat);
- String path = Storage.DIRECTORY + '/' + filename;
- String tmpPath = path + ".tmp";
- mCurrentVideoValues = new ContentValues(9);
- mCurrentVideoValues.put(Video.Media.TITLE, title);
- mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, filename);
- mCurrentVideoValues.put(Video.Media.DATE_TAKEN, dateTaken);
- mCurrentVideoValues.put(MediaColumns.DATE_MODIFIED, dateTaken / 1000);
- mCurrentVideoValues.put(Video.Media.MIME_TYPE, mime);
- mCurrentVideoValues.put(Video.Media.DATA, path);
- mCurrentVideoValues.put(Video.Media.RESOLUTION,
- Integer.toString(mProfile.videoFrameWidth) + "x" +
- Integer.toString(mProfile.videoFrameHeight));
- Location loc = mLocationManager.getCurrentLocation();
- if (loc != null) {
- mCurrentVideoValues.put(Video.Media.LATITUDE, loc.getLatitude());
- mCurrentVideoValues.put(Video.Media.LONGITUDE, loc.getLongitude());
- }
- mVideoFilename = tmpPath;
- Log.v(TAG, "New video filename: " + mVideoFilename);
- }
-
- private void saveVideo() {
- if (mVideoFileDescriptor == null) {
- long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
- if (duration > 0) {
- if (mCaptureTimeLapse) {
- duration = getTimeLapseVideoLength(duration);
- }
- } else {
- Log.w(TAG, "Video duration <= 0 : " + duration);
- }
- mActivity.getMediaSaveService().addVideo(mCurrentVideoFilename,
- duration, mCurrentVideoValues,
- mOnVideoSavedListener, mContentResolver);
- }
- mCurrentVideoValues = null;
- }
-
- private void deleteVideoFile(String fileName) {
- Log.v(TAG, "Deleting video " + fileName);
- File f = new File(fileName);
- if (!f.delete()) {
- Log.v(TAG, "Could not delete " + fileName);
- }
- }
-
- private PreferenceGroup filterPreferenceScreenByIntent(
- PreferenceGroup screen) {
- Intent intent = mActivity.getIntent();
- if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
- CameraSettings.removePreferenceFromScreen(screen,
- CameraSettings.KEY_VIDEO_QUALITY);
- }
-
- if (intent.hasExtra(MediaStore.EXTRA_DURATION_LIMIT)) {
- CameraSettings.removePreferenceFromScreen(screen,
- CameraSettings.KEY_VIDEO_QUALITY);
- }
- return screen;
- }
-
- // from MediaRecorder.OnErrorListener
- @Override
- public void onError(MediaRecorder mr, int what, int extra) {
- Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
- if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
- // We may have run out of space on the sdcard.
- stopVideoRecording();
- mActivity.updateStorageSpaceAndHint();
- }
- }
-
- // from MediaRecorder.OnInfoListener
- @Override
- public void onInfo(MediaRecorder mr, int what, int extra) {
- if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
- if (mMediaRecorderRecording) onStopVideoRecording();
- } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
- if (mMediaRecorderRecording) onStopVideoRecording();
-
- // Show the toast.
- Toast.makeText(mActivity, R.string.video_reach_size_limit,
- Toast.LENGTH_LONG).show();
- }
- }
-
- /*
- * Make sure we're not recording music playing in the background, ask the
- * MediaPlaybackService to pause playback.
- */
- private void pauseAudioPlayback() {
- // Shamelessly copied from MediaPlaybackService.java, which
- // should be public, but isn't.
- Intent i = new Intent("com.android.music.musicservicecommand");
- i.putExtra("command", "pause");
-
- mActivity.sendBroadcast(i);
- }
-
- // For testing.
- public boolean isRecording() {
- return mMediaRecorderRecording;
- }
-
- private void startVideoRecording() {
- Log.v(TAG, "startVideoRecording");
- mUI.cancelAnimations();
- mUI.setSwipingEnabled(false);
-
- mActivity.updateStorageSpaceAndHint();
- if (mActivity.getStorageSpace() <= Storage.LOW_STORAGE_THRESHOLD) {
- Log.v(TAG, "Storage issue, ignore the start request");
- return;
- }
-
- //??
- //if (!mCameraDevice.waitDone()) return;
- mCurrentVideoUri = null;
- if (effectsActive()) {
- initializeEffectsRecording();
- if (mEffectsRecorder == null) {
- Log.e(TAG, "Fail to initialize effect recorder");
- return;
- }
- } else {
- initializeRecorder();
- if (mMediaRecorder == null) {
- Log.e(TAG, "Fail to initialize media recorder");
- return;
- }
- }
-
- pauseAudioPlayback();
-
- if (effectsActive()) {
- try {
- mEffectsRecorder.startRecording();
- } catch (RuntimeException e) {
- Log.e(TAG, "Could not start effects recorder. ", e);
- releaseEffectsRecorder();
- return;
- }
- } else {
- try {
- mMediaRecorder.start(); // Recording is now started
- } catch (RuntimeException e) {
- Log.e(TAG, "Could not start media recorder. ", e);
- releaseMediaRecorder();
- // If start fails, frameworks will not lock the camera for us.
- mCameraDevice.lock();
- return;
- }
- }
-
- // Make sure the video recording has started before announcing
- // this in accessibility.
- AccessibilityUtils.makeAnnouncement(mUI.getShutterButton(),
- mActivity.getString(R.string.video_recording_started));
-
- // The parameters might have been altered by MediaRecorder already.
- // We need to force mCameraDevice to refresh before getting it.
- mCameraDevice.refreshParameters();
- // The parameters may have been changed by MediaRecorder upon starting
- // recording. We need to alter the parameters if we support camcorder
- // zoom. To reduce latency when setting the parameters during zoom, we
- // update mParameters here once.
- if (ApiHelper.HAS_ZOOM_WHEN_RECORDING) {
- mParameters = mCameraDevice.getParameters();
- }
-
- mUI.enableCameraControls(false);
-
- mMediaRecorderRecording = true;
- mOrientationManager.lockOrientation();
- mRecordingStartTime = SystemClock.uptimeMillis();
- mUI.showRecordingUI(true, mParameters.isZoomSupported());
-
- updateRecordingTime();
- keepScreenOn();
- UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
- UsageStatistics.ACTION_CAPTURE_START, "Video");
- }
-
- private Bitmap getVideoThumbnail() {
- Bitmap bitmap = null;
- if (mVideoFileDescriptor != null) {
- bitmap = Thumbnail.createVideoThumbnailBitmap(mVideoFileDescriptor.getFileDescriptor(),
- mDesiredPreviewWidth);
- } else if (mCurrentVideoFilename != null) {
- bitmap = Thumbnail.createVideoThumbnailBitmap(mCurrentVideoFilename,
- mDesiredPreviewWidth);
- }
- if (bitmap != null) {
- // MetadataRetriever already rotates the thumbnail. We should rotate
- // it to match the UI orientation (and mirror if it is front-facing camera).
- CameraInfo[] info = CameraHolder.instance().getCameraInfo();
- boolean mirror = (info[mCameraId].facing == CameraInfo.CAMERA_FACING_FRONT);
- bitmap = Util.rotateAndMirror(bitmap, 0, mirror);
- }
- return bitmap;
- }
-
- private void showCaptureResult() {
- mIsInReviewMode = true;
- Bitmap bitmap = getVideoThumbnail();
- if (bitmap != null) {
- mUI.showReviewImage(bitmap);
- }
- mUI.showReviewControls();
- mUI.enableCameraControls(false);
- mUI.showTimeLapseUI(false);
- }
-
- private void hideAlert() {
- mUI.enableCameraControls(true);
- mUI.hideReviewUI();
- if (mCaptureTimeLapse) {
- mUI.showTimeLapseUI(true);
- }
- }
-
- private boolean stopVideoRecording() {
- Log.v(TAG, "stopVideoRecording");
- mUI.setSwipingEnabled(true);
- mUI.showSwitcher();
-
- boolean fail = false;
- if (mMediaRecorderRecording) {
- boolean shouldAddToMediaStoreNow = false;
-
- try {
- if (effectsActive()) {
- // This is asynchronous, so we can't add to media store now because thumbnail
- // may not be ready. In such case saveVideo() is called later
- // through a callback from the MediaEncoderFilter to EffectsRecorder,
- // and then to the VideoModule.
- mEffectsRecorder.stopRecording();
- } else {
- mMediaRecorder.setOnErrorListener(null);
- mMediaRecorder.setOnInfoListener(null);
- mMediaRecorder.stop();
- shouldAddToMediaStoreNow = true;
- }
- mCurrentVideoFilename = mVideoFilename;
- Log.v(TAG, "stopVideoRecording: Setting current video filename: "
- + mCurrentVideoFilename);
- AccessibilityUtils.makeAnnouncement(mUI.getShutterButton(),
- mActivity.getString(R.string.video_recording_stopped));
- } catch (RuntimeException e) {
- Log.e(TAG, "stop fail", e);
- if (mVideoFilename != null) deleteVideoFile(mVideoFilename);
- fail = true;
- }
- mMediaRecorderRecording = false;
- mOrientationManager.unlockOrientation();
-
- // If the activity is paused, this means activity is interrupted
- // during recording. Release the camera as soon as possible because
- // face unlock or other applications may need to use the camera.
- // However, if the effects are active, then we can only release the
- // camera and cannot release the effects recorder since that will
- // stop the graph. It is possible to separate out the Camera release
- // part and the effects release part. However, the effects recorder
- // does hold on to the camera, hence, it needs to be "disconnected"
- // from the camera in the closeCamera call.
- if (mPaused) {
- // Closing only the camera part if effects active. Effects will
- // be closed in the callback from effects.
- boolean closeEffects = !effectsActive();
- closeCamera(closeEffects);
- }
-
- mUI.showRecordingUI(false, mParameters.isZoomSupported());
- if (!mIsVideoCaptureIntent) {
- mUI.enableCameraControls(true);
- }
- // The orientation was fixed during video recording. Now make it
- // reflect the device orientation as video recording is stopped.
- mUI.setOrientationIndicator(0, true);
- keepScreenOnAwhile();
- if (shouldAddToMediaStoreNow) {
- saveVideo();
- }
- }
- // always release media recorder if no effects running
- if (!effectsActive()) {
- releaseMediaRecorder();
- if (!mPaused) {
- mCameraDevice.lock();
- if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
- stopPreview();
- mUI.hideSurfaceView();
- // Switch back to use SurfaceTexture for preview.
- startPreview();
- }
- }
- }
- // Update the parameters here because the parameters might have been altered
- // by MediaRecorder.
- if (!mPaused) mParameters = mCameraDevice.getParameters();
- UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
- fail ? UsageStatistics.ACTION_CAPTURE_FAIL :
- UsageStatistics.ACTION_CAPTURE_DONE, "Video",
- SystemClock.uptimeMillis() - mRecordingStartTime);
- return fail;
- }
-
- private void resetScreenOn() {
- mHandler.removeMessages(CLEAR_SCREEN_DELAY);
- mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
-
- private void keepScreenOnAwhile() {
- mHandler.removeMessages(CLEAR_SCREEN_DELAY);
- mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
- }
-
- private void keepScreenOn() {
- mHandler.removeMessages(CLEAR_SCREEN_DELAY);
- mActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
-
- private static String millisecondToTimeString(long milliSeconds, boolean displayCentiSeconds) {
- long seconds = milliSeconds / 1000; // round down to compute seconds
- long minutes = seconds / 60;
- long hours = minutes / 60;
- long remainderMinutes = minutes - (hours * 60);
- long remainderSeconds = seconds - (minutes * 60);
-
- StringBuilder timeStringBuilder = new StringBuilder();
-
- // Hours
- if (hours > 0) {
- if (hours < 10) {
- timeStringBuilder.append('0');
- }
- timeStringBuilder.append(hours);
-
- timeStringBuilder.append(':');
- }
-
- // Minutes
- if (remainderMinutes < 10) {
- timeStringBuilder.append('0');
- }
- timeStringBuilder.append(remainderMinutes);
- timeStringBuilder.append(':');
-
- // Seconds
- if (remainderSeconds < 10) {
- timeStringBuilder.append('0');
- }
- timeStringBuilder.append(remainderSeconds);
-
- // Centi seconds
- if (displayCentiSeconds) {
- timeStringBuilder.append('.');
- long remainderCentiSeconds = (milliSeconds - seconds * 1000) / 10;
- if (remainderCentiSeconds < 10) {
- timeStringBuilder.append('0');
- }
- timeStringBuilder.append(remainderCentiSeconds);
- }
-
- return timeStringBuilder.toString();
- }
-
- private long getTimeLapseVideoLength(long deltaMs) {
- // For better approximation calculate fractional number of frames captured.
- // This will update the video time at a higher resolution.
- double numberOfFrames = (double) deltaMs / mTimeBetweenTimeLapseFrameCaptureMs;
- return (long) (numberOfFrames / mProfile.videoFrameRate * 1000);
- }
-
- private void updateRecordingTime() {
- if (!mMediaRecorderRecording) {
- return;
- }
- long now = SystemClock.uptimeMillis();
- long delta = now - mRecordingStartTime;
-
- // Starting a minute before reaching the max duration
- // limit, we'll countdown the remaining time instead.
- boolean countdownRemainingTime = (mMaxVideoDurationInMs != 0
- && delta >= mMaxVideoDurationInMs - 60000);
-
- long deltaAdjusted = delta;
- if (countdownRemainingTime) {
- deltaAdjusted = Math.max(0, mMaxVideoDurationInMs - deltaAdjusted) + 999;
- }
- String text;
-
- long targetNextUpdateDelay;
- if (!mCaptureTimeLapse) {
- text = millisecondToTimeString(deltaAdjusted, false);
- targetNextUpdateDelay = 1000;
- } else {
- // The length of time lapse video is different from the length
- // of the actual wall clock time elapsed. Display the video length
- // only in format hh:mm:ss.dd, where dd are the centi seconds.
- text = millisecondToTimeString(getTimeLapseVideoLength(delta), true);
- targetNextUpdateDelay = mTimeBetweenTimeLapseFrameCaptureMs;
- }
-
- mUI.setRecordingTime(text);
-
- if (mRecordingTimeCountsDown != countdownRemainingTime) {
- // Avoid setting the color on every update, do it only
- // when it needs changing.
- mRecordingTimeCountsDown = countdownRemainingTime;
-
- int color = mActivity.getResources().getColor(countdownRemainingTime
- ? R.color.recording_time_remaining_text
- : R.color.recording_time_elapsed_text);
-
- mUI.setRecordingTimeTextColor(color);
- }
-
- long actualNextUpdateDelay = targetNextUpdateDelay - (delta % targetNextUpdateDelay);
- mHandler.sendEmptyMessageDelayed(
- UPDATE_RECORD_TIME, actualNextUpdateDelay);
- }
-
- private static boolean isSupported(String value, List<String> supported) {
- return supported == null ? false : supported.indexOf(value) >= 0;
- }
-
- @SuppressWarnings("deprecation")
- private void setCameraParameters() {
- mParameters.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
- int[] fpsRange = Util.getMaxPreviewFpsRange(mParameters);
- if (fpsRange.length > 0) {
- mParameters.setPreviewFpsRange(
- fpsRange[Parameters.PREVIEW_FPS_MIN_INDEX],
- fpsRange[Parameters.PREVIEW_FPS_MAX_INDEX]);
- } else {
- mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
- }
-
- // Set flash mode.
- String flashMode;
- if (mUI.isVisible()) {
- flashMode = mPreferences.getString(
- CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
- mActivity.getString(R.string.pref_camera_video_flashmode_default));
- } else {
- flashMode = Parameters.FLASH_MODE_OFF;
- }
- List<String> supportedFlash = mParameters.getSupportedFlashModes();
- if (isSupported(flashMode, supportedFlash)) {
- mParameters.setFlashMode(flashMode);
- } else {
- flashMode = mParameters.getFlashMode();
- if (flashMode == null) {
- flashMode = mActivity.getString(
- R.string.pref_camera_flashmode_no_flash);
- }
- }
-
- // Set white balance parameter.
- String whiteBalance = mPreferences.getString(
- CameraSettings.KEY_WHITE_BALANCE,
- mActivity.getString(R.string.pref_camera_whitebalance_default));
- if (isSupported(whiteBalance,
- mParameters.getSupportedWhiteBalance())) {
- mParameters.setWhiteBalance(whiteBalance);
- } else {
- whiteBalance = mParameters.getWhiteBalance();
- if (whiteBalance == null) {
- whiteBalance = Parameters.WHITE_BALANCE_AUTO;
- }
- }
-
- // Set zoom.
- if (mParameters.isZoomSupported()) {
- mParameters.setZoom(mZoomValue);
- }
-
- // Set continuous autofocus.
- List<String> supportedFocus = mParameters.getSupportedFocusModes();
- if (isSupported(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, supportedFocus)) {
- mParameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- }
-
- mParameters.set(Util.RECORDING_HINT, Util.TRUE);
-
- // Enable video stabilization. Convenience methods not available in API
- // level <= 14
- String vstabSupported = mParameters.get("video-stabilization-supported");
- if ("true".equals(vstabSupported)) {
- mParameters.set("video-stabilization", "true");
- }
-
- // Set picture size.
- // 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 = mParameters.getSupportedPictureSizes();
- Size optimalSize = Util.getOptimalVideoSnapshotPictureSize(supported,
- (double) mDesiredPreviewWidth / mDesiredPreviewHeight);
- Size original = mParameters.getPictureSize();
- if (!original.equals(optimalSize)) {
- mParameters.setPictureSize(optimalSize.width, optimalSize.height);
- }
- Log.v(TAG, "Video snapshot size is " + optimalSize.width + "x" +
- optimalSize.height);
-
- // Set JPEG quality.
- int jpegQuality = CameraProfile.getJpegEncodingQualityParameter(mCameraId,
- CameraProfile.QUALITY_HIGH);
- mParameters.setJpegQuality(jpegQuality);
-
- mCameraDevice.setParameters(mParameters);
- // Keep preview size up to date.
- mParameters = mCameraDevice.getParameters();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case REQUEST_EFFECT_BACKDROPPER:
- if (resultCode == Activity.RESULT_OK) {
- // onActivityResult() runs before onResume(), so this parameter will be
- // seen by startPreview from onResume()
- mEffectUriFromGallery = data.getData().toString();
- Log.v(TAG, "Received URI from gallery: " + mEffectUriFromGallery);
- mResetEffect = false;
- } else {
- mEffectUriFromGallery = null;
- Log.w(TAG, "No URI from gallery");
- mResetEffect = true;
- }
- break;
- }
- }
-
- @Override
- public void onEffectsUpdate(int effectId, int effectMsg) {
- Log.v(TAG, "onEffectsUpdate. Effect Message = " + effectMsg);
- if (effectMsg == EffectsRecorder.EFFECT_MSG_EFFECTS_STOPPED) {
- // Effects have shut down. Hide learning message if any,
- // and restart regular preview.
- checkQualityAndStartPreview();
- } else if (effectMsg == EffectsRecorder.EFFECT_MSG_RECORDING_DONE) {
- // This follows the codepath from onStopVideoRecording.
- if (mEffectsDisplayResult) {
- saveVideo();
- if (mIsVideoCaptureIntent) {
- if (mQuickCapture) {
- doReturnToCaller(true);
- } else {
- showCaptureResult();
- }
- }
- }
- mEffectsDisplayResult = false;
- // In onPause, these were not called if the effects were active. We
- // had to wait till the effects recording is complete to do this.
- if (mPaused) {
- closeVideoFileDescriptor();
- }
- } else if (effectMsg == EffectsRecorder.EFFECT_MSG_PREVIEW_RUNNING) {
- // Enable the shutter button once the preview is complete.
- mUI.enableShutter(true);
- }
- // In onPause, this was not called if the effects were active. We had to
- // wait till the effects completed to do this.
- if (mPaused) {
- Log.v(TAG, "OnEffectsUpdate: closing effects if activity paused");
- closeEffects();
- }
- }
-
- public void onCancelBgTraining(View v) {
- // Write default effect out to shared prefs
- writeDefaultEffectToPrefs();
- // Tell VideoCamer to re-init based on new shared pref values.
- onSharedPreferenceChanged();
- }
-
- @Override
- public synchronized void onEffectsError(Exception exception, String fileName) {
- // TODO: Eventually we may want to show the user an error dialog, and then restart the
- // camera and encoder gracefully. For now, we just delete the file and bail out.
- if (fileName != null && new File(fileName).exists()) {
- deleteVideoFile(fileName);
- }
- try {
- if (Class.forName("android.filterpacks.videosink.MediaRecorderStopException")
- .isInstance(exception)) {
- Log.w(TAG, "Problem recoding video file. Removing incomplete file.");
- return;
- }
- } catch (ClassNotFoundException ex) {
- Log.w(TAG, ex);
- }
- throw new RuntimeException("Error during recording!", exception);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- Log.v(TAG, "onConfigurationChanged");
- setDisplayOrientation();
- }
-
- @Override
- public void onOverriddenPreferencesClicked() {
- }
-
- @Override
- // TODO: Delete this after old camera code is removed
- public void onRestorePreferencesClicked() {
- }
-
- private boolean effectsActive() {
- return (mEffectType != EffectsRecorder.EFFECT_NONE);
- }
-
- @Override
- public void onSharedPreferenceChanged() {
- // ignore the events after "onPause()" or preview has not started yet
- if (mPaused) return;
- synchronized (mPreferences) {
- // If mCameraDevice is not ready then we can set the parameter in
- // startPreview().
- if (mCameraDevice == null) return;
-
- boolean recordLocation = RecordLocationPreference.get(
- mPreferences, mContentResolver);
- mLocationManager.recordLocation(recordLocation);
-
- // Check if the current effects selection has changed
- if (updateEffectSelection()) return;
-
- readVideoPreferences();
- mUI.showTimeLapseUI(mCaptureTimeLapse);
- // We need to restart the preview if preview size is changed.
- Size size = mParameters.getPreviewSize();
- if (size.width != mDesiredPreviewWidth
- || size.height != mDesiredPreviewHeight) {
- if (!effectsActive()) {
- stopPreview();
- } else {
- mEffectsRecorder.release();
- mEffectsRecorder = null;
- }
- resizeForPreviewAspectRatio();
- startPreview(); // Parameters will be set in startPreview().
- } else {
- setCameraParameters();
- }
- mUI.updateOnScreenIndicators(mParameters, mPreferences);
- }
- }
-
- protected void setCameraId(int cameraId) {
- ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID);
- pref.setValue("" + cameraId);
- }
-
- private void switchCamera() {
- if (mPaused) return;
-
- Log.d(TAG, "Start to switch camera.");
- mCameraId = mPendingSwitchCameraId;
- mPendingSwitchCameraId = -1;
- setCameraId(mCameraId);
-
- closeCamera();
- mUI.collapseCameraControls();
- // Restart the camera and initialize the UI. From onCreate.
- mPreferences.setLocalId(mActivity, mCameraId);
- CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
- openCamera();
- readVideoPreferences();
- startPreview();
- initializeVideoSnapshot();
- resizeForPreviewAspectRatio();
- initializeVideoControl();
-
- // From onResume
- mZoomValue = 0;
- mUI.initializeZoom(mParameters);
- mUI.setOrientationIndicator(0, false);
-
- // Start switch camera animation. Post a message because
- // onFrameAvailable from the old camera may already exist.
- mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION);
- mUI.updateOnScreenIndicators(mParameters, mPreferences);
- }
-
- // Preview texture has been copied. Now camera can be released and the
- // animation can be started.
- @Override
- public void onPreviewTextureCopied() {
- mHandler.sendEmptyMessage(SWITCH_CAMERA);
- }
-
- @Override
- public void onCaptureTextureCopied() {
- }
-
- private boolean updateEffectSelection() {
- int previousEffectType = mEffectType;
- Object previousEffectParameter = mEffectParameter;
- mEffectType = CameraSettings.readEffectType(mPreferences);
- mEffectParameter = CameraSettings.readEffectParameter(mPreferences);
-
- if (mEffectType == previousEffectType) {
- if (mEffectType == EffectsRecorder.EFFECT_NONE) return false;
- if (mEffectParameter.equals(previousEffectParameter)) return false;
- }
- Log.v(TAG, "New effect selection: " + mPreferences.getString(
- CameraSettings.KEY_VIDEO_EFFECT, "none"));
-
- if (mEffectType == EffectsRecorder.EFFECT_NONE) {
- // Stop effects and return to normal preview
- mEffectsRecorder.stopPreview();
- mPreviewing = false;
- return true;
- }
- if (mEffectType == EffectsRecorder.EFFECT_BACKDROPPER &&
- ((String) mEffectParameter).equals(EFFECT_BG_FROM_GALLERY)) {
- // Request video from gallery to use for background
- Intent i = new Intent(Intent.ACTION_PICK);
- i.setDataAndType(Video.Media.EXTERNAL_CONTENT_URI,
- "video/*");
- i.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
- mActivity.startActivityForResult(i, REQUEST_EFFECT_BACKDROPPER);
- return true;
- }
- if (previousEffectType == EffectsRecorder.EFFECT_NONE) {
- // Stop regular preview and start effects.
- stopPreview();
- checkQualityAndStartPreview();
- } else {
- // Switch currently running effect
- mEffectsRecorder.setEffect(mEffectType, mEffectParameter);
- }
- return true;
- }
-
- // Verifies that the current preview view size is correct before starting
- // preview. If not, resets the surface texture and resizes the view.
- private void checkQualityAndStartPreview() {
- readVideoPreferences();
- mUI.showTimeLapseUI(mCaptureTimeLapse);
- Size size = mParameters.getPreviewSize();
- if (size.width != mDesiredPreviewWidth
- || size.height != mDesiredPreviewHeight) {
- resizeForPreviewAspectRatio();
- }
- // Start up preview again
- startPreview();
- }
-
- private void initializeVideoSnapshot() {
- if (mParameters == null) return;
- if (Util.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
- // Show the tap to focus toast if this is the first start.
- if (mPreferences.getBoolean(
- CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, true)) {
- // Delay the toast for one second to wait for orientation.
- mHandler.sendEmptyMessageDelayed(SHOW_TAP_TO_SNAPSHOT_TOAST, 1000);
- }
- }
- }
-
- void showVideoSnapshotUI(boolean enabled) {
- if (mParameters == null) return;
- if (Util.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
- if (enabled) {
- mUI.animateFlash();
- } else {
- mUI.showPreviewBorder(enabled);
- }
- mUI.enableShutter(!enabled);
- }
- }
-
- @Override
- public void updateCameraAppView() {
- if (!mPreviewing || mParameters.getFlashMode() == null) return;
-
- // When going to and back from gallery, we need to turn off/on the flash.
- if (!mUI.isVisible()) {
- if (mParameters.getFlashMode().equals(Parameters.FLASH_MODE_OFF)) {
- mRestoreFlash = false;
- return;
- }
- mRestoreFlash = true;
- setCameraParameters();
- } else if (mRestoreFlash) {
- mRestoreFlash = false;
- setCameraParameters();
- }
- }
-
- @Override
- public void onSwitchMode(boolean toCamera) {
- mUI.onSwitchMode(toCamera);
- }
-
- private final class JpegPictureCallback implements CameraPictureCallback {
- Location mLocation;
-
- public JpegPictureCallback(Location loc) {
- mLocation = loc;
- }
-
- @Override
- public void onPictureTaken(byte [] jpegData, CameraProxy camera) {
- Log.v(TAG, "onPictureTaken");
- mSnapshotInProgress = false;
- showVideoSnapshotUI(false);
- storeImage(jpegData, mLocation);
- }
- }
-
- private void storeImage(final byte[] data, Location loc) {
- long dateTaken = System.currentTimeMillis();
- String title = Util.createJpegName(dateTaken);
- ExifInterface exif = Exif.getExif(data);
- int orientation = Exif.getOrientation(exif);
- Size s = mParameters.getPictureSize();
- mActivity.getMediaSaveService().addImage(
- data, title, dateTaken, loc, s.width, s.height, orientation,
- exif, mOnPhotoSavedListener, mContentResolver);
- }
-
- private boolean resetEffect() {
- if (mResetEffect) {
- String value = mPreferences.getString(CameraSettings.KEY_VIDEO_EFFECT,
- mPrefVideoEffectDefault);
- if (!mPrefVideoEffectDefault.equals(value)) {
- writeDefaultEffectToPrefs();
- return true;
- }
- }
- mResetEffect = true;
- return false;
- }
-
- private String convertOutputFormatToMimeType(int outputFileFormat) {
- if (outputFileFormat == MediaRecorder.OutputFormat.MPEG_4) {
- return "video/mp4";
- }
- return "video/3gpp";
- }
-
- private String convertOutputFormatToFileExt(int outputFileFormat) {
- if (outputFileFormat == MediaRecorder.OutputFormat.MPEG_4) {
- return ".mp4";
- }
- return ".3gp";
- }
-
- private void closeVideoFileDescriptor() {
- if (mVideoFileDescriptor != null) {
- try {
- mVideoFileDescriptor.close();
- } catch (IOException e) {
- Log.e(TAG, "Fail to close fd", e);
- }
- mVideoFileDescriptor = null;
- }
- }
-
- private void showTapToSnapshotToast() {
- new RotateTextToast(mActivity, R.string.video_snapshot_hint, 0)
- .show();
- // Clear the preference.
- Editor editor = mPreferences.edit();
- editor.putBoolean(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, false);
- editor.apply();
- }
-
- @Override
- public boolean updateStorageHintOnResume() {
- return true;
- }
-
- // required by OnPreferenceChangedListener
- @Override
- public void onCameraPickerClicked(int cameraId) {
- if (mPaused || mPendingSwitchCameraId != -1) return;
-
- mPendingSwitchCameraId = cameraId;
- Log.d(TAG, "Start to copy texture.");
- // We need to keep a preview frame for the animation before
- // releasing the camera. This will trigger onPreviewTextureCopied.
- // TODO: ((CameraScreenNail) mActivity.mCameraScreenNail).copyTexture();
- // Disable all camera controls.
- mSwitchingCamera = true;
-
- }
-
- @Override
- public void onShowSwitcherPopup() {
- mUI.onShowSwitcherPopup();
- }
-
- @Override
- public void onMediaSaveServiceConnected(MediaSaveService s) {
- // do nothing.
- }
-
- @Override
- public void onPreviewUIReady() {
- startPreview();
- }
-
- @Override
- public void onPreviewUIDestroyed() {
- stopPreview();
- }
-}
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
deleted file mode 100644
index 72587381c..000000000
--- a/src/com/android/camera/VideoUI.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera.Parameters;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.TextureView;
-import android.view.TextureView.SurfaceTextureListener;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLayoutChangeListener;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.FrameLayout.LayoutParams;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.camera.CameraPreference.OnPreferenceChangedListener;
-import com.android.camera.ui.AbstractSettingPopup;
-import com.android.camera.ui.CameraControls;
-import com.android.camera.ui.CameraRootView;
-import com.android.camera.ui.CameraSwitcher;
-import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
-import com.android.camera.ui.PieRenderer;
-import com.android.camera.ui.RenderOverlay;
-import com.android.camera.ui.RotateLayout;
-import com.android.camera.ui.ZoomRenderer;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.List;
-
-public class VideoUI implements PieRenderer.PieListener,
- PreviewGestures.SingleTapListener,
- CameraRootView.MyDisplayListener,
- SurfaceTextureListener, SurfaceHolder.Callback {
- private static final String TAG = "CAM_VideoUI";
- private static final int UPDATE_TRANSFORM_MATRIX = 1;
- // module fields
- private CameraActivity mActivity;
- private View mRootView;
- private TextureView mTextureView;
- // An review image having same size as preview. It is displayed when
- // recording is stopped in capture intent.
- private ImageView mReviewImage;
- private View mReviewCancelButton;
- private View mReviewDoneButton;
- private View mReviewPlayButton;
- private ShutterButton mShutterButton;
- private CameraSwitcher mSwitcher;
- private TextView mRecordingTimeView;
- private LinearLayout mLabelsLinearLayout;
- private View mTimeLapseLabel;
- private RenderOverlay mRenderOverlay;
- private PieRenderer mPieRenderer;
- private VideoMenu mVideoMenu;
- private CameraControls mCameraControls;
- private AbstractSettingPopup mPopup;
- private ZoomRenderer mZoomRenderer;
- private PreviewGestures mGestures;
- private View mMenuButton;
- private View mBlocker;
- private OnScreenIndicators mOnScreenIndicators;
- private RotateLayout mRecordingTimeRect;
- private final Object mLock = new Object();
- private SurfaceTexture mSurfaceTexture;
- private VideoController mController;
- private int mZoomMax;
- private List<Integer> mZoomRatios;
- private View mPreviewThumb;
- private View mFlashOverlay;
-
- private SurfaceView mSurfaceView = null;
- private int mPreviewWidth = 0;
- private int mPreviewHeight = 0;
- private float mSurfaceTextureUncroppedWidth;
- private float mSurfaceTextureUncroppedHeight;
- private float mAspectRatio = 4f / 3f;
- private Matrix mMatrix = null;
- private final AnimationManager mAnimationManager;
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case UPDATE_TRANSFORM_MATRIX:
- setTransformMatrix(mPreviewWidth, mPreviewHeight);
- break;
- default:
- break;
- }
- }
- };
- private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right,
- int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
- int width = right - left;
- int height = bottom - top;
- // Full-screen screennail
- int w = width;
- int h = height;
- if (Util.getDisplayRotation(mActivity) % 180 != 0) {
- w = height;
- h = width;
- }
- if (mPreviewWidth != width || mPreviewHeight != height) {
- mPreviewWidth = width;
- mPreviewHeight = height;
- onScreenSizeChanged(width, height, w, h);
- }
- }
- };
-
- public VideoUI(CameraActivity activity, VideoController controller, View parent) {
- mActivity = activity;
- mController = controller;
- mRootView = parent;
- mActivity.getLayoutInflater().inflate(R.layout.video_module, (ViewGroup) mRootView, true);
- mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
- mTextureView.setSurfaceTextureListener(this);
- mRootView.addOnLayoutChangeListener(mLayoutListener);
- ((CameraRootView) mRootView).setDisplayChangeListener(this);
- mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);
- mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
- mSwitcher = (CameraSwitcher) mRootView.findViewById(R.id.camera_switcher);
- mSwitcher.setCurrentIndex(CameraSwitcher.VIDEO_MODULE_INDEX);
- mSwitcher.setSwitchListener((CameraSwitchListener) mActivity);
- initializeMiscControls();
- initializeControlByIntent();
- initializeOverlay();
- mAnimationManager = new AnimationManager();
- }
-
-
- public void initializeSurfaceView() {
- mSurfaceView = new SurfaceView(mActivity);
- ((ViewGroup) mRootView).addView(mSurfaceView, 0);
- mSurfaceView.getHolder().addCallback(this);
- }
-
- private void initializeControlByIntent() {
- mBlocker = mActivity.findViewById(R.id.blocker);
- mMenuButton = mActivity.findViewById(R.id.menu);
- mMenuButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mPieRenderer != null) {
- mPieRenderer.showInCenter();
- }
- }
- });
-
- mCameraControls = (CameraControls) mActivity.findViewById(R.id.camera_controls);
- mOnScreenIndicators = new OnScreenIndicators(mActivity,
- mActivity.findViewById(R.id.on_screen_indicators));
- mOnScreenIndicators.resetToDefault();
- if (mController.isVideoCaptureIntent()) {
- hideSwitcher();
- mActivity.getLayoutInflater().inflate(R.layout.review_module_control,
- (ViewGroup) mCameraControls);
- // Cannot use RotateImageView for "done" and "cancel" button because
- // the tablet layout uses RotateLayout, which cannot be cast to
- // RotateImageView.
- mReviewDoneButton = mActivity.findViewById(R.id.btn_done);
- mReviewCancelButton = mActivity.findViewById(R.id.btn_cancel);
- mReviewPlayButton = mActivity.findViewById(R.id.btn_play);
- mReviewCancelButton.setVisibility(View.VISIBLE);
- mReviewDoneButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onReviewDoneClicked(v);
- }
- });
- mReviewCancelButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onReviewCancelClicked(v);
- }
- });
- mReviewPlayButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mController.onReviewPlayClicked(v);
- }
- });
- }
- }
-
- public void setPreviewSize(int width, int height) {
- if (width == 0 || height == 0) {
- Log.w(TAG, "Preview size should not be 0.");
- return;
- }
- if (width > height) {
- mAspectRatio = (float) width / height;
- } else {
- mAspectRatio = (float) height / width;
- }
- mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
- }
-
- public int getPreviewWidth() {
- return mPreviewWidth;
- }
-
- public int getPreviewHeight() {
- return mPreviewHeight;
- }
-
- public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) {
- setTransformMatrix(width, height);
- }
-
- private void setTransformMatrix(int width, int height) {
- mMatrix = mTextureView.getTransform(mMatrix);
- int orientation = Util.getDisplayRotation(mActivity);
- float scaleX = 1f, scaleY = 1f;
- float scaledTextureWidth, scaledTextureHeight;
- if (width > height) {
- scaledTextureWidth = Math.max(width,
- (int) (height * mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int)(width / mAspectRatio));
- } else {
- scaledTextureWidth = Math.max(width,
- (int) (height / mAspectRatio));
- scaledTextureHeight = Math.max(height,
- (int) (width * mAspectRatio));
- }
-
- if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
- mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
- mSurfaceTextureUncroppedWidth = scaledTextureWidth;
- mSurfaceTextureUncroppedHeight = scaledTextureHeight;
- }
- scaleX = scaledTextureWidth / width;
- scaleY = scaledTextureHeight / height;
- mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2);
- mTextureView.setTransform(mMatrix);
-
- if (mSurfaceView != null && mSurfaceView.getVisibility() == View.VISIBLE) {
- LayoutParams lp = (LayoutParams) mSurfaceView.getLayoutParams();
- lp.width = (int) mSurfaceTextureUncroppedWidth;
- lp.height = (int) mSurfaceTextureUncroppedHeight;
- lp.gravity = Gravity.CENTER;
- mSurfaceView.requestLayout();
- }
- }
-
- /**
- * Starts a flash animation
- */
- public void animateFlash() {
- mAnimationManager.startFlashAnimation(mFlashOverlay);
- }
-
- /**
- * Starts a capture animation
- * @param bitmap the captured image that we shrink and slide in the animation
- */
- public void animateCapture(Bitmap bitmap) {
- ((ImageView) mPreviewThumb).setImageBitmap(bitmap);
- mAnimationManager.startCaptureAnimation(mPreviewThumb);
- }
-
- /**
- * Cancels on-going animations
- */
- public void cancelAnimations() {
- mAnimationManager.cancelAnimations();
- }
-
- public void hideUI() {
- mCameraControls.setVisibility(View.INVISIBLE);
- mSwitcher.closePopup();
- }
-
- public void showUI() {
- mCameraControls.setVisibility(View.VISIBLE);
- }
-
- public void hideSwitcher() {
- mSwitcher.closePopup();
- mSwitcher.setVisibility(View.INVISIBLE);
- }
-
- public void showSwitcher() {
- mSwitcher.setVisibility(View.VISIBLE);
- }
-
- public boolean collapseCameraControls() {
- boolean ret = false;
- if (mPopup != null) {
- dismissPopup(false);
- ret = true;
- }
- return ret;
- }
-
- public boolean removeTopLevelPopup() {
- if (mPopup != null) {
- dismissPopup(true);
- return true;
- }
- return false;
- }
-
- public void enableCameraControls(boolean enable) {
- if (mGestures != null) {
- mGestures.setZoomOnly(!enable);
- }
- if (mPieRenderer != null && mPieRenderer.showsItems()) {
- mPieRenderer.hide();
- }
- }
-
- public void overrideSettings(final String... keyvalues) {
- mVideoMenu.overrideSettings(keyvalues);
- }
-
- public void setOrientationIndicator(int orientation, boolean animation) {
- // We change the orientation of the linearlayout only for phone UI
- // because when in portrait the width is not enough.
- if (mLabelsLinearLayout != null) {
- if (((orientation / 90) & 1) == 0) {
- mLabelsLinearLayout.setOrientation(LinearLayout.VERTICAL);
- } else {
- mLabelsLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
- }
- }
- mRecordingTimeRect.setOrientation(0, animation);
- }
-
- public SurfaceHolder getSurfaceHolder() {
- return mSurfaceView.getHolder();
- }
-
- public void hideSurfaceView() {
- mSurfaceView.setVisibility(View.GONE);
- mTextureView.setVisibility(View.VISIBLE);
- setTransformMatrix(mPreviewWidth, mPreviewHeight);
- }
-
- public void showSurfaceView() {
- mSurfaceView.setVisibility(View.VISIBLE);
- mTextureView.setVisibility(View.GONE);
- setTransformMatrix(mPreviewWidth, mPreviewHeight);
- }
-
- private void initializeOverlay() {
- mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);
- if (mPieRenderer == null) {
- mPieRenderer = new PieRenderer(mActivity);
- mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer);
- mPieRenderer.setPieListener(this);
- }
- mRenderOverlay.addRenderer(mPieRenderer);
- if (mZoomRenderer == null) {
- mZoomRenderer = new ZoomRenderer(mActivity);
- }
- mRenderOverlay.addRenderer(mZoomRenderer);
- if (mGestures == null) {
- mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer);
- mRenderOverlay.setGestures(mGestures);
- }
- mGestures.setRenderOverlay(mRenderOverlay);
-
- mPreviewThumb = mActivity.findViewById(R.id.preview_thumb);
- mPreviewThumb.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO: Go to filmstrip view
- }
- });
- }
-
- public void setPrefChangedListener(OnPreferenceChangedListener listener) {
- mVideoMenu.setListener(listener);
- }
-
- private void initializeMiscControls() {
- mReviewImage = (ImageView) mRootView.findViewById(R.id.review_image);
- mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
- mShutterButton.setOnShutterButtonListener(mController);
- mShutterButton.setVisibility(View.VISIBLE);
- mShutterButton.requestFocus();
- mShutterButton.enableTouch(true);
- mRecordingTimeView = (TextView) mRootView.findViewById(R.id.recording_time);
- mRecordingTimeRect = (RotateLayout) mRootView.findViewById(R.id.recording_time_rect);
- mTimeLapseLabel = mRootView.findViewById(R.id.time_lapse_label);
- // The R.id.labels can only be found in phone layout.
- // That is, mLabelsLinearLayout should be null in tablet layout.
- mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels);
- }
-
- public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) {
- mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode());
- boolean location = RecordLocationPreference.get(
- prefs, mActivity.getContentResolver());
- mOnScreenIndicators.updateLocationIndicator(location);
-
- }
-
- public void setAspectRatio(double ratio) {
- // mPreviewFrameLayout.setAspectRatio(ratio);
- }
-
- public void showTimeLapseUI(boolean enable) {
- if (mTimeLapseLabel != null) {
- mTimeLapseLabel.setVisibility(enable ? View.VISIBLE : View.GONE);
- }
- }
-
- private void openMenu() {
- if (mPieRenderer != null) {
- mPieRenderer.showInCenter();
- }
- }
-
- public void showPopup(AbstractSettingPopup popup) {
- hideUI();
- mBlocker.setVisibility(View.INVISIBLE);
- setShowMenu(false);
- mPopup = popup;
- mPopup.setVisibility(View.VISIBLE);
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER;
- ((FrameLayout) mRootView).addView(mPopup, lp);
- }
-
- public void dismissPopup(boolean topLevelOnly) {
- dismissPopup(topLevelOnly, true);
- }
-
- public void dismissPopup(boolean topLevelPopupOnly, boolean fullScreen) {
- // In review mode, we do not want to bring up the camera UI
- if (mController.isInReviewMode()) return;
-
- if (fullScreen) {
- showUI();
- mBlocker.setVisibility(View.VISIBLE);
- }
- setShowMenu(fullScreen);
- if (mPopup != null) {
- ((FrameLayout) mRootView).removeView(mPopup);
- mPopup = null;
- }
- mVideoMenu.popupDismissed(topLevelPopupOnly);
- }
-
- public void onShowSwitcherPopup() {
- hidePieRenderer();
- }
-
- public boolean hidePieRenderer() {
- if (mPieRenderer != null && mPieRenderer.showsItems()) {
- mPieRenderer.hide();
- return true;
- }
- return false;
- }
-
- // disable preview gestures after shutter is pressed
- public void setShutterPressed(boolean pressed) {
- if (mGestures == null) return;
- mGestures.setEnabled(!pressed);
- }
-
- public void enableShutter(boolean enable) {
- if (mShutterButton != null) {
- mShutterButton.setEnabled(enable);
- }
- }
-
- // PieListener
- @Override
- public void onPieOpened(int centerX, int centerY) {
- setSwipingEnabled(false);
- dismissPopup(false, true);
- }
-
- @Override
- public void onPieClosed() {
- setSwipingEnabled(true);
- }
-
- public void setSwipingEnabled(boolean enable) {
- mActivity.setSwipingEnabled(enable);
- }
-
- public void showPreviewBorder(boolean enable) {
- // TODO: mPreviewFrameLayout.showBorder(enable);
- }
-
- // SingleTapListener
- // Preview area is touched. Take a picture.
- @Override
- public void onSingleTapUp(View view, int x, int y) {
- mController.onSingleTapUp(view, x, y);
- }
-
- public void showRecordingUI(boolean recording, boolean zoomSupported) {
- mMenuButton.setVisibility(recording ? View.GONE : View.VISIBLE);
- mOnScreenIndicators.setVisibility(recording ? View.GONE : View.VISIBLE);
- if (recording) {
- mShutterButton.setImageResource(R.drawable.btn_shutter_video_recording);
- hideSwitcher();
- mRecordingTimeView.setText("");
- mRecordingTimeView.setVisibility(View.VISIBLE);
- // The camera is not allowed to be accessed in older api levels during
- // recording. It is therefore necessary to hide the zoom UI on older
- // platforms.
- // See the documentation of android.media.MediaRecorder.start() for
- // further explanation.
- if (!ApiHelper.HAS_ZOOM_WHEN_RECORDING && zoomSupported) {
- // TODO: disable zoom UI here.
- }
- } else {
- mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
- showSwitcher();
- mRecordingTimeView.setVisibility(View.GONE);
- if (!ApiHelper.HAS_ZOOM_WHEN_RECORDING && zoomSupported) {
- // TODO: enable zoom UI here.
- }
- }
- }
-
- public void showReviewImage(Bitmap bitmap) {
- mReviewImage.setImageBitmap(bitmap);
- mReviewImage.setVisibility(View.VISIBLE);
- }
-
- public void showReviewControls() {
- Util.fadeOut(mShutterButton);
- Util.fadeIn(mReviewDoneButton);
- Util.fadeIn(mReviewPlayButton);
- mReviewImage.setVisibility(View.VISIBLE);
- mMenuButton.setVisibility(View.GONE);
- mOnScreenIndicators.setVisibility(View.GONE);
- }
-
- public void hideReviewUI() {
- mReviewImage.setVisibility(View.GONE);
- mShutterButton.setEnabled(true);
- mMenuButton.setVisibility(View.VISIBLE);
- mOnScreenIndicators.setVisibility(View.VISIBLE);
- Util.fadeOut(mReviewDoneButton);
- Util.fadeOut(mReviewPlayButton);
- Util.fadeIn(mShutterButton);
- }
-
- private void setShowMenu(boolean show) {
- if (mOnScreenIndicators != null) {
- mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- if (mMenuButton != null) {
- mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE);
- }
- }
-
- public void onSwitchMode(boolean toCamera) {
- if (toCamera) {
- showUI();
- } else {
- hideUI();
- }
- if (mGestures != null) {
- mGestures.setEnabled(toCamera);
- }
- if (mPopup != null) {
- dismissPopup(false, toCamera);
- }
- if (mRenderOverlay != null) {
- // this can not happen in capture mode
- mRenderOverlay.setVisibility(toCamera ? View.VISIBLE : View.GONE);
- }
- setShowMenu(toCamera);
- }
-
- public void initializePopup(PreferenceGroup pref) {
- mVideoMenu.initialize(pref);
- }
-
- public void initializeZoom(Parameters param) {
- if (param == null || !param.isZoomSupported()) {
- mGestures.setZoomEnabled(false);
- return;
- }
- mGestures.setZoomEnabled(true);
- mZoomMax = param.getMaxZoom();
- mZoomRatios = param.getZoomRatios();
- // Currently we use immediate zoom for fast zooming to get better UX and
- // there is no plan to take advantage of the smooth zoom.
- mZoomRenderer.setZoomMax(mZoomMax);
- mZoomRenderer.setZoom(param.getZoom());
- mZoomRenderer.setZoomValue(mZoomRatios.get(param.getZoom()));
- mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener());
- }
-
- public void clickShutter() {
- mShutterButton.performClick();
- }
-
- public void pressShutter(boolean pressed) {
- mShutterButton.setPressed(pressed);
- }
-
- public View getShutterButton() {
- return mShutterButton;
- }
-
- public void setRecordingTime(String text) {
- mRecordingTimeView.setText(text);
- }
-
- public void setRecordingTimeTextColor(int color) {
- mRecordingTimeView.setTextColor(color);
- }
-
- public boolean isVisible() {
- return mTextureView.getVisibility() == View.VISIBLE;
- }
-
- public void onDisplayChanged() {
- mCameraControls.checkLayoutFlip();
- mController.updateCameraOrientation();
- }
-
- private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener {
- @Override
- public void onZoomValueChanged(int index) {
- int newZoom = mController.onZoomChanged(index);
- if (mZoomRenderer != null) {
- mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom));
- }
- }
-
- @Override
- public void onZoomStart() {
- }
-
- @Override
- public void onZoomEnd() {
- }
- }
-
- public SurfaceTexture getSurfaceTexture() {
- return mSurfaceTexture;
- }
-
- // SurfaceTexture callbacks
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- mSurfaceTexture = surface;
- mController.onPreviewUIReady();
- }
-
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- mSurfaceTexture = null;
- mController.onPreviewUIDestroyed();
- Log.d(TAG, "surfaceTexture is destroyed");
- return true;
- }
-
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- }
-
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- }
-
- // SurfaceHolder callbacks
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- Log.v(TAG, "Surface changed. width=" + width + ". height=" + height);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.v(TAG, "Surface created");
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- Log.v(TAG, "Surface destroyed");
- mController.stopPreview();
- }
-}
diff --git a/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java b/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java
deleted file mode 100644
index 5df87f5a8..000000000
--- a/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.Uri;
-
-/**
- * An abstract {@link LocalDataAdapter} implementation to wrap another
- * {@link LocalDataAdapter}. All implementations related to data id is not
- * addressed in this abstract class since wrapping another data adapter
- * surely makes things different for data id.
- *
- * @see FixedFirstDataAdapter
- * @see FixedLastDataAdapter
- */
-public abstract class AbstractLocalDataAdapterWrapper implements LocalDataAdapter {
-
- protected final LocalDataAdapter mAdapter;
- protected int mSuggestedWidth;
- protected int mSuggestedHeight;
-
- /**
- * Constructor.
- *
- * @param wrappedAdapter The {@link LocalDataAdapter} to be wrapped.
- */
- AbstractLocalDataAdapterWrapper(LocalDataAdapter wrappedAdapter) {
- if (wrappedAdapter == null) {
- throw new AssertionError("data adapter is null");
- }
- mAdapter = wrappedAdapter;
- }
-
- @Override
- public void suggestViewSizeBound(int w, int h) {
- mSuggestedWidth = w;
- mSuggestedHeight = h;
- }
-
- @Override
- public void setListener(Listener listener) {
- mAdapter.setListener(listener);
- }
-
- @Override
- public void requestLoad(ContentResolver resolver) {
- mAdapter.requestLoad(resolver);
- }
-
- @Override
- public void addNewVideo(ContentResolver resolver, Uri uri) {
- mAdapter.addNewVideo(resolver, uri);
- }
-
- @Override
- public void addNewPhoto(ContentResolver resolver, Uri uri) {
- mAdapter.addNewPhoto(resolver, uri);
- }
-
- @Override
- public void insertData(LocalData data) {
- mAdapter.insertData(data);
- }
-
- @Override
- public void flush() {
- mAdapter.flush();
- }
-
- @Override
- public boolean executeDeletion(Context context) {
- return mAdapter.executeDeletion(context);
- }
-
- @Override
- public boolean undoDataRemoval() {
- return mAdapter.undoDataRemoval();
- }
-
- @Override
- public void refresh(ContentResolver resolver, Uri uri) {
- mAdapter.refresh(resolver, uri);
- }
-}
diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
deleted file mode 100644
index aaf5ebe59..000000000
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.View;
-
-import com.android.camera.Storage;
-import com.android.camera.ui.FilmStripView.ImageData;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * A {@link LocalDataAdapter} that provides data in the camera folder.
- */
-public class CameraDataAdapter implements LocalDataAdapter {
- private static final String TAG = "CAM_CameraDataAdapter";
-
- private static final int DEFAULT_DECODE_SIZE = 3000;
- private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" };
-
- private List<LocalData> mImages;
-
- private Listener mListener;
- private Drawable mPlaceHolder;
-
- private int mSuggestedWidth = DEFAULT_DECODE_SIZE;
- private int mSuggestedHeight = DEFAULT_DECODE_SIZE;
-
- private LocalData mLocalDataToDelete;
-
- public CameraDataAdapter(Drawable placeHolder) {
- mPlaceHolder = placeHolder;
- }
-
- @Override
- public void requestLoad(ContentResolver resolver) {
- QueryTask qtask = new QueryTask();
- qtask.execute(resolver);
- }
-
- @Override
- public LocalData getLocalData(int dataID) {
- if (mImages == null || dataID < 0 || dataID >= mImages.size()) {
- return null;
- }
-
- return mImages.get(dataID);
- }
-
- @Override
- public int getTotalNumber() {
- if (mImages == null) {
- return 0;
- }
- return mImages.size();
- }
-
- @Override
- public ImageData getImageData(int id) {
- return getLocalData(id);
- }
-
- @Override
- public void suggestViewSizeBound(int w, int h) {
- if (w <= 0 || h <= 0) {
- mSuggestedWidth = mSuggestedHeight = DEFAULT_DECODE_SIZE;
- } else {
- mSuggestedWidth = (w < DEFAULT_DECODE_SIZE ? w : DEFAULT_DECODE_SIZE);
- mSuggestedHeight = (h < DEFAULT_DECODE_SIZE ? h : DEFAULT_DECODE_SIZE);
- }
- }
-
- @Override
- public View getView(Context c, int dataID) {
- if (mImages == null) {
- return null;
- }
- if (dataID >= mImages.size() || dataID < 0) {
- return null;
- }
-
- return mImages.get(dataID).getView(
- c, mSuggestedWidth, mSuggestedHeight,
- mPlaceHolder.getConstantState().newDrawable());
- }
-
- @Override
- public void setListener(Listener listener) {
- mListener = listener;
- if (mImages != null) {
- mListener.onDataLoaded();
- }
- }
-
- @Override
- public void onDataFullScreen(int dataID, boolean fullScreen) {
- if (dataID < mImages.size() && dataID >= 0) {
- mImages.get(dataID).onFullScreen(fullScreen);
- }
- }
-
- @Override
- public boolean canSwipeInFullScreen(int dataID) {
- if (dataID < mImages.size() && dataID > 0) {
- return mImages.get(dataID).canSwipeInFullScreen();
- }
- return true;
- }
-
- @Override
- public void removeData(Context c, int dataID) {
- if (dataID >= mImages.size()) return;
- LocalData d = mImages.remove(dataID);
- // Delete previously removed data first.
- executeDeletion(c);
- mLocalDataToDelete = d;
- mListener.onDataRemoved(dataID, d);
- }
-
- // TODO: put the database query on background thread
- @Override
- public void addNewVideo(ContentResolver cr, Uri uri) {
- Cursor c = cr.query(uri,
- LocalData.Video.QUERY_PROJECTION,
- MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Video.QUERY_ORDER);
- if (c == null || !c.moveToFirst()) {
- return;
- }
- int pos = findDataByContentUri(uri);
- LocalData.Video newData = LocalData.Video.buildFromCursor(c);
- if (pos != -1) {
- // A duplicate one, just do a substitute.
- updateData(pos, newData);
- } else {
- // A new data.
- insertData(newData);
- }
- }
-
- // TODO: put the database query on background thread
- @Override
- public void addNewPhoto(ContentResolver cr, Uri uri) {
- Cursor c = cr.query(uri,
- LocalData.Photo.QUERY_PROJECTION,
- MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Photo.QUERY_ORDER);
- if (c == null || !c.moveToFirst()) {
- return;
- }
- int pos = findDataByContentUri(uri);
- LocalData.Photo newData = LocalData.Photo.buildFromCursor(c);
- if (pos != -1) {
- // a duplicate one, just do a substitute.
- Log.v(TAG, "found duplicate photo");
- updateData(pos, newData);
- } else {
- // a new data.
- insertData(newData);
- }
- }
-
- @Override
- public int findDataByContentUri(Uri uri) {
- for (int i = 0; i < mImages.size(); i++) {
- Uri u = mImages.get(i).getContentUri();
- if (u == null) {
- continue;
- }
- if (u.equals(uri)) {
- return i;
- }
- }
- return -1;
- }
-
- @Override
- public boolean undoDataRemoval() {
- if (mLocalDataToDelete == null) return false;
- LocalData d = mLocalDataToDelete;
- mLocalDataToDelete = null;
- insertData(d);
- return true;
- }
-
- @Override
- public boolean executeDeletion(Context c) {
- if (mLocalDataToDelete == null) return false;
-
- DeletionTask task = new DeletionTask(c);
- task.execute(mLocalDataToDelete);
- mLocalDataToDelete = null;
- return true;
- }
-
- @Override
- public void flush() {
- replaceData(null);
- }
-
- @Override
- public void refresh(ContentResolver resolver, Uri contentUri) {
- int pos = findDataByContentUri(contentUri);
- if (pos == -1) {
- return;
- }
-
- LocalData data = mImages.get(pos);
- if (data.refresh(resolver)) {
- updateData(pos, data);
- }
- }
-
- @Override
- public void updateData(final int pos, LocalData data) {
- mImages.set(pos, data);
- if (mListener != null) {
- mListener.onDataUpdated(new UpdateReporter() {
- @Override
- public boolean isDataRemoved(int dataID) {
- return false;
- }
-
- @Override
- public boolean isDataUpdated(int dataID) {
- return (dataID == pos);
- }
- });
- }
- }
-
- @Override
- public void insertData(LocalData data) {
- if (mImages == null) {
- mImages = new ArrayList<LocalData>();
- }
-
- // Since this function is mostly for adding the newest data,
- // a simple linear search should yield the best performance over a
- // binary search.
- int pos = 0;
- Comparator<LocalData> comp = new LocalData.NewestFirstComparator();
- for (; pos < mImages.size()
- && comp.compare(data, mImages.get(pos)) > 0; pos++);
- mImages.add(pos, data);
- if (mListener != null) {
- mListener.onDataInserted(pos, data);
- }
- }
-
- /** Update all the data */
- private void replaceData(List<LocalData> list) {
- boolean changed = (list != mImages);
- mImages = list;
- if (changed) {
- mListener.onDataLoaded();
- }
- }
-
- private class QueryTask extends AsyncTask<ContentResolver, Void, List<LocalData>> {
- @Override
- protected List<LocalData> doInBackground(ContentResolver... resolver) {
- List<LocalData> l = new ArrayList<LocalData>();
- // Photos
- Cursor c = resolver[0].query(
- LocalData.Photo.CONTENT_URI,
- LocalData.Photo.QUERY_PROJECTION,
- MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Photo.QUERY_ORDER);
- if (c != null && c.moveToFirst()) {
- // build up the list.
- while (true) {
- LocalData data = LocalData.Photo.buildFromCursor(c);
- if (data != null) {
- l.add(data);
- } else {
- Log.e(TAG, "Error loading data:"
- + c.getString(LocalData.Photo.COL_DATA));
- }
- if (c.isLast()) {
- break;
- }
- c.moveToNext();
- }
- }
- if (c != null) {
- c.close();
- }
-
- c = resolver[0].query(
- LocalData.Video.CONTENT_URI,
- LocalData.Video.QUERY_PROJECTION,
- MediaStore.Video.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Video.QUERY_ORDER);
- if (c != null && c.moveToFirst()) {
- // build up the list.
- c.moveToFirst();
- while (true) {
- LocalData data = LocalData.Video.buildFromCursor(c);
- if (data != null) {
- l.add(data);
- } else {
- Log.e(TAG, "Error loading data:"
- + c.getString(LocalData.Video.COL_DATA));
- }
- if (!c.isLast()) {
- c.moveToNext();
- } else {
- break;
- }
- }
- }
- if (c != null) {
- c.close();
- }
-
- if (l.size() == 0) return null;
-
- Collections.sort(l, new LocalData.NewestFirstComparator());
- return l;
- }
-
- @Override
- protected void onPostExecute(List<LocalData> l) {
- replaceData(l);
- }
- }
-
- private class DeletionTask extends AsyncTask<LocalData, Void, Void> {
- Context mContext;
-
- DeletionTask(Context context) {
- mContext = context;
- }
-
- @Override
- protected Void doInBackground(LocalData... data) {
- for (int i = 0; i < data.length; i++) {
- if (!data[i].isDataActionSupported(LocalData.ACTION_DELETE)) {
- Log.v(TAG, "Deletion is not supported:" + data[i]);
- continue;
- }
- data[i].delete(mContext);
- }
- return null;
- }
- }
-}
diff --git a/src/com/android/camera/data/CameraPreviewData.java b/src/com/android/camera/data/CameraPreviewData.java
deleted file mode 100644
index 8f8e2138d..000000000
--- a/src/com/android/camera/data/CameraPreviewData.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.view.View;
-
-import com.android.camera.ui.FilmStripView.ImageData;
-
-/**
- * A class implementing {@link LocalData} to represent a camera preview.
- */
-public class CameraPreviewData extends LocalData.LocalViewData {
-
- private boolean mPreviewLocked;
-
- /**
- * Constructor.
- *
- * @param v The {@link android.view.View} for camera preview.
- * @param width The width of the camera preview.
- * @param height The height of the camera preview.
- */
- public CameraPreviewData(View v, int width, int height) {
- super(v, width, height, -1, -1);
- mPreviewLocked = true;
- }
-
- @Override
- public int getType() {
- return ImageData.TYPE_CAMERA_PREVIEW;
- }
-
- @Override
- public boolean canSwipeInFullScreen() {
- return !mPreviewLocked;
- }
-
- /**
- * Locks the camera preview. When the camera preview is locked, swipe
- * to film strip is not allowed. One case is when the video recording
- * is in progress.
- *
- * @param lock {@code true} if the preview should be locked. {@code false}
- * otherwise.
- */
- public void lockPreview(boolean lock) {
- mPreviewLocked = lock;
- }
-}
diff --git a/src/com/android/camera/data/FixedFirstDataAdapter.java b/src/com/android/camera/data/FixedFirstDataAdapter.java
deleted file mode 100644
index 2bff22aa4..000000000
--- a/src/com/android/camera/data/FixedFirstDataAdapter.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.Context;
-import android.net.Uri;
-import android.view.View;
-
-import com.android.camera.ui.FilmStripView;
-import com.android.camera.ui.FilmStripView.DataAdapter;
-import com.android.camera.ui.FilmStripView.ImageData;
-
-/**
- * A {@link LocalDataAdapter} which puts a {@link LocalData} fixed at the first
- * position. It's done by combining a {@link LocalData} and another
- * {@link LocalDataAdapter}.
- */
-public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper
- implements DataAdapter.Listener {
-
- private LocalData mFirstData;
- private Listener mListener;
-
- /**
- * Constructor.
- *
- * @param wrappedAdapter The {@link LocalDataAdapter} to be wrapped.
- * @param firstData The {@link LocalData} to be placed at the first
- * position.
- */
- public FixedFirstDataAdapter(
- LocalDataAdapter wrappedAdapter,
- LocalData firstData) {
- super(wrappedAdapter);
- if (firstData == null) {
- throw new AssertionError("data is null");
- }
- mFirstData = firstData;
- }
-
- @Override
- public LocalData getLocalData(int dataID) {
- if (dataID == 0) {
- return mFirstData;
- }
- return mAdapter.getLocalData(dataID - 1);
- }
-
- @Override
- public void removeData(Context context, int dataID) {
- if (dataID > 0) {
- mAdapter.removeData(context, dataID - 1);
- }
- }
-
- @Override
- public int findDataByContentUri(Uri uri) {
- int pos = mAdapter.findDataByContentUri(uri);
- if (pos != -1) {
- return pos + 1;
- }
- return -1;
- }
-
- @Override
- public void updateData(int pos, LocalData data) {
- if (pos == 0) {
- mFirstData = data;
- if (mListener != null) {
- mListener.onDataUpdated(new UpdateReporter() {
- @Override
- public boolean isDataRemoved(int dataID) {
- return false;
- }
-
- @Override
- public boolean isDataUpdated(int dataID) {
- return (dataID == 0);
- }
- });
- }
- } else {
- mAdapter.updateData(pos - 1, data);
- }
- }
-
- @Override
- public int getTotalNumber() {
- return (mAdapter.getTotalNumber() + 1);
- }
-
- @Override
- public View getView(Context context, int dataID) {
- if (dataID == 0) {
- return mFirstData.getView(
- context, mSuggestedWidth, mSuggestedHeight, null);
- }
- return mAdapter.getView(context, dataID - 1);
- }
-
- @Override
- public ImageData getImageData(int dataID) {
- if (dataID == 0) {
- return mFirstData;
- }
- return mAdapter.getImageData(dataID - 1);
- }
-
- @Override
- public void onDataFullScreen(int dataID, boolean fullScreen) {
- if (dataID == 0) {
- mFirstData.onFullScreen(fullScreen);
- } else {
- mAdapter.onDataFullScreen(dataID - 1, fullScreen);
- }
- }
-
- @Override
- public void setListener(Listener listener) {
- mListener = listener;
- mAdapter.setListener((listener == null) ? null : this);
- }
-
- @Override
- public boolean canSwipeInFullScreen(int dataID) {
- if (dataID == 0) {
- return mFirstData.canSwipeInFullScreen();
- }
- return mAdapter.canSwipeInFullScreen(dataID - 1);
- }
-
- @Override
- public void onDataLoaded() {
- mListener.onDataLoaded();
- }
-
- @Override
- public void onDataUpdated(final UpdateReporter reporter) {
- mListener.onDataUpdated(new UpdateReporter() {
- @Override
- public boolean isDataRemoved(int dataID) {
- return reporter.isDataRemoved(dataID - 1);
- }
-
- @Override
- public boolean isDataUpdated(int dataID) {
- return reporter.isDataUpdated(dataID - 1);
- }
- });
- }
-
- @Override
- public void onDataInserted(int dataID, ImageData data) {
- mListener.onDataInserted(dataID + 1, data);
- }
-
- @Override
- public void onDataRemoved(int dataID, ImageData data) {
- mListener.onDataRemoved(dataID + 1, data);
- }
-}
diff --git a/src/com/android/camera/data/FixedLastDataAdapter.java b/src/com/android/camera/data/FixedLastDataAdapter.java
deleted file mode 100644
index b8325ec72..000000000
--- a/src/com/android/camera/data/FixedLastDataAdapter.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.Context;
-import android.net.Uri;
-import android.view.View;
-
-import com.android.camera.ui.FilmStripView;
-
-/**
- * A {@link LocalDataAdapter} which puts a {@link LocalData} fixed at the last
- * position. It's done by combining a {@link LocalData} and another
- * {@link LocalDataAdapter}.
- */
-public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper {
-
- private LocalData mLastData;
- private Listener mListener;
-
- /**
- * Constructor.
- *
- * @param wrappedAdapter The {@link LocalDataAdapter} to be wrapped.
- * @param lastData The {@link LocalData} to be placed at the last position.
- */
- public FixedLastDataAdapter(
- LocalDataAdapter wrappedAdapter,
- LocalData lastData) {
- super(wrappedAdapter);
- if (lastData == null) {
- throw new AssertionError("data is null");
- }
- mLastData = lastData;
- }
-
- @Override
- public void setListener(Listener listener) {
- super.setListener(listener);
- mListener = listener;
- }
-
- @Override
- public LocalData getLocalData(int dataID) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (dataID < totalNumber) {
- return mAdapter.getLocalData(dataID);
- } else if (dataID == totalNumber) {
- return mLastData;
- }
-
- return null;
- }
-
- @Override
- public void removeData(Context context, int dataID) {
- if (dataID < mAdapter.getTotalNumber()) {
- mAdapter.removeData(context, dataID);
- }
- }
-
- @Override
- public int findDataByContentUri(Uri uri) {
- return mAdapter.findDataByContentUri(uri);
- }
-
- @Override
- public void updateData(final int pos, LocalData data) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (pos < totalNumber) {
- mAdapter.updateData(pos, data);
- } else if (pos == totalNumber) {
- mLastData = data;
- if (mListener != null) {
- mListener.onDataUpdated(new UpdateReporter() {
- @Override
- public boolean isDataRemoved(int dataID) {
- return false;
- }
-
- @Override
- public boolean isDataUpdated(int dataID) {
- return (dataID == pos);
- }
- });
- }
- }
- }
-
- @Override
- public int getTotalNumber() {
- return mAdapter.getTotalNumber() + 1;
- }
-
- @Override
- public View getView(Context context, int dataID) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (dataID < totalNumber) {
- return mAdapter.getView(context, dataID);
- } else if (dataID == totalNumber) {
- return mLastData.getView(context,
- mSuggestedWidth, mSuggestedHeight, null);
- }
-
- return null;
- }
-
- @Override
- public FilmStripView.ImageData getImageData(int dataID) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (dataID < totalNumber) {
- return mAdapter.getImageData(dataID);
- } else if (dataID == totalNumber) {
- return mLastData;
- }
- return null;
- }
-
- @Override
- public void onDataFullScreen(int dataID, boolean fullScreen) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (dataID < totalNumber) {
- mAdapter.onDataFullScreen(dataID, fullScreen);
- } else if (dataID == totalNumber) {
- mLastData.onFullScreen(fullScreen);
- }
- }
-
- @Override
- public boolean canSwipeInFullScreen(int dataID) {
- int totalNumber = mAdapter.getTotalNumber();
-
- if (dataID < totalNumber) {
- return mAdapter.canSwipeInFullScreen(dataID);
- } else if (dataID == totalNumber) {
- return mLastData.canSwipeInFullScreen();
- }
- return false;
- }
-}
-
diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java
deleted file mode 100644
index 74055230f..000000000
--- a/src/com/android/camera/data/LocalData.java
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.MediaMetadataRetriever;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.provider.MediaStore.Video.VideoColumns;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import com.android.camera.Util;
-import com.android.camera.data.PanoramaMetadataLoader.PanoramaMetadataCallback;
-import com.android.camera.ui.FilmStripView;
-import com.android.gallery3d.R;
-import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
-import com.android.gallery3d.util.PanoramaViewHelper;
-
-import java.io.File;
-import java.util.Comparator;
-import java.util.Date;
-
-/**
- * An abstract interface that represents the local media data. Also implements
- * Comparable interface so we can sort in DataAdapter.
- */
-public interface LocalData extends FilmStripView.ImageData {
- static final String TAG = "CAM_LocalData";
-
- public static final int ACTION_NONE = 0;
- public static final int ACTION_PLAY = 1;
- public static final int ACTION_DELETE = (1 << 1);
-
- View getView(Context c, int width, int height, Drawable placeHolder);
-
- /**
- * Gets the date when this data is created. The returned date is also used
- * for sorting data.
- *
- * @return The date when this data is created.
- * @see {@link NewestFirstComparator}
- */
- long getDateTaken();
-
- /**
- * Gets the date when this data is modified. The returned date is also used
- * for sorting data.
- *
- * @return The date when this data is modified.
- * @see {@link NewestFirstComparator}
- */
- long getDateModified();
-
- /** Gets the title of this data */
- String getTitle();
-
- /**
- * Checks if the data actions (delete/play ...) can be applied on this data.
- *
- * @param actions The actions to check.
- * @return Whether all the actions are supported.
- */
- boolean isDataActionSupported(int actions);
-
- boolean delete(Context c);
-
- void onFullScreen(boolean fullScreen);
-
- /** Returns {@code true} if it allows swipe to filmstrip in full screen. */
- boolean canSwipeInFullScreen();
-
- /**
- * Returns the path to the data on the storage.
- *
- * @return Empty path if there's none.
- */
- String getPath();
-
- /**
- * Returns the content URI of this data item.
- *
- * @return {@code Uri.EMPTY} if not valid.
- */
- Uri getContentUri();
-
- /**
- * Refresh the data content.
- *
- * @param resolver {@link ContentResolver} to refresh the data.
- * @return {@code true} if success, {@code false} otherwise.
- */
- boolean refresh(ContentResolver resolver);
-
- static class NewestFirstComparator implements Comparator<LocalData> {
-
- /** Compare taken/modified date of LocalData in descent order to make
- newer data in the front.
- The negative numbers here are always considered "bigger" than
- positive ones. Thus, if any one of the numbers is negative, the logic
- is reversed. */
- private static int compareDate(long v1, long v2) {
- if (v1 >= 0 && v2 >= 0) {
- return ((v1 < v2) ? 1 : ((v1 > v2) ? -1 : 0));
- }
- return ((v2 < v1) ? 1 : ((v2 > v1) ? -1 : 0));
- }
-
- @Override
- public int compare(LocalData d1, LocalData d2) {
- int cmp = compareDate(d1.getDateTaken(), d2.getDateTaken());
- if (cmp == 0) {
- cmp = compareDate(d1.getDateModified(), d2.getDateModified());
- }
- if (cmp == 0) {
- cmp = d1.getTitle().compareTo(d2.getTitle());
- }
- return cmp;
- }
- }
-
- // Implementations below.
-
- /**
- * A base class for all the local media files. The bitmap is loaded in
- * background thread. Subclasses should implement their own background
- * loading thread by sub-classing BitmapLoadTask and overriding
- * doInBackground() to return a bitmap.
- */
- abstract static class LocalMediaData implements LocalData {
- protected long id;
- protected String title;
- protected String mimeType;
- protected long dateTaken;
- protected long dateModified;
- protected String path;
- // width and height should be adjusted according to orientation.
- protected int width;
- protected int height;
-
- /** The panorama metadata information of this media data. */
- private PanoramaMetadata mPanoramaMetadata;
-
- /** Used to load photo sphere metadata from image files. */
- private PanoramaMetadataLoader mPanoramaMetadataLoader = null;
-
- // true if this data has a corresponding visible view.
- protected Boolean mUsing = false;
-
- @Override
- public long getDateTaken() {
- return dateTaken;
- }
-
- @Override
- public long getDateModified() {
- return dateModified;
- }
-
- @Override
- public String getTitle() {
- return new String(title);
- }
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean delete(Context ctx) {
- File f = new File(path);
- return f.delete();
- }
-
- @Override
- public void viewPhotoSphere(PanoramaViewHelper helper) {
- helper.showPanorama(getContentUri());
- }
-
- @Override
- public void isPhotoSphere(Context context, final PanoramaSupportCallback callback) {
- // If we already have metadata, use it.
- if (mPanoramaMetadata != null) {
- callback.panoramaInfoAvailable(mPanoramaMetadata.mUsePanoramaViewer,
- mPanoramaMetadata.mIsPanorama360);
- }
-
- // Otherwise prepare a loader, if we don't have one already.
- if (mPanoramaMetadataLoader == null) {
- mPanoramaMetadataLoader = new PanoramaMetadataLoader(getContentUri());
- }
-
- // Load the metadata asynchronously.
- mPanoramaMetadataLoader.getPanoramaMetadata(context, new PanoramaMetadataCallback() {
- @Override
- public void onPanoramaMetadataLoaded(PanoramaMetadata metadata) {
- // Store the metadata and remove the loader to free up space.
- mPanoramaMetadata = metadata;
- mPanoramaMetadataLoader = null;
- callback.panoramaInfoAvailable(metadata.mUsePanoramaViewer,
- metadata.mIsPanorama360);
- }
- });
- }
-
- @Override
- public void onFullScreen(boolean fullScreen) {
- // do nothing.
- }
-
- @Override
- public boolean canSwipeInFullScreen() {
- return true;
- }
-
- protected ImageView fillImageView(Context ctx, ImageView v,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
- v.setScaleType(ImageView.ScaleType.FIT_XY);
- v.setImageDrawable(placeHolder);
-
- BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight);
- task.execute();
- return v;
- }
-
- @Override
- public View getView(Context ctx,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
- return fillImageView(ctx, new ImageView(ctx),
- decodeWidth, decodeHeight, placeHolder);
- }
-
- @Override
- public void prepare() {
- synchronized (mUsing) {
- mUsing = true;
- }
- }
-
- @Override
- public void recycle() {
- synchronized (mUsing) {
- mUsing = false;
- }
- }
-
- protected boolean isUsing() {
- synchronized (mUsing) {
- return mUsing;
- }
- }
-
- @Override
- public abstract int getType();
-
- protected abstract BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight);
-
- /**
- * An AsyncTask class that loads the bitmap in the background thread.
- * Sub-classes should implement their own "protected Bitmap doInBackground(Void... )"
- */
- protected abstract class BitmapLoadTask extends AsyncTask<Void, Void, Bitmap> {
- protected ImageView mView;
-
- protected BitmapLoadTask(ImageView v) {
- mView = v;
- }
-
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- if (!isUsing()) return;
- if (bitmap == null) {
- Log.e(TAG, "Failed decoding bitmap for file:" + path);
- return;
- }
- BitmapDrawable d = new BitmapDrawable(bitmap);
- mView.setScaleType(ImageView.ScaleType.FIT_XY);
- mView.setImageDrawable(d);
- }
- }
- }
-
- static class Photo extends LocalMediaData {
- public static final int COL_ID = 0;
- public static final int COL_TITLE = 1;
- public static final int COL_MIME_TYPE = 2;
- public static final int COL_DATE_TAKEN = 3;
- public static final int COL_DATE_MODIFIED = 4;
- public static final int COL_DATA = 5;
- public static final int COL_ORIENTATION = 6;
- public static final int COL_WIDTH = 7;
- public static final int COL_HEIGHT = 8;
-
- static final Uri CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-
- static final String QUERY_ORDER = ImageColumns.DATE_TAKEN + " DESC, "
- + ImageColumns._ID + " DESC";
- /**
- * These values should be kept in sync with column IDs (COL_*) above.
- */
- static final String[] QUERY_PROJECTION = {
- ImageColumns._ID, // 0, int
- ImageColumns.TITLE, // 1, string
- ImageColumns.MIME_TYPE, // 2, string
- ImageColumns.DATE_TAKEN, // 3, int
- ImageColumns.DATE_MODIFIED, // 4, int
- ImageColumns.DATA, // 5, string
- ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270
- ImageColumns.WIDTH, // 7, int
- ImageColumns.HEIGHT, // 8, int
- };
-
- private static final int mSupportedUIActions =
- FilmStripView.ImageData.ACTION_DEMOTE
- | FilmStripView.ImageData.ACTION_PROMOTE;
- private static final int mSupportedDataActions =
- LocalData.ACTION_DELETE;
-
- /** 32K buffer. */
- private static final byte[] DECODE_TEMP_STORAGE = new byte[32 * 1024];
-
- /** from MediaStore, can only be 0, 90, 180, 270 */
- public int orientation;
-
- static Photo buildFromCursor(Cursor c) {
- Photo d = new Photo();
- d.id = c.getLong(COL_ID);
- d.title = c.getString(COL_TITLE);
- d.mimeType = c.getString(COL_MIME_TYPE);
- d.dateTaken = c.getLong(COL_DATE_TAKEN);
- d.dateModified = c.getLong(COL_DATE_MODIFIED);
- d.path = c.getString(COL_DATA);
- d.orientation = c.getInt(COL_ORIENTATION);
- d.width = c.getInt(COL_WIDTH);
- d.height = c.getInt(COL_HEIGHT);
- if (d.width <= 0 || d.height <= 0) {
- Log.w(TAG, "Warning! zero dimension for "
- + d.path + ":" + d.width + "x" + d.height);
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(d.path, opts);
- if (opts.outWidth != -1 && opts.outHeight != -1) {
- d.width = opts.outWidth;
- d.height = opts.outHeight;
- } else {
- Log.w(TAG, "Warning! dimension decode failed for " + d.path);
- Bitmap b = BitmapFactory.decodeFile(d.path);
- if (b == null) {
- return null;
- }
- d.width = b.getWidth();
- d.height = b.getHeight();
- }
- }
- if (d.orientation == 90 || d.orientation == 270) {
- int b = d.width;
- d.width = d.height;
- d.height = b;
- }
- return d;
- }
-
- @Override
- public String toString() {
- return "Photo:" + ",data=" + path + ",mimeType=" + mimeType
- + "," + width + "x" + height + ",orientation=" + orientation
- + ",date=" + new Date(dateTaken);
- }
-
- @Override
- public int getType() {
- return TYPE_PHOTO;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return ((action & mSupportedUIActions) == action);
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return ((action & mSupportedDataActions) == action);
- }
-
- @Override
- public boolean delete(Context c) {
- ContentResolver cr = c.getContentResolver();
- cr.delete(CONTENT_URI, ImageColumns._ID + "=" + id, null);
- return super.delete(c);
- }
-
- @Override
- public Uri getContentUri() {
- Uri baseUri = CONTENT_URI;
- return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- Cursor c = resolver.query(
- getContentUri(), QUERY_PROJECTION, null, null, null);
- if (c == null || !c.moveToFirst()) {
- return false;
- }
- Photo newData = buildFromCursor(c);
- id = newData.id;
- title = newData.title;
- mimeType = newData.mimeType;
- dateTaken = newData.dateTaken;
- dateModified = newData.dateModified;
- path = newData.path;
- orientation = newData.orientation;
- width = newData.width;
- height = newData.height;
- return true;
- }
-
- @Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight) {
- return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight);
- }
-
- private final class PhotoBitmapLoadTask extends BitmapLoadTask {
- private int mDecodeWidth;
- private int mDecodeHeight;
-
- public PhotoBitmapLoadTask(ImageView v, int decodeWidth, int decodeHeight) {
- super(v);
- mDecodeWidth = decodeWidth;
- mDecodeHeight = decodeHeight;
- }
-
- @Override
- protected Bitmap doInBackground(Void... v) {
- BitmapFactory.Options opts = null;
- Bitmap b;
- int sample = 1;
- while (mDecodeWidth * sample < width
- || mDecodeHeight * sample < height) {
- sample *= 2;
- }
- opts = new BitmapFactory.Options();
- opts.inSampleSize = sample;
- opts.inTempStorage = DECODE_TEMP_STORAGE;
- if (isCancelled() || !isUsing()) {
- return null;
- }
- b = BitmapFactory.decodeFile(path, opts);
- if (orientation != 0) {
- if (isCancelled() || !isUsing()) {
- return null;
- }
- Matrix m = new Matrix();
- m.setRotate(orientation);
- b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
- }
- return b;
- }
- }
- }
-
- static class Video extends LocalMediaData {
- public static final int COL_ID = 0;
- public static final int COL_TITLE = 1;
- public static final int COL_MIME_TYPE = 2;
- public static final int COL_DATE_TAKEN = 3;
- public static final int COL_DATE_MODIFIED = 4;
- public static final int COL_DATA = 5;
- public static final int COL_WIDTH = 6;
- public static final int COL_HEIGHT = 7;
- public static final int COL_RESOLUTION = 8;
-
- static final Uri CONTENT_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-
- private static final int mSupportedUIActions =
- FilmStripView.ImageData.ACTION_DEMOTE
- | FilmStripView.ImageData.ACTION_PROMOTE;
- private static final int mSupportedDataActions =
- LocalData.ACTION_DELETE
- | LocalData.ACTION_PLAY;
-
- static final String QUERY_ORDER = VideoColumns.DATE_TAKEN + " DESC, "
- + VideoColumns._ID + " DESC";
- /**
- * These values should be kept in sync with column IDs (COL_*) above.
- */
- static final String[] QUERY_PROJECTION = {
- VideoColumns._ID, // 0, int
- VideoColumns.TITLE, // 1, string
- VideoColumns.MIME_TYPE, // 2, string
- VideoColumns.DATE_TAKEN, // 3, int
- VideoColumns.DATE_MODIFIED, // 4, int
- VideoColumns.DATA, // 5, string
- VideoColumns.WIDTH, // 6, int
- VideoColumns.HEIGHT, // 7, int
- VideoColumns.RESOLUTION // 8, string
- };
-
- private Uri mPlayUri;
-
- static Video buildFromCursor(Cursor c) {
- Video d = new Video();
- d.id = c.getLong(COL_ID);
- d.title = c.getString(COL_TITLE);
- d.mimeType = c.getString(COL_MIME_TYPE);
- d.dateTaken = c.getLong(COL_DATE_TAKEN);
- d.dateModified = c.getLong(COL_DATE_MODIFIED);
- d.path = c.getString(COL_DATA);
- d.width = c.getInt(COL_WIDTH);
- d.height = c.getInt(COL_HEIGHT);
- d.mPlayUri = d.getContentUri();
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(d.path);
- String rotation = retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
- if (d.width == 0 || d.height == 0) {
- d.width = Integer.parseInt(retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
- d.height = Integer.parseInt(retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
- }
- retriever.release();
- if (rotation != null
- && (rotation.equals("90") || rotation.equals("270"))) {
- int b = d.width;
- d.width = d.height;
- d.height = b;
- }
- return d;
- }
-
- @Override
- public String toString() {
- return "Video:" + ",data=" + path + ",mimeType=" + mimeType
- + "," + width + "x" + height + ",date=" + new Date(dateTaken);
- }
-
- @Override
- public int getType() {
- return TYPE_PHOTO;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return ((action & mSupportedUIActions) == action);
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return ((action & mSupportedDataActions) == action);
- }
-
- @Override
- public boolean delete(Context ctx) {
- ContentResolver cr = ctx.getContentResolver();
- cr.delete(CONTENT_URI, VideoColumns._ID + "=" + id, null);
- return super.delete(ctx);
- }
-
- @Override
- public Uri getContentUri() {
- Uri baseUri = CONTENT_URI;
- return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- Cursor c = resolver.query(
- getContentUri(), QUERY_PROJECTION, null, null, null);
- if (c == null && !c.moveToFirst()) {
- return false;
- }
- Video newData = buildFromCursor(c);
- id = newData.id;
- title = newData.title;
- mimeType = newData.mimeType;
- dateTaken = newData.dateTaken;
- dateModified = newData.dateModified;
- path = newData.path;
- width = newData.width;
- height = newData.height;
- mPlayUri = newData.mPlayUri;
- return true;
- }
-
- @Override
- public View getView(final Context ctx,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
-
- // ImageView for the bitmap.
- ImageView iv = new ImageView(ctx);
- iv.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
- fillImageView(ctx, iv, decodeWidth, decodeHeight, placeHolder);
-
- // ImageView for the play icon.
- ImageView icon = new ImageView(ctx);
- icon.setImageResource(R.drawable.ic_control_play);
- icon.setScaleType(ImageView.ScaleType.CENTER);
- icon.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
- icon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Util.playVideo(ctx, mPlayUri, title);
- }
- });
-
- FrameLayout f = new FrameLayout(ctx);
- f.addView(iv);
- f.addView(icon);
- return f;
- }
-
- @Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight) {
- return new VideoBitmapLoadTask(v);
- }
-
- private final class VideoBitmapLoadTask extends BitmapLoadTask {
-
- public VideoBitmapLoadTask(ImageView v) {
- super(v);
- }
-
- @Override
- protected Bitmap doInBackground(Void... v) {
- if (isCancelled() || !isUsing()) {
- return null;
- }
- android.media.MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(path);
- byte[] data = retriever.getEmbeddedPicture();
- Bitmap bitmap = null;
- if (isCancelled() || !isUsing()) {
- retriever.release();
- return null;
- }
- if (data != null) {
- bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- if (bitmap == null) {
- bitmap = retriever.getFrameAtTime();
- }
- retriever.release();
- return bitmap;
- }
- }
- }
-
- /**
- * A LocalData that does nothing but only shows a view.
- */
- public static class LocalViewData implements LocalData {
- private int mWidth;
- private int mHeight;
- private View mView;
- private long mDateTaken;
- private long mDateModified;
-
- public LocalViewData(View v,
- int width, int height,
- int dateTaken, int dateModified) {
- mView = v;
- mWidth = width;
- mHeight = height;
- mDateTaken = dateTaken;
- mDateModified = dateModified;
- }
-
- @Override
- public long getDateTaken() {
- return mDateTaken;
- }
-
- @Override
- public long getDateModified() {
- return mDateModified;
- }
-
- @Override
- public String getTitle() {
- return "";
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- @Override
- public int getType() {
- return FilmStripView.ImageData.TYPE_PHOTO;
- }
-
- @Override
- public String getPath() {
- return "";
- }
-
- @Override
- public Uri getContentUri() {
- return Uri.EMPTY;
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- return false;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean delete(Context c) {
- return false;
- }
-
- @Override
- public View getView(Context c, int width, int height, Drawable placeHolder) {
- return mView;
- }
-
- @Override
- public void prepare() {
- // do nothing.
- }
-
- @Override
- public void recycle() {
- // do nothing.
- }
-
- @Override
- public void isPhotoSphere(Context context, PanoramaSupportCallback callback) {
- // Not a photo sphere panorama.
- callback.panoramaInfoAvailable(false, false);
- }
-
- @Override
- public void viewPhotoSphere(PanoramaViewHelper helper) {
- // do nothing.
- }
-
- @Override
- public void onFullScreen(boolean fullScreen) {
- // do nothing.
- }
-
- @Override
- public boolean canSwipeInFullScreen() {
- return true;
- }
- }
-}
-
diff --git a/src/com/android/camera/data/LocalDataAdapter.java b/src/com/android/camera/data/LocalDataAdapter.java
deleted file mode 100644
index 0a5fde0b5..000000000
--- a/src/com/android/camera/data/LocalDataAdapter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.Uri;
-
-import static com.android.camera.ui.FilmStripView.DataAdapter;
-
-/**
- * An interface which extends {@link DataAdapter} and defines operations on
- * the data in the local camera folder.
- */
-public interface LocalDataAdapter extends DataAdapter {
-
- /**
- * Request for loading the local data.
- *
- * @param resolver {@link ContentResolver} used for data loading.
- */
- public void requestLoad(ContentResolver resolver);
-
- /**
- * Returns the specified {@link LocalData}.
- *
- * @param dataID The ID of the {@link LocalData} to get.
- * @return The {@link LocalData} to get. {@code null} if not available.
- */
- public LocalData getLocalData(int dataID);
-
- /**
- * Remove the data in the local camera folder.
- *
- * @param context {@link Context} used to remove the data.
- * @param dataID ID of data to be deleted.
- */
- public void removeData(Context context, int dataID);
-
- /**
- * Add new local video data.
- *
- * @param resolver {@link ContentResolver} used to add the data.
- * @param uri {@link Uri} of the video.
- */
- public void addNewVideo(ContentResolver resolver, Uri uri);
-
- /**
- * Adds new local photo data.
- *
- * @param resolver {@link ContentResolver} used to add the data.
- * @param uri {@link Uri} of the photo.
- */
- public void addNewPhoto(ContentResolver resolver, Uri uri);
-
- /**
- * Refresh the data by {@link Uri}.
- *
- * @param resolver {@link ContentResolver} used to refresh the data.
- * @param uri The {@link Uri} of the data to refresh.
- */
- public void refresh(ContentResolver resolver, Uri uri);
-
- /**
- * Finds the {@link LocalData} of the specified content Uri.
- *
- * @param Uri The content Uri of the {@link LocalData}.
- * @return The index of the data. {@code -1} if not found.
- */
- public int findDataByContentUri(Uri uri);
-
- /**
- * Clears all the data currently loaded.
- */
- public void flush();
-
- /**
- * Executes the deletion task. Delete the data waiting in the deletion queue.
- *
- * @param context The {@link Context} from the caller.
- * @return {@code true} if task has been executed, {@code false}
- * otherwise.
- */
- public boolean executeDeletion(Context context);
-
- /**
- * Undo a deletion. If there is any data waiting to be deleted in the queue,
- * move it out of the deletion queue.
- *
- * @return {@code true} if there are items in the queue, {@code false} otherwise.
- */
- public boolean undoDataRemoval();
-
- /**
- * Update the data in a specific position.
- *
- * @param pos The position of the data to be updated.
- * @param data The new data.
- */
- public void updateData(int pos, LocalData data);
-
- /** Insert a data. */
- public void insertData(LocalData data);
-}
diff --git a/src/com/android/camera/data/PanoramaMetadataLoader.java b/src/com/android/camera/data/PanoramaMetadataLoader.java
deleted file mode 100644
index 21b5f8a3d..000000000
--- a/src/com/android/camera/data/PanoramaMetadataLoader.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2013 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.data;
-
-import android.content.Context;
-import android.net.Uri;
-
-import com.android.gallery3d.util.LightCycleHelper;
-import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
-
-import java.util.ArrayList;
-
-/**
- * This class breaks out the off-thread panorama support.
- */
-public class PanoramaMetadataLoader {
- /**
- * Classes implementing this interface can get information about loaded
- * photo sphere metadata.
- */
- public static interface PanoramaMetadataCallback {
- /**
- * Called with the loaded metadata or <code>null</code>.
- */
- public void onPanoramaMetadataLoaded(PanoramaMetadata metadata);
- }
-
- private PanoramaMetadata mPanoramaMetadata;
- private ArrayList<PanoramaMetadataCallback> mCallbacksWaiting;
- private Uri mMediaUri;
-
- /**
- * Instantiated the meta data loader for the image resource with the given
- * URI.
- */
- public PanoramaMetadataLoader(Uri uri) {
- mMediaUri = uri;
- }
-
- /**
- * Asynchronously extract and return panorama metadata from the item with
- * the given URI.
- * <p>
- * NOTE: This call is backed by a cache to speed up successive calls, which
- * will return immediately. Use {@link #clearCachedValues()} is called.
- */
- public synchronized void getPanoramaMetadata(final Context context,
- PanoramaMetadataCallback callback) {
- if (mPanoramaMetadata != null) {
- // Return the cached data right away, no need to fetch it again.
- callback.onPanoramaMetadataLoaded(mPanoramaMetadata);
- } else {
- if (mCallbacksWaiting == null) {
- mCallbacksWaiting = new ArrayList<PanoramaMetadataCallback>();
-
- // TODO: Don't create a new thread each time, use a pool or
- // single instance.
- (new Thread() {
- @Override
- public void run() {
- onLoadingDone(LightCycleHelper.getPanoramaMetadata(context,
- mMediaUri));
- }
- }).start();
- }
- mCallbacksWaiting.add(callback);
- }
- }
-
- /**
- * Clear cached value and stop all running loading threads.
- */
- public synchronized void clearCachedValues() {
- if (mPanoramaMetadata != null) {
- mPanoramaMetadata = null;
- }
-
- // TODO: Cancel running loading thread if active.
- }
-
- private synchronized void onLoadingDone(PanoramaMetadata metadata) {
- mPanoramaMetadata = metadata;
- if (mPanoramaMetadata == null) {
- // Error getting panorama data from file. Treat as not panorama.
- mPanoramaMetadata = LightCycleHelper.NOT_PANORAMA;
- }
- for (PanoramaMetadataCallback cb : mCallbacksWaiting) {
- cb.onPanoramaMetadataLoaded(mPanoramaMetadata);
- }
- mCallbacksWaiting = null;
- }
-}
diff --git a/src/com/android/camera/drawable/TextDrawable.java b/src/com/android/camera/drawable/TextDrawable.java
deleted file mode 100644
index 60d8719c4..000000000
--- a/src/com/android/camera/drawable/TextDrawable.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2012 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.drawable;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.graphics.Paint.Align;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.TypedValue;
-
-
-public class TextDrawable extends Drawable {
-
- private static final int DEFAULT_COLOR = Color.WHITE;
- private static final int DEFAULT_TEXTSIZE = 15;
-
- private Paint mPaint;
- private CharSequence mText;
- private int mIntrinsicWidth;
- private int mIntrinsicHeight;
- private boolean mUseDropShadow;
-
- public TextDrawable(Resources res) {
- this(res, "");
- }
-
- public TextDrawable(Resources res, CharSequence text) {
- mText = text;
- updatePaint();
- float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
- DEFAULT_TEXTSIZE, res.getDisplayMetrics());
- mPaint.setTextSize(textSize);
- mIntrinsicWidth = (int) (mPaint.measureText(mText, 0, mText.length()) + .5);
- mIntrinsicHeight = mPaint.getFontMetricsInt(null);
- }
-
- private void updatePaint() {
- if (mPaint == null) {
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- }
- mPaint.setColor(DEFAULT_COLOR);
- mPaint.setTextAlign(Align.CENTER);
- if (mUseDropShadow) {
- mPaint.setTypeface(Typeface.DEFAULT_BOLD);
- mPaint.setShadowLayer(10, 0, 0, 0xff000000);
- } else {
- mPaint.setTypeface(Typeface.DEFAULT);
- mPaint.setShadowLayer(0, 0, 0, 0);
- }
- }
-
- public void setText(CharSequence txt) {
- mText = txt;
- if (txt == null) {
- mIntrinsicWidth = 0;
- mIntrinsicHeight = 0;
- } else {
- mIntrinsicWidth = (int) (mPaint.measureText(mText, 0, mText.length()) + .5);
- mIntrinsicHeight = mPaint.getFontMetricsInt(null);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- if (mText != null) {
- Rect bounds = getBounds();
- canvas.drawText(mText, 0, mText.length(),
- bounds.centerX(), bounds.centerY(), mPaint);
- }
- }
-
- public void setDropShadow(boolean shadow) {
- mUseDropShadow = shadow;
- updatePaint();
- }
-
- @Override
- public int getOpacity() {
- return mPaint.getAlpha();
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mIntrinsicWidth;
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mIntrinsicHeight;
- }
-
- @Override
- public void setAlpha(int alpha) {
- mPaint.setAlpha(alpha);
- }
-
- @Override
- public void setColorFilter(ColorFilter filter) {
- mPaint.setColorFilter(filter);
- }
-
-}
diff --git a/src/com/android/camera/ui/AbstractSettingPopup.java b/src/com/android/camera/ui/AbstractSettingPopup.java
deleted file mode 100644
index 783b6c771..000000000
--- a/src/com/android/camera/ui/AbstractSettingPopup.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.gallery3d.R;
-
-// A popup window that shows one or more camera settings.
-abstract public class AbstractSettingPopup extends RotateLayout {
- protected ViewGroup mSettingList;
- protected TextView mTitle;
-
- public AbstractSettingPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- mTitle = (TextView) findViewById(R.id.title);
- mSettingList = (ViewGroup) findViewById(R.id.settingList);
- }
-
- abstract public void reloadPreference();
-}
diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java
deleted file mode 100644
index 7fa6890a7..000000000
--- a/src/com/android/camera/ui/CameraControls.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-public class CameraControls extends RotatableLayout {
-
- private static final String TAG = "CAM_Controls";
-
- private View mBackgroundView;
- private View mShutter;
- private View mSwitcher;
- private View mMenu;
- private View mIndicators;
- private View mPreview;
-
- public CameraControls(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public CameraControls(Context context) {
- super(context);
- }
-
- @Override
- public void onFinishInflate() {
- super.onFinishInflate();
- mBackgroundView = findViewById(R.id.blocker);
- mSwitcher = findViewById(R.id.camera_switcher);
- mShutter = findViewById(R.id.shutter_button);
- mMenu = findViewById(R.id.menu);
- mIndicators = findViewById(R.id.on_screen_indicators);
- mPreview = findViewById(R.id.preview_thumb);
- }
-
- @Override
- public void onLayout(boolean changed, int l, int t, int r, int b) {
- int orientation = getResources().getConfiguration().orientation;
- int size = getResources().getDimensionPixelSize(R.dimen.camera_controls_size);
- int rotation = getUnifiedRotation();
- adjustBackground();
- // As l,t,r,b are positions relative to parents, we need to convert them
- // to child's coordinates
- r = r - l;
- b = b - t;
- l = 0;
- t = 0;
- for (int i = 0; i < getChildCount(); i++) {
- View v = getChildAt(i);
- v.layout(l, t, r, b);
- }
- Rect shutter = new Rect();
- topRight(mPreview, l, t, r, b);
- if (size > 0) {
- // restrict controls to size
- switch (rotation) {
- case 0:
- case 180:
- l = (l + r - size) / 2;
- r = l + size;
- break;
- case 90:
- case 270:
- t = (t + b - size) / 2;
- b = t + size;
- break;
- }
- }
- center(mShutter, l, t, r, b, orientation, rotation, shutter);
- center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect());
- toLeft(mSwitcher, shutter, rotation);
- toRight(mMenu, shutter, rotation);
- toRight(mIndicators, shutter, rotation);
- View retake = findViewById(R.id.btn_retake);
- if (retake != null) {
- center(retake, shutter, rotation);
- View cancel = findViewById(R.id.btn_cancel);
- toLeft(cancel, shutter, rotation);
- View done = findViewById(R.id.btn_done);
- toRight(done, shutter, rotation);
- }
- }
-
- private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
- int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
- int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
- switch (rotation) {
- case 0:
- // phone portrait; controls bottom
- result.left = (r + l) / 2 - tw / 2 + lp.leftMargin;
- result.right = (r + l) / 2 + tw / 2 - lp.rightMargin;
- result.bottom = b - lp.bottomMargin;
- result.top = b - th + lp.topMargin;
- break;
- case 90:
- // phone landscape: controls right
- result.right = r - lp.rightMargin;
- result.left = r - tw + lp.leftMargin;
- result.top = (b + t) / 2 - th / 2 + lp.topMargin;
- result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin;
- break;
- case 180:
- // phone upside down: controls top
- result.left = (r + l) / 2 - tw / 2 + lp.leftMargin;
- result.right = (r + l) / 2 + tw / 2 - lp.rightMargin;
- result.top = t + lp.topMargin;
- result.bottom = t + th - lp.bottomMargin;
- break;
- case 270:
- // reverse landscape: controls left
- result.left = l + lp.leftMargin;
- result.right = l + tw - lp.rightMargin;
- result.top = (b + t) / 2 - th / 2 + lp.topMargin;
- result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin;
- break;
- }
- v.layout(result.left, result.top, result.right, result.bottom);
- }
-
- private void center(View v, Rect other, int rotation) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
- int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
- int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
- int cx = (other.left + other.right) / 2;
- int cy = (other.top + other.bottom) / 2;
- v.layout(cx - tw / 2 + lp.leftMargin,
- cy - th / 2 + lp.topMargin,
- cx + tw / 2 - lp.rightMargin,
- cy + th / 2 - lp.bottomMargin);
- }
-
- private void toLeft(View v, Rect other, int rotation) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
- int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
- int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
- int cx = (other.left + other.right) / 2;
- int cy = (other.top + other.bottom) / 2;
- int l = 0, r = 0, t = 0, b = 0;
- switch (rotation) {
- case 0:
- // portrait, to left of anchor at bottom
- l = other.left - tw + lp.leftMargin;
- r = other.left - lp.rightMargin;
- t = cy - th / 2 + lp.topMargin;
- b = cy + th / 2 - lp.bottomMargin;
- break;
- case 90:
- // phone landscape: below anchor on right
- l = cx - tw / 2 + lp.leftMargin;
- r = cx + tw / 2 - lp.rightMargin;
- t = other.bottom + lp.topMargin;
- b = other.bottom + th - lp.bottomMargin;
- break;
- case 180:
- // phone upside down: right of anchor at top
- l = other.right + lp.leftMargin;
- r = other.right + tw - lp.rightMargin;
- t = cy - th / 2 + lp.topMargin;
- b = cy + th / 2 - lp.bottomMargin;
- break;
- case 270:
- // reverse landscape: above anchor on left
- l = cx - tw / 2 + lp.leftMargin;
- r = cx + tw / 2 - lp.rightMargin;
- t = other.top - th + lp.topMargin;
- b = other.top - lp.bottomMargin;
- break;
- }
- v.layout(l, t, r, b);
- }
-
- private void toRight(View v, Rect other, int rotation) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
- int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
- int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
- int cx = (other.left + other.right) / 2;
- int cy = (other.top + other.bottom) / 2;
- int l = 0, r = 0, t = 0, b = 0;
- switch (rotation) {
- case 0:
- l = other.right + lp.leftMargin;
- r = other.right + tw - lp.rightMargin;
- t = cy - th / 2 + lp.topMargin;
- b = cy + th / 2 - lp.bottomMargin;
- break;
- case 90:
- l = cx - tw / 2 + lp.leftMargin;
- r = cx + tw / 2 - lp.rightMargin;
- t = other.top - th + lp.topMargin;
- b = other.top - lp.bottomMargin;
- break;
- case 180:
- l = other.left - tw + lp.leftMargin;
- r = other.left - lp.rightMargin;
- t = cy - th / 2 + lp.topMargin;
- b = cy + th / 2 - lp.bottomMargin;
- break;
- case 270:
- l = cx - tw / 2 + lp.leftMargin;
- r = cx + tw / 2 - lp.rightMargin;
- t = other.bottom + lp.topMargin;
- b = other.bottom + th - lp.bottomMargin;
- break;
- }
- v.layout(l, t, r, b);
- }
-
- private void topRight(View v, int l, int t, int r, int b) {
- // layout using the specific margins; the rotation code messes up the others
- int mt = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_top);
- int mr = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_right);
- v.layout(r - v.getMeasuredWidth() - mr, t + mt, r - mr, t + mt + v.getMeasuredHeight());
- }
-
- private void adjustBackground() {
- int rotation = getUnifiedRotation();
- // remove current drawable and reset rotation
- mBackgroundView.setBackgroundDrawable(null);
- mBackgroundView.setRotationX(0);
- mBackgroundView.setRotationY(0);
- // if the switcher background is top aligned we need to flip the background
- // drawable vertically; if left aligned, flip horizontally
- switch (rotation) {
- case 180:
- mBackgroundView.setRotationX(180);
- break;
- case 270:
- mBackgroundView.setRotationY(180);
- break;
- default:
- break;
- }
- mBackgroundView.setBackgroundResource(R.drawable.switcher_bg);
- }
-
-}
diff --git a/src/com/android/camera/ui/CameraRootView.java b/src/com/android/camera/ui/CameraRootView.java
deleted file mode 100644
index adda70697..000000000
--- a/src/com/android/camera/ui/CameraRootView.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.camera.Util;
-import com.android.gallery3d.common.ApiHelper;
-
-public class CameraRootView extends FrameLayout {
-
- private int mTopMargin = 0;
- private int mBottomMargin = 0;
- private int mLeftMargin = 0;
- private int mRightMargin = 0;
- private Rect mCurrentInsets;
- private int mOffset = 0;
- private Object mDisplayListener;
- private MyDisplayListener mListener;
- public interface MyDisplayListener {
- public void onDisplayChanged();
- }
-
- public CameraRootView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initDisplayListener();
- setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
-
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- super.fitSystemWindows(insets);
- mCurrentInsets = insets;
- // insets include status bar, navigation bar, etc
- // In this case, we are only concerned with the size of nav bar
- if (mOffset > 0) return true;
-
- if (insets.bottom > 0) {
- mOffset = insets.bottom;
- } else if (insets.right > 0) {
- mOffset = insets.right;
- }
- return true;
- }
-
- public void initDisplayListener() {
- if (ApiHelper.HAS_DISPLAY_LISTENER) {
- mDisplayListener = new DisplayListener() {
-
- @Override
- public void onDisplayAdded(int arg0) {}
-
- @Override
- public void onDisplayChanged(int arg0) {
- mListener.onDisplayChanged();
- }
-
- @Override
- public void onDisplayRemoved(int arg0) {}
- };
- }
- }
-
- public void setDisplayChangeListener(MyDisplayListener listener) {
- mListener = listener;
- }
-
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (ApiHelper.HAS_DISPLAY_LISTENER) {
- ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
- .registerDisplayListener((DisplayListener) mDisplayListener, null);
- }
- }
-
- @Override
- public void onDetachedFromWindow () {
- super.onDetachedFromWindow();
- if (ApiHelper.HAS_DISPLAY_LISTENER) {
- ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
- .unregisterDisplayListener((DisplayListener) mDisplayListener);
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int rotation = Util.getDisplayRotation((Activity) getContext());
- // all the layout code assumes camera device orientation to be portrait
- // adjust rotation for landscape
- int orientation = getResources().getConfiguration().orientation;
- int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
- : Configuration.ORIENTATION_LANDSCAPE;
- if (camOrientation != orientation) {
- rotation = (rotation + 90) % 360;
- }
- // calculate margins
- mLeftMargin = 0;
- mRightMargin = 0;
- mBottomMargin = 0;
- mTopMargin = 0;
- switch (rotation) {
- case 0:
- mBottomMargin += mOffset;
- break;
- case 90:
- mRightMargin += mOffset;
- break;
- case 180:
- mTopMargin += mOffset;
- break;
- case 270:
- mLeftMargin += mOffset;
- break;
- }
- if (mCurrentInsets != null) {
- if (mCurrentInsets.right > 0) {
- // navigation bar on the right
- mRightMargin = mRightMargin > 0 ? mRightMargin : mCurrentInsets.right;
- } else {
- // navigation bar on the bottom
- mBottomMargin = mBottomMargin > 0 ? mBottomMargin : mCurrentInsets.bottom;
- }
- }
- // make sure all the children are resized
- super.onMeasure(widthMeasureSpec - mLeftMargin - mRightMargin,
- heightMeasureSpec - mTopMargin - mBottomMargin);
- setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
- }
-
- @Override
- public void onLayout(boolean changed, int l, int t, int r, int b) {
- r -= l;
- b -= t;
- l = 0;
- t = 0;
- int orientation = getResources().getConfiguration().orientation;
- // Lay out children
- for (int i = 0; i < getChildCount(); i++) {
- View v = getChildAt(i);
- if (v instanceof CameraControls) {
- // Lay out camera controls to center on the short side of the screen
- // so that they stay in place during rotation
- int width = v.getMeasuredWidth();
- int height = v.getMeasuredHeight();
- if (orientation == Configuration.ORIENTATION_PORTRAIT) {
- int left = (l + r - width) / 2;
- v.layout(left, t + mTopMargin, left + width, b - mBottomMargin);
- } else {
- int top = (t + b - height) / 2;
- v.layout(l + mLeftMargin, top, r - mRightMargin, top + height);
- }
- } else {
- v.layout(l + mLeftMargin, t + mTopMargin, r - mRightMargin, b - mBottomMargin);
- }
- }
- }
-}
diff --git a/src/com/android/camera/ui/CameraSwitcher.java b/src/com/android/camera/ui/CameraSwitcher.java
deleted file mode 100644
index 6e4321571..000000000
--- a/src/com/android/camera/ui/CameraSwitcher.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup;
-import android.widget.FrameLayout.LayoutParams;
-import android.widget.LinearLayout;
-
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.util.LightCycleHelper;
-import com.android.gallery3d.util.UsageStatistics;
-
-public class CameraSwitcher extends RotateImageView
- implements OnClickListener, OnTouchListener {
-
- private static final String TAG = "CAM_Switcher";
- private static final int SWITCHER_POPUP_ANIM_DURATION = 200;
-
- public static final int PHOTO_MODULE_INDEX = 0;
- public static final int VIDEO_MODULE_INDEX = 1;
- public static final int LIGHTCYCLE_MODULE_INDEX = 2;
- public static final int REFOCUS_MODULE_INDEX = 3;
- private static final int[] DRAW_IDS = {
- R.drawable.ic_switch_camera,
- R.drawable.ic_switch_video,
- R.drawable.ic_switch_photosphere,
- R.drawable.ic_switch_refocus
- };
- public interface CameraSwitchListener {
- public void onCameraSelected(int i);
- public void onShowSwitcherPopup();
- }
-
- private CameraSwitchListener mListener;
- private int mCurrentIndex;
- private int[] mModuleIds;
- private int[] mDrawIds;
- private int mItemSize;
- private View mPopup;
- private View mParent;
- private boolean mShowingPopup;
- private boolean mNeedsAnimationSetup;
- private Drawable mIndicator;
-
- private float mTranslationX = 0;
- private float mTranslationY = 0;
-
- private AnimatorListener mHideAnimationListener;
- private AnimatorListener mShowAnimationListener;
-
- public CameraSwitcher(Context context) {
- super(context);
- init(context);
- }
-
- public CameraSwitcher(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- private void init(Context context) {
- mItemSize = context.getResources().getDimensionPixelSize(R.dimen.switcher_size);
- setOnClickListener(this);
- mIndicator = context.getResources().getDrawable(R.drawable.ic_switcher_menu_indicator);
- initializeDrawables(context);
- }
-
- public void initializeDrawables(Context context) {
- int totaldrawid = (LightCycleHelper.hasLightCycleCapture(context)
- ? DRAW_IDS.length : DRAW_IDS.length - 1);
-
- int[] drawids = new int[totaldrawid];
- int[] moduleids = new int[totaldrawid];
- int ix = 0;
- for (int i = 0; i < DRAW_IDS.length; i++) {
- if (i == LIGHTCYCLE_MODULE_INDEX && !LightCycleHelper.hasLightCycleCapture(context)) {
- continue; // not enabled, so don't add to UI
- }
- moduleids[ix] = i;
- drawids[ix++] = DRAW_IDS[i];
- }
- setIds(moduleids, drawids);
- }
-
- public void setIds(int[] moduleids, int[] drawids) {
- mDrawIds = drawids;
- mModuleIds = moduleids;
- }
-
- public void setCurrentIndex(int i) {
- mCurrentIndex = i;
- setImageResource(mDrawIds[i]);
- }
-
- public void setSwitchListener(CameraSwitchListener l) {
- mListener = l;
- }
-
- @Override
- public void onClick(View v) {
- showSwitcher();
- mListener.onShowSwitcherPopup();
- }
-
- private void onCameraSelected(int ix) {
- hidePopup();
- if ((ix != mCurrentIndex) && (mListener != null)) {
- UsageStatistics.onEvent("CameraModeSwitch", null, null);
- UsageStatistics.setPendingTransitionCause(
- UsageStatistics.TRANSITION_MENU_TAP);
- setCurrentIndex(ix);
- mListener.onCameraSelected(mModuleIds[ix]);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- mIndicator.setBounds(getDrawable().getBounds());
- mIndicator.draw(canvas);
- }
-
- private void initPopup() {
- mParent = LayoutInflater.from(getContext()).inflate(R.layout.switcher_popup,
- (ViewGroup) getParent());
- LinearLayout content = (LinearLayout) mParent.findViewById(R.id.content);
- mPopup = content;
- // Set the gravity of the popup, so that it shows up at the right position
- // on screen
- LayoutParams lp = ((LayoutParams) mPopup.getLayoutParams());
- lp.gravity = ((LayoutParams) mParent.findViewById(R.id.camera_switcher)
- .getLayoutParams()).gravity;
- mPopup.setLayoutParams(lp);
-
- mPopup.setVisibility(View.INVISIBLE);
- mNeedsAnimationSetup = true;
- for (int i = mDrawIds.length - 1; i >= 0; i--) {
- RotateImageView item = new RotateImageView(getContext());
- item.setImageResource(mDrawIds[i]);
- item.setBackgroundResource(R.drawable.bg_pressed);
- final int index = i;
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (showsPopup()) onCameraSelected(index);
- }
- });
- switch (mDrawIds[i]) {
- case R.drawable.ic_switch_camera:
- item.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_switch_to_camera));
- break;
- case R.drawable.ic_switch_video:
- item.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_switch_to_video));
- break;
- case R.drawable.ic_switch_photosphere:
- item.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_switch_to_new_panorama));
- break;
- case R.drawable.ic_switch_refocus:
- item.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_switch_to_refocus));
- break;
- default:
- break;
- }
- content.addView(item, new LinearLayout.LayoutParams(mItemSize, mItemSize));
- }
- mPopup.measure(MeasureSpec.makeMeasureSpec(mParent.getWidth(), MeasureSpec.AT_MOST),
- MeasureSpec.makeMeasureSpec(mParent.getHeight(), MeasureSpec.AT_MOST));
- }
-
- public boolean showsPopup() {
- return mShowingPopup;
- }
-
- public boolean isInsidePopup(MotionEvent evt) {
- if (!showsPopup()) return false;
- int topLeft[] = new int[2];
- mPopup.getLocationOnScreen(topLeft);
- int left = topLeft[0];
- int top = topLeft[1];
- int bottom = top + mPopup.getHeight();
- int right = left + mPopup.getWidth();
- return evt.getX() >= left && evt.getX() < right
- && evt.getY() >= top && evt.getY() < bottom;
- }
-
- private void hidePopup() {
- mShowingPopup = false;
- setVisibility(View.VISIBLE);
- if (mPopup != null && !animateHidePopup()) {
- mPopup.setVisibility(View.INVISIBLE);
- }
- mParent.setOnTouchListener(null);
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- if (showsPopup()) {
- ((ViewGroup) mParent).removeView(mPopup);
- mPopup = null;
- initPopup();
- mPopup.setVisibility(View.VISIBLE);
- }
- }
-
- private void showSwitcher() {
- mShowingPopup = true;
- if (mPopup == null) {
- initPopup();
- }
- layoutPopup();
- mPopup.setVisibility(View.VISIBLE);
- if (!animateShowPopup()) {
- setVisibility(View.INVISIBLE);
- }
- mParent.setOnTouchListener(this);
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- closePopup();
- return true;
- }
-
- public void closePopup() {
- if (showsPopup()) {
- hidePopup();
- }
- }
-
- @Override
- public void setOrientation(int degree, boolean animate) {
- super.setOrientation(degree, animate);
- ViewGroup content = (ViewGroup) mPopup;
- if (content == null) return;
- for (int i = 0; i < content.getChildCount(); i++) {
- RotateImageView iv = (RotateImageView) content.getChildAt(i);
- iv.setOrientation(degree, animate);
- }
- }
-
- private void layoutPopup() {
- int orientation = Util.getDisplayRotation((Activity) getContext());
- int w = mPopup.getMeasuredWidth();
- int h = mPopup.getMeasuredHeight();
- if (orientation == 0) {
- mPopup.layout(getRight() - w, getBottom() - h, getRight(), getBottom());
- mTranslationX = 0;
- mTranslationY = h / 3;
- } else if (orientation == 90) {
- mTranslationX = w / 3;
- mTranslationY = - h / 3;
- mPopup.layout(getRight() - w, getTop(), getRight(), getTop() + h);
- } else if (orientation == 180) {
- mTranslationX = - w / 3;
- mTranslationY = - h / 3;
- mPopup.layout(getLeft(), getTop(), getLeft() + w, getTop() + h);
- } else {
- mTranslationX = - w / 3;
- mTranslationY = h - getHeight();
- mPopup.layout(getLeft(), getBottom() - h, getLeft() + w, getBottom());
- }
- }
-
- @Override
- public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mPopup != null) {
- layoutPopup();
- }
- }
-
- private void popupAnimationSetup() {
- if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) {
- return;
- }
- layoutPopup();
- mPopup.setScaleX(0.3f);
- mPopup.setScaleY(0.3f);
- mPopup.setTranslationX(mTranslationX);
- mPopup.setTranslationY(mTranslationY);
- mNeedsAnimationSetup = false;
- }
-
- private boolean animateHidePopup() {
- if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) {
- return false;
- }
- if (mHideAnimationListener == null) {
- mHideAnimationListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Verify that we weren't canceled
- if (!showsPopup() && mPopup != null) {
- mPopup.setVisibility(View.INVISIBLE);
- ((ViewGroup) mParent).removeView(mPopup);
- mPopup = null;
- }
- }
- };
- }
- mPopup.animate()
- .alpha(0f)
- .scaleX(0.3f).scaleY(0.3f)
- .translationX(mTranslationX)
- .translationY(mTranslationY)
- .setDuration(SWITCHER_POPUP_ANIM_DURATION)
- .setListener(mHideAnimationListener);
- animate().alpha(1f).setDuration(SWITCHER_POPUP_ANIM_DURATION)
- .setListener(null);
- return true;
- }
-
- private boolean animateShowPopup() {
- if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) {
- return false;
- }
- if (mNeedsAnimationSetup) {
- popupAnimationSetup();
- }
- if (mShowAnimationListener == null) {
- mShowAnimationListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Verify that we weren't canceled
- if (showsPopup()) {
- setVisibility(View.INVISIBLE);
- // request layout to make sure popup is laid out correctly on ICS
- mPopup.requestLayout();
- }
- }
- };
- }
- mPopup.animate()
- .alpha(1f)
- .scaleX(1f).scaleY(1f)
- .translationX(0)
- .translationY(0)
- .setDuration(SWITCHER_POPUP_ANIM_DURATION)
- .setListener(null);
- animate().alpha(0f).setDuration(SWITCHER_POPUP_ANIM_DURATION)
- .setListener(mShowAnimationListener);
- return true;
- }
-}
diff --git a/src/com/android/camera/ui/CheckedLinearLayout.java b/src/com/android/camera/ui/CheckedLinearLayout.java
deleted file mode 100644
index 4e7750499..000000000
--- a/src/com/android/camera/ui/CheckedLinearLayout.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Checkable;
-import android.widget.LinearLayout;
-
-public class CheckedLinearLayout extends LinearLayout implements Checkable {
- private static final int[] CHECKED_STATE_SET = {
- android.R.attr.state_checked
- };
- private boolean mChecked;
-
- public CheckedLinearLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public boolean isChecked() {
- return mChecked;
- }
-
- @Override
- public void setChecked(boolean checked) {
- if (mChecked != checked) {
- mChecked = checked;
- refreshDrawableState();
- }
- }
-
- @Override
- public void toggle() {
- setChecked(!mChecked);
- }
-
- @Override
- public int[] onCreateDrawableState(int extraSpace) {
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
- if (mChecked) {
- mergeDrawableStates(drawableState, CHECKED_STATE_SET);
- }
- return drawableState;
- }
-}
diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java
deleted file mode 100644
index 907d33508..000000000
--- a/src/com/android/camera/ui/CountDownView.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import java.util.Locale;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.SoundPool;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.android.gallery3d.R;
-
-public class CountDownView extends FrameLayout {
-
- private static final String TAG = "CAM_CountDownView";
- private static final int SET_TIMER_TEXT = 1;
- private TextView mRemainingSecondsView;
- private int mRemainingSecs = 0;
- private OnCountDownFinishedListener mListener;
- private Animation mCountDownAnim;
- private SoundPool mSoundPool;
- private int mBeepTwice;
- private int mBeepOnce;
- private boolean mPlaySound;
- private final Handler mHandler = new MainHandler();
-
- public CountDownView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mCountDownAnim = AnimationUtils.loadAnimation(context, R.anim.count_down_exit);
- // Load the beeps
- mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
- mBeepOnce = mSoundPool.load(context, R.raw.beep_once, 1);
- mBeepTwice = mSoundPool.load(context, R.raw.beep_twice, 1);
- }
-
- public boolean isCountingDown() {
- return mRemainingSecs > 0;
- };
-
- public interface OnCountDownFinishedListener {
- public void onCountDownFinished();
- }
-
- private void remainingSecondsChanged(int newVal) {
- mRemainingSecs = newVal;
- if (newVal == 0) {
- // Countdown has finished
- setVisibility(View.INVISIBLE);
- mListener.onCountDownFinished();
- } else {
- Locale locale = getResources().getConfiguration().locale;
- String localizedValue = String.format(locale, "%d", newVal);
- mRemainingSecondsView.setText(localizedValue);
- // Fade-out animation
- mCountDownAnim.reset();
- mRemainingSecondsView.clearAnimation();
- mRemainingSecondsView.startAnimation(mCountDownAnim);
-
- // Play sound effect for the last 3 seconds of the countdown
- if (mPlaySound) {
- if (newVal == 1) {
- mSoundPool.play(mBeepTwice, 1.0f, 1.0f, 0, 0, 1.0f);
- } else if (newVal <= 3) {
- mSoundPool.play(mBeepOnce, 1.0f, 1.0f, 0, 0, 1.0f);
- }
- }
- // Schedule the next remainingSecondsChanged() call in 1 second
- mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000);
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds);
- }
-
- public void setCountDownFinishedListener(OnCountDownFinishedListener listener) {
- mListener = listener;
- }
-
- public void startCountDown(int sec, boolean playSound) {
- if (sec <= 0) {
- Log.w(TAG, "Invalid input for countdown timer: " + sec + " seconds");
- return;
- }
- setVisibility(View.VISIBLE);
- mPlaySound = playSound;
- remainingSecondsChanged(sec);
- }
-
- public void cancelCountDown() {
- if (mRemainingSecs > 0) {
- mRemainingSecs = 0;
- mHandler.removeMessages(SET_TIMER_TEXT);
- setVisibility(View.INVISIBLE);
- }
- }
-
- private class MainHandler extends Handler {
- @Override
- public void handleMessage(Message message) {
- if (message.what == SET_TIMER_TEXT) {
- remainingSecondsChanged(mRemainingSecs -1);
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/com/android/camera/ui/CountdownTimerPopup.java b/src/com/android/camera/ui/CountdownTimerPopup.java
deleted file mode 100644
index 7c3572b55..000000000
--- a/src/com/android/camera/ui/CountdownTimerPopup.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.NumberPicker;
-import android.widget.NumberPicker.OnValueChangeListener;
-
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-import java.util.Locale;
-
-/**
- * This is a popup window that allows users to specify a countdown timer
- */
-
-public class CountdownTimerPopup extends AbstractSettingPopup {
- private static final String TAG = "TimerSettingPopup";
- private NumberPicker mNumberSpinner;
- private String[] mDurations;
- private ListPreference mTimer;
- private ListPreference mBeep;
- private Listener mListener;
- private Button mConfirmButton;
- private View mPickerTitle;
- private CheckBox mTimerSound;
- private View mSoundTitle;
-
- static public interface Listener {
- public void onListPrefChanged(ListPreference pref);
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public CountdownTimerPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void initialize(ListPreference timer, ListPreference beep) {
- mTimer = timer;
- mBeep = beep;
- // Set title.
- mTitle.setText(mTimer.getTitle());
-
- // Duration
- CharSequence[] entries = mTimer.getEntryValues();
- mDurations = new String[entries.length];
- Locale locale = getResources().getConfiguration().locale;
- mDurations[0] = getResources().getString(R.string.setting_off); // Off
- for (int i = 1; i < entries.length; i++)
- mDurations[i] = String.format(locale, "%d", Integer.parseInt(entries[i].toString()));
- int durationCount = mDurations.length;
- mNumberSpinner = (NumberPicker) findViewById(R.id.duration);
- mNumberSpinner.setMinValue(0);
- mNumberSpinner.setMaxValue(durationCount - 1);
- mNumberSpinner.setDisplayedValues(mDurations);
- mNumberSpinner.setWrapSelectorWheel(false);
- mNumberSpinner.setOnValueChangedListener(new OnValueChangeListener() {
- @Override
- public void onValueChange(NumberPicker picker, int oldValue, int newValue) {
- setTimeSelectionEnabled(newValue != 0);
- }
- });
- mConfirmButton = (Button) findViewById(R.id.timer_set_button);
- mPickerTitle = findViewById(R.id.set_time_interval_title);
-
- // Disable focus on the spinners to prevent keyboard from coming up
- mNumberSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
-
- mConfirmButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- updateInputState();
- }
- });
- mTimerSound = (CheckBox) findViewById(R.id.sound_check_box);
- mSoundTitle = findViewById(R.id.beep_title);
- }
-
- private void restoreSetting() {
- int index = mTimer.findIndexOfValue(mTimer.getValue());
- if (index == -1) {
- Log.e(TAG, "Invalid preference value.");
- mTimer.print();
- throw new IllegalArgumentException();
- } else {
- setTimeSelectionEnabled(index != 0);
- mNumberSpinner.setValue(index);
- }
- boolean checked = mBeep.findIndexOfValue(mBeep.getValue()) != 0;
- mTimerSound.setChecked(checked);
- }
-
- @Override
- public void setVisibility(int visibility) {
- if (visibility == View.VISIBLE) {
- if (getVisibility() != View.VISIBLE) {
- // Set the number pickers and on/off switch to be consistent
- // with the preference
- restoreSetting();
- }
- }
- super.setVisibility(visibility);
- }
-
- protected void setTimeSelectionEnabled(boolean enabled) {
- mPickerTitle.setVisibility(enabled ? VISIBLE : INVISIBLE);
- mTimerSound.setEnabled(enabled);
- mSoundTitle.setEnabled(enabled);
- }
-
- @Override
- public void reloadPreference() {
- }
-
- private void updateInputState() {
- mTimer.setValueIndex(mNumberSpinner.getValue());
- mBeep.setValueIndex(mTimerSound.isChecked() ? 1 : 0);
- if (mListener != null) {
- mListener.onListPrefChanged(mTimer);
- mListener.onListPrefChanged(mBeep);
- }
- }
-}
diff --git a/src/com/android/camera/ui/EffectSettingPopup.java b/src/com/android/camera/ui/EffectSettingPopup.java
deleted file mode 100644
index 568781a01..000000000
--- a/src/com/android/camera/ui/EffectSettingPopup.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.GridView;
-import android.widget.SimpleAdapter;
-
-import com.android.camera.IconListPreference;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-// A popup window that shows video effect setting. It has two grid view.
-// One shows the goofy face effects. The other shows the background replacer
-// effects.
-public class EffectSettingPopup extends AbstractSettingPopup implements
- AdapterView.OnItemClickListener, View.OnClickListener {
- private static final String TAG = "EffectSettingPopup";
- private String mNoEffect;
- private IconListPreference mPreference;
- private Listener mListener;
- private View mClearEffects;
- private GridView mSillyFacesGrid;
- private GridView mBackgroundGrid;
-
- // Data for silly face items. (text, image, and preference value)
- ArrayList<HashMap<String, Object>> mSillyFacesItem =
- new ArrayList<HashMap<String, Object>>();
-
- // Data for background replacer items. (text, image, and preference value)
- ArrayList<HashMap<String, Object>> mBackgroundItem =
- new ArrayList<HashMap<String, Object>>();
-
-
- static public interface Listener {
- public void onSettingChanged();
- }
-
- public EffectSettingPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- mNoEffect = context.getString(R.string.pref_video_effect_default);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mClearEffects = findViewById(R.id.clear_effects);
- mClearEffects.setOnClickListener(this);
- mSillyFacesGrid = (GridView) findViewById(R.id.effect_silly_faces);
- mBackgroundGrid = (GridView) findViewById(R.id.effect_background);
- }
-
- public void initialize(IconListPreference preference) {
- mPreference = preference;
- Context context = getContext();
- CharSequence[] entries = mPreference.getEntries();
- CharSequence[] entryValues = mPreference.getEntryValues();
- int[] iconIds = mPreference.getImageIds();
- if (iconIds == null) {
- iconIds = mPreference.getLargeIconIds();
- }
-
- // Set title.
- mTitle.setText(mPreference.getTitle());
-
- for(int i = 0; i < entries.length; ++i) {
- String value = entryValues[i].toString();
- if (value.equals(mNoEffect)) continue; // no effect, skip it.
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("value", value);
- map.put("text", entries[i].toString());
- if (iconIds != null) map.put("image", iconIds[i]);
- if (value.startsWith("goofy_face")) {
- mSillyFacesItem.add(map);
- } else if (value.startsWith("backdropper")) {
- mBackgroundItem.add(map);
- }
- }
-
- boolean hasSillyFaces = mSillyFacesItem.size() > 0;
- boolean hasBackground = mBackgroundItem.size() > 0;
-
- // Initialize goofy face if it is supported.
- if (hasSillyFaces) {
- findViewById(R.id.effect_silly_faces_title).setVisibility(View.VISIBLE);
- findViewById(R.id.effect_silly_faces_title_separator).setVisibility(View.VISIBLE);
- mSillyFacesGrid.setVisibility(View.VISIBLE);
- SimpleAdapter sillyFacesItemAdapter = new SimpleAdapter(context,
- mSillyFacesItem, R.layout.effect_setting_item,
- new String[] {"text", "image"},
- new int[] {R.id.text, R.id.image});
- mSillyFacesGrid.setAdapter(sillyFacesItemAdapter);
- mSillyFacesGrid.setOnItemClickListener(this);
- }
-
- if (hasSillyFaces && hasBackground) {
- findViewById(R.id.effect_background_separator).setVisibility(View.VISIBLE);
- }
-
- // Initialize background replacer if it is supported.
- if (hasBackground) {
- findViewById(R.id.effect_background_title).setVisibility(View.VISIBLE);
- findViewById(R.id.effect_background_title_separator).setVisibility(View.VISIBLE);
- mBackgroundGrid.setVisibility(View.VISIBLE);
- SimpleAdapter backgroundItemAdapter = new SimpleAdapter(context,
- mBackgroundItem, R.layout.effect_setting_item,
- new String[] {"text", "image"},
- new int[] {R.id.text, R.id.image});
- mBackgroundGrid.setAdapter(backgroundItemAdapter);
- mBackgroundGrid.setOnItemClickListener(this);
- }
-
- reloadPreference();
- }
-
- @Override
- public void setVisibility(int visibility) {
- if (visibility == View.VISIBLE) {
- if (getVisibility() != View.VISIBLE) {
- // Do not show or hide "Clear effects" button when the popup
- // is already visible. Otherwise it looks strange.
- boolean noEffect = mPreference.getValue().equals(mNoEffect);
- mClearEffects.setVisibility(noEffect ? View.GONE : View.VISIBLE);
- }
- reloadPreference();
- }
- super.setVisibility(visibility);
- }
-
- // The value of the preference may have changed. Update the UI.
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- @Override
- public void reloadPreference() {
- mBackgroundGrid.setItemChecked(mBackgroundGrid.getCheckedItemPosition(), false);
- mSillyFacesGrid.setItemChecked(mSillyFacesGrid.getCheckedItemPosition(), false);
-
- String value = mPreference.getValue();
- if (value.equals(mNoEffect)) return;
-
- for (int i = 0; i < mSillyFacesItem.size(); i++) {
- if (value.equals(mSillyFacesItem.get(i).get("value"))) {
- mSillyFacesGrid.setItemChecked(i, true);
- return;
- }
- }
-
- for (int i = 0; i < mBackgroundItem.size(); i++) {
- if (value.equals(mBackgroundItem.get(i).get("value"))) {
- mBackgroundGrid.setItemChecked(i, true);
- return;
- }
- }
-
- Log.e(TAG, "Invalid preference value: " + value);
- mPreference.print();
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int index, long id) {
- String value;
- if (parent == mSillyFacesGrid) {
- value = (String) mSillyFacesItem.get(index).get("value");
- } else if (parent == mBackgroundGrid) {
- value = (String) mBackgroundItem.get(index).get("value");
- } else {
- return;
- }
-
- // Tapping the selected effect will deselect it (clear effects).
- if (value.equals(mPreference.getValue())) {
- mPreference.setValue(mNoEffect);
- } else {
- mPreference.setValue(value);
- }
- reloadPreference();
- if (mListener != null) mListener.onSettingChanged();
- }
-
- @Override
- public void onClick(View v) {
- // Clear the effect.
- mPreference.setValue(mNoEffect);
- reloadPreference();
- if (mListener != null) mListener.onSettingChanged();
- }
-}
diff --git a/src/com/android/camera/ui/ExpandedGridView.java b/src/com/android/camera/ui/ExpandedGridView.java
deleted file mode 100644
index 13cf58f34..000000000
--- a/src/com/android/camera/ui/ExpandedGridView.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.GridView;
-
-public class ExpandedGridView extends GridView {
- public ExpandedGridView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // If UNSPECIFIED is passed to GridView, it will show only one row.
- // Here GridView is put in a ScrollView, so pass it a very big size with
- // AT_MOST to show all the rows.
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(65536, MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- }
-}
diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java
deleted file mode 100644
index 7d66dc079..000000000
--- a/src/com/android/camera/ui/FaceView.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Paint.Style;
-import android.graphics.RectF;
-import android.hardware.Camera.Face;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-
-import com.android.camera.PhotoUI;
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-@TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
-public class FaceView extends View
- implements FocusIndicator, Rotatable,
- PhotoUI.SurfaceTextureSizeChangedListener {
- private static final String TAG = "CAM FaceView";
- private final boolean LOGV = false;
- // The value for android.hardware.Camera.setDisplayOrientation.
- private int mDisplayOrientation;
- // The orientation compensation for the face indicator to make it look
- // correctly in all device orientations. Ex: if the value is 90, the
- // indicator should be rotated 90 degrees counter-clockwise.
- private int mOrientation;
- private boolean mMirror;
- private boolean mPause;
- private Matrix mMatrix = new Matrix();
- private RectF mRect = new RectF();
- // As face detection can be flaky, we add a layer of filtering on top of it
- // to avoid rapid changes in state (eg, flickering between has faces and
- // not having faces)
- private Face[] mFaces;
- private Face[] mPendingFaces;
- private int mColor;
- private final int mFocusingColor;
- private final int mFocusedColor;
- private final int mFailColor;
- private Paint mPaint;
- private volatile boolean mBlocked;
-
- private int mUncroppedWidth;
- private int mUncroppedHeight;
- private static final int MSG_SWITCH_FACES = 1;
- private static final int SWITCH_DELAY = 70;
- private boolean mStateSwitchPending = false;
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_SWITCH_FACES:
- mStateSwitchPending = false;
- mFaces = mPendingFaces;
- invalidate();
- break;
- }
- }
- };
-
- public FaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
- Resources res = getResources();
- mFocusingColor = res.getColor(R.color.face_detect_start);
- mFocusedColor = res.getColor(R.color.face_detect_success);
- mFailColor = res.getColor(R.color.face_detect_fail);
- mColor = mFocusingColor;
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- mPaint.setStyle(Style.STROKE);
- mPaint.setStrokeWidth(res.getDimension(R.dimen.face_circle_stroke));
- }
-
- @Override
- public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight) {
- mUncroppedWidth = uncroppedWidth;
- mUncroppedHeight = uncroppedHeight;
- }
-
- public void setFaces(Face[] faces) {
- if (LOGV) Log.v(TAG, "Num of faces=" + faces.length);
- if (mPause) return;
- if (mFaces != null) {
- if ((faces.length > 0 && mFaces.length == 0)
- || (faces.length == 0 && mFaces.length > 0)) {
- mPendingFaces = faces;
- if (!mStateSwitchPending) {
- mStateSwitchPending = true;
- mHandler.sendEmptyMessageDelayed(MSG_SWITCH_FACES, SWITCH_DELAY);
- }
- return;
- }
- }
- if (mStateSwitchPending) {
- mStateSwitchPending = false;
- mHandler.removeMessages(MSG_SWITCH_FACES);
- }
- mFaces = faces;
- invalidate();
- }
-
- public void setDisplayOrientation(int orientation) {
- mDisplayOrientation = orientation;
- if (LOGV) Log.v(TAG, "mDisplayOrientation=" + orientation);
- }
-
- @Override
- public void setOrientation(int orientation, boolean animation) {
- mOrientation = orientation;
- invalidate();
- }
-
- public void setMirror(boolean mirror) {
- mMirror = mirror;
- if (LOGV) Log.v(TAG, "mMirror=" + mirror);
- }
-
- public boolean faceExists() {
- return (mFaces != null && mFaces.length > 0);
- }
-
- @Override
- public void showStart() {
- mColor = mFocusingColor;
- invalidate();
- }
-
- // Ignore the parameter. No autofocus animation for face detection.
- @Override
- public void showSuccess(boolean timeout) {
- mColor = mFocusedColor;
- invalidate();
- }
-
- // Ignore the parameter. No autofocus animation for face detection.
- @Override
- public void showFail(boolean timeout) {
- mColor = mFailColor;
- invalidate();
- }
-
- @Override
- public void clear() {
- // Face indicator is displayed during preview. Do not clear the
- // drawable.
- mColor = mFocusingColor;
- mFaces = null;
- invalidate();
- }
-
- public void pause() {
- mPause = true;
- }
-
- public void resume() {
- mPause = false;
- }
-
- public void setBlockDraw(boolean block) {
- mBlocked = block;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (!mBlocked && (mFaces != null) && (mFaces.length > 0)) {
- int rw, rh;
- rw = mUncroppedWidth;
- rh = mUncroppedHeight;
- // Prepare the matrix.
- if (((rh > rw) && ((mDisplayOrientation == 0) || (mDisplayOrientation == 180)))
- || ((rw > rh) && ((mDisplayOrientation == 90) || (mDisplayOrientation == 270)))) {
- int temp = rw;
- rw = rh;
- rh = temp;
- }
- Util.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, rw, rh);
- int dx = (getWidth() - rw) / 2;
- int dy = (getHeight() - rh) / 2;
-
- // Focus indicator is directional. Rotate the matrix and the canvas
- // so it looks correctly in all orientations.
- canvas.save();
- mMatrix.postRotate(mOrientation); // postRotate is clockwise
- canvas.rotate(-mOrientation); // rotate is counter-clockwise (for canvas)
- for (int i = 0; i < mFaces.length; i++) {
- // Filter out false positives.
- if (mFaces[i].score < 50) continue;
-
- // Transform the coordinates.
- mRect.set(mFaces[i].rect);
- if (LOGV) Util.dumpRect(mRect, "Original rect");
- mMatrix.mapRect(mRect);
- if (LOGV) Util.dumpRect(mRect, "Transformed rect");
- mPaint.setColor(mColor);
- mRect.offset(dx, dy);
- canvas.drawOval(mRect, mPaint);
- }
- canvas.restore();
- }
- super.onDraw(canvas);
- }
-}
diff --git a/src/com/android/camera/ui/FilmStripGestureRecognizer.java b/src/com/android/camera/ui/FilmStripGestureRecognizer.java
deleted file mode 100644
index f870b5829..000000000
--- a/src/com/android/camera/ui/FilmStripGestureRecognizer.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.content.Context;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-
-// This class aggregates three gesture detectors: GestureDetector,
-// ScaleGestureDetector.
-public class FilmStripGestureRecognizer {
- @SuppressWarnings("unused")
- private static final String TAG = "FilmStripGestureRecognizer";
-
- public interface Listener {
- boolean onSingleTapUp(float x, float y);
- boolean onDoubleTap(float x, float y);
- boolean onScroll(float x, float y, float dx, float dy);
- boolean onFling(float velocityX, float velocityY);
- boolean onScaleBegin(float focusX, float focusY);
- boolean onScale(float focusX, float focusY, float scale);
- boolean onDown(float x, float y);
- boolean onUp(float x, float y);
- void onScaleEnd();
- }
-
- private final GestureDetector mGestureDetector;
- private final ScaleGestureDetector mScaleDetector;
- private final Listener mListener;
-
- public FilmStripGestureRecognizer(Context context, Listener listener) {
- mListener = listener;
- mGestureDetector = new GestureDetector(context, new MyGestureListener(),
- null, true /* ignoreMultitouch */);
- mScaleDetector = new ScaleGestureDetector(
- context, new MyScaleListener());
- }
-
- public void onTouchEvent(MotionEvent event) {
- mGestureDetector.onTouchEvent(event);
- mScaleDetector.onTouchEvent(event);
- if (event.getAction() == MotionEvent.ACTION_UP) {
- mListener.onUp(event.getX(), event.getY());
- }
- }
-
- private class MyGestureListener
- extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- return mListener.onSingleTapUp(e.getX(), e.getY());
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- return mListener.onDoubleTap(e.getX(), e.getY());
- }
-
- @Override
- public boolean onScroll(
- MotionEvent e1, MotionEvent e2, float dx, float dy) {
- return mListener.onScroll(e2.getX(), e2.getY(), dx, dy);
- }
-
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- return mListener.onFling(velocityX, velocityY);
- }
-
- @Override
- public boolean onDown(MotionEvent e) {
- mListener.onDown(e.getX(), e.getY());
- return super.onDown(e);
- }
- }
-
- private class MyScaleListener
- extends ScaleGestureDetector.SimpleOnScaleGestureListener {
- @Override
- public boolean onScaleBegin(ScaleGestureDetector detector) {
- return mListener.onScaleBegin(
- detector.getFocusX(), detector.getFocusY());
- }
-
- @Override
- public boolean onScale(ScaleGestureDetector detector) {
- return mListener.onScale(detector.getFocusX(),
- detector.getFocusY(), detector.getScaleFactor());
- }
-
- @Override
- public void onScaleEnd(ScaleGestureDetector detector) {
- mListener.onScaleEnd();
- }
- }
-}
diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java
deleted file mode 100644
index 8bc46b0d4..000000000
--- a/src/com/android/camera/ui/FilmStripView.java
+++ /dev/null
@@ -1,1724 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.animation.Animator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.ImageButton;
-import android.widget.Scroller;
-
-import com.android.camera.ui.FilmStripView.ImageData.PanoramaSupportCallback;
-import com.android.gallery3d.R;
-import com.android.gallery3d.util.PanoramaViewHelper;
-
-public class FilmStripView extends ViewGroup {
- @SuppressWarnings("unused")
- private static final String TAG = "CAM_FilmStripView";
-
- private static final int BUFFER_SIZE = 5;
- private static final int DURATION_GEOMETRY_ADJUST = 200;
- private static final float FILM_STRIP_SCALE = 0.6f;
- private static final float FULLSCREEN_SCALE = 1f;
- // Only check for intercepting touch events within first 500ms
- private static final int SWIPE_TIME_OUT = 500;
-
- private Context mContext;
- private FilmStripGestureRecognizer mGestureRecognizer;
- private DataAdapter mDataAdapter;
- private int mViewGap;
- private final Rect mDrawArea = new Rect();
-
- private final int mCurrentInfo = (BUFFER_SIZE - 1) / 2;
- private float mScale;
- private MyController mController;
- private int mCenterX = -1;
- private ViewInfo[] mViewInfo = new ViewInfo[BUFFER_SIZE];
-
- private Listener mListener;
-
- private MotionEvent mDown;
- private boolean mCheckToIntercept = true;
- private View mCameraView;
- private int mSlop;
- private TimeInterpolator mViewAnimInterpolator;
-
- private ImageButton mViewPhotoSphereButton;
- private PanoramaViewHelper mPanoramaViewHelper;
- private long mLastItemId = -1;
-
- // This is used to resolve the misalignment problem when the device
- // orientation is changed. If the current item is in fullscreen, it might
- // be shifted because mCenterX is not adjusted with the orientation.
- // Set this to true when onSizeChanged is called to make sure we adjust
- // mCenterX accordingly.
- private boolean mAnchorPending;
-
- /**
- * Common interface for all images in the filmstrip.
- */
- public interface ImageData {
- /**
- * Interface that is used to tell the caller whether an image is a photo
- * sphere.
- */
- public static interface PanoramaSupportCallback {
- /**
- * Called then photo sphere info has been loaded.
- *
- * @param isPanorama whether the image is a valid photo sphere
- * @param isPanorama360 whether the photo sphere is a full 360
- * degree horizontal panorama
- */
- void panoramaInfoAvailable(boolean isPanorama,
- boolean isPanorama360);
- }
-
- // Image data types.
- public static final int TYPE_NONE = 0;
- public static final int TYPE_CAMERA_PREVIEW = 1;
- public static final int TYPE_PHOTO = 2;
-
- // Actions allowed to be performed on the image data.
- // The actions are defined bit-wise so we can use bit operations like
- // | and &.
- public static final int ACTION_NONE = 0;
- public static final int ACTION_PROMOTE = 1;
- public static final int ACTION_DEMOTE = (1 << 1);
-
- /**
- * SIZE_FULL can be returned by {@link ImageData#getWidth()} and
- * {@link ImageData#getHeight()}.
- * When SIZE_FULL is returned for width/height, it means the the
- * width or height will be disregarded when deciding the view size
- * of this ImageData, just use full screen size.
- */
- public static final int SIZE_FULL = -2;
-
- /**
- * Returns the width of the image. The final layout of the view returned
- * by {@link DataAdapter#getView(android.content.Context, int)} will
- * preserve the aspect ratio of
- * {@link com.android.camera.ui.FilmStripView.ImageData#getWidth()} and
- * {@link com.android.camera.ui.FilmStripView.ImageData#getHeight()}.
- */
- public int getWidth();
-
-
- /**
- * Returns the width of the image. The final layout of the view returned
- * by {@link DataAdapter#getView(android.content.Context, int)} will
- * preserve the aspect ratio of
- * {@link com.android.camera.ui.FilmStripView.ImageData#getWidth()} and
- * {@link com.android.camera.ui.FilmStripView.ImageData#getHeight()}.
- */
- public int getHeight();
-
- /** Returns the image data type */
- public int getType();
-
- /**
- * Checks if the UI action is supported.
- *
- * @param action The UI actions to check.
- * @return {@code false} if at least one of the actions is not
- * supported. {@code true} otherwise.
- */
- public boolean isUIActionSupported(int action);
-
- /**
- * Gives the data a hint when its view is going to be displayed.
- * {@code FilmStripView} should always call this function before
- * showing its corresponding view every time.
- */
- public void prepare();
-
- /**
- * Gives the data a hint when its view is going to be removed from the
- * view hierarchy. {@code FilmStripView} should always call this
- * function after its corresponding view is removed from the view
- * hierarchy.
- */
- public void recycle();
-
- /**
- * Asynchronously checks if the image is a photo sphere. Notified the
- * callback when the results are available.
- */
- public void isPhotoSphere(Context context, PanoramaSupportCallback callback);
-
- /**
- * If the item is a valid photo sphere panorama, this method will launch
- * the viewer.
- */
- public void viewPhotoSphere(PanoramaViewHelper helper);
- }
-
- /**
- * An interfaces which defines the interactions between the
- * {@link ImageData} and the {@link FilmStripView}.
- */
- public interface DataAdapter {
- /**
- * An interface which defines the update report used to return to
- * the {@link com.android.camera.ui.FilmStripView.Listener}.
- */
- public interface UpdateReporter {
- /** Checks if the data of dataID is removed. */
- public boolean isDataRemoved(int dataID);
-
- /** Checks if the data of dataID is updated. */
- public boolean isDataUpdated(int dataID);
- }
-
- /**
- * An interface which defines the listener for data events over
- * {@link ImageData}.
- */
- public interface Listener {
- // Called when the whole data loading is done. No any assumption
- // on previous data.
- public void onDataLoaded();
-
- // Only some of the data is changed. The listener should check
- // if any thing needs to be updated.
- public void onDataUpdated(UpdateReporter reporter);
-
- public void onDataInserted(int dataID, ImageData data);
-
- public void onDataRemoved(int dataID, ImageData data);
- }
-
- /** Returns the total number of image data */
- public int getTotalNumber();
-
- /**
- * Returns the view to visually present the image data.
- *
- * @param context The {@link Context} to create the view.
- * @param dataID The ID of the image data to be presented.
- * @return The view representing the image data. Null if
- * unavailable or the {@code dataID} is out of range.
- */
- public View getView(Context context, int dataID);
-
- /**
- * Returns the {@link ImageData} specified by the ID.
- *
- * @param dataID The ID of the {@link ImageData}.
- * @return The specified {@link ImageData}. Null if not available.
- */
- public ImageData getImageData(int dataID);
-
- /**
- * Suggests the data adapter the maximum possible size of the layout
- * so the {@link DataAdapter} can optimize the view returned for the
- * {@link ImageData}.
- *
- * @param w Maximum width.
- * @param h Maximum height.
- */
- public void suggestViewSizeBound(int w, int h);
-
- /**
- * Sets the listener for data events over the ImageData.
- *
- * @param listener The listener to use.
- */
- public void setListener(Listener listener);
-
- /**
- * The callback when the item enters/leaves full-screen.
- * TODO: Call this function actually.
- *
- * @param dataID The ID of the image data.
- * @param fullScreen {@code true} if the data is entering full-screen.
- * {@code false} otherwise.
- */
- public void onDataFullScreen(int dataID, boolean fullScreen);
-
- /**
- * Returns {@code true} if the view of the data can be moved by swipe
- * gesture when in full-screen.
- *
- * @param dataID The ID of the data.
- * @return {@code true} if the view can be moved,
- * {@code false} otherwise.
- */
- public boolean canSwipeInFullScreen(int dataID);
- }
-
- /**
- * An interface which defines the FilmStripView UI action listener.
- */
- public interface Listener {
- /**
- * Callback when the data is promoted.
- *
- * @param dataID The ID of the promoted data.
- */
- public void onDataPromoted(int dataID);
-
- /**
- * Callback when the data is demoted.
- *
- * @param dataID The ID of the demoted data.
- */
- public void onDataDemoted(int dataID);
-
- public void onDataFullScreenChange(int dataID, boolean full);
-
- /**
- * Callback when entering/leaving camera mode.
- *
- * @param toCamera {@code true} if entering camera mode. Otherwise,
- * {@code false}
- */
- public void onSwitchMode(boolean toCamera);
-
- /**
- * The callback when the item is centered/off-centered.
- *
- * @param dataID The ID of the image data.
- * @param current {@code true} if the data is the current one.
- * {@code false} otherwise.
- */
- public void onCurrentDataChanged(int dataID, boolean current);
- }
-
- /**
- * An interface which defines the controller of {@link FilmStripView}.
- */
- public interface Controller {
- public boolean isScalling();
-
- public void scroll(float deltaX);
-
- public void fling(float velocity);
-
- public void scrollTo(int position, int duration, boolean interruptible);
-
- public boolean stopScrolling();
-
- public boolean isScrolling();
-
- public void lockAtCurrentView();
-
- public void unlockPosition();
-
- public void gotoCameraFullScreen();
-
- public void gotoFilmStrip();
-
- public void gotoFullScreen();
- }
-
- /**
- * A helper class to tract and calculate the view coordination.
- */
- private static class ViewInfo {
- private int mDataID;
- /** The position of the left of the view in the whole filmstrip. */
- private int mLeftPosition;
- private View mView;
- private RectF mViewArea;
-
- public ViewInfo(int id, View v) {
- v.setPivotX(0f);
- v.setPivotY(0f);
- mDataID = id;
- mView = v;
- mLeftPosition = -1;
- mViewArea = new RectF();
- }
-
- public int getID() {
- return mDataID;
- }
-
- public void setID(int id) {
- mDataID = id;
- }
-
- public void setLeftPosition(int pos) {
- mLeftPosition = pos;
- }
-
- public int getLeftPosition() {
- return mLeftPosition;
- }
-
- public float getTranslationY(float scale) {
- return mView.getTranslationY() / scale;
- }
-
- public float getTranslationX(float scale) {
- return mView.getTranslationX();
- }
-
- public void setTranslationY(float transY, float scale) {
- mView.setTranslationY(transY * scale);
- }
-
- public void setTranslationX(float transX, float scale) {
- mView.setTranslationX(transX * scale);
- }
-
- public void translateXBy(float transX, float scale) {
- mView.setTranslationX(mView.getTranslationX() + transX * scale);
- }
-
- public int getCenterX() {
- return mLeftPosition + mView.getWidth() / 2;
- }
-
- public View getView() {
- return mView;
- }
-
- private void layoutAt(int left, int top) {
- mView.layout(left, top, left + mView.getMeasuredWidth(),
- top + mView.getMeasuredHeight());
- }
-
- public void layoutIn(Rect drawArea, int refCenter, float scale) {
- // drawArea is where to layout in.
- // refCenter is the absolute horizontal position of the center of
- // drawArea.
- int left = (int) (drawArea.centerX() + (mLeftPosition - refCenter) * scale);
- int top = (int) (drawArea.centerY() - (mView.getMeasuredHeight() / 2) * scale);
- layoutAt(left, top);
- mView.setScaleX(scale);
- mView.setScaleY(scale);
-
- // update mViewArea for touch detection.
- int l = mView.getLeft();
- int t = mView.getTop();
- mViewArea.set(l, t,
- l + mView.getWidth() * scale,
- t + mView.getHeight() * scale);
- }
-
- public boolean areaContains(float x, float y) {
- return mViewArea.contains(x, y);
- }
- }
-
- /** Constructor. */
- public FilmStripView(Context context) {
- super(context);
- init(context);
- }
-
- /** Constructor. */
- public FilmStripView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- /** Constructor. */
- public FilmStripView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
-
- private void init(Context context) {
- // This is for positioning camera controller at the same place in
- // different orientations.
- setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-
- setWillNotDraw(false);
- mContext = context;
- mScale = 1.0f;
- mController = new MyController(context);
- mViewAnimInterpolator = new DecelerateInterpolator();
- mGestureRecognizer =
- new FilmStripGestureRecognizer(context, new MyGestureReceiver());
- mSlop = (int) getContext().getResources().getDimension(R.dimen.pie_touch_slop);
- }
-
- /**
- * Returns the controller.
- *
- * @return The {@code Controller}.
- */
- public Controller getController() {
- return mController;
- }
-
- public void setListener(Listener l) {
- mListener = l;
- }
-
- public void setViewGap(int viewGap) {
- mViewGap = viewGap;
- }
-
- /**
- * Sets the helper that's to be used to open photo sphere panoramas.
- */
- public void setPanoramaViewHelper(PanoramaViewHelper helper) {
- mPanoramaViewHelper = helper;
- }
-
- public float getScale() {
- return mScale;
- }
-
- public boolean isAnchoredTo(int id) {
- if (mViewInfo[mCurrentInfo].getID() == id
- && mViewInfo[mCurrentInfo].getCenterX() == mCenterX) {
- return true;
- }
- return false;
- }
-
- private int getCurrentType() {
- if (mDataAdapter == null) {
- return ImageData.TYPE_NONE;
- }
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr == null) {
- return ImageData.TYPE_NONE;
- }
- return mDataAdapter.getImageData(curr.getID()).getType();
- }
-
- @Override
- public void onDraw(Canvas c) {
- if (mController.hasNewGeometry()) {
- layoutChildren();
- }
- }
-
- /** Returns [width, height] preserving image aspect ratio. */
- private int[] calculateChildDimension(
- int imageWidth, int imageHeight,
- int boundWidth, int boundHeight) {
-
- if (imageWidth == ImageData.SIZE_FULL
- || imageHeight == ImageData.SIZE_FULL) {
- imageWidth = boundWidth;
- imageHeight = boundHeight;
- }
-
- int[] ret = new int[2];
- ret[0] = boundWidth;
- ret[1] = boundHeight;
-
- if (imageWidth * ret[1] > ret[0] * imageHeight) {
- ret[1] = imageHeight * ret[0] / imageWidth;
- } else {
- ret[0] = imageWidth * ret[1] / imageHeight;
- }
-
- return ret;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- int boundWidth = MeasureSpec.getSize(widthMeasureSpec);
- int boundHeight = MeasureSpec.getSize(heightMeasureSpec);
- if (boundWidth == 0 || boundHeight == 0) {
- // Either width or height is unknown, can't measure children yet.
- return;
- }
-
- if (mDataAdapter != null) {
- mDataAdapter.suggestViewSizeBound(boundWidth / 2, boundHeight / 2);
- }
-
- for (ViewInfo info : mViewInfo) {
- if (info == null) continue;
-
- int id = info.getID();
- int[] dim = calculateChildDimension(
- mDataAdapter.getImageData(id).getWidth(),
- mDataAdapter.getImageData(id).getHeight(),
- boundWidth, boundHeight);
-
- info.getView().measure(
- MeasureSpec.makeMeasureSpec(
- dim[0], MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(
- dim[1], MeasureSpec.EXACTLY));
- }
- }
-
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- if (mViewPhotoSphereButton != null) {
- // Set the position of the "View Photo Sphere" button.
- FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mViewPhotoSphereButton
- .getLayoutParams();
- params.bottomMargin = insets.bottom;
- mViewPhotoSphereButton.setLayoutParams(params);
- }
-
- return super.fitSystemWindows(insets);
- }
-
- private int findTheNearestView(int pointX) {
-
- int nearest = 0;
- // Find the first non-null ViewInfo.
- while (nearest < BUFFER_SIZE
- && (mViewInfo[nearest] == null || mViewInfo[nearest].getLeftPosition() == -1)) {
- nearest++;
- }
- // No existing available ViewInfo
- if (nearest == BUFFER_SIZE) {
- return -1;
- }
- int min = Math.abs(pointX - mViewInfo[nearest].getCenterX());
-
- for (int infoID = nearest + 1; infoID < BUFFER_SIZE && mViewInfo[infoID] != null; infoID++) {
- // Not measured yet.
- if (mViewInfo[infoID].getLeftPosition() == -1)
- continue;
-
- int c = mViewInfo[infoID].getCenterX();
- int dist = Math.abs(pointX - c);
- if (dist < min) {
- min = dist;
- nearest = infoID;
- }
- }
- return nearest;
- }
-
- private ViewInfo buildInfoFromData(int dataID) {
- ImageData data = mDataAdapter.getImageData(dataID);
- if (data == null) {
- return null;
- }
- data.prepare();
- View v = mDataAdapter.getView(mContext, dataID);
- if (v == null) {
- return null;
- }
- ViewInfo info = new ViewInfo(dataID, v);
- v = info.getView();
- if (v != mCameraView) {
- addView(info.getView());
- } else {
- v.setVisibility(View.VISIBLE);
- }
- return info;
- }
-
- private void removeInfo(int infoID) {
- if (infoID >= mViewInfo.length || mViewInfo[infoID] == null) {
- return;
- }
-
- ImageData data = mDataAdapter.getImageData(mViewInfo[infoID].getID());
- checkForRemoval(data, mViewInfo[infoID].getView());
- mViewInfo[infoID] = null;
- }
-
- /**
- * We try to keep the one closest to the center of the screen at position
- * mCurrentInfo.
- */
- private void stepIfNeeded() {
- if (!inFilmStrip() && !inFullScreen()) {
- // The good timing to step to the next view is when everything is
- // not in transition.
- return;
- }
- int nearest = findTheNearestView(mCenterX);
- // no change made.
- if (nearest == -1 || nearest == mCurrentInfo)
- return;
-
- // Going to change the current info, notify the listener.
- if (mListener != null) {
- mListener.onCurrentDataChanged(mViewInfo[mCurrentInfo].getID(), false);
- }
- int adjust = nearest - mCurrentInfo;
- if (adjust > 0) {
- for (int k = 0; k < adjust; k++) {
- removeInfo(k);
- }
- for (int k = 0; k + adjust < BUFFER_SIZE; k++) {
- mViewInfo[k] = mViewInfo[k + adjust];
- }
- for (int k = BUFFER_SIZE - adjust; k < BUFFER_SIZE; k++) {
- mViewInfo[k] = null;
- if (mViewInfo[k - 1] != null) {
- mViewInfo[k] = buildInfoFromData(mViewInfo[k - 1].getID() + 1);
- }
- }
- } else {
- for (int k = BUFFER_SIZE - 1; k >= BUFFER_SIZE + adjust; k--) {
- removeInfo(k);
- }
- for (int k = BUFFER_SIZE - 1; k + adjust >= 0; k--) {
- mViewInfo[k] = mViewInfo[k + adjust];
- }
- for (int k = -1 - adjust; k >= 0; k--) {
- mViewInfo[k] = null;
- if (mViewInfo[k + 1] != null) {
- mViewInfo[k] = buildInfoFromData(mViewInfo[k + 1].getID() - 1);
- }
- }
- }
- if (mListener != null) {
- mListener.onCurrentDataChanged(mViewInfo[mCurrentInfo].getID(), true);
- }
- }
-
- /** Don't go beyond the bound. */
- private void clampCenterX() {
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr == null) {
- return;
- }
-
- if (curr.getID() == 0 && mCenterX < curr.getCenterX()) {
- mCenterX = curr.getCenterX();
- if (mController.isScrolling()) {
- mController.stopScrolling();
- }
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW
- && !mController.isScalling()
- && mScale != FULLSCREEN_SCALE) {
- mController.gotoFullScreen();
- }
- }
- if (curr.getID() == mDataAdapter.getTotalNumber() - 1
- && mCenterX > curr.getCenterX()) {
- mCenterX = curr.getCenterX();
- if (!mController.isScrolling()) {
- mController.stopScrolling();
- }
- }
- }
-
- private void adjustChildZOrder() {
- for (int i = BUFFER_SIZE - 1; i >= 0; i--) {
- if (mViewInfo[i] == null)
- continue;
- bringChildToFront(mViewInfo[i].getView());
- }
- }
-
- /**
- * If the current photo is a photo sphere, this will launch the Photo Sphere
- * panorama viewer.
- */
- private void showPhotoSphere() {
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr != null) {
- mDataAdapter.getImageData(curr.getID()).viewPhotoSphere(mPanoramaViewHelper);
- }
- }
-
- /**
- * @return The ID of the current item, or -1.
- */
- public int getCurrentId() {
- ViewInfo current = mViewInfo[mCurrentInfo];
- if (current == null) {
- return -1;
- }
- return current.getID();
- }
-
- /**
- * Updates the visibility of the View Photo Sphere button.
- */
- private void updatePhotoSphereViewButton() {
- if (mViewPhotoSphereButton == null) {
- mViewPhotoSphereButton = (ImageButton) ((View) getParent())
- .findViewById(R.id.filmstrip_bottom_control_panorama);
- mViewPhotoSphereButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- showPhotoSphere();
- }
- });
- }
- final int requestId = getCurrentId();
-
- // Check if the item has changed since the last time we updated the
- // visibility status. Only then check of the current image is a photo
- // sphere.
- if (requestId == mLastItemId || requestId < 0) {
- return;
- }
-
- ImageData data = mDataAdapter.getImageData(requestId);
- data.isPhotoSphere(mContext, new PanoramaSupportCallback() {
- @Override
- public void panoramaInfoAvailable(final boolean isPanorama,
- boolean isPanorama360) {
- // Make sure the returned data is for the current image.
- if (requestId == getCurrentId()) {
- mViewPhotoSphereButton.post(new Runnable() {
- @Override
- public void run() {
- mViewPhotoSphereButton.setVisibility(isPanorama ? View.VISIBLE
- : View.GONE);
- }
- });
- }
- }
- });
- }
-
- private void layoutChildren() {
- if (mAnchorPending) {
- mCenterX = mViewInfo[mCurrentInfo].getCenterX();
- mAnchorPending = false;
- }
-
- if (mController.hasNewGeometry()) {
- mCenterX = mController.getNewPosition();
- mScale = mController.getNewScale();
- }
-
- clampCenterX();
-
- mViewInfo[mCurrentInfo].layoutIn(mDrawArea, mCenterX, mScale);
-
- int currentViewLeft = mViewInfo[mCurrentInfo].getLeftPosition();
- int currentViewCenter = mViewInfo[mCurrentInfo].getCenterX();
- int fullScreenWidth = mDrawArea.width() + mViewGap;
- float scaleFraction = mViewAnimInterpolator.getInterpolation(
- (mScale - FILM_STRIP_SCALE) / (FULLSCREEN_SCALE - FILM_STRIP_SCALE));
-
- // images on the left
- for (int infoID = mCurrentInfo - 1; infoID >= 0; infoID--) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr == null) {
- continue;
- }
-
- ViewInfo next = mViewInfo[infoID + 1];
- int myLeft =
- next.getLeftPosition() - curr.getView().getMeasuredWidth() - mViewGap;
- curr.setLeftPosition(myLeft);
- curr.layoutIn(mDrawArea, mCenterX, mScale);
- curr.getView().setAlpha(1f);
- int infoDiff = mCurrentInfo - infoID;
- curr.setTranslationX(
- (currentViewCenter
- - fullScreenWidth * infoDiff - curr.getCenterX()) * scaleFraction,
- mScale);
- }
-
- // images on the right
- for (int infoID = mCurrentInfo + 1; infoID < BUFFER_SIZE; infoID++) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr == null) {
- continue;
- }
-
- ViewInfo prev = mViewInfo[infoID - 1];
- int myLeft =
- prev.getLeftPosition() + prev.getView().getMeasuredWidth() + mViewGap;
- curr.setLeftPosition(myLeft);
- curr.layoutIn(mDrawArea, mCenterX, mScale);
- if (infoID == mCurrentInfo + 1) {
- curr.getView().setAlpha(1f - scaleFraction);
- } else {
- if (scaleFraction == 0f) {
- curr.getView().setAlpha(1f);
- } else {
- curr.getView().setAlpha(0f);
- }
- }
- curr.setTranslationX((currentViewLeft - myLeft) * scaleFraction, mScale);
- }
-
- stepIfNeeded();
- adjustChildZOrder();
- invalidate();
- updatePhotoSphereViewButton();
- mLastItemId = getCurrentId();
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- if (mViewInfo[mCurrentInfo] == null) {
- return;
- }
-
- mDrawArea.left = l;
- mDrawArea.top = t;
- mDrawArea.right = r;
- mDrawArea.bottom = b;
-
- layoutChildren();
- }
-
- // Keeps the view in the view hierarchy if it's camera preview.
- // Remove from the hierarchy otherwise.
- private void checkForRemoval(ImageData data, View v) {
- if (data.getType() != ImageData.TYPE_CAMERA_PREVIEW) {
- removeView(v);
- data.recycle();
- } else {
- v.setVisibility(View.INVISIBLE);
- if (mCameraView != null && mCameraView != v) {
- removeView(mCameraView);
- }
- mCameraView = v;
- }
- }
-
- private void slideViewBack(View v) {
- v.animate().translationX(0)
- .alpha(1f)
- .setDuration(DURATION_GEOMETRY_ADJUST)
- .setInterpolator(mViewAnimInterpolator)
- .start();
- }
-
- private void updateRemoval(int dataID, final ImageData data) {
- int removedInfo = findInfoByDataID(dataID);
-
- // adjust the data id to be consistent
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null || mViewInfo[i].getID() <= dataID) {
- continue;
- }
- mViewInfo[i].setID(mViewInfo[i].getID() - 1);
- }
- if (removedInfo == -1) {
- return;
- }
-
- final View removedView = mViewInfo[removedInfo].getView();
- final int offsetX = removedView.getMeasuredWidth() + mViewGap;
-
- for (int i = removedInfo + 1; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] != null) {
- mViewInfo[i].setLeftPosition(mViewInfo[i].getLeftPosition() - offsetX);
- }
- }
-
- if (removedInfo >= mCurrentInfo
- && mViewInfo[removedInfo].getID() < mDataAdapter.getTotalNumber()) {
- // Fill the removed info by left shift when the current one or
- // anyone on the right is removed, and there's more data on the
- // right available.
- for (int i = removedInfo; i < BUFFER_SIZE - 1; i++) {
- mViewInfo[i] = mViewInfo[i + 1];
- }
-
- // pull data out from the DataAdapter for the last one.
- int curr = BUFFER_SIZE - 1;
- int prev = curr - 1;
- if (mViewInfo[prev] != null) {
- mViewInfo[curr] = buildInfoFromData(mViewInfo[prev].getID() + 1);
- }
-
- // Translate the views to their original places.
- for (int i = removedInfo; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] != null) {
- mViewInfo[i].setTranslationX(offsetX, mScale);
- }
- }
-
- // The end of the filmstrip might have been changed.
- // The mCenterX might be out of the bound.
- ViewInfo currInfo = mViewInfo[mCurrentInfo];
- if (currInfo.getID() == mDataAdapter.getTotalNumber() - 1
- && mCenterX > currInfo.getCenterX()) {
- int adjustDiff = currInfo.getCenterX() - mCenterX;
- mCenterX = currInfo.getCenterX();
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] != null) {
- mViewInfo[i].translateXBy(adjustDiff, mScale);
- }
- }
- }
- } else {
- // fill the removed place by right shift
- mCenterX -= offsetX;
-
- for (int i = removedInfo; i > 0; i--) {
- mViewInfo[i] = mViewInfo[i - 1];
- }
-
- // pull data out from the DataAdapter for the first one.
- int curr = 0;
- int next = curr + 1;
- if (mViewInfo[next] != null) {
- mViewInfo[curr] = buildInfoFromData(mViewInfo[next].getID() - 1);
- }
-
- // Translate the views to their original places.
- for (int i = removedInfo; i >= 0; i--) {
- if (mViewInfo[i] != null) {
- mViewInfo[i].setTranslationX(-offsetX, mScale);
- }
- }
- }
-
- // Now, slide every one back.
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] != null
- && mViewInfo[i].getTranslationX(mScale) != 0f) {
- slideViewBack(mViewInfo[i].getView());
- }
- }
-
- int transY = getHeight() / 8;
- if (removedView.getTranslationY() < 0) {
- transY = -transY;
- }
- removedView.animate()
- .alpha(0f)
- .translationYBy(transY)
- .setInterpolator(mViewAnimInterpolator)
- .setDuration(DURATION_GEOMETRY_ADJUST)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- checkForRemoval(data, removedView);
- }
- })
- .start();
- layoutChildren();
- }
-
- // returns -1 on failure.
- private int findInfoByDataID(int dataID) {
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] != null
- && mViewInfo[i].getID() == dataID) {
- return i;
- }
- }
- return -1;
- }
-
- private void updateInsertion(int dataID) {
- int insertedInfo = findInfoByDataID(dataID);
- if (insertedInfo == -1) {
- // Not in the current info buffers. Check if it's inserted
- // at the end.
- if (dataID == mDataAdapter.getTotalNumber() - 1) {
- int prev = findInfoByDataID(dataID - 1);
- if (prev >= 0 && prev < BUFFER_SIZE - 1) {
- // The previous data is in the buffer and we still
- // have room for the inserted data.
- insertedInfo = prev + 1;
- }
- }
- }
-
- // adjust the data id to be consistent
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null || mViewInfo[i].getID() < dataID) {
- continue;
- }
- mViewInfo[i].setID(mViewInfo[i].getID() + 1);
- }
- if (insertedInfo == -1) {
- return;
- }
-
- final ImageData data = mDataAdapter.getImageData(dataID);
- int[] dim = calculateChildDimension(
- data.getWidth(), data.getHeight(),
- getMeasuredWidth(), getMeasuredHeight());
- final int offsetX = dim[0] + mViewGap;
- ViewInfo viewInfo = buildInfoFromData(dataID);
-
- if (insertedInfo >= mCurrentInfo) {
- if (insertedInfo == mCurrentInfo) {
- viewInfo.setLeftPosition(mViewInfo[mCurrentInfo].getLeftPosition());
- }
- // Shift right to make rooms for newly inserted item.
- removeInfo(BUFFER_SIZE - 1);
- for (int i = BUFFER_SIZE - 1; i > insertedInfo; i--) {
- mViewInfo[i] = mViewInfo[i - 1];
- if (mViewInfo[i] != null) {
- mViewInfo[i].setTranslationX(-offsetX, mScale);
- slideViewBack(mViewInfo[i].getView());
- }
- }
- } else {
- // Shift left. Put the inserted data on the left instead of the
- // found position.
- --insertedInfo;
- if (insertedInfo < 0) {
- return;
- }
- removeInfo(0);
- for (int i = 1; i <= insertedInfo; i++) {
- if (mViewInfo[i] != null) {
- mViewInfo[i].setTranslationX(offsetX, mScale);
- slideViewBack(mViewInfo[i].getView());
- mViewInfo[i - 1] = mViewInfo[i];
- }
- }
- }
-
- mViewInfo[insertedInfo] = viewInfo;
- View insertedView = mViewInfo[insertedInfo].getView();
- insertedView.setAlpha(0f);
- insertedView.setTranslationY(getHeight() / 8);
- insertedView.animate()
- .alpha(1f)
- .translationY(0f)
- .setInterpolator(mViewAnimInterpolator)
- .setDuration(DURATION_GEOMETRY_ADJUST)
- .start();
- invalidate();
- }
-
- public void setDataAdapter(DataAdapter adapter) {
- mDataAdapter = adapter;
- mDataAdapter.suggestViewSizeBound(getMeasuredWidth(), getMeasuredHeight());
- mDataAdapter.setListener(new DataAdapter.Listener() {
- @Override
- public void onDataLoaded() {
- reload();
- }
-
- @Override
- public void onDataUpdated(DataAdapter.UpdateReporter reporter) {
- update(reporter);
- }
-
- @Override
- public void onDataInserted(int dataID, ImageData data) {
- if (mViewInfo[mCurrentInfo] == null) {
- // empty now, simply do a reload.
- reload();
- return;
- }
- updateInsertion(dataID);
- }
-
- @Override
- public void onDataRemoved(int dataID, ImageData data) {
- updateRemoval(dataID, data);
- }
- });
- }
-
- public boolean inFilmStrip() {
- return (mScale == FILM_STRIP_SCALE);
- }
-
- public boolean inFullScreen() {
- return (mScale == FULLSCREEN_SCALE);
- }
-
- public boolean inCameraFullscreen() {
- return isAnchoredTo(0) && inFullScreen()
- && (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (inFilmStrip()) {
- return true;
- }
-
- if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mCheckToIntercept = true;
- mDown = MotionEvent.obtain(ev);
- ViewInfo viewInfo = mViewInfo[mCurrentInfo];
- // Do not intercept touch if swipe is not enabled
- if (viewInfo != null && !mDataAdapter.canSwipeInFullScreen(viewInfo.getID())) {
- mCheckToIntercept = false;
- }
- return false;
- } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- // Do not intercept touch once child is in zoom mode
- mCheckToIntercept = false;
- return false;
- } else {
- if (!mCheckToIntercept) {
- return false;
- }
- if (ev.getEventTime() - ev.getDownTime() > SWIPE_TIME_OUT) {
- return false;
- }
- int deltaX = (int) (ev.getX() - mDown.getX());
- int deltaY = (int) (ev.getY() - mDown.getY());
- if (ev.getActionMasked() == MotionEvent.ACTION_MOVE
- && deltaX < mSlop * (-1)) {
- // intercept left swipe
- if (Math.abs(deltaX) >= Math.abs(deltaY) * 2) {
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- mGestureRecognizer.onTouchEvent(ev);
- return true;
- }
-
- private void updateViewInfo(int infoID) {
- ViewInfo info = mViewInfo[infoID];
- removeView(info.getView());
- mViewInfo[infoID] = buildInfoFromData(info.getID());
- }
-
- /** Some of the data is changed. */
- private void update(DataAdapter.UpdateReporter reporter) {
- // No data yet.
- if (mViewInfo[mCurrentInfo] == null) {
- reload();
- return;
- }
-
- // Check the current one.
- ViewInfo curr = mViewInfo[mCurrentInfo];
- int dataID = curr.getID();
- if (reporter.isDataRemoved(dataID)) {
- mCenterX = -1;
- reload();
- return;
- }
- if (reporter.isDataUpdated(dataID)) {
- updateViewInfo(mCurrentInfo);
- }
-
- // Check left
- for (int i = mCurrentInfo - 1; i >= 0; i--) {
- curr = mViewInfo[i];
- if (curr != null) {
- dataID = curr.getID();
- if (reporter.isDataRemoved(dataID) || reporter.isDataUpdated(dataID)) {
- updateViewInfo(i);
- }
- } else {
- ViewInfo next = mViewInfo[i + 1];
- if (next != null) {
- mViewInfo[i] = buildInfoFromData(next.getID() - 1);
- }
- }
- }
-
- // Check right
- for (int i = mCurrentInfo + 1; i < BUFFER_SIZE; i++) {
- curr = mViewInfo[i];
- if (curr != null) {
- dataID = curr.getID();
- if (reporter.isDataRemoved(dataID) || reporter.isDataUpdated(dataID)) {
- updateViewInfo(i);
- }
- } else {
- ViewInfo prev = mViewInfo[i - 1];
- if (prev != null) {
- mViewInfo[i] = buildInfoFromData(prev.getID() + 1);
- }
- }
- }
- }
-
- /**
- * The whole data might be totally different. Flush all and load from the
- * start.
- */
- private void reload() {
- removeAllViews();
- int dataNumber = mDataAdapter.getTotalNumber();
- if (dataNumber == 0) {
- return;
- }
-
- mViewInfo[mCurrentInfo] = buildInfoFromData(0);
- mViewInfo[mCurrentInfo].setLeftPosition(0);
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW) {
- // we are in camera mode by default.
- mController.lockAtCurrentView();
- }
- for (int i = 1; mCurrentInfo + i < BUFFER_SIZE || mCurrentInfo - i >= 0; i++) {
- int infoID = mCurrentInfo + i;
- if (infoID < BUFFER_SIZE && mViewInfo[infoID - 1] != null) {
- mViewInfo[infoID] = buildInfoFromData(mViewInfo[infoID - 1].getID() + 1);
- }
- infoID = mCurrentInfo - i;
- if (infoID >= 0 && mViewInfo[infoID + 1] != null) {
- mViewInfo[infoID] = buildInfoFromData(mViewInfo[infoID + 1].getID() - 1);
- }
- }
- layoutChildren();
- }
-
- private void promoteData(int infoID, int dataID) {
- if (mListener != null) {
- mListener.onDataPromoted(dataID);
- }
- }
-
- private void demoteData(int infoID, int dataID) {
- if (mListener != null) {
- mListener.onDataDemoted(dataID);
- }
- }
-
- /**
- * MyController controls all the geometry animations. It passively tells the
- * geometry information on demand.
- */
- private class MyController implements
- Controller,
- ValueAnimator.AnimatorUpdateListener,
- Animator.AnimatorListener {
-
- private ValueAnimator mScaleAnimator;
- private boolean mHasNewScale;
- private float mNewScale;
-
- private Scroller mScroller;
- private boolean mHasNewPosition;
- private DecelerateInterpolator mDecelerateInterpolator;
-
- private boolean mCanStopScroll;
-
- private boolean mIsPositionLocked;
- private int mLockedViewInfo;
-
- MyController(Context context) {
- mScroller = new Scroller(context);
- mHasNewPosition = false;
- mScaleAnimator = new ValueAnimator();
- mScaleAnimator.addUpdateListener(MyController.this);
- mScaleAnimator.addListener(MyController.this);
- mDecelerateInterpolator = new DecelerateInterpolator();
- mCanStopScroll = true;
- mHasNewScale = false;
- }
-
- @Override
- public boolean isScrolling() {
- return !mScroller.isFinished();
- }
-
- @Override
- public boolean isScalling() {
- return mScaleAnimator.isRunning();
- }
-
- boolean hasNewGeometry() {
- mHasNewPosition = mScroller.computeScrollOffset();
- if (!mHasNewPosition) {
- mCanStopScroll = true;
- }
- // If the position is locked, then we always return true to force
- // the position value to use the locked value.
- return (mHasNewPosition || mHasNewScale || mIsPositionLocked);
- }
-
- /**
- * Always call {@link #hasNewGeometry()} before getting the new scale
- * value.
- */
- float getNewScale() {
- if (!mHasNewScale) {
- return mScale;
- }
- mHasNewScale = false;
- return mNewScale;
- }
-
- /**
- * Always call {@link #hasNewGeometry()} before getting the new position
- * value.
- */
- int getNewPosition() {
- if (mIsPositionLocked) {
- if (mViewInfo[mLockedViewInfo] == null)
- return mCenterX;
- return mViewInfo[mLockedViewInfo].getCenterX();
- }
- if (!mHasNewPosition)
- return mCenterX;
- return mScroller.getCurrX();
- }
-
- @Override
- public void lockAtCurrentView() {
- mIsPositionLocked = true;
- mLockedViewInfo = mCurrentInfo;
- }
-
- @Override
- public void unlockPosition() {
- if (mIsPositionLocked) {
- // only when the position is previously locked we set the
- // current position to make it consistent.
- if (mViewInfo[mLockedViewInfo] != null) {
- mCenterX = mViewInfo[mLockedViewInfo].getCenterX();
- }
- mIsPositionLocked = false;
- }
- }
-
- private int estimateMinX(int dataID, int leftPos, int viewWidth) {
- return leftPos - (dataID + 100) * (viewWidth + mViewGap);
- }
-
- private int estimateMaxX(int dataID, int leftPos, int viewWidth) {
- return leftPos
- + (mDataAdapter.getTotalNumber() - dataID + 100)
- * (viewWidth + mViewGap);
- }
-
- @Override
- public void scroll(float deltaX) {
- if (mController.isScrolling()) {
- return;
- }
- mCenterX += deltaX;
- }
-
- @Override
- public void fling(float velocityX) {
- if (!stopScrolling() || mIsPositionLocked) {
- return;
- }
- ViewInfo info = mViewInfo[mCurrentInfo];
- if (info == null) {
- return;
- }
-
- float scaledVelocityX = velocityX / mScale;
- if (inCameraFullscreen() && scaledVelocityX < 0) {
- // Swipe left in camera preview.
- gotoFilmStrip();
- }
-
- int w = getWidth();
- // Estimation of possible length on the left. To ensure the
- // velocity doesn't become too slow eventually, we add a huge number
- // to the estimated maximum.
- int minX = estimateMinX(info.getID(), info.getLeftPosition(), w);
- // Estimation of possible length on the right. Likewise, exaggerate
- // the possible maximum too.
- int maxX = estimateMaxX(info.getID(), info.getLeftPosition(), w);
- mScroller.fling(mCenterX, 0, (int) -velocityX, 0, minX, maxX, 0, 0);
-
- layoutChildren();
- }
-
- @Override
- public boolean stopScrolling() {
- if (!mCanStopScroll)
- return false;
- mScroller.forceFinished(true);
- mHasNewPosition = false;
- return true;
- }
-
- private void stopScale() {
- mScaleAnimator.cancel();
- mHasNewScale = false;
- }
-
- @Override
- public void scrollTo(int position, int duration, boolean interruptible) {
- if (!stopScrolling() || mIsPositionLocked)
- return;
- mCanStopScroll = interruptible;
- stopScrolling();
- mScroller.startScroll(mCenterX, 0, position - mCenterX,
- 0, duration);
- invalidate();
- }
-
- private void scaleTo(float scale, int duration) {
- stopScale();
- mScaleAnimator.setDuration(duration);
- mScaleAnimator.setFloatValues(mScale, scale);
- mScaleAnimator.setInterpolator(mDecelerateInterpolator);
- mScaleAnimator.start();
- mHasNewScale = true;
- layoutChildren();
- }
-
- @Override
- public void gotoFilmStrip() {
- unlockPosition();
- scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST);
- if (mListener != null) {
- mListener.onSwitchMode(false);
- }
- }
-
- @Override
- public void gotoFullScreen() {
- if (mViewInfo[mCurrentInfo] != null) {
- mController.scrollTo(mViewInfo[mCurrentInfo].getCenterX(),
- DURATION_GEOMETRY_ADJUST, false);
- }
- enterFullScreen();
- }
-
- private void enterFullScreen() {
- if (mListener != null) {
- // TODO: After full size images snapping to fill the screen at
- // the end of a scroll/fling is implemented, we should only make
- // this call when the view on the center of the screen is
- // camera preview
- mListener.onSwitchMode(true);
- }
- if (inFullScreen()) {
- return;
- }
- scaleTo(1f, DURATION_GEOMETRY_ADJUST);
- }
-
- @Override
- public void gotoCameraFullScreen() {
- if (mDataAdapter.getImageData(0).getType()
- != ImageData.TYPE_CAMERA_PREVIEW) {
- return;
- }
- gotoFullScreen();
- scrollTo(
- estimateMinX(mViewInfo[mCurrentInfo].getID(),
- mViewInfo[mCurrentInfo].getLeftPosition(),
- getWidth()),
- DURATION_GEOMETRY_ADJUST, false);
- }
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mHasNewScale = true;
- mNewScale = (Float) animation.getAnimatedValue();
- layoutChildren();
- }
-
- @Override
- public void onAnimationStart(Animator anim) {
- }
-
- @Override
- public void onAnimationEnd(Animator anim) {
- ViewInfo info = mViewInfo[mCurrentInfo];
- if (info != null && mCenterX == info.getCenterX()) {
- if (inFullScreen()) {
- lockAtCurrentView();
- } else if (inFilmStrip()) {
- unlockPosition();
- }
- }
- }
-
- @Override
- public void onAnimationCancel(Animator anim) {
- }
-
- @Override
- public void onAnimationRepeat(Animator anim) {
- }
- }
-
- private class MyGestureReceiver implements FilmStripGestureRecognizer.Listener {
- // Indicating the current trend of scaling is up (>1) or down (<1).
- private float mScaleTrend;
-
- @Override
- public boolean onSingleTapUp(float x, float y) {
- if (inFilmStrip()) {
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null) {
- continue;
- }
-
- if (mViewInfo[i].areaContains(x, y)) {
- mController.scrollTo(mViewInfo[i].getCenterX(),
- DURATION_GEOMETRY_ADJUST, false);
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public boolean onDoubleTap(float x, float y) {
- if (inFilmStrip()) {
- ViewInfo centerInfo = mViewInfo[mCurrentInfo];
- if (centerInfo != null && centerInfo.areaContains(x, y)) {
- mController.gotoFullScreen();
- return true;
- }
- } else if (inFullScreen()) {
- mController.gotoFilmStrip();
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onDown(float x, float y) {
- if (mController.isScrolling()) {
- mController.stopScrolling();
- }
- return true;
- }
-
- @Override
- public boolean onUp(float x, float y) {
- float halfH = getHeight() / 2;
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null) {
- continue;
- }
- float transY = mViewInfo[i].getTranslationY(mScale);
- if (transY == 0) {
- continue;
- }
- int id = mViewInfo[i].getID();
-
- if (mDataAdapter.getImageData(id)
- .isUIActionSupported(ImageData.ACTION_DEMOTE)
- && transY > halfH) {
- demoteData(i, id);
- } else if (mDataAdapter.getImageData(id)
- .isUIActionSupported(ImageData.ACTION_PROMOTE)
- && transY < -halfH) {
- promoteData(i, id);
- } else {
- // put the view back.
- mViewInfo[i].getView().animate()
- .translationY(0f)
- .alpha(1f)
- .setDuration(DURATION_GEOMETRY_ADJUST)
- .start();
- }
- }
- return false;
- }
-
- @Override
- public boolean onScroll(float x, float y, float dx, float dy) {
- int deltaX = (int) (dx / mScale);
- if (inFilmStrip()) {
- if (Math.abs(dx) > Math.abs(dy)) {
- if (deltaX > 0 && inCameraFullscreen()) {
- mController.gotoFilmStrip();
- }
- mController.scroll(deltaX);
- } else {
- // Vertical part. Promote or demote.
- // int scaledDeltaY = (int) (dy * mScale);
- int hit = 0;
- Rect hitRect = new Rect();
- for (; hit < BUFFER_SIZE; hit++) {
- if (mViewInfo[hit] == null) {
- continue;
- }
- mViewInfo[hit].getView().getHitRect(hitRect);
- if (hitRect.contains((int) x, (int) y)) {
- break;
- }
- }
- if (hit == BUFFER_SIZE) {
- return false;
- }
-
- ImageData data = mDataAdapter.getImageData(mViewInfo[hit].getID());
- float transY = mViewInfo[hit].getTranslationY(mScale) - dy / mScale;
- if (!data.isUIActionSupported(ImageData.ACTION_DEMOTE) && transY > 0f) {
- transY = 0f;
- }
- if (!data.isUIActionSupported(ImageData.ACTION_PROMOTE) && transY < 0f) {
- transY = 0f;
- }
- mViewInfo[hit].setTranslationY(transY, mScale);
- }
- } else if (inFullScreen()) {
- if (deltaX > 0 && inCameraFullscreen()) {
- mController.gotoFilmStrip();
- }
- mController.scroll(deltaX);
- }
- layoutChildren();
-
- return true;
- }
-
- @Override
- public boolean onFling(float velocityX, float velocityY) {
- if (Math.abs(velocityX) > Math.abs(velocityY)) {
- mController.fling(velocityX);
- } else {
- // ignore vertical fling.
- }
- return true;
- }
-
- @Override
- public boolean onScaleBegin(float focusX, float focusY) {
- if (inCameraFullscreen()) {
- return false;
- }
- mScaleTrend = 1f;
- return true;
- }
-
- @Override
- public boolean onScale(float focusX, float focusY, float scale) {
- if (inCameraFullscreen()) {
- return false;
- }
-
- mScaleTrend = mScaleTrend * 0.3f + scale * 0.7f;
- mScale *= scale;
- if (mScale <= FILM_STRIP_SCALE) {
- mScale = FILM_STRIP_SCALE;
- }
- if (mScale >= FULLSCREEN_SCALE) {
- mScale = FULLSCREEN_SCALE;
- }
- layoutChildren();
- return true;
- }
-
- @Override
- public void onScaleEnd() {
- if (mScaleTrend >= 1f) {
- mController.gotoFullScreen();
- } else {
- mController.gotoFilmStrip();
- }
- mScaleTrend = 1f;
- }
- }
-}
diff --git a/src/com/android/camera/ui/FocusIndicator.java b/src/com/android/camera/ui/FocusIndicator.java
deleted file mode 100644
index e06057041..000000000
--- a/src/com/android/camera/ui/FocusIndicator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-public interface FocusIndicator {
- public void showStart();
- public void showSuccess(boolean timeout);
- public void showFail(boolean timeout);
- public void clear();
-}
diff --git a/src/com/android/camera/ui/InLineSettingCheckBox.java b/src/com/android/camera/ui/InLineSettingCheckBox.java
deleted file mode 100644
index c1aa5a91c..000000000
--- a/src/com/android/camera/ui/InLineSettingCheckBox.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-
-
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-/* A check box setting control which turns on/off the setting. */
-public class InLineSettingCheckBox extends InLineSettingItem {
- private CheckBox mCheckBox;
-
- OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean desiredState) {
- changeIndex(desiredState ? 1 : 0);
- }
- };
-
- public InLineSettingCheckBox(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mCheckBox = (CheckBox) findViewById(R.id.setting_check_box);
- mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
- }
-
- @Override
- public void initialize(ListPreference preference) {
- super.initialize(preference);
- // Add content descriptions for the increment and decrement buttons.
- mCheckBox.setContentDescription(getContext().getResources().getString(
- R.string.accessibility_check_box, mPreference.getTitle()));
- }
-
- @Override
- protected void updateView() {
- mCheckBox.setOnCheckedChangeListener(null);
- if (mOverrideValue == null) {
- mCheckBox.setChecked(mIndex == 1);
- } else {
- int index = mPreference.findIndexOfValue(mOverrideValue);
- mCheckBox.setChecked(index == 1);
- }
- mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- event.getText().add(mPreference.getTitle());
- return true;
- }
-
- @Override
- public void setEnabled(boolean enable) {
- if (mTitle != null) mTitle.setEnabled(enable);
- if (mCheckBox != null) mCheckBox.setEnabled(enable);
- }
-}
diff --git a/src/com/android/camera/ui/InLineSettingItem.java b/src/com/android/camera/ui/InLineSettingItem.java
deleted file mode 100644
index 839a77fd0..000000000
--- a/src/com/android/camera/ui/InLineSettingItem.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-/**
- * A one-line camera setting could be one of three types: knob, switch or restore
- * preference button. The setting includes a title for showing the preference
- * title which is initialized in the SimpleAdapter. A knob also includes
- * (ex: Picture size), a previous button, the current value (ex: 5MP),
- * and a next button. A switch, i.e. the preference RecordLocationPreference,
- * has only two values on and off which will be controlled in a switch button.
- * Other setting popup window includes several InLineSettingItem items with
- * different types if possible.
- */
-public abstract class InLineSettingItem extends LinearLayout {
- private Listener mListener;
- protected ListPreference mPreference;
- protected int mIndex;
- // Scene mode can override the original preference value.
- protected String mOverrideValue;
- protected TextView mTitle;
-
- static public interface Listener {
- public void onSettingChanged(ListPreference pref);
- }
-
- public InLineSettingItem(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- protected void setTitle(ListPreference preference) {
- mTitle = ((TextView) findViewById(R.id.title));
- mTitle.setText(preference.getTitle());
- }
-
- public void initialize(ListPreference preference) {
- setTitle(preference);
- if (preference == null) return;
- mPreference = preference;
- reloadPreference();
- }
-
- protected abstract void updateView();
-
- protected boolean changeIndex(int index) {
- if (index >= mPreference.getEntryValues().length || index < 0) return false;
- mIndex = index;
- mPreference.setValueIndex(mIndex);
- if (mListener != null) {
- mListener.onSettingChanged(mPreference);
- }
- updateView();
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- return true;
- }
-
- // The value of the preference may have changed. Update the UI.
- public void reloadPreference() {
- mIndex = mPreference.findIndexOfValue(mPreference.getValue());
- updateView();
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public void overrideSettings(String value) {
- mOverrideValue = value;
- updateView();
- }
-}
diff --git a/src/com/android/camera/ui/InLineSettingMenu.java b/src/com/android/camera/ui/InLineSettingMenu.java
deleted file mode 100644
index 8e45c3e38..000000000
--- a/src/com/android/camera/ui/InLineSettingMenu.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.TextView;
-
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-/* Setting menu item that will bring up a menu when you click on it. */
-public class InLineSettingMenu extends InLineSettingItem {
- private static final String TAG = "InLineSettingMenu";
- // The view that shows the current selected setting. Ex: 5MP
- private TextView mEntry;
-
- public InLineSettingMenu(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mEntry = (TextView) findViewById(R.id.current_setting);
- }
-
- @Override
- public void initialize(ListPreference preference) {
- super.initialize(preference);
- //TODO: add contentDescription
- }
-
- @Override
- protected void updateView() {
- if (mOverrideValue == null) {
- mEntry.setText(mPreference.getEntry());
- } else {
- int index = mPreference.findIndexOfValue(mOverrideValue);
- if (index != -1) {
- mEntry.setText(mPreference.getEntries()[index]);
- } else {
- // Avoid the crash if camera driver has bugs.
- Log.e(TAG, "Fail to find override value=" + mOverrideValue);
- mPreference.print();
- }
- }
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- event.getText().add(mPreference.getTitle() + mPreference.getEntry());
- return true;
- }
-
- @Override
- public void setEnabled(boolean enable) {
- super.setEnabled(enable);
- if (mTitle != null) mTitle.setEnabled(enable);
- if (mEntry != null) mEntry.setEnabled(enable);
- }
-}
diff --git a/src/com/android/camera/ui/LayoutChangeHelper.java b/src/com/android/camera/ui/LayoutChangeHelper.java
deleted file mode 100644
index ef4eb6a7a..000000000
--- a/src/com/android/camera/ui/LayoutChangeHelper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.view.View;
-
-public class LayoutChangeHelper implements LayoutChangeNotifier {
- private LayoutChangeNotifier.Listener mListener;
- private boolean mFirstTimeLayout;
- private View mView;
-
- public LayoutChangeHelper(View v) {
- mView = v;
- mFirstTimeLayout = true;
- }
-
- @Override
- public void setOnLayoutChangeListener(LayoutChangeNotifier.Listener listener) {
- mListener = listener;
- }
-
- public void onLayout(boolean changed, int l, int t, int r, int b) {
- if (mListener == null) return;
- if (mFirstTimeLayout || changed) {
- mFirstTimeLayout = false;
- mListener.onLayoutChange(mView, l, t, r, b);
- }
- }
-}
diff --git a/src/com/android/camera/ui/LayoutChangeNotifier.java b/src/com/android/camera/ui/LayoutChangeNotifier.java
deleted file mode 100644
index 6261d34f6..000000000
--- a/src/com/android/camera/ui/LayoutChangeNotifier.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.view.View;
-
-public interface LayoutChangeNotifier {
- public interface Listener {
- // Invoked only when the layout has changed or it is the first layout.
- public void onLayoutChange(View v, int l, int t, int r, int b);
- }
-
- public void setOnLayoutChangeListener(LayoutChangeNotifier.Listener listener);
-}
diff --git a/src/com/android/camera/ui/LayoutNotifyView.java b/src/com/android/camera/ui/LayoutNotifyView.java
deleted file mode 100644
index 6e118fc3a..000000000
--- a/src/com/android/camera/ui/LayoutNotifyView.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-/*
- * Customized view to support onLayoutChange() at or before API 10.
- */
-public class LayoutNotifyView extends View implements LayoutChangeNotifier {
- private LayoutChangeHelper mLayoutChangeHelper = new LayoutChangeHelper(this);
-
- public LayoutNotifyView(Context context) {
- super(context);
- }
-
- public LayoutNotifyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void setOnLayoutChangeListener(
- LayoutChangeNotifier.Listener listener) {
- mLayoutChangeHelper.setOnLayoutChangeListener(listener);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- mLayoutChangeHelper.onLayout(changed, l, t, r, b);
- }
-}
diff --git a/src/com/android/camera/ui/ListPrefSettingPopup.java b/src/com/android/camera/ui/ListPrefSettingPopup.java
deleted file mode 100644
index cfef73f49..000000000
--- a/src/com/android/camera/ui/ListPrefSettingPopup.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ListView;
-import android.widget.AdapterView;
-import android.widget.ImageView;
-import android.widget.SimpleAdapter;
-
-import com.android.camera.IconListPreference;
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-// A popup window that shows one camera setting. The title is the name of the
-// setting (ex: white-balance). The entries are the supported values (ex:
-// daylight, incandescent, etc). If initialized with an IconListPreference,
-// the entries will contain both text and icons. Otherwise, entries will be
-// shown in text.
-public class ListPrefSettingPopup extends AbstractSettingPopup implements
- AdapterView.OnItemClickListener {
- private static final String TAG = "ListPrefSettingPopup";
- private ListPreference mPreference;
- private Listener mListener;
-
- static public interface Listener {
- public void onListPrefChanged(ListPreference pref);
- }
-
- public ListPrefSettingPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- private class ListPrefSettingAdapter extends SimpleAdapter {
- ListPrefSettingAdapter(Context context, List<? extends Map<String, ?>> data,
- int resource, String[] from, int[] to) {
- super(context, data, resource, from, to);
- }
-
- @Override
- public void setViewImage(ImageView v, String value) {
- if ("".equals(value)) {
- // Some settings have no icons. Ex: exposure compensation.
- v.setVisibility(View.GONE);
- } else {
- super.setViewImage(v, value);
- }
- }
- }
-
- public void initialize(ListPreference preference) {
- mPreference = preference;
- Context context = getContext();
- CharSequence[] entries = mPreference.getEntries();
- int[] iconIds = null;
- if (preference instanceof IconListPreference) {
- iconIds = ((IconListPreference) mPreference).getImageIds();
- if (iconIds == null) {
- iconIds = ((IconListPreference) mPreference).getLargeIconIds();
- }
- }
- // Set title.
- mTitle.setText(mPreference.getTitle());
-
- // Prepare the ListView.
- ArrayList<HashMap<String, Object>> listItem =
- new ArrayList<HashMap<String, Object>>();
- for(int i = 0; i < entries.length; ++i) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("text", entries[i].toString());
- if (iconIds != null) map.put("image", iconIds[i]);
- listItem.add(map);
- }
- SimpleAdapter listItemAdapter = new ListPrefSettingAdapter(context, listItem,
- R.layout.setting_item,
- new String[] {"text", "image"},
- new int[] {R.id.text, R.id.image});
- ((ListView) mSettingList).setAdapter(listItemAdapter);
- ((ListView) mSettingList).setOnItemClickListener(this);
- reloadPreference();
- }
-
- // The value of the preference may have changed. Update the UI.
- @Override
- public void reloadPreference() {
- int index = mPreference.findIndexOfValue(mPreference.getValue());
- if (index != -1) {
- ((ListView) mSettingList).setItemChecked(index, true);
- } else {
- Log.e(TAG, "Invalid preference value.");
- mPreference.print();
- }
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int index, long id) {
- mPreference.setValueIndex(index);
- if (mListener != null) mListener.onListPrefChanged(mPreference);
- }
-}
diff --git a/src/com/android/camera/ui/MoreSettingPopup.java b/src/com/android/camera/ui/MoreSettingPopup.java
deleted file mode 100644
index 5900058df..000000000
--- a/src/com/android/camera/ui/MoreSettingPopup.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import com.android.camera.ListPreference;
-import com.android.camera.PreferenceGroup;
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-
-/* A popup window that contains several camera settings. */
-public class MoreSettingPopup extends AbstractSettingPopup
- implements InLineSettingItem.Listener,
- AdapterView.OnItemClickListener {
- @SuppressWarnings("unused")
- private static final String TAG = "MoreSettingPopup";
-
- private Listener mListener;
- private ArrayList<ListPreference> mListItem = new ArrayList<ListPreference>();
-
- // Keep track of which setting items are disabled
- // e.g. White balance will be disabled when scene mode is set to non-auto
- private boolean[] mEnabled;
-
- static public interface Listener {
- public void onSettingChanged(ListPreference pref);
- public void onPreferenceClicked(ListPreference pref);
- }
-
- private class MoreSettingAdapter extends ArrayAdapter<ListPreference> {
- LayoutInflater mInflater;
- String mOnString;
- String mOffString;
- MoreSettingAdapter() {
- super(MoreSettingPopup.this.getContext(), 0, mListItem);
- Context context = getContext();
- mInflater = LayoutInflater.from(context);
- mOnString = context.getString(R.string.setting_on);
- mOffString = context.getString(R.string.setting_off);
- }
-
- private int getSettingLayoutId(ListPreference pref) {
-
- if (isOnOffPreference(pref)) {
- return R.layout.in_line_setting_check_box;
- }
- return R.layout.in_line_setting_menu;
- }
-
- private boolean isOnOffPreference(ListPreference pref) {
- CharSequence[] entries = pref.getEntries();
- if (entries.length != 2) return false;
- String str1 = entries[0].toString();
- String str2 = entries[1].toString();
- return ((str1.equals(mOnString) && str2.equals(mOffString)) ||
- (str1.equals(mOffString) && str2.equals(mOnString)));
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView != null) return convertView;
-
- ListPreference pref = mListItem.get(position);
-
- int viewLayoutId = getSettingLayoutId(pref);
- InLineSettingItem view = (InLineSettingItem)
- mInflater.inflate(viewLayoutId, parent, false);
-
- view.initialize(pref); // no init for restore one
- view.setSettingChangedListener(MoreSettingPopup.this);
- if (position >= 0 && position < mEnabled.length) {
- view.setEnabled(mEnabled[position]);
- } else {
- Log.w(TAG, "Invalid input: enabled list length, " + mEnabled.length
- + " position " + position);
- }
- return view;
- }
-
- @Override
- public boolean isEnabled(int position) {
- if (position >= 0 && position < mEnabled.length) {
- return mEnabled[position];
- }
- return true;
- }
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public MoreSettingPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void initialize(PreferenceGroup group, String[] keys) {
- // Prepare the setting items.
- for (int i = 0; i < keys.length; ++i) {
- ListPreference pref = group.findPreference(keys[i]);
- if (pref != null) mListItem.add(pref);
- }
-
- ArrayAdapter<ListPreference> mListItemAdapter = new MoreSettingAdapter();
- ((ListView) mSettingList).setAdapter(mListItemAdapter);
- ((ListView) mSettingList).setOnItemClickListener(this);
- ((ListView) mSettingList).setSelector(android.R.color.transparent);
- // Initialize mEnabled
- mEnabled = new boolean[mListItem.size()];
- for (int i = 0; i < mEnabled.length; i++) {
- mEnabled[i] = true;
- }
- }
-
- // When preferences are disabled, we will display them grayed out. Users
- // will not be able to change the disabled preferences, but they can still see
- // the current value of the preferences
- public void setPreferenceEnabled(String key, boolean enable) {
- int count = mEnabled == null ? 0 : mEnabled.length;
- for (int j = 0; j < count; j++) {
- ListPreference pref = mListItem.get(j);
- if (pref != null && key.equals(pref.getKey())) {
- mEnabled[j] = enable;
- break;
- }
- }
- }
-
- public void onSettingChanged(ListPreference pref) {
- if (mListener != null) {
- mListener.onSettingChanged(pref);
- }
- }
-
- // Scene mode can override other camera settings (ex: flash mode).
- public void overrideSettings(final String ... keyvalues) {
- int count = mEnabled == null ? 0 : mEnabled.length;
- for (int i = 0; i < keyvalues.length; i += 2) {
- String key = keyvalues[i];
- String value = keyvalues[i + 1];
- for (int j = 0; j < count; j++) {
- ListPreference pref = mListItem.get(j);
- if (pref != null && key.equals(pref.getKey())) {
- // Change preference
- if (value != null) pref.setValue(value);
- // If the preference is overridden, disable the preference
- boolean enable = value == null;
- mEnabled[j] = enable;
- if (mSettingList.getChildCount() > j) {
- mSettingList.getChildAt(j).setEnabled(enable);
- }
- }
- }
- }
- reloadPreference();
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- if (mListener != null) {
- ListPreference pref = mListItem.get(position);
- mListener.onPreferenceClicked(pref);
- }
- }
-
- @Override
- public void reloadPreference() {
- int count = mSettingList.getChildCount();
- for (int i = 0; i < count; i++) {
- ListPreference pref = mListItem.get(i);
- if (pref != null) {
- InLineSettingItem settingItem =
- (InLineSettingItem) mSettingList.getChildAt(i);
- settingItem.reloadPreference();
- }
- }
- }
-}
diff --git a/src/com/android/camera/ui/OnIndicatorEventListener.java b/src/com/android/camera/ui/OnIndicatorEventListener.java
deleted file mode 100644
index 566f5c7a8..000000000
--- a/src/com/android/camera/ui/OnIndicatorEventListener.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-public interface OnIndicatorEventListener {
- public static int EVENT_ENTER_SECOND_LEVEL_INDICATOR_BAR = 0;
- public static int EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR = 1;
- public static int EVENT_ENTER_ZOOM_CONTROL = 2;
- public static int EVENT_LEAVE_ZOOM_CONTROL = 3;
- void onIndicatorEvent(int event);
-}
diff --git a/src/com/android/camera/ui/OverlayRenderer.java b/src/com/android/camera/ui/OverlayRenderer.java
deleted file mode 100644
index 417e219aa..000000000
--- a/src/com/android/camera/ui/OverlayRenderer.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.view.MotionEvent;
-
-public abstract class OverlayRenderer implements RenderOverlay.Renderer {
-
- private static final String TAG = "CAM OverlayRenderer";
- protected RenderOverlay mOverlay;
-
- protected int mLeft, mTop, mRight, mBottom;
-
- protected boolean mVisible;
-
- public void setVisible(boolean vis) {
- mVisible = vis;
- update();
- }
-
- public boolean isVisible() {
- return mVisible;
- }
-
- // default does not handle touch
- @Override
- public boolean handlesTouch() {
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent evt) {
- return false;
- }
-
- public abstract void onDraw(Canvas canvas);
-
- public void draw(Canvas canvas) {
- if (mVisible) {
- onDraw(canvas);
- }
- }
-
- @Override
- public void setOverlay(RenderOverlay overlay) {
- mOverlay = overlay;
- }
-
- @Override
- public void layout(int left, int top, int right, int bottom) {
- mLeft = left;
- mRight = right;
- mTop = top;
- mBottom = bottom;
- }
-
- protected Context getContext() {
- if (mOverlay != null) {
- return mOverlay.getContext();
- } else {
- return null;
- }
- }
-
- public int getWidth() {
- return mRight - mLeft;
- }
-
- public int getHeight() {
- return mBottom - mTop;
- }
-
- protected void update() {
- if (mOverlay != null) {
- mOverlay.update();
- }
- }
-
-}
diff --git a/src/com/android/camera/ui/PieItem.java b/src/com/android/camera/ui/PieItem.java
deleted file mode 100644
index 47fe06758..000000000
--- a/src/com/android/camera/ui/PieItem.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.graphics.drawable.Drawable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Pie menu item
- */
-public class PieItem {
-
- public static interface OnClickListener {
- void onClick(PieItem item);
- }
-
- private Drawable mDrawable;
- private int level;
-
- private boolean mSelected;
- private boolean mEnabled;
- private List<PieItem> mItems;
- private Path mPath;
- private OnClickListener mOnClickListener;
- private float mAlpha;
- private CharSequence mLabel;
-
- // Gray out the view when disabled
- private static final float ENABLED_ALPHA = 1;
- private static final float DISABLED_ALPHA = (float) 0.3;
- private boolean mChangeAlphaWhenDisabled = true;
-
- public PieItem(Drawable drawable, int level) {
- mDrawable = drawable;
- this.level = level;
- if (drawable != null) {
- setAlpha(1f);
- }
- mEnabled = true;
- }
-
- public void setLabel(CharSequence txt) {
- mLabel = txt;
- }
-
- public CharSequence getLabel() {
- return mLabel;
- }
-
- public boolean hasItems() {
- return mItems != null;
- }
-
- public List<PieItem> getItems() {
- return mItems;
- }
-
- public void addItem(PieItem item) {
- if (mItems == null) {
- mItems = new ArrayList<PieItem>();
- }
- mItems.add(item);
- }
-
- public void clearItems() {
- mItems = null;
- }
-
- public void setLevel(int level) {
- this.level = level;
- }
-
- public void setPath(Path p) {
- mPath = p;
- }
-
- public Path getPath() {
- return mPath;
- }
-
- public void setChangeAlphaWhenDisabled (boolean enable) {
- mChangeAlphaWhenDisabled = enable;
- }
-
- public void setAlpha(float alpha) {
- mAlpha = alpha;
- mDrawable.setAlpha((int) (255 * alpha));
- }
-
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- if (mChangeAlphaWhenDisabled) {
- if (mEnabled) {
- setAlpha(ENABLED_ALPHA);
- } else {
- setAlpha(DISABLED_ALPHA);
- }
- }
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
-
- public void setSelected(boolean s) {
- mSelected = s;
- }
-
- public boolean isSelected() {
- return mSelected;
- }
-
- public int getLevel() {
- return level;
- }
-
-
- public void setOnClickListener(OnClickListener listener) {
- mOnClickListener = listener;
- }
-
- public void performClick() {
- if (mOnClickListener != null) {
- mOnClickListener.onClick(this);
- }
- }
-
- public int getIntrinsicWidth() {
- return mDrawable.getIntrinsicWidth();
- }
-
- public int getIntrinsicHeight() {
- return mDrawable.getIntrinsicHeight();
- }
-
- public void setBounds(int left, int top, int right, int bottom) {
- mDrawable.setBounds(left, top, right, bottom);
- }
-
- public void draw(Canvas canvas) {
- mDrawable.draw(canvas);
- }
-
- public void setImageResource(Context context, int resId) {
- Drawable d = context.getResources().getDrawable(resId).mutate();
- d.setBounds(mDrawable.getBounds());
- mDrawable = d;
- setAlpha(mAlpha);
- }
-
-}
diff --git a/src/com/android/camera/ui/PieMenuButton.java b/src/com/android/camera/ui/PieMenuButton.java
deleted file mode 100644
index 0e23226b2..000000000
--- a/src/com/android/camera/ui/PieMenuButton.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-public class PieMenuButton extends View {
- private boolean mPressed;
- private boolean mReadyToClick = false;
- public PieMenuButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
- mPressed = isPressed();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- boolean handled = super.onTouchEvent(event);
- if (MotionEvent.ACTION_UP == event.getAction() && mPressed) {
- // Perform a customized click as soon as the ACTION_UP event
- // is received. The reason for doing this is that Framework
- // delays the performClick() call after ACTION_UP. But we do not
- // want the delay because it affects an important state change
- // for PieRenderer.
- mReadyToClick = true;
- performClick();
- }
- return handled;
- }
-
- @Override
- public boolean performClick() {
- if (mReadyToClick) {
- // We only respond to our customized click which happens right
- // after ACTION_UP event is received, with no delay.
- mReadyToClick = false;
- return super.performClick();
- }
- return false;
- }
-}; \ No newline at end of file
diff --git a/src/com/android/camera/ui/PieRenderer.java b/src/com/android/camera/ui/PieRenderer.java
deleted file mode 100644
index c78107ce9..000000000
--- a/src/com/android/camera/ui/PieRenderer.java
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.os.Message;
-import android.util.FloatMath;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-
-import com.android.camera.drawable.TextDrawable;
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PieRenderer extends OverlayRenderer
- implements FocusIndicator {
-
- private static final String TAG = "CAM Pie";
-
- // Sometimes continuous autofocus starts and stops several times quickly.
- // These states are used to make sure the animation is run for at least some
- // time.
- private volatile int mState;
- private ScaleAnimation mAnimation = new ScaleAnimation();
- private static final int STATE_IDLE = 0;
- private static final int STATE_FOCUSING = 1;
- private static final int STATE_FINISHING = 2;
- private static final int STATE_PIE = 8;
-
- private static final float MATH_PI_2 = (float)(Math.PI / 2);
-
- private Runnable mDisappear = new Disappear();
- private Animation.AnimationListener mEndAction = new EndAction();
- private static final int SCALING_UP_TIME = 600;
- private static final int SCALING_DOWN_TIME = 100;
- private static final int DISAPPEAR_TIMEOUT = 200;
- private static final int DIAL_HORIZONTAL = 157;
- // fade out timings
- private static final int PIE_FADE_OUT_DURATION = 600;
-
- private static final long PIE_FADE_IN_DURATION = 200;
- private static final long PIE_XFADE_DURATION = 200;
- private static final long PIE_SELECT_FADE_DURATION = 300;
- private static final long PIE_OPEN_SUB_DELAY = 400;
- private static final long PIE_SLICE_DURATION = 80;
-
- private static final int MSG_OPEN = 0;
- private static final int MSG_CLOSE = 1;
- private static final int MSG_OPENSUBMENU = 2;
-
- protected static float CENTER = (float) Math.PI / 2;
- protected static float RAD24 = (float)(24 * Math.PI / 180);
- protected static final float SWEEP_SLICE = 0.14f;
- protected static final float SWEEP_ARC = 0.23f;
-
- // geometry
- private int mRadius;
- private int mRadiusInc;
-
- // the detection if touch is inside a slice is offset
- // inbounds by this amount to allow the selection to show before the
- // finger covers it
- private int mTouchOffset;
-
- private List<PieItem> mOpen;
-
- private Paint mSelectedPaint;
- private Paint mSubPaint;
- private Paint mMenuArcPaint;
-
- // touch handling
- private PieItem mCurrentItem;
-
- private Paint mFocusPaint;
- private int mSuccessColor;
- private int mFailColor;
- private int mCircleSize;
- private int mFocusX;
- private int mFocusY;
- private int mCenterX;
- private int mCenterY;
- private int mArcCenterY;
- private int mSliceCenterY;
- private int mPieCenterX;
- private int mPieCenterY;
- private int mSliceRadius;
- private int mArcRadius;
- private int mArcOffset;
-
- private int mDialAngle;
- private RectF mCircle;
- private RectF mDial;
- private Point mPoint1;
- private Point mPoint2;
- private int mStartAnimationAngle;
- private boolean mFocused;
- private int mInnerOffset;
- private int mOuterStroke;
- private int mInnerStroke;
- private boolean mTapMode;
- private boolean mBlockFocus;
- private int mTouchSlopSquared;
- private Point mDown;
- private boolean mOpening;
- private ValueAnimator mXFade;
- private ValueAnimator mFadeIn;
- private ValueAnimator mFadeOut;
- private ValueAnimator mSlice;
- private volatile boolean mFocusCancelled;
- private PointF mPolar = new PointF();
- private TextDrawable mLabel;
- private int mDeadZone;
- private int mAngleZone;
- private float mCenterAngle;
-
-
-
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case MSG_OPEN:
- if (mListener != null) {
- mListener.onPieOpened(mPieCenterX, mPieCenterY);
- }
- break;
- case MSG_CLOSE:
- if (mListener != null) {
- mListener.onPieClosed();
- }
- break;
- case MSG_OPENSUBMENU:
- onEnterOpen();
- break;
- }
-
- }
- };
-
- private PieListener mListener;
-
- static public interface PieListener {
- public void onPieOpened(int centerX, int centerY);
- public void onPieClosed();
- }
-
- public void setPieListener(PieListener pl) {
- mListener = pl;
- }
-
- public PieRenderer(Context context) {
- init(context);
- }
-
- private void init(Context ctx) {
- setVisible(false);
- mOpen = new ArrayList<PieItem>();
- mOpen.add(new PieItem(null, 0));
- Resources res = ctx.getResources();
- mRadius = (int) res.getDimensionPixelSize(R.dimen.pie_radius_start);
- mRadiusInc = (int) res.getDimensionPixelSize(R.dimen.pie_radius_increment);
- mCircleSize = mRadius - res.getDimensionPixelSize(R.dimen.focus_radius_offset);
- mTouchOffset = (int) res.getDimensionPixelSize(R.dimen.pie_touch_offset);
- mSelectedPaint = new Paint();
- mSelectedPaint.setColor(Color.argb(255, 51, 181, 229));
- mSelectedPaint.setAntiAlias(true);
- mSubPaint = new Paint();
- mSubPaint.setAntiAlias(true);
- mSubPaint.setColor(Color.argb(200, 250, 230, 128));
- mFocusPaint = new Paint();
- mFocusPaint.setAntiAlias(true);
- mFocusPaint.setColor(Color.WHITE);
- mFocusPaint.setStyle(Paint.Style.STROKE);
- mSuccessColor = Color.GREEN;
- mFailColor = Color.RED;
- mCircle = new RectF();
- mDial = new RectF();
- mPoint1 = new Point();
- mPoint2 = new Point();
- mInnerOffset = res.getDimensionPixelSize(R.dimen.focus_inner_offset);
- mOuterStroke = res.getDimensionPixelSize(R.dimen.focus_outer_stroke);
- mInnerStroke = res.getDimensionPixelSize(R.dimen.focus_inner_stroke);
- mState = STATE_IDLE;
- mBlockFocus = false;
- mTouchSlopSquared = ViewConfiguration.get(ctx).getScaledTouchSlop();
- mTouchSlopSquared = mTouchSlopSquared * mTouchSlopSquared;
- mDown = new Point();
- mMenuArcPaint = new Paint();
- mMenuArcPaint.setAntiAlias(true);
- mMenuArcPaint.setColor(Color.argb(140, 255, 255, 255));
- mMenuArcPaint.setStrokeWidth(10);
- mMenuArcPaint.setStyle(Paint.Style.STROKE);
- mSliceRadius = res.getDimensionPixelSize(R.dimen.pie_item_radius);
- mArcRadius = res.getDimensionPixelSize(R.dimen.pie_arc_radius);
- mArcOffset = res.getDimensionPixelSize(R.dimen.pie_arc_offset);
- mLabel = new TextDrawable(res);
- mLabel.setDropShadow(true);
- mDeadZone = res.getDimensionPixelSize(R.dimen.pie_deadzone_width);
- mAngleZone = res.getDimensionPixelSize(R.dimen.pie_anglezone_width);
- }
-
- private PieItem getRoot() {
- return mOpen.get(0);
- }
-
- public boolean showsItems() {
- return mTapMode;
- }
-
- public void addItem(PieItem item) {
- // add the item to the pie itself
- getRoot().addItem(item);
- }
-
- public void clearItems() {
- getRoot().clearItems();
- }
-
- public void showInCenter() {
- if ((mState == STATE_PIE) && isVisible()) {
- mTapMode = false;
- show(false);
- } else {
- if (mState != STATE_IDLE) {
- cancelFocus();
- }
- mState = STATE_PIE;
- resetPieCenter();
- setCenter(mPieCenterX, mPieCenterY);
- mTapMode = true;
- show(true);
- }
- }
-
- public void hide() {
- show(false);
- }
-
- /**
- * guaranteed has center set
- * @param show
- */
- private void show(boolean show) {
- if (show) {
- if (mXFade != null) {
- mXFade.cancel();
- }
- mState = STATE_PIE;
- // ensure clean state
- mCurrentItem = null;
- PieItem root = getRoot();
- for (PieItem openItem : mOpen) {
- if (openItem.hasItems()) {
- for (PieItem item : openItem.getItems()) {
- item.setSelected(false);
- }
- }
- }
- mLabel.setText("");
- mOpen.clear();
- mOpen.add(root);
- layoutPie();
- fadeIn();
- } else {
- mState = STATE_IDLE;
- mTapMode = false;
- if (mXFade != null) {
- mXFade.cancel();
- }
- if (mLabel != null) {
- mLabel.setText("");
- }
- }
- setVisible(show);
- mHandler.sendEmptyMessage(show ? MSG_OPEN : MSG_CLOSE);
- }
-
- public boolean isOpen() {
- return mState == STATE_PIE && isVisible();
- }
-
- private void fadeIn() {
- mFadeIn = new ValueAnimator();
- mFadeIn.setFloatValues(0f, 1f);
- mFadeIn.setDuration(PIE_FADE_IN_DURATION);
- // linear interpolation
- mFadeIn.setInterpolator(null);
- mFadeIn.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mFadeIn = null;
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationCancel(Animator arg0) {
- }
- });
- mFadeIn.start();
- }
-
- public void setCenter(int x, int y) {
- mPieCenterX = x;
- mPieCenterY = y;
- mSliceCenterY = y + mSliceRadius - mArcOffset;
- mArcCenterY = y - mArcOffset + mArcRadius;
- }
-
- @Override
- public void layout(int l, int t, int r, int b) {
- super.layout(l, t, r, b);
- mCenterX = (r - l) / 2;
- mCenterY = (b - t) / 2;
-
- mFocusX = mCenterX;
- mFocusY = mCenterY;
- resetPieCenter();
- setCircle(mFocusX, mFocusY);
- if (isVisible() && mState == STATE_PIE) {
- setCenter(mPieCenterX, mPieCenterY);
- layoutPie();
- }
- }
-
- private void resetPieCenter() {
- mPieCenterX = mCenterX;
- mPieCenterY = (int) (getHeight() - 2.5f * mDeadZone);
- }
-
- private void layoutPie() {
- mCenterAngle = getCenterAngle();
- layoutItems(0, getRoot().getItems());
- layoutLabel(getLevel());
- }
-
- private void layoutLabel(int level) {
- int x = mPieCenterX - (int) (FloatMath.sin(mCenterAngle - CENTER)
- * (mArcRadius + (level + 2) * mRadiusInc));
- int y = mArcCenterY - mArcRadius - (level + 2) * mRadiusInc;
- int w = mLabel.getIntrinsicWidth();
- int h = mLabel.getIntrinsicHeight();
- mLabel.setBounds(x - w/2, y - h/2, x + w/2, y + h/2);
- }
-
- private void layoutItems(int level, List<PieItem> items) {
- int extend = 1;
- Path path = makeSlice(getDegrees(0) + extend, getDegrees(SWEEP_ARC) - extend,
- mArcRadius, mArcRadius + mRadiusInc + mRadiusInc / 4,
- mPieCenterX, mArcCenterY - level * mRadiusInc);
- final int count = items.size();
- int pos = 0;
- for (PieItem item : items) {
- // shared between items
- item.setPath(path);
- float angle = getArcCenter(item, pos, count);
- int w = item.getIntrinsicWidth();
- int h = item.getIntrinsicHeight();
- // move views to outer border
- int r = mArcRadius + mRadiusInc * 2 / 3;
- int x = (int) (r * Math.cos(angle));
- int y = mArcCenterY - (level * mRadiusInc) - (int) (r * Math.sin(angle)) - h / 2;
- x = mPieCenterX + x - w / 2;
- item.setBounds(x, y, x + w, y + h);
- item.setLevel(level);
- if (item.hasItems()) {
- layoutItems(level + 1, item.getItems());
- }
- pos++;
- }
- }
-
- private Path makeSlice(float start, float end, int inner, int outer, int cx, int cy) {
- RectF bb =
- new RectF(cx - outer, cy - outer, cx + outer,
- cy + outer);
- RectF bbi =
- new RectF(cx - inner, cy - inner, cx + inner,
- cy + inner);
- Path path = new Path();
- path.arcTo(bb, start, end - start, true);
- path.arcTo(bbi, end, start - end);
- path.close();
- return path;
- }
-
- private float getArcCenter(PieItem item, int pos, int count) {
- return getCenter(pos, count, SWEEP_ARC);
- }
-
- private float getSliceCenter(PieItem item, int pos, int count) {
- float center = (getCenterAngle() - CENTER) * 0.5f + CENTER;
- return center + (count - 1) * SWEEP_SLICE / 2f
- - pos * SWEEP_SLICE;
- }
-
- private float getCenter(int pos, int count, float sweep) {
- return mCenterAngle + (count - 1) * sweep / 2f - pos * sweep;
- }
-
- private float getCenterAngle() {
- float center = CENTER;
- if (mPieCenterX < mDeadZone + mAngleZone) {
- center = CENTER - (mAngleZone - mPieCenterX + mDeadZone) * RAD24
- / (float) mAngleZone;
- } else if (mPieCenterX > getWidth() - mDeadZone - mAngleZone) {
- center = CENTER + (mPieCenterX - (getWidth() - mDeadZone - mAngleZone)) * RAD24
- / (float) mAngleZone;
- }
- return center;
- }
-
- /**
- * converts a
- * @param angle from 0..PI to Android degrees (clockwise starting at 3 o'clock)
- * @return skia angle
- */
- private float getDegrees(double angle) {
- return (float) (360 - 180 * angle / Math.PI);
- }
-
- private void startFadeOut(final PieItem item) {
- if (mFadeIn != null) {
- mFadeIn.cancel();
- }
- if (mXFade != null) {
- mXFade.cancel();
- }
- mFadeOut = new ValueAnimator();
- mFadeOut.setFloatValues(1f, 0f);
- mFadeOut.setDuration(PIE_FADE_OUT_DURATION);
- mFadeOut.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animator) {
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- item.performClick();
- mFadeOut = null;
- deselect();
- show(false);
- mOverlay.setAlpha(1);
- }
-
- @Override
- public void onAnimationRepeat(Animator animator) {
- }
-
- @Override
- public void onAnimationCancel(Animator animator) {
- }
-
- });
- mFadeOut.start();
- }
-
- // root does not count
- private boolean hasOpenItem() {
- return mOpen.size() > 1;
- }
-
- // pop an item of the open item stack
- private PieItem closeOpenItem() {
- PieItem item = getOpenItem();
- mOpen.remove(mOpen.size() -1);
- return item;
- }
-
- private PieItem getOpenItem() {
- return mOpen.get(mOpen.size() - 1);
- }
-
- // return the children either the root or parent of the current open item
- private PieItem getParent() {
- return mOpen.get(Math.max(0, mOpen.size() - 2));
- }
-
- private int getLevel() {
- return mOpen.size() - 1;
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- float alpha = 1;
- if (mXFade != null) {
- alpha = (Float) mXFade.getAnimatedValue();
- } else if (mFadeIn != null) {
- alpha = (Float) mFadeIn.getAnimatedValue();
- } else if (mFadeOut != null) {
- alpha = (Float) mFadeOut.getAnimatedValue();
- }
- int state = canvas.save();
- if (mFadeIn != null) {
- float sf = 0.9f + alpha * 0.1f;
- canvas.scale(sf, sf, mPieCenterX, mPieCenterY);
- }
- if (mState != STATE_PIE) {
- drawFocus(canvas);
- }
- if (mState == STATE_FINISHING) {
- canvas.restoreToCount(state);
- return;
- }
- if (mState != STATE_PIE) return;
- if (!hasOpenItem() || (mXFade != null)) {
- // draw base menu
- drawArc(canvas, getLevel(), getParent());
- List<PieItem> items = getParent().getItems();
- final int count = items.size();
- int pos = 0;
- for (PieItem item : getParent().getItems()) {
- drawItem(Math.max(0, mOpen.size() - 2), pos, count, canvas, item, alpha);
- pos++;
- }
- mLabel.draw(canvas);
- }
- if (hasOpenItem()) {
- int level = getLevel();
- drawArc(canvas, level, getOpenItem());
- List<PieItem> items = getOpenItem().getItems();
- final int count = items.size();
- int pos = 0;
- for (PieItem inner : items) {
- if (mFadeOut != null) {
- drawItem(level, pos, count, canvas, inner, alpha);
- } else {
- drawItem(level, pos, count, canvas, inner, (mXFade != null) ? (1 - 0.5f * alpha) : 1);
- }
- pos++;
- }
- mLabel.draw(canvas);
- }
- canvas.restoreToCount(state);
- }
-
- private void drawArc(Canvas canvas, int level, PieItem item) {
- // arc
- if (mState == STATE_PIE) {
- final int count = item.getItems().size();
- float start = mCenterAngle + (count * SWEEP_ARC / 2f);
- float end = mCenterAngle - (count * SWEEP_ARC / 2f);
- int cy = mArcCenterY - level * mRadiusInc;
- canvas.drawArc(new RectF(mPieCenterX - mArcRadius, cy - mArcRadius,
- mPieCenterX + mArcRadius, cy + mArcRadius),
- getDegrees(end), getDegrees(start) - getDegrees(end), false, mMenuArcPaint);
- }
- }
-
- private void drawItem(int level, int pos, int count, Canvas canvas, PieItem item, float alpha) {
- if (mState == STATE_PIE) {
- if (item.getPath() != null) {
- int y = mArcCenterY - level * mRadiusInc;
- if (item.isSelected()) {
- Paint p = mSelectedPaint;
- int state = canvas.save();
- float angle = 0;
- if (mSlice != null) {
- angle = (Float) mSlice.getAnimatedValue();
- } else {
- angle = getArcCenter(item, pos, count) - SWEEP_ARC / 2f;
- }
- angle = getDegrees(angle);
- canvas.rotate(angle, mPieCenterX, y);
- if (mFadeOut != null) {
- p.setAlpha((int)(255 * alpha));
- }
- canvas.drawPath(item.getPath(), p);
- if (mFadeOut != null) {
- p.setAlpha(255);
- }
- canvas.restoreToCount(state);
- }
- if (mFadeOut == null) {
- alpha = alpha * (item.isEnabled() ? 1 : 0.3f);
- // draw the item view
- item.setAlpha(alpha);
- }
- item.draw(canvas);
- }
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent evt) {
- float x = evt.getX();
- float y = evt.getY();
- int action = evt.getActionMasked();
- getPolar(x, y, !mTapMode, mPolar);
- if (MotionEvent.ACTION_DOWN == action) {
- if ((x < mDeadZone) || (x > getWidth() - mDeadZone)) {
- return false;
- }
- mDown.x = (int) evt.getX();
- mDown.y = (int) evt.getY();
- mOpening = false;
- if (mTapMode) {
- PieItem item = findItem(mPolar);
- if ((item != null) && (mCurrentItem != item)) {
- mState = STATE_PIE;
- onEnter(item);
- }
- } else {
- setCenter((int) x, (int) y);
- show(true);
- }
- return true;
- } else if (MotionEvent.ACTION_UP == action) {
- if (isVisible()) {
- PieItem item = mCurrentItem;
- if (mTapMode) {
- item = findItem(mPolar);
- if (mOpening) {
- mOpening = false;
- return true;
- }
- }
- if (item == null) {
- mTapMode = false;
- show(false);
- } else if (!mOpening && !item.hasItems()) {
- startFadeOut(item);
- mTapMode = false;
- } else {
- mTapMode = true;
- }
- return true;
- }
- } else if (MotionEvent.ACTION_CANCEL == action) {
- if (isVisible() || mTapMode) {
- show(false);
- }
- deselect();
- mHandler.removeMessages(MSG_OPENSUBMENU);
- return false;
- } else if (MotionEvent.ACTION_MOVE == action) {
- if (pulledToCenter(mPolar)) {
- mHandler.removeMessages(MSG_OPENSUBMENU);
- if (hasOpenItem()) {
- if (mCurrentItem != null) {
- mCurrentItem.setSelected(false);
- }
- closeOpenItem();
- mCurrentItem = null;
- } else {
- deselect();
- }
- mLabel.setText("");
- return false;
- }
- PieItem item = findItem(mPolar);
- boolean moved = hasMoved(evt);
- if ((item != null) && (mCurrentItem != item) && (!mOpening || moved)) {
- mHandler.removeMessages(MSG_OPENSUBMENU);
- // only select if we didn't just open or have moved past slop
- if (moved) {
- // switch back to swipe mode
- mTapMode = false;
- }
- onEnterSelect(item);
- mHandler.sendEmptyMessageDelayed(MSG_OPENSUBMENU, PIE_OPEN_SUB_DELAY);
- }
- }
- return false;
- }
-
- private boolean pulledToCenter(PointF polarCoords) {
- return polarCoords.y < mArcRadius - mRadiusInc;
- }
-
- private boolean inside(PointF polar, PieItem item, int pos, int count) {
- float start = getSliceCenter(item, pos, count) - SWEEP_SLICE / 2f;
- boolean res = (mArcRadius < polar.y)
- && (start < polar.x)
- && (start + SWEEP_SLICE > polar.x)
- && (!mTapMode || (mArcRadius + mRadiusInc > polar.y));
- return res;
- }
-
- private void getPolar(float x, float y, boolean useOffset, PointF res) {
- // get angle and radius from x/y
- res.x = (float) Math.PI / 2;
- x = x - mPieCenterX;
- float y1 = mSliceCenterY - getLevel() * mRadiusInc - y;
- float y2 = mArcCenterY - getLevel() * mRadiusInc - y;
- res.y = (float) Math.sqrt(x * x + y2 * y2);
- if (x != 0) {
- res.x = (float) Math.atan2(y1, x);
- if (res.x < 0) {
- res.x = (float) (2 * Math.PI + res.x);
- }
- }
- res.y = res.y + (useOffset ? mTouchOffset : 0);
- }
-
- private boolean hasMoved(MotionEvent e) {
- return mTouchSlopSquared < (e.getX() - mDown.x) * (e.getX() - mDown.x)
- + (e.getY() - mDown.y) * (e.getY() - mDown.y);
- }
-
- private void onEnterSelect(PieItem item) {
- if (mCurrentItem != null) {
- mCurrentItem.setSelected(false);
- }
- if (item != null && item.isEnabled()) {
- moveSelection(mCurrentItem, item);
- item.setSelected(true);
- mCurrentItem = item;
- mLabel.setText(mCurrentItem.getLabel());
- layoutLabel(getLevel());
- } else {
- mCurrentItem = null;
- }
- }
-
- private void onEnterOpen() {
- if ((mCurrentItem != null) && (mCurrentItem != getOpenItem()) && mCurrentItem.hasItems()) {
- openCurrentItem();
- }
- }
-
- /**
- * enter a slice for a view
- * updates model only
- * @param item
- */
- private void onEnter(PieItem item) {
- if (mCurrentItem != null) {
- mCurrentItem.setSelected(false);
- }
- if (item != null && item.isEnabled()) {
- item.setSelected(true);
- mCurrentItem = item;
- mLabel.setText(mCurrentItem.getLabel());
- if ((mCurrentItem != getOpenItem()) && mCurrentItem.hasItems()) {
- openCurrentItem();
- layoutLabel(getLevel());
- }
- } else {
- mCurrentItem = null;
- }
- }
-
- private void deselect() {
- if (mCurrentItem != null) {
- mCurrentItem.setSelected(false);
- }
- if (hasOpenItem()) {
- PieItem item = closeOpenItem();
- onEnter(item);
- } else {
- mCurrentItem = null;
- }
- }
-
- private int getItemPos(PieItem target) {
- List<PieItem> items = getOpenItem().getItems();
- return items.indexOf(target);
- }
-
- private int getCurrentCount() {
- return getOpenItem().getItems().size();
- }
-
- private void moveSelection(PieItem from, PieItem to) {
- final int count = getCurrentCount();
- final int fromPos = getItemPos(from);
- final int toPos = getItemPos(to);
- if (fromPos != -1 && toPos != -1) {
- float startAngle = getArcCenter(from, getItemPos(from), count)
- - SWEEP_ARC / 2f;
- float endAngle = getArcCenter(to, getItemPos(to), count)
- - SWEEP_ARC / 2f;
- mSlice = new ValueAnimator();
- mSlice.setFloatValues(startAngle, endAngle);
- // linear interpolater
- mSlice.setInterpolator(null);
- mSlice.setDuration(PIE_SLICE_DURATION);
- mSlice.addListener(new AnimatorListener() {
- @Override
- public void onAnimationEnd(Animator arg0) {
- mSlice = null;
- }
-
- @Override
- public void onAnimationRepeat(Animator arg0) {
- }
-
- @Override
- public void onAnimationStart(Animator arg0) {
- }
-
- @Override
- public void onAnimationCancel(Animator arg0) {
- }
- });
- mSlice.start();
- }
- }
-
- private void openCurrentItem() {
- if ((mCurrentItem != null) && mCurrentItem.hasItems()) {
- mOpen.add(mCurrentItem);
- layoutLabel(getLevel());
- mOpening = true;
- if (mFadeIn != null) {
- mFadeIn.cancel();
- }
- mXFade = new ValueAnimator();
- mXFade.setFloatValues(1f, 0f);
- mXFade.setDuration(PIE_XFADE_DURATION);
- // Linear interpolation
- mXFade.setInterpolator(null);
- final PieItem ci = mCurrentItem;
- mXFade.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mXFade = null;
- ci.setSelected(false);
- mOpening = false;
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationCancel(Animator arg0) {
- }
- });
- mXFade.start();
- }
- }
-
- /**
- * @param polar x: angle, y: dist
- * @return the item at angle/dist or null
- */
- private PieItem findItem(PointF polar) {
- // find the matching item:
- List<PieItem> items = getOpenItem().getItems();
- final int count = items.size();
- int pos = 0;
- for (PieItem item : items) {
- if (inside(polar, item, pos, count)) {
- return item;
- }
- pos++;
- }
- return null;
- }
-
-
- @Override
- public boolean handlesTouch() {
- return true;
- }
-
- // focus specific code
-
- public void setBlockFocus(boolean blocked) {
- mBlockFocus = blocked;
- if (blocked) {
- clear();
- }
- }
-
- public void setFocus(int x, int y) {
- mFocusX = x;
- mFocusY = y;
- setCircle(mFocusX, mFocusY);
- }
-
- public void alignFocus(int x, int y) {
- mOverlay.removeCallbacks(mDisappear);
- mAnimation.cancel();
- mAnimation.reset();
- mFocusX = x;
- mFocusY = y;
- mDialAngle = DIAL_HORIZONTAL;
- setCircle(x, y);
- mFocused = false;
- }
-
- public int getSize() {
- return 2 * mCircleSize;
- }
-
- private int getRandomRange() {
- return (int)(-60 + 120 * Math.random());
- }
-
- private void setCircle(int cx, int cy) {
- mCircle.set(cx - mCircleSize, cy - mCircleSize,
- cx + mCircleSize, cy + mCircleSize);
- mDial.set(cx - mCircleSize + mInnerOffset, cy - mCircleSize + mInnerOffset,
- cx + mCircleSize - mInnerOffset, cy + mCircleSize - mInnerOffset);
- }
-
- public void drawFocus(Canvas canvas) {
- if (mBlockFocus) return;
- mFocusPaint.setStrokeWidth(mOuterStroke);
- canvas.drawCircle((float) mFocusX, (float) mFocusY, (float) mCircleSize, mFocusPaint);
- if (mState == STATE_PIE) return;
- int color = mFocusPaint.getColor();
- if (mState == STATE_FINISHING) {
- mFocusPaint.setColor(mFocused ? mSuccessColor : mFailColor);
- }
- mFocusPaint.setStrokeWidth(mInnerStroke);
- drawLine(canvas, mDialAngle, mFocusPaint);
- drawLine(canvas, mDialAngle + 45, mFocusPaint);
- drawLine(canvas, mDialAngle + 180, mFocusPaint);
- drawLine(canvas, mDialAngle + 225, mFocusPaint);
- canvas.save();
- // rotate the arc instead of its offset to better use framework's shape caching
- canvas.rotate(mDialAngle, mFocusX, mFocusY);
- canvas.drawArc(mDial, 0, 45, false, mFocusPaint);
- canvas.drawArc(mDial, 180, 45, false, mFocusPaint);
- canvas.restore();
- mFocusPaint.setColor(color);
- }
-
- private void drawLine(Canvas canvas, int angle, Paint p) {
- convertCart(angle, mCircleSize - mInnerOffset, mPoint1);
- convertCart(angle, mCircleSize - mInnerOffset + mInnerOffset / 3, mPoint2);
- canvas.drawLine(mPoint1.x + mFocusX, mPoint1.y + mFocusY,
- mPoint2.x + mFocusX, mPoint2.y + mFocusY, p);
- }
-
- private static void convertCart(int angle, int radius, Point out) {
- double a = 2 * Math.PI * (angle % 360) / 360;
- out.x = (int) (radius * Math.cos(a) + 0.5);
- out.y = (int) (radius * Math.sin(a) + 0.5);
- }
-
- @Override
- public void showStart() {
- if (mState == STATE_PIE) return;
- cancelFocus();
- mStartAnimationAngle = 67;
- int range = getRandomRange();
- startAnimation(SCALING_UP_TIME,
- false, mStartAnimationAngle, mStartAnimationAngle + range);
- mState = STATE_FOCUSING;
- }
-
- @Override
- public void showSuccess(boolean timeout) {
- if (mState == STATE_FOCUSING) {
- startAnimation(SCALING_DOWN_TIME,
- timeout, mStartAnimationAngle);
- mState = STATE_FINISHING;
- mFocused = true;
- }
- }
-
- @Override
- public void showFail(boolean timeout) {
- if (mState == STATE_FOCUSING) {
- startAnimation(SCALING_DOWN_TIME,
- timeout, mStartAnimationAngle);
- mState = STATE_FINISHING;
- mFocused = false;
- }
- }
-
- private void cancelFocus() {
- mFocusCancelled = true;
- mOverlay.removeCallbacks(mDisappear);
- if (mAnimation != null && !mAnimation.hasEnded()) {
- mAnimation.cancel();
- }
- mFocusCancelled = false;
- mFocused = false;
- mState = STATE_IDLE;
- }
-
- @Override
- public void clear() {
- if (mState == STATE_PIE) return;
- cancelFocus();
- mOverlay.post(mDisappear);
- }
-
- private void startAnimation(long duration, boolean timeout,
- float toScale) {
- startAnimation(duration, timeout, mDialAngle,
- toScale);
- }
-
- private void startAnimation(long duration, boolean timeout,
- float fromScale, float toScale) {
- setVisible(true);
- mAnimation.reset();
- mAnimation.setDuration(duration);
- mAnimation.setScale(fromScale, toScale);
- mAnimation.setAnimationListener(timeout ? mEndAction : null);
- mOverlay.startAnimation(mAnimation);
- update();
- }
-
- private class EndAction implements Animation.AnimationListener {
- @Override
- public void onAnimationEnd(Animation animation) {
- // Keep the focus indicator for some time.
- if (!mFocusCancelled) {
- mOverlay.postDelayed(mDisappear, DISAPPEAR_TIMEOUT);
- }
- }
-
- @Override
- public void onAnimationRepeat(Animation animation) {
- }
-
- @Override
- public void onAnimationStart(Animation animation) {
- }
- }
-
- private class Disappear implements Runnable {
- @Override
- public void run() {
- if (mState == STATE_PIE) return;
- setVisible(false);
- mFocusX = mCenterX;
- mFocusY = mCenterY;
- mState = STATE_IDLE;
- setCircle(mFocusX, mFocusY);
- mFocused = false;
- }
- }
-
- private class ScaleAnimation extends Animation {
- private float mFrom = 1f;
- private float mTo = 1f;
-
- public ScaleAnimation() {
- setFillAfter(true);
- }
-
- public void setScale(float from, float to) {
- mFrom = from;
- mTo = to;
- }
-
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- mDialAngle = (int)(mFrom + (mTo - mFrom) * interpolatedTime);
- }
- }
-
-}
diff --git a/src/com/android/camera/ui/PopupManager.java b/src/com/android/camera/ui/PopupManager.java
deleted file mode 100644
index 0dcf34fd7..000000000
--- a/src/com/android/camera/ui/PopupManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.view.View;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * A manager which notifies the event of a new popup in order to dismiss the
- * old popup if exists.
- */
-public class PopupManager {
- private static HashMap<Context, PopupManager> sMap =
- new HashMap<Context, PopupManager>();
-
- public interface OnOtherPopupShowedListener {
- public void onOtherPopupShowed();
- }
-
- private PopupManager() {}
-
- private ArrayList<OnOtherPopupShowedListener> mListeners = new ArrayList<OnOtherPopupShowedListener>();
-
- public void notifyShowPopup(View view) {
- for (OnOtherPopupShowedListener listener : mListeners) {
- if ((View) listener != view) {
- listener.onOtherPopupShowed();
- }
- }
- }
-
- public void setOnOtherPopupShowedListener(OnOtherPopupShowedListener listener) {
- mListeners.add(listener);
- }
-
- public static PopupManager getInstance(Context context) {
- PopupManager instance = sMap.get(context);
- if (instance == null) {
- instance = new PopupManager();
- sMap.put(context, instance);
- }
- return instance;
- }
-
- public static void removeInstance(Context context) {
- PopupManager instance = sMap.get(context);
- sMap.remove(context);
- }
-}
diff --git a/src/com/android/camera/ui/PreviewSurfaceView.java b/src/com/android/camera/ui/PreviewSurfaceView.java
deleted file mode 100644
index 9a428e23c..000000000
--- a/src/com/android/camera/ui/PreviewSurfaceView.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewGroup;
-
-import com.android.gallery3d.common.ApiHelper;
-
-public class PreviewSurfaceView extends SurfaceView {
- public PreviewSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setZOrderMediaOverlay(true);
- getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- }
-
- public void shrink() {
- setLayoutSize(1);
- }
-
- public void expand() {
- setLayoutSize(ViewGroup.LayoutParams.MATCH_PARENT);
- }
-
- private void setLayoutSize(int size) {
- ViewGroup.LayoutParams p = getLayoutParams();
- if (p.width != size || p.height != size) {
- p.width = size;
- p.height = size;
- setLayoutParams(p);
- }
- }
-}
diff --git a/src/com/android/camera/ui/RenderOverlay.java b/src/com/android/camera/ui/RenderOverlay.java
deleted file mode 100644
index d82ce18b6..000000000
--- a/src/com/android/camera/ui/RenderOverlay.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.camera.PreviewGestures;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class RenderOverlay extends FrameLayout {
-
- private static final String TAG = "CAM_Overlay";
-
- interface Renderer {
-
- public boolean handlesTouch();
- public boolean onTouchEvent(MotionEvent evt);
- public void setOverlay(RenderOverlay overlay);
- public void layout(int left, int top, int right, int bottom);
- public void draw(Canvas canvas);
-
- }
-
- private RenderView mRenderView;
- private List<Renderer> mClients;
- private PreviewGestures mGestures;
- // reverse list of touch clients
- private List<Renderer> mTouchClients;
- private int[] mPosition = new int[2];
-
- public RenderOverlay(Context context, AttributeSet attrs) {
- super(context, attrs);
- mRenderView = new RenderView(context);
- addView(mRenderView, new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- mClients = new ArrayList<Renderer>(10);
- mTouchClients = new ArrayList<Renderer>(10);
- setWillNotDraw(false);
- }
-
- public void setGestures(PreviewGestures gestures) {
- mGestures = gestures;
- }
-
- public void addRenderer(Renderer renderer) {
- mClients.add(renderer);
- renderer.setOverlay(this);
- if (renderer.handlesTouch()) {
- mTouchClients.add(0, renderer);
- }
- renderer.layout(getLeft(), getTop(), getRight(), getBottom());
- }
-
- public void addRenderer(int pos, Renderer renderer) {
- mClients.add(pos, renderer);
- renderer.setOverlay(this);
- renderer.layout(getLeft(), getTop(), getRight(), getBottom());
- }
-
- public void remove(Renderer renderer) {
- mClients.remove(renderer);
- renderer.setOverlay(null);
- }
-
- public int getClientSize() {
- return mClients.size();
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mGestures != null) {
- if (!mGestures.isEnabled()) return false;
- mGestures.dispatchTouch(m);
- }
- return true;
- }
-
- public boolean directDispatchTouch(MotionEvent m, Renderer target) {
- mRenderView.setTouchTarget(target);
- boolean res = mRenderView.dispatchTouchEvent(m);
- mRenderView.setTouchTarget(null);
- return res;
- }
-
- private void adjustPosition() {
- getLocationInWindow(mPosition);
- }
-
- public int getWindowPositionX() {
- return mPosition[0];
- }
-
- public int getWindowPositionY() {
- return mPosition[1];
- }
-
- public void update() {
- mRenderView.invalidate();
- }
-
- private class RenderView extends View {
-
- private Renderer mTouchTarget;
-
- public RenderView(Context context) {
- super(context);
- setWillNotDraw(false);
- }
-
- public void setTouchTarget(Renderer target) {
- mTouchTarget = target;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent evt) {
-
- if (mTouchTarget != null) {
- return mTouchTarget.onTouchEvent(evt);
- }
- if (mTouchClients != null) {
- boolean res = false;
- for (Renderer client : mTouchClients) {
- res |= client.onTouchEvent(evt);
- }
- return res;
- }
- return false;
- }
-
- @Override
- public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- adjustPosition();
- super.onLayout(changed, left, top, right, bottom);
- if (mClients == null) return;
- for (Renderer renderer : mClients) {
- renderer.layout(left, top, right, bottom);
- }
- }
-
- @Override
- public void draw(Canvas canvas) {
- super.draw(canvas);
- if (mClients == null) return;
- boolean redraw = false;
- for (Renderer renderer : mClients) {
- renderer.draw(canvas);
- redraw = redraw || ((OverlayRenderer) renderer).isVisible();
- }
- if (redraw) {
- invalidate();
- }
- }
- }
-
-}
diff --git a/src/com/android/camera/ui/Rotatable.java b/src/com/android/camera/ui/Rotatable.java
deleted file mode 100644
index 6d428b8c6..000000000
--- a/src/com/android/camera/ui/Rotatable.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-public interface Rotatable {
- // Set parameter 'animation' to true to have animation when rotation.
- public void setOrientation(int orientation, boolean animation);
-}
diff --git a/src/com/android/camera/ui/RotatableLayout.java b/src/com/android/camera/ui/RotatableLayout.java
deleted file mode 100644
index 965d62a90..000000000
--- a/src/com/android/camera/ui/RotatableLayout.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2013 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.ui;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.android.camera.Util;
-
-/* RotatableLayout rotates itself as well as all its children when orientation
- * changes. Specifically, when going from portrait to landscape, camera
- * controls move from the bottom of the screen to right side of the screen
- * (i.e. counter clockwise). Similarly, when the screen changes to portrait, we
- * need to move the controls from right side to the bottom of the screen, which
- * is a clockwise rotation.
- */
-
-public class RotatableLayout extends FrameLayout {
-
- private static final String TAG = "RotatableLayout";
- // Initial orientation of the layout (ORIENTATION_PORTRAIT, or ORIENTATION_LANDSCAPE)
- private int mInitialOrientation;
- private int mPrevRotation;
- private RotationListener mListener = null;
- public interface RotationListener {
- public void onRotation(int rotation);
- }
- public RotatableLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mInitialOrientation = getResources().getConfiguration().orientation;
- }
-
- public RotatableLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- mInitialOrientation = getResources().getConfiguration().orientation;
- }
-
- public RotatableLayout(Context context) {
- super(context);
- mInitialOrientation = getResources().getConfiguration().orientation;
- }
-
- @Override
- public void onAttachedToWindow() {
- mPrevRotation = Util.getDisplayRotation((Activity) getContext());
- // check if there is any rotation before the view is attached to window
- int currentOrientation = getResources().getConfiguration().orientation;
- int orientation = getUnifiedRotation();
- if (mInitialOrientation == currentOrientation && orientation < 180) {
- return;
- }
-
- if (mInitialOrientation == Configuration.ORIENTATION_LANDSCAPE
- && currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
- rotateLayout(true);
- } else if (mInitialOrientation == Configuration.ORIENTATION_PORTRAIT
- && currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
- rotateLayout(false);
- }
- // In reverse landscape and reverse portrait, camera controls will be laid out
- // on the wrong side of the screen. We need to make adjustment to move the controls
- // to the USB side
- if (orientation >= 180) {
- flipChildren();
- }
- }
-
- protected int getUnifiedRotation() {
- // all the layout code assumes camera device orientation to be portrait
- // adjust rotation for landscape
- int orientation = getResources().getConfiguration().orientation;
- int rotation = Util.getDisplayRotation((Activity) getContext());
- int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
- : Configuration.ORIENTATION_LANDSCAPE;
- if (camOrientation != orientation) {
- return (rotation + 90) % 360;
- }
- return rotation;
- }
-
- public void checkLayoutFlip() {
- int currentRotation = Util.getDisplayRotation((Activity) getContext());
- if ((currentRotation - mPrevRotation + 360) % 360 == 180) {
- mPrevRotation = currentRotation;
- flipChildren();
- getParent().requestLayout();
- }
- }
-
- @Override
- public void onWindowVisibilityChanged(int visibility) {
- if (visibility == View.VISIBLE) {
- // Make sure when coming back from onPause, the layout is rotated correctly
- checkLayoutFlip();
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- super.onConfigurationChanged(config);
- int rotation = Util.getDisplayRotation((Activity) getContext());
- int diff = (rotation - mPrevRotation + 360) % 360;
- if ( diff == 0) {
- // No rotation
- return;
- } else if (diff == 180) {
- // 180-degree rotation
- mPrevRotation = rotation;
- flipChildren();
- return;
- }
- // 90 or 270-degree rotation
- boolean clockwise = isClockWiseRotation(mPrevRotation, rotation);
- mPrevRotation = rotation;
- rotateLayout(clockwise);
- }
-
- protected void rotateLayout(boolean clockwise) {
- // Change the size of the layout
- ViewGroup.LayoutParams lp = getLayoutParams();
- int width = lp.width;
- int height = lp.height;
- lp.height = width;
- lp.width = height;
- setLayoutParams(lp);
-
- // rotate all the children
- rotateChildren(clockwise);
- }
-
- protected void rotateChildren(boolean clockwise) {
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- rotate(child, clockwise);
- }
- if (mListener != null) mListener.onRotation(clockwise ? 90 : 270);
- }
-
- protected void flipChildren() {
- int childCount = getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = getChildAt(i);
- flip(child);
- }
- if (mListener != null) mListener.onRotation(180);
- }
-
- public void setRotationListener(RotationListener listener) {
- mListener = listener;
- }
-
- public static boolean isClockWiseRotation(int prevRotation, int currentRotation) {
- if (prevRotation == (currentRotation + 90) % 360) {
- return true;
- }
- return false;
- }
-
- public static void rotate(View view, boolean isClockwise) {
- if (isClockwise) {
- rotateClockwise(view);
- } else {
- rotateCounterClockwise(view);
- }
- }
-
- private static boolean contains(int value, int mask) {
- return (value & mask) == mask;
- }
-
- public static void rotateClockwise(View view) {
- if (view == null) return;
- LayoutParams lp = (LayoutParams) view.getLayoutParams();
- int gravity = lp.gravity;
- int ngravity = 0;
- // rotate gravity
- if (contains(gravity, Gravity.LEFT)) {
- ngravity |= Gravity.TOP;
- }
- if (contains(gravity, Gravity.RIGHT)) {
- ngravity |= Gravity.BOTTOM;
- }
- if (contains(gravity, Gravity.TOP)) {
- ngravity |= Gravity.RIGHT;
- }
- if (contains(gravity, Gravity.BOTTOM)) {
- ngravity |= Gravity.LEFT;
- }
- if (contains(gravity, Gravity.CENTER)) {
- ngravity |= Gravity.CENTER;
- }
- if (contains(gravity, Gravity.CENTER_HORIZONTAL)) {
- ngravity |= Gravity.CENTER_VERTICAL;
- }
- if (contains(gravity, Gravity.CENTER_VERTICAL)) {
- ngravity |= Gravity.CENTER_HORIZONTAL;
- }
- lp.gravity = ngravity;
- int ml = lp.leftMargin;
- int mr = lp.rightMargin;
- int mt = lp.topMargin;
- int mb = lp.bottomMargin;
- lp.leftMargin = mb;
- lp.rightMargin = mt;
- lp.topMargin = ml;
- lp.bottomMargin = mr;
- int width = lp.width;
- int height = lp.height;
- lp.width = height;
- lp.height = width;
- view.setLayoutParams(lp);
- }
-
- public static void rotateCounterClockwise(View view) {
- if (view == null) return;
- LayoutParams lp = (LayoutParams) view.getLayoutParams();
- int gravity = lp.gravity;
- int ngravity = 0;
- // change gravity
- if (contains(gravity, Gravity.RIGHT)) {
- ngravity |= Gravity.TOP;
- }
- if (contains(gravity, Gravity.LEFT)) {
- ngravity |= Gravity.BOTTOM;
- }
- if (contains(gravity, Gravity.TOP)) {
- ngravity |= Gravity.LEFT;
- }
- if (contains(gravity, Gravity.BOTTOM)) {
- ngravity |= Gravity.RIGHT;
- }
- if (contains(gravity, Gravity.CENTER)) {
- ngravity |= Gravity.CENTER;
- }
- if (contains(gravity, Gravity.CENTER_HORIZONTAL)) {
- ngravity |= Gravity.CENTER_VERTICAL;
- }
- if (contains(gravity, Gravity.CENTER_VERTICAL)) {
- ngravity |= Gravity.CENTER_HORIZONTAL;
- }
- lp.gravity = ngravity;
- int ml = lp.leftMargin;
- int mr = lp.rightMargin;
- int mt = lp.topMargin;
- int mb = lp.bottomMargin;
- lp.leftMargin = mt;
- lp.rightMargin = mb;
- lp.topMargin = mr;
- lp.bottomMargin = ml;
- int width = lp.width;
- int height = lp.height;
- lp.width = height;
- lp.height = width;
- view.setLayoutParams(lp);
- }
-
- // Rotate a given view 180 degrees
- public static void flip(View view) {
- rotateClockwise(view);
- rotateClockwise(view);
- }
-} \ No newline at end of file
diff --git a/src/com/android/camera/ui/RotateImageView.java b/src/com/android/camera/ui/RotateImageView.java
deleted file mode 100644
index 05e1a7c5b..000000000
--- a/src/com/android/camera/ui/RotateImageView.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2009 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.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.TransitionDrawable;
-import android.media.ThumbnailUtils;
-import android.util.AttributeSet;
-import android.view.ViewGroup.LayoutParams;
-import android.view.animation.AnimationUtils;
-import android.widget.ImageView;
-
-/**
- * A @{code ImageView} which can rotate it's content.
- */
-public class RotateImageView extends TwoStateImageView implements Rotatable {
-
- @SuppressWarnings("unused")
- private static final String TAG = "RotateImageView";
-
- private static final int ANIMATION_SPEED = 270; // 270 deg/sec
-
- private int mCurrentDegree = 0; // [0, 359]
- private int mStartDegree = 0;
- private int mTargetDegree = 0;
-
- private boolean mClockwise = false, mEnableAnimation = true;
-
- private long mAnimationStartTime = 0;
- private long mAnimationEndTime = 0;
-
- public RotateImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public RotateImageView(Context context) {
- super(context);
- }
-
- protected int getDegree() {
- return mTargetDegree;
- }
-
- // Rotate the view counter-clockwise
- @Override
- public void setOrientation(int degree, boolean animation) {
- mEnableAnimation = animation;
- // make sure in the range of [0, 359]
- degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
- if (degree == mTargetDegree) return;
-
- mTargetDegree = degree;
- if (mEnableAnimation) {
- mStartDegree = mCurrentDegree;
- mAnimationStartTime = AnimationUtils.currentAnimationTimeMillis();
-
- int diff = mTargetDegree - mCurrentDegree;
- diff = diff >= 0 ? diff : 360 + diff; // make it in range [0, 359]
-
- // Make it in range [-179, 180]. That's the shorted distance between the
- // two angles
- diff = diff > 180 ? diff - 360 : diff;
-
- mClockwise = diff >= 0;
- mAnimationEndTime = mAnimationStartTime
- + Math.abs(diff) * 1000 / ANIMATION_SPEED;
- } else {
- mCurrentDegree = mTargetDegree;
- }
-
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- Drawable drawable = getDrawable();
- if (drawable == null) return;
-
- Rect bounds = drawable.getBounds();
- int w = bounds.right - bounds.left;
- int h = bounds.bottom - bounds.top;
-
- if (w == 0 || h == 0) return; // nothing to draw
-
- if (mCurrentDegree != mTargetDegree) {
- long time = AnimationUtils.currentAnimationTimeMillis();
- if (time < mAnimationEndTime) {
- int deltaTime = (int)(time - mAnimationStartTime);
- int degree = mStartDegree + ANIMATION_SPEED
- * (mClockwise ? deltaTime : -deltaTime) / 1000;
- degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
- mCurrentDegree = degree;
- invalidate();
- } else {
- mCurrentDegree = mTargetDegree;
- }
- }
-
- int left = getPaddingLeft();
- int top = getPaddingTop();
- int right = getPaddingRight();
- int bottom = getPaddingBottom();
- int width = getWidth() - left - right;
- int height = getHeight() - top - bottom;
-
- int saveCount = canvas.getSaveCount();
-
- // Scale down the image first if required.
- if ((getScaleType() == ImageView.ScaleType.FIT_CENTER) &&
- ((width < w) || (height < h))) {
- float ratio = Math.min((float) width / w, (float) height / h);
- canvas.scale(ratio, ratio, width / 2.0f, height / 2.0f);
- }
- canvas.translate(left + width / 2, top + height / 2);
- canvas.rotate(-mCurrentDegree);
- canvas.translate(-w / 2, -h / 2);
- drawable.draw(canvas);
- canvas.restoreToCount(saveCount);
- }
-
- private Bitmap mThumb;
- private Drawable[] mThumbs;
- private TransitionDrawable mThumbTransition;
-
- public void setBitmap(Bitmap bitmap) {
- // Make sure uri and original are consistently both null or both
- // non-null.
- if (bitmap == null) {
- mThumb = null;
- mThumbs = null;
- setImageDrawable(null);
- setVisibility(GONE);
- return;
- }
-
- LayoutParams param = getLayoutParams();
- final int miniThumbWidth = param.width
- - getPaddingLeft() - getPaddingRight();
- final int miniThumbHeight = param.height
- - getPaddingTop() - getPaddingBottom();
- mThumb = ThumbnailUtils.extractThumbnail(
- bitmap, miniThumbWidth, miniThumbHeight);
- Drawable drawable;
- if (mThumbs == null || !mEnableAnimation) {
- mThumbs = new Drawable[2];
- mThumbs[1] = new BitmapDrawable(getContext().getResources(), mThumb);
- setImageDrawable(mThumbs[1]);
- } else {
- mThumbs[0] = mThumbs[1];
- mThumbs[1] = new BitmapDrawable(getContext().getResources(), mThumb);
- mThumbTransition = new TransitionDrawable(mThumbs);
- setImageDrawable(mThumbTransition);
- mThumbTransition.startTransition(500);
- }
- setVisibility(VISIBLE);
- }
-}
diff --git a/src/com/android/camera/ui/RotateLayout.java b/src/com/android/camera/ui/RotateLayout.java
deleted file mode 100644
index 86f5c814d..000000000
--- a/src/com/android/camera/ui/RotateLayout.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.util.MotionEventHelper;
-
-// A RotateLayout is designed to display a single item and provides the
-// capabilities to rotate the item.
-public class RotateLayout extends ViewGroup implements Rotatable {
- @SuppressWarnings("unused")
- private static final String TAG = "RotateLayout";
- private int mOrientation;
- private Matrix mMatrix = new Matrix();
- protected View mChild;
-
- public RotateLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- // The transparent background here is a workaround of the render issue
- // happened when the view is rotated as the device's orientation
- // changed. The view looks fine in landscape. After rotation, the view
- // is invisible.
- setBackgroundResource(android.R.color.transparent);
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- @Override
- protected void onFinishInflate() {
- mChild = getChildAt(0);
- if (ApiHelper.HAS_VIEW_TRANSFORM_PROPERTIES) {
- mChild.setPivotX(0);
- mChild.setPivotY(0);
- }
- }
-
- @Override
- protected void onLayout(
- boolean change, int left, int top, int right, int bottom) {
- int width = right - left;
- int height = bottom - top;
- switch (mOrientation) {
- case 0:
- case 180:
- mChild.layout(0, 0, width, height);
- break;
- case 90:
- case 270:
- mChild.layout(0, 0, height, width);
- break;
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- if (!ApiHelper.HAS_VIEW_TRANSFORM_PROPERTIES) {
- final int w = getMeasuredWidth();
- final int h = getMeasuredHeight();
- switch (mOrientation) {
- case 0:
- mMatrix.setTranslate(0, 0);
- break;
- case 90:
- mMatrix.setTranslate(0, -h);
- break;
- case 180:
- mMatrix.setTranslate(-w, -h);
- break;
- case 270:
- mMatrix.setTranslate(-w, 0);
- break;
- }
- mMatrix.postRotate(mOrientation);
- event = MotionEventHelper.transformEvent(event, mMatrix);
- }
- return super.dispatchTouchEvent(event);
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- if (ApiHelper.HAS_VIEW_TRANSFORM_PROPERTIES) {
- super.dispatchDraw(canvas);
- } else {
- canvas.save();
- int w = getMeasuredWidth();
- int h = getMeasuredHeight();
- switch (mOrientation) {
- case 0:
- canvas.translate(0, 0);
- break;
- case 90:
- canvas.translate(0, h);
- break;
- case 180:
- canvas.translate(w, h);
- break;
- case 270:
- canvas.translate(w, 0);
- break;
- }
- canvas.rotate(-mOrientation, 0, 0);
- super.dispatchDraw(canvas);
- canvas.restore();
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- @Override
- protected void onMeasure(int widthSpec, int heightSpec) {
- int w = 0, h = 0;
- switch(mOrientation) {
- case 0:
- case 180:
- measureChild(mChild, widthSpec, heightSpec);
- w = mChild.getMeasuredWidth();
- h = mChild.getMeasuredHeight();
- break;
- case 90:
- case 270:
- measureChild(mChild, heightSpec, widthSpec);
- w = mChild.getMeasuredHeight();
- h = mChild.getMeasuredWidth();
- break;
- }
- setMeasuredDimension(w, h);
-
- if (ApiHelper.HAS_VIEW_TRANSFORM_PROPERTIES) {
- switch (mOrientation) {
- case 0:
- mChild.setTranslationX(0);
- mChild.setTranslationY(0);
- break;
- case 90:
- mChild.setTranslationX(0);
- mChild.setTranslationY(h);
- break;
- case 180:
- mChild.setTranslationX(w);
- mChild.setTranslationY(h);
- break;
- case 270:
- mChild.setTranslationX(w);
- mChild.setTranslationY(0);
- break;
- }
- mChild.setRotation(-mOrientation);
- }
- }
-
- @Override
- public boolean shouldDelayChildPressedState() {
- return false;
- }
-
- // Rotate the view counter-clockwise
- @Override
- public void setOrientation(int orientation, boolean animation) {
- orientation = orientation % 360;
- if (mOrientation == orientation) return;
- mOrientation = orientation;
- requestLayout();
- }
-
- public int getOrientation() {
- return mOrientation;
- }
-
- @Override
- public ViewParent invalidateChildInParent(int[] location, Rect r) {
- if (!ApiHelper.HAS_VIEW_TRANSFORM_PROPERTIES && mOrientation != 0) {
- // The workaround invalidates the entire rotate layout. After
- // rotation, the correct area to invalidate may be larger than the
- // size of the child. Ex: ListView. There is no way to invalidate
- // only the necessary area.
- r.set(0, 0, getWidth(), getHeight());
- }
- return super.invalidateChildInParent(location, r);
- }
-}
diff --git a/src/com/android/camera/ui/RotateTextToast.java b/src/com/android/camera/ui/RotateTextToast.java
deleted file mode 100644
index c78a258b0..000000000
--- a/src/com/android/camera/ui/RotateTextToast.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-
-public class RotateTextToast {
- private static final int TOAST_DURATION = 5000; // milliseconds
- ViewGroup mLayoutRoot;
- RotateLayout mToast;
- Handler mHandler;
-
- public RotateTextToast(Activity activity, int textResourceId, int orientation) {
- mLayoutRoot = (ViewGroup) activity.getWindow().getDecorView();
- LayoutInflater inflater = activity.getLayoutInflater();
- View v = inflater.inflate(R.layout.rotate_text_toast, mLayoutRoot);
- mToast = (RotateLayout) v.findViewById(R.id.rotate_toast);
- TextView tv = (TextView) mToast.findViewById(R.id.message);
- tv.setText(textResourceId);
- mToast.setOrientation(orientation, false);
- mHandler = new Handler();
- }
-
- private final Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- Util.fadeOut(mToast);
- mLayoutRoot.removeView(mToast);
- mToast = null;
- }
- };
-
- public void show() {
- mToast.setVisibility(View.VISIBLE);
- mHandler.postDelayed(mRunnable, TOAST_DURATION);
- }
-}
diff --git a/src/com/android/camera/ui/Switch.java b/src/com/android/camera/ui/Switch.java
deleted file mode 100644
index ac21758a7..000000000
--- a/src/com/android/camera/ui/Switch.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.text.Layout;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.CompoundButton;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.Arrays;
-
-/**
- * A Switch is a two-state toggle switch widget that can select between two
- * options. The user may drag the "thumb" back and forth to choose the selected option,
- * or simply tap to toggle as if it were a checkbox.
- */
-public class Switch extends CompoundButton {
- private static final int TOUCH_MODE_IDLE = 0;
- private static final int TOUCH_MODE_DOWN = 1;
- private static final int TOUCH_MODE_DRAGGING = 2;
-
- private Drawable mThumbDrawable;
- private Drawable mTrackDrawable;
- private int mThumbTextPadding;
- private int mSwitchMinWidth;
- private int mSwitchTextMaxWidth;
- private int mSwitchPadding;
- private CharSequence mTextOn;
- private CharSequence mTextOff;
-
- private int mTouchMode;
- private int mTouchSlop;
- private float mTouchX;
- private float mTouchY;
- private VelocityTracker mVelocityTracker = VelocityTracker.obtain();
- private int mMinFlingVelocity;
-
- private float mThumbPosition;
- private int mSwitchWidth;
- private int mSwitchHeight;
- private int mThumbWidth; // Does not include padding
-
- private int mSwitchLeft;
- private int mSwitchTop;
- private int mSwitchRight;
- private int mSwitchBottom;
-
- private TextPaint mTextPaint;
- private ColorStateList mTextColors;
- private Layout mOnLayout;
- private Layout mOffLayout;
-
- @SuppressWarnings("hiding")
- private final Rect mTempRect = new Rect();
-
- private static final int[] CHECKED_STATE_SET = {
- android.R.attr.state_checked
- };
-
- /**
- * Construct a new Switch with default styling, overriding specific style
- * attributes as requested.
- *
- * @param context The Context that will determine this widget's theming.
- * @param attrs Specification of attributes that should deviate from default styling.
- */
- public Switch(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.switchStyle);
- }
-
- /**
- * Construct a new Switch with a default style determined by the given theme attribute,
- * overriding specific style attributes as requested.
- *
- * @param context The Context that will determine this widget's theming.
- * @param attrs Specification of attributes that should deviate from the default styling.
- * @param defStyle An attribute ID within the active theme containing a reference to the
- * default style for this widget. e.g. android.R.attr.switchStyle.
- */
- public Switch(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
- Resources res = getResources();
- DisplayMetrics dm = res.getDisplayMetrics();
- mTextPaint.density = dm.density;
- mThumbDrawable = res.getDrawable(R.drawable.switch_inner_holo_dark);
- mTrackDrawable = res.getDrawable(R.drawable.switch_track_holo_dark);
- mTextOn = res.getString(R.string.capital_on);
- mTextOff = res.getString(R.string.capital_off);
- mThumbTextPadding = res.getDimensionPixelSize(R.dimen.thumb_text_padding);
- mSwitchMinWidth = res.getDimensionPixelSize(R.dimen.switch_min_width);
- mSwitchTextMaxWidth = res.getDimensionPixelSize(R.dimen.switch_text_max_width);
- mSwitchPadding = res.getDimensionPixelSize(R.dimen.switch_padding);
- setSwitchTextAppearance(context, android.R.style.TextAppearance_Holo_Small);
-
- ViewConfiguration config = ViewConfiguration.get(context);
- mTouchSlop = config.getScaledTouchSlop();
- mMinFlingVelocity = config.getScaledMinimumFlingVelocity();
-
- // Refresh display with current params
- refreshDrawableState();
- setChecked(isChecked());
- }
-
- /**
- * Sets the switch text color, size, style, hint color, and highlight color
- * from the specified TextAppearance resource.
- */
- public void setSwitchTextAppearance(Context context, int resid) {
- Resources res = getResources();
- mTextColors = getTextColors();
- int ts = res.getDimensionPixelSize(R.dimen.thumb_text_size);
- if (ts != mTextPaint.getTextSize()) {
- mTextPaint.setTextSize(ts);
- requestLayout();
- }
- }
-
- @Override
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- if (mOnLayout == null) {
- mOnLayout = makeLayout(mTextOn, mSwitchTextMaxWidth);
- }
- if (mOffLayout == null) {
- mOffLayout = makeLayout(mTextOff, mSwitchTextMaxWidth);
- }
-
- mTrackDrawable.getPadding(mTempRect);
- final int maxTextWidth = Math.min(mSwitchTextMaxWidth,
- Math.max(mOnLayout.getWidth(), mOffLayout.getWidth()));
- final int switchWidth = Math.max(mSwitchMinWidth,
- maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);
- final int switchHeight = mTrackDrawable.getIntrinsicHeight();
-
- mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
-
- mSwitchWidth = switchWidth;
- mSwitchHeight = switchHeight;
-
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- final int measuredHeight = getMeasuredHeight();
- final int measuredWidth = getMeasuredWidth();
- if (measuredHeight < switchHeight) {
- setMeasuredDimension(measuredWidth, switchHeight);
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(event);
- CharSequence text = isChecked() ? mOnLayout.getText() : mOffLayout.getText();
- if (!TextUtils.isEmpty(text)) {
- event.getText().add(text);
- }
- }
-
- private Layout makeLayout(CharSequence text, int maxWidth) {
- int actual_width = (int) Math.ceil(Layout.getDesiredWidth(text, mTextPaint));
- StaticLayout l = new StaticLayout(text, 0, text.length(), mTextPaint,
- actual_width,
- Layout.Alignment.ALIGN_NORMAL, 1.f, 0, true,
- TextUtils.TruncateAt.END,
- (int) Math.min(actual_width, maxWidth));
- return l;
- }
-
- /**
- * @return true if (x, y) is within the target area of the switch thumb
- */
- private boolean hitThumb(float x, float y) {
- mThumbDrawable.getPadding(mTempRect);
- final int thumbTop = mSwitchTop - mTouchSlop;
- final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop;
- final int thumbRight = thumbLeft + mThumbWidth +
- mTempRect.left + mTempRect.right + mTouchSlop;
- final int thumbBottom = mSwitchBottom + mTouchSlop;
- return x > thumbLeft && x < thumbRight && y > thumbTop && y < thumbBottom;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- mVelocityTracker.addMovement(ev);
- final int action = ev.getActionMasked();
- switch (action) {
- case MotionEvent.ACTION_DOWN: {
- final float x = ev.getX();
- final float y = ev.getY();
- if (isEnabled() && hitThumb(x, y)) {
- mTouchMode = TOUCH_MODE_DOWN;
- mTouchX = x;
- mTouchY = y;
- }
- break;
- }
-
- case MotionEvent.ACTION_MOVE: {
- switch (mTouchMode) {
- case TOUCH_MODE_IDLE:
- // Didn't target the thumb, treat normally.
- break;
-
- case TOUCH_MODE_DOWN: {
- final float x = ev.getX();
- final float y = ev.getY();
- if (Math.abs(x - mTouchX) > mTouchSlop ||
- Math.abs(y - mTouchY) > mTouchSlop) {
- mTouchMode = TOUCH_MODE_DRAGGING;
- getParent().requestDisallowInterceptTouchEvent(true);
- mTouchX = x;
- mTouchY = y;
- return true;
- }
- break;
- }
-
- case TOUCH_MODE_DRAGGING: {
- final float x = ev.getX();
- final float dx = x - mTouchX;
- float newPos = Math.max(0,
- Math.min(mThumbPosition + dx, getThumbScrollRange()));
- if (newPos != mThumbPosition) {
- mThumbPosition = newPos;
- mTouchX = x;
- invalidate();
- }
- return true;
- }
- }
- break;
- }
-
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL: {
- if (mTouchMode == TOUCH_MODE_DRAGGING) {
- stopDrag(ev);
- return true;
- }
- mTouchMode = TOUCH_MODE_IDLE;
- mVelocityTracker.clear();
- break;
- }
- }
-
- return super.onTouchEvent(ev);
- }
-
- private void cancelSuperTouch(MotionEvent ev) {
- MotionEvent cancel = MotionEvent.obtain(ev);
- cancel.setAction(MotionEvent.ACTION_CANCEL);
- super.onTouchEvent(cancel);
- cancel.recycle();
- }
-
- /**
- * Called from onTouchEvent to end a drag operation.
- *
- * @param ev Event that triggered the end of drag mode - ACTION_UP or ACTION_CANCEL
- */
- private void stopDrag(MotionEvent ev) {
- mTouchMode = TOUCH_MODE_IDLE;
- // Up and not canceled, also checks the switch has not been disabled during the drag
- boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
-
- cancelSuperTouch(ev);
-
- if (commitChange) {
- boolean newState;
- mVelocityTracker.computeCurrentVelocity(1000);
- float xvel = mVelocityTracker.getXVelocity();
- if (Math.abs(xvel) > mMinFlingVelocity) {
- newState = xvel > 0;
- } else {
- newState = getTargetCheckedState();
- }
- animateThumbToCheckedState(newState);
- } else {
- animateThumbToCheckedState(isChecked());
- }
- }
-
- private void animateThumbToCheckedState(boolean newCheckedState) {
- setChecked(newCheckedState);
- }
-
- private boolean getTargetCheckedState() {
- return mThumbPosition >= getThumbScrollRange() / 2;
- }
-
- private void setThumbPosition(boolean checked) {
- mThumbPosition = checked ? getThumbScrollRange() : 0;
- }
-
- @Override
- public void setChecked(boolean checked) {
- super.setChecked(checked);
- setThumbPosition(checked);
- invalidate();
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
-
- setThumbPosition(isChecked());
-
- int switchRight;
- int switchLeft;
-
- switchRight = getWidth() - getPaddingRight();
- switchLeft = switchRight - mSwitchWidth;
-
- int switchTop = 0;
- int switchBottom = 0;
- switch (getGravity() & Gravity.VERTICAL_GRAVITY_MASK) {
- default:
- case Gravity.TOP:
- switchTop = getPaddingTop();
- switchBottom = switchTop + mSwitchHeight;
- break;
-
- case Gravity.CENTER_VERTICAL:
- switchTop = (getPaddingTop() + getHeight() - getPaddingBottom()) / 2 -
- mSwitchHeight / 2;
- switchBottom = switchTop + mSwitchHeight;
- break;
-
- case Gravity.BOTTOM:
- switchBottom = getHeight() - getPaddingBottom();
- switchTop = switchBottom - mSwitchHeight;
- break;
- }
-
- mSwitchLeft = switchLeft;
- mSwitchTop = switchTop;
- mSwitchBottom = switchBottom;
- mSwitchRight = switchRight;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // Draw the switch
- int switchLeft = mSwitchLeft;
- int switchTop = mSwitchTop;
- int switchRight = mSwitchRight;
- int switchBottom = mSwitchBottom;
-
- mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
- mTrackDrawable.draw(canvas);
-
- canvas.save();
-
- mTrackDrawable.getPadding(mTempRect);
- int switchInnerLeft = switchLeft + mTempRect.left;
- int switchInnerTop = switchTop + mTempRect.top;
- int switchInnerRight = switchRight - mTempRect.right;
- int switchInnerBottom = switchBottom - mTempRect.bottom;
- canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
-
- mThumbDrawable.getPadding(mTempRect);
- final int thumbPos = (int) (mThumbPosition + 0.5f);
- int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;
- int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;
-
- mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
- mThumbDrawable.draw(canvas);
-
- // mTextColors should not be null, but just in case
- if (mTextColors != null) {
- mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(),
- mTextColors.getDefaultColor()));
- }
- mTextPaint.drawableState = getDrawableState();
-
- Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
-
- canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getEllipsizedWidth() / 2,
- (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2);
- switchText.draw(canvas);
-
- canvas.restore();
- }
-
- @Override
- public int getCompoundPaddingRight() {
- int padding = super.getCompoundPaddingRight() + mSwitchWidth;
- if (!TextUtils.isEmpty(getText())) {
- padding += mSwitchPadding;
- }
- return padding;
- }
-
- private int getThumbScrollRange() {
- if (mTrackDrawable == null) {
- return 0;
- }
- mTrackDrawable.getPadding(mTempRect);
- return mSwitchWidth - mThumbWidth - mTempRect.left - mTempRect.right;
- }
-
- @Override
- protected int[] onCreateDrawableState(int extraSpace) {
- final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-
- if (isChecked()) {
- mergeDrawableStates(drawableState, CHECKED_STATE_SET);
- }
- return drawableState;
- }
-
- @Override
- protected void drawableStateChanged() {
- super.drawableStateChanged();
-
- int[] myDrawableState = getDrawableState();
-
- // Set the state of the Drawable
- // Drawable may be null when checked state is set from XML, from super constructor
- if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState);
- if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState);
-
- invalidate();
- }
-
- @Override
- protected boolean verifyDrawable(Drawable who) {
- return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable;
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- @Override
- public void jumpDrawablesToCurrentState() {
- super.jumpDrawablesToCurrentState();
- mThumbDrawable.jumpToCurrentState();
- mTrackDrawable.jumpToCurrentState();
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- event.setClassName(Switch.class.getName());
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.setClassName(Switch.class.getName());
- CharSequence switchText = isChecked() ? mTextOn : mTextOff;
- if (!TextUtils.isEmpty(switchText)) {
- CharSequence oldText = info.getText();
- if (TextUtils.isEmpty(oldText)) {
- info.setText(switchText);
- } else {
- StringBuilder newText = new StringBuilder();
- newText.append(oldText).append(' ').append(switchText);
- info.setText(newText);
- }
- }
- }
-}
diff --git a/src/com/android/camera/ui/TimeIntervalPopup.java b/src/com/android/camera/ui/TimeIntervalPopup.java
deleted file mode 100644
index 18ad9f5da..000000000
--- a/src/com/android/camera/ui/TimeIntervalPopup.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CompoundButton;
-import android.widget.NumberPicker;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import com.android.camera.IconListPreference;
-import com.android.camera.ListPreference;
-import com.android.gallery3d.R;
-
-/**
- * This is a popup window that allows users to turn on/off time lapse feature,
- * and to select a time interval for taking a time lapse video.
- */
-public class TimeIntervalPopup extends AbstractSettingPopup {
- private static final String TAG = "TimeIntervalPopup";
- private NumberPicker mNumberSpinner;
- private NumberPicker mUnitSpinner;
- private Switch mTimeLapseSwitch;
- private final String[] mUnits;
- private final String[] mDurations;
- private IconListPreference mPreference;
- private Listener mListener;
- private Button mConfirmButton;
- private TextView mHelpText;
- private View mTimePicker;
-
- static public interface Listener {
- public void onListPrefChanged(ListPreference pref);
- }
-
- public void setSettingChangedListener(Listener listener) {
- mListener = listener;
- }
-
- public TimeIntervalPopup(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- Resources res = context.getResources();
- mUnits = res.getStringArray(R.array.pref_video_time_lapse_frame_interval_units);
- mDurations = res
- .getStringArray(R.array.pref_video_time_lapse_frame_interval_duration_values);
- }
-
- public void initialize(IconListPreference preference) {
- mPreference = preference;
-
- // Set title.
- mTitle.setText(mPreference.getTitle());
-
- // Duration
- int durationCount = mDurations.length;
- mNumberSpinner = (NumberPicker) findViewById(R.id.duration);
- mNumberSpinner.setMinValue(0);
- mNumberSpinner.setMaxValue(durationCount - 1);
- mNumberSpinner.setDisplayedValues(mDurations);
- mNumberSpinner.setWrapSelectorWheel(false);
-
- // Units for duration (i.e. seconds, minutes, etc)
- mUnitSpinner = (NumberPicker) findViewById(R.id.duration_unit);
- mUnitSpinner.setMinValue(0);
- mUnitSpinner.setMaxValue(mUnits.length - 1);
- mUnitSpinner.setDisplayedValues(mUnits);
- mUnitSpinner.setWrapSelectorWheel(false);
-
- mTimePicker = findViewById(R.id.time_interval_picker);
- mTimeLapseSwitch = (Switch) findViewById(R.id.time_lapse_switch);
- mHelpText = (TextView) findViewById(R.id.set_time_interval_help_text);
- mConfirmButton = (Button) findViewById(R.id.time_lapse_interval_set_button);
-
- // Disable focus on the spinners to prevent keyboard from coming up
- mNumberSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
- mUnitSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
-
- mTimeLapseSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- setTimeSelectionEnabled(isChecked);
- }
- });
- mConfirmButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- updateInputState();
- }
- });
- }
-
- private void restoreSetting() {
- int index = mPreference.findIndexOfValue(mPreference.getValue());
- if (index == -1) {
- Log.e(TAG, "Invalid preference value.");
- mPreference.print();
- throw new IllegalArgumentException();
- } else if (index == 0) {
- // default choice: time lapse off
- mTimeLapseSwitch.setChecked(false);
- setTimeSelectionEnabled(false);
- } else {
- mTimeLapseSwitch.setChecked(true);
- setTimeSelectionEnabled(true);
- int durationCount = mNumberSpinner.getMaxValue() + 1;
- int unit = (index - 1) / durationCount;
- int number = (index - 1) % durationCount;
- mUnitSpinner.setValue(unit);
- mNumberSpinner.setValue(number);
- }
- }
-
- @Override
- public void setVisibility(int visibility) {
- if (visibility == View.VISIBLE) {
- if (getVisibility() != View.VISIBLE) {
- // Set the number pickers and on/off switch to be consistent
- // with the preference
- restoreSetting();
- }
- }
- super.setVisibility(visibility);
- }
-
- protected void setTimeSelectionEnabled(boolean enabled) {
- mHelpText.setVisibility(enabled ? GONE : VISIBLE);
- mTimePicker.setVisibility(enabled ? VISIBLE : GONE);
- }
-
- @Override
- public void reloadPreference() {
- }
-
- private void updateInputState() {
- if (mTimeLapseSwitch.isChecked()) {
- int newId = mUnitSpinner.getValue() * (mNumberSpinner.getMaxValue() + 1)
- + mNumberSpinner.getValue() + 1;
- mPreference.setValueIndex(newId);
- } else {
- mPreference.setValueIndex(0);
- }
-
- if (mListener != null) {
- mListener.onListPrefChanged(mPreference);
- }
- }
-}
diff --git a/src/com/android/camera/ui/TwoStateImageView.java b/src/com/android/camera/ui/TwoStateImageView.java
deleted file mode 100644
index cd5b27fc1..000000000
--- a/src/com/android/camera/ui/TwoStateImageView.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 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.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.ImageView;
-
-/**
- * A @{code ImageView} which change the opacity of the icon if disabled.
- */
-public class TwoStateImageView extends ImageView {
- private static final int ENABLED_ALPHA = 255;
- private static final int DISABLED_ALPHA = (int) (255 * 0.4);
- private boolean mFilterEnabled = true;
-
- public TwoStateImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public TwoStateImageView(Context context) {
- this(context, null);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- if (mFilterEnabled) {
- if (enabled) {
- setAlpha(ENABLED_ALPHA);
- } else {
- setAlpha(DISABLED_ALPHA);
- }
- }
- }
-
- public void enableFilter(boolean enabled) {
- mFilterEnabled = enabled;
- }
-}
diff --git a/src/com/android/camera/ui/ZoomRenderer.java b/src/com/android/camera/ui/ZoomRenderer.java
deleted file mode 100644
index 86b82b459..000000000
--- a/src/com/android/camera/ui/ZoomRenderer.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2012 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.ui;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.view.ScaleGestureDetector;
-
-import com.android.gallery3d.R;
-
-public class ZoomRenderer extends OverlayRenderer
- implements ScaleGestureDetector.OnScaleGestureListener {
-
- private static final String TAG = "CAM_Zoom";
-
- private int mMaxZoom;
- private int mMinZoom;
- private OnZoomChangedListener mListener;
-
- private ScaleGestureDetector mDetector;
- private Paint mPaint;
- private Paint mTextPaint;
- private int mCircleSize;
- private int mCenterX;
- private int mCenterY;
- private float mMaxCircle;
- private float mMinCircle;
- private int mInnerStroke;
- private int mOuterStroke;
- private int mZoomSig;
- private int mZoomFraction;
- private Rect mTextBounds;
-
- public interface OnZoomChangedListener {
- void onZoomStart();
- void onZoomEnd();
- void onZoomValueChanged(int index); // only for immediate zoom
- }
-
- public ZoomRenderer(Context ctx) {
- Resources res = ctx.getResources();
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(Color.WHITE);
- mPaint.setStyle(Paint.Style.STROKE);
- mTextPaint = new Paint(mPaint);
- mTextPaint.setStyle(Paint.Style.FILL);
- mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.zoom_font_size));
- mTextPaint.setTextAlign(Paint.Align.LEFT);
- mTextPaint.setAlpha(192);
- mInnerStroke = res.getDimensionPixelSize(R.dimen.focus_inner_stroke);
- mOuterStroke = res.getDimensionPixelSize(R.dimen.focus_outer_stroke);
- mDetector = new ScaleGestureDetector(ctx, this);
- mMinCircle = res.getDimensionPixelSize(R.dimen.zoom_ring_min);
- mTextBounds = new Rect();
- setVisible(false);
- }
-
- // set from module
- public void setZoomMax(int zoomMaxIndex) {
- mMaxZoom = zoomMaxIndex;
- mMinZoom = 0;
- }
-
- public void setZoom(int index) {
- mCircleSize = (int) (mMinCircle + index * (mMaxCircle - mMinCircle) / (mMaxZoom - mMinZoom));
- }
-
- public void setZoomValue(int value) {
- value = value / 10;
- mZoomSig = value / 10;
- mZoomFraction = value % 10;
- }
-
- public void setOnZoomChangeListener(OnZoomChangedListener listener) {
- mListener = listener;
- }
-
- @Override
- public void layout(int l, int t, int r, int b) {
- super.layout(l, t, r, b);
- mCenterX = (r - l) / 2;
- mCenterY = (b - t) / 2;
- mMaxCircle = Math.min(getWidth(), getHeight());
- mMaxCircle = (mMaxCircle - mMinCircle) / 2;
- }
-
- public boolean isScaling() {
- return mDetector.isInProgress();
- }
-
- @Override
- public void onDraw(Canvas canvas) {
- mPaint.setStrokeWidth(mInnerStroke);
- canvas.drawCircle(mCenterX, mCenterY, mMinCircle, mPaint);
- canvas.drawCircle(mCenterX, mCenterY, mMaxCircle, mPaint);
- canvas.drawLine(mCenterX - mMinCircle, mCenterY,
- mCenterX - mMaxCircle - 4, mCenterY, mPaint);
- mPaint.setStrokeWidth(mOuterStroke);
- canvas.drawCircle((float) mCenterX, (float) mCenterY,
- (float) mCircleSize, mPaint);
- String txt = mZoomSig+"."+mZoomFraction+"x";
- mTextPaint.getTextBounds(txt, 0, txt.length(), mTextBounds);
- canvas.drawText(txt, mCenterX - mTextBounds.centerX(), mCenterY - mTextBounds.centerY(),
- mTextPaint);
- }
-
- @Override
- public boolean onScale(ScaleGestureDetector detector) {
- final float sf = detector.getScaleFactor();
- float circle = (int) (mCircleSize * sf * sf);
- circle = Math.max(mMinCircle, circle);
- circle = Math.min(mMaxCircle, circle);
- if (mListener != null && (int) circle != mCircleSize) {
- mCircleSize = (int) circle;
- int zoom = mMinZoom + (int) ((mCircleSize - mMinCircle) * (mMaxZoom - mMinZoom) / (mMaxCircle - mMinCircle));
- mListener.onZoomValueChanged(zoom);
- }
- return true;
- }
-
- @Override
- public boolean onScaleBegin(ScaleGestureDetector detector) {
- setVisible(true);
- if (mListener != null) {
- mListener.onZoomStart();
- }
- update();
- return true;
- }
-
- @Override
- public void onScaleEnd(ScaleGestureDetector detector) {
- setVisible(false);
- if (mListener != null) {
- mListener.onZoomEnd();
- }
- }
-
-}
diff --git a/src/com/android/gallery3d/app/GalleryApp.java b/src/com/android/gallery3d/app/GalleryApp.java
index b56b8a82c..98bf75b62 100644
--- a/src/com/android/gallery3d/app/GalleryApp.java
+++ b/src/com/android/gallery3d/app/GalleryApp.java
@@ -29,7 +29,6 @@ import com.android.gallery3d.util.ThreadPool;
public interface GalleryApp {
public DataManager getDataManager();
- public StitchingProgressManager getStitchingProgressManager();
public ImageCacheService getImageCacheService();
public DownloadCache getDownloadCache();
public ThreadPool getThreadPool();
diff --git a/src/com/android/gallery3d/app/GalleryAppImpl.java b/src/com/android/gallery3d/app/GalleryAppImpl.java
index d080a0331..c6e7a0b57 100644
--- a/src/com/android/gallery3d/app/GalleryAppImpl.java
+++ b/src/com/android/gallery3d/app/GalleryAppImpl.java
@@ -42,22 +42,15 @@ public class GalleryAppImpl extends Application implements GalleryApp {
private DataManager mDataManager;
private ThreadPool mThreadPool;
private DownloadCache mDownloadCache;
- private StitchingProgressManager mStitchingProgressManager;
@Override
public void onCreate() {
super.onCreate();
- com.android.camera.Util.initialize(this);
initializeAsyncTask();
GalleryUtils.initialize(this);
WidgetUtils.initialize(this);
PicasaSource.initialize(this);
UsageStatistics.initialize(this);
-
- mStitchingProgressManager = LightCycleHelper.createStitchingManagerInstance(this);
- if (mStitchingProgressManager != null) {
- mStitchingProgressManager.addChangeListener(getDataManager());
- }
}
@Override
@@ -74,10 +67,6 @@ public class GalleryAppImpl extends Application implements GalleryApp {
return mDataManager;
}
- @Override
- public StitchingProgressManager getStitchingProgressManager() {
- return mStitchingProgressManager;
- }
@Override
public ImageCacheService getImageCacheService() {
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 7a71e9109..3c3738a60 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -39,8 +39,6 @@ import android.widget.RelativeLayout;
import android.widget.ShareActionProvider;
import android.widget.Toast;
-import com.android.camera.CameraActivity;
-import com.android.camera.ProxyLauncher;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.data.ComboAlbum;
@@ -88,7 +86,6 @@ public abstract class PhotoPage extends ActivityState implements
private static final int MSG_ON_PICTURE_CENTER = 10;
private static final int MSG_REFRESH_IMAGE = 11;
private static final int MSG_UPDATE_PHOTO_UI = 12;
- private static final int MSG_UPDATE_PROGRESS = 13;
private static final int MSG_UPDATE_DEFERRED = 14;
private static final int MSG_UPDATE_SHARE_URI = 15;
private static final int MSG_UPDATE_PANORAMA_UI = 16;
@@ -146,7 +143,6 @@ public abstract class PhotoPage extends ActivityState implements
private boolean mIsMenuVisible;
private boolean mHaveImageEditor;
private PhotoPageBottomControls mBottomControls;
- private PhotoPageProgressBar mProgressBar;
private MediaItem mCurrentPhoto = null;
private MenuExecutor mMenuExecutor;
private boolean mIsActive;
@@ -183,7 +179,6 @@ public abstract class PhotoPage extends ActivityState implements
private final MyMenuVisibilityListener mMenuVisibilityListener =
new MyMenuVisibilityListener();
- private UpdateProgressListener mProgressListener;
private final PanoramaSupportCallback mUpdatePanoramaMenuItemsCallback = new PanoramaSupportCallback() {
@Override
@@ -233,33 +228,6 @@ public abstract class PhotoPage extends ActivityState implements
}
}
- private class UpdateProgressListener implements StitchingChangeListener {
-
- @Override
- public void onStitchingResult(Uri uri) {
- sendUpdate(uri, MSG_REFRESH_IMAGE);
- }
-
- @Override
- public void onStitchingQueued(Uri uri) {
- sendUpdate(uri, MSG_UPDATE_PROGRESS);
- }
-
- @Override
- public void onStitchingProgress(Uri uri, final int progress) {
- sendUpdate(uri, MSG_UPDATE_PROGRESS);
- }
-
- private void sendUpdate(Uri uri, int message) {
- MediaObject currentPhoto = mCurrentPhoto;
- boolean isCurrentPhoto = currentPhoto instanceof LocalImage
- && currentPhoto.getContentUri().equals(uri);
- if (isCurrentPhoto) {
- mHandler.sendEmptyMessage(message);
- }
- }
- };
-
@Override
protected int getBackgroundColorId() {
return R.color.photo_background;
@@ -379,10 +347,6 @@ public abstract class PhotoPage extends ActivityState implements
updateUIForCurrentPhoto();
break;
}
- case MSG_UPDATE_PROGRESS: {
- updateProgressBar();
- break;
- }
case MSG_UPDATE_SHARE_URI: {
if (mCurrentPhoto == message.obj) {
boolean isPanorama360 = message.arg1 != 0;
@@ -577,15 +541,6 @@ public abstract class PhotoPage extends ActivityState implements
if (mSecureAlbum == null) {
mBottomControls = new PhotoPageBottomControls(this, mActivity, galleryRoot);
}
- StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
- if (progressManager != null) {
- mProgressBar = new PhotoPageProgressBar(mActivity, galleryRoot);
- mProgressListener = new UpdateProgressListener();
- progressManager.addChangeListener(mProgressListener);
- if (mSecureAlbum != null) {
- progressManager.addChangeListener(mSecureAlbum);
- }
- }
}
}
@@ -696,10 +651,11 @@ public abstract class PhotoPage extends ActivityState implements
}
private void launchCamera() {
- Intent intent = new Intent(mActivity, CameraActivity.class)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mRecenterCameraOnResume = false;
- mActivity.startActivity(intent);
+ throw new RuntimeException("Not implemented yet.");
+// Intent intent = new Intent(mActivity, CameraActivity.class)
+// .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+// mRecenterCameraOnResume = false;
+// mActivity.startActivity(intent);
}
private void launchPhotoEditor() {
@@ -774,7 +730,6 @@ public abstract class PhotoPage extends ActivityState implements
&& (mCurrentPhoto.getSupportedOperations() & MediaItem.SUPPORT_SHARE) != 0) {
mCurrentPhoto.getPanoramaSupport(mUpdateShareURICallback);
}
- updateProgressBar();
}
private void updateCurrentPhoto(MediaItem photo) {
@@ -787,19 +742,6 @@ public abstract class PhotoPage extends ActivityState implements
}
}
- private void updateProgressBar() {
- if (mProgressBar != null) {
- mProgressBar.hideProgress();
- StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
- if (progressManager != null && mCurrentPhoto instanceof LocalImage) {
- Integer progress = progressManager.getProgress(mCurrentPhoto.getContentUri());
- if (progress != null) {
- mProgressBar.setProgress(progress);
- }
- }
- }
- }
-
private void updateMenuOperations() {
Menu menu = mActionBar.getMenu();
@@ -1016,10 +958,6 @@ public abstract class PhotoPage extends ActivityState implements
onUpPressed();
} else {
if (mOriginalSetPathString == null) return;
- if (mProgressBar != null) {
- updateCurrentPhoto(null);
- mProgressBar.hideProgress();
- }
Bundle data = new Bundle(getData());
data.putString(AlbumPage.KEY_MEDIA_PATH, mOriginalSetPathString);
data.putString(AlbumPage.KEY_PARENT_MEDIA_PATH,
@@ -1295,10 +1233,6 @@ public abstract class PhotoPage extends ActivityState implements
// This is a reset, not a canceled
return;
}
- if (resultCode == ProxyLauncher.RESULT_USER_CANCELED) {
- // Unmap reset vs. canceled
- resultCode = Activity.RESULT_CANCELED;
- }
mRecenterCameraOnResume = false;
switch (requestCode) {
case REQUEST_EDIT:
diff --git a/src/com/android/gallery3d/app/StateManager.java b/src/com/android/gallery3d/app/StateManager.java
index 53c3fc228..aa372a824 100644
--- a/src/com/android/gallery3d/app/StateManager.java
+++ b/src/com/android/gallery3d/app/StateManager.java
@@ -24,7 +24,6 @@ import android.os.Parcelable;
import android.view.Menu;
import android.view.MenuItem;
-import com.android.camera.CameraActivity;
import com.android.gallery3d.anim.StateTransitionAnimation;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.util.UsageStatistics;
diff --git a/src/com/android/gallery3d/data/Exif.java b/src/com/android/gallery3d/data/Exif.java
index 950e7de18..20f072454 100644
--- a/src/com/android/gallery3d/data/Exif.java
+++ b/src/com/android/gallery3d/data/Exif.java
@@ -24,9 +24,11 @@ import java.io.IOException;
import java.io.InputStream;
public class Exif {
- private static final String TAG = "CameraExif";
+ private static final String TAG = "GalleryExif";
- // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
+ /**
+ * Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
+ */
public static int getOrientation(InputStream is) {
if (is == null) {
return 0;
@@ -45,4 +47,42 @@ public class Exif {
return 0;
}
}
+
+ /**
+ * Returns an exif interface instance for the given JPEG image.
+ *
+ * @param jpegData a valid JPEG image containing EXIF data
+ */
+ public static ExifInterface getExif(byte[] jpegData) {
+ ExifInterface exif = new ExifInterface();
+ try {
+ exif.readExif(jpegData);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to read EXIF data", e);
+ }
+ return exif;
+ }
+
+ /**
+ * Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
+ */
+ public static int getOrientation(ExifInterface exif) {
+ Integer val = exif.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+ if (val == null) {
+ return 0;
+ } else {
+ return ExifInterface.getRotationForOrientationValue(val.shortValue());
+ }
+ }
+
+ /**
+ * See {@link #getOrientation(byte[])}, but using the picture bytes instead.
+ */
+ public static int getOrientation(byte[] jpegData) {
+ if (jpegData == null)
+ return 0;
+
+ ExifInterface exif = getExif(jpegData);
+ return getOrientation(exif);
+ }
}
diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java
index cc70dd457..94cb05936 100644
--- a/src/com/android/gallery3d/data/LocalImage.java
+++ b/src/com/android/gallery3d/data/LocalImage.java
@@ -32,7 +32,6 @@ import android.util.Log;
import com.android.gallery3d.app.GalleryApp;
import com.android.gallery3d.app.PanoramaMetadataSupport;
-import com.android.gallery3d.app.StitchingProgressManager;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.BitmapUtils;
import com.android.gallery3d.exif.ExifInterface;
@@ -237,10 +236,6 @@ public class LocalImage extends LocalMediaItem {
@Override
public int getSupportedOperations() {
- StitchingProgressManager progressManager = mApplication.getStitchingProgressManager();
- if (progressManager != null && progressManager.getProgress(getContentUri()) != null) {
- return 0; // doesn't support anything while stitching!
- }
int operation = SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_CROP
| SUPPORT_SETAS | SUPPORT_EDIT | SUPPORT_INFO;
if (BitmapUtils.isSupportedByRegionDecoder(mimeType)) {
diff --git a/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
index 30868c22b..c6504a561 100644
--- a/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
+++ b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
@@ -24,7 +24,7 @@ import android.mtp.MtpObjectInfo;
import android.util.DisplayMetrics;
import android.view.WindowManager;
-import com.android.camera.Exif;
+import com.android.gallery3d.data.Exif;
import com.android.photos.data.GalleryBitmapPool;
public class MtpBitmapFetch {
diff --git a/src/com/android/photos/GalleryActivity.java b/src/com/android/photos/GalleryActivity.java
index 710767d77..f3279fe07 100644
--- a/src/com/android/photos/GalleryActivity.java
+++ b/src/com/android/photos/GalleryActivity.java
@@ -29,7 +29,6 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
-import com.android.camera.CameraActivity;
import com.android.gallery3d.R;
import java.util.ArrayList;
@@ -80,10 +79,12 @@ public class GalleryActivity extends Activity implements MultiChoiceManager.Prov
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_camera:
- Intent intent = new Intent(this, CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- return true;
+ // TODO: Call the correct Camera intent.
+ throw new RuntimeException("Not implemented yet.");
+// Intent intent = new Intent(this, CameraActivity.class);
+// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+// startActivity(intent);
+// return true;
default:
return super.onOptionsItemSelected(item);
}
diff --git a/src_pd/com/android/camera/PanoramaStitchingManager.java b/src_pd/com/android/camera/PanoramaStitchingManager.java
deleted file mode 100644
index 5ba16b863..000000000
--- a/src_pd/com/android/camera/PanoramaStitchingManager.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.content.Context;
-import android.net.Uri;
-
-class PanoramaStitchingManager implements ImageTaskManager {
-
- public PanoramaStitchingManager(Context ctx) {
- }
-
- @Override
- public void addTaskListener(TaskListener l) {
- // do nothing.
- }
-
- @Override
- public void removeTaskListener(TaskListener l) {
- // do nothing.
- }
-
- @Override
- public int getTaskProgress(Uri uri) {
- return -1;
- }
-}
diff --git a/src_pd/com/android/gallery3d/util/LightCycleHelper.java b/src_pd/com/android/gallery3d/util/LightCycleHelper.java
index 7ef7699df..350882463 100644
--- a/src_pd/com/android/gallery3d/util/LightCycleHelper.java
+++ b/src_pd/com/android/gallery3d/util/LightCycleHelper.java
@@ -18,13 +18,8 @@ package com.android.gallery3d.util;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.net.Uri;
-import com.android.camera.CameraModule;
-import com.android.gallery3d.app.GalleryApp;
-import com.android.gallery3d.app.StitchingProgressManager;
-
public class LightCycleHelper {
public static class PanoramaMetadata {
// Whether a panorama viewer should be used
@@ -40,26 +35,10 @@ public class LightCycleHelper {
public static final PanoramaMetadata NOT_PANORAMA = new PanoramaMetadata(false, false);
- public static void setupCaptureIntent(Context context, Intent it, String outputDir) {
- /* Do nothing */
- }
-
- public static boolean hasLightCycleCapture(Context context) {
- return false;
- }
-
public static PanoramaMetadata getPanoramaMetadata(Context context, Uri uri) {
return NOT_PANORAMA;
}
- public static CameraModule createPanoramaModule() {
- return null;
- }
-
- public static StitchingProgressManager createStitchingManagerInstance(GalleryApp app) {
- return null;
- }
-
/**
* Get the file path from a Media storage URI.
*/
diff --git a/src_pd/com/android/gallery3d/util/RefocusHelper.java b/src_pd/com/android/gallery3d/util/RefocusHelper.java
deleted file mode 100644
index 39ded4740..000000000
--- a/src_pd/com/android/gallery3d/util/RefocusHelper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2013 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.gallery3d.util;
-
-import com.android.camera.CameraModule;
-
-public class RefocusHelper {
- public static CameraModule createRefocusModule() {
- return null;
- }
-}
diff --git a/tests/src/com/android/gallery3d/CameraTestRunner.java b/tests/src/com/android/gallery3d/CameraTestRunner.java
deleted file mode 100755
index 503233675..000000000
--- a/tests/src/com/android/gallery3d/CameraTestRunner.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-
-import com.android.gallery3d.functional.CameraTest;
-import com.android.gallery3d.functional.ImageCaptureIntentTest;
-import com.android.gallery3d.functional.VideoCaptureIntentTest;
-import com.android.gallery3d.unittest.CameraUnitTest;
-
-import junit.framework.TestSuite;
-
-
-public class CameraTestRunner extends InstrumentationTestRunner {
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(CameraTest.class);
- suite.addTestSuite(ImageCaptureIntentTest.class);
- suite.addTestSuite(VideoCaptureIntentTest.class);
- suite.addTestSuite(CameraUnitTest.class);
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- return CameraTestRunner.class.getClassLoader();
- }
-}
diff --git a/tests/src/com/android/gallery3d/StressTests.java b/tests/src/com/android/gallery3d/StressTests.java
deleted file mode 100755
index b991e9e8d..000000000
--- a/tests/src/com/android/gallery3d/StressTests.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 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.gallery3d;
-
-import com.android.gallery3d.stress.CameraLatency;
-import com.android.gallery3d.stress.CameraStartUp;
-import com.android.gallery3d.stress.ImageCapture;
-import com.android.gallery3d.stress.SwitchPreview;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Instrumentation Test Runner for all Camera tests.
- *
- * Running all tests:
- *
- * adb shell am instrument \
- * -e class com.android.gallery3d.StressTests \
- * -w com.google.android.gallery3d.tests/com.android.gallery3d.stress.CameraStressTestRunner
- */
-
-public class StressTests extends TestSuite {
- public static Test suite() {
- TestSuite result = new TestSuite();
- result.addTestSuite(CameraLatency.class);
- result.addTestSuite(CameraStartUp.class);
- result.addTestSuite(ImageCapture.class);
-// result.addTestSuite(SwitchPreview.class);
- return result;
- }
-}
diff --git a/tests/src/com/android/gallery3d/data/GalleryAppStub.java b/tests/src/com/android/gallery3d/data/GalleryAppStub.java
index 5aff2a2b2..47693d2d4 100644
--- a/tests/src/com/android/gallery3d/data/GalleryAppStub.java
+++ b/tests/src/com/android/gallery3d/data/GalleryAppStub.java
@@ -18,7 +18,6 @@ package com.android.gallery3d.data;
import com.android.gallery3d.app.GalleryApp;
import com.android.gallery3d.app.StateManager;
-import com.android.gallery3d.app.StitchingProgressManager;
import com.android.gallery3d.ui.GLRoot;
import com.android.gallery3d.util.ThreadPool;
@@ -43,5 +42,4 @@ class GalleryAppStub implements GalleryApp {
public ContentResolver getContentResolver() { return null; }
public ThreadPool getThreadPool() { return null; }
public DownloadCache getDownloadCache() { return null; }
- public StitchingProgressManager getStitchingProgressManager() { return null; }
}
diff --git a/tests/src/com/android/gallery3d/functional/CameraTest.java b/tests/src/com/android/gallery3d/functional/CameraTest.java
deleted file mode 100644
index c293c0d4a..000000000
--- a/tests/src/com/android/gallery3d/functional/CameraTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 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.gallery3d.functional;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Process;
-import android.provider.MediaStore;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-public class CameraTest extends InstrumentationTestCase {
- @LargeTest
- public void testVideoCaptureIntentFdLeak() throws Exception {
- Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse("file://"
- + Environment.getExternalStorageDirectory().toString()
- + "test_fd_leak.3gp"));
- getInstrumentation().startActivitySync(intent).finish();
- // Test if the fd is closed.
- for (File f: new File("/proc/" + Process.myPid() + "/fd").listFiles()) {
- assertEquals(-1, f.getCanonicalPath().indexOf("test_fd_leak.3gp"));
- }
- }
-
- @LargeTest
- public void testActivityLeak() throws Exception {
- checkActivityLeak(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
- checkActivityLeak(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- }
-
- private void checkActivityLeak(String action) throws Exception {
- final int TEST_COUNT = 5;
- Intent intent = new Intent(action);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- ArrayList<WeakReference<Activity>> refs =
- new ArrayList<WeakReference<Activity>>();
- for (int i = 0; i < TEST_COUNT; i++) {
- Activity activity = getInstrumentation().startActivitySync(intent);
- refs.add(new WeakReference<Activity>(activity));
- activity.finish();
- getInstrumentation().waitForIdleSync();
- activity = null;
- }
- Runtime.getRuntime().gc();
- Runtime.getRuntime().runFinalization();
- Runtime.getRuntime().gc();
- int refCount = 0;
- for (WeakReference<Activity> c: refs) {
- if (c.get() != null) refCount++;
- }
- // If applications are leaking activity, every reference is reachable.
- assertTrue(refCount != TEST_COUNT);
- }
-}
diff --git a/tests/src/com/android/gallery3d/functional/ImageCaptureIntentTest.java b/tests/src/com/android/gallery3d/functional/ImageCaptureIntentTest.java
deleted file mode 100644
index 8d394b5db..000000000
--- a/tests/src/com/android/gallery3d/functional/ImageCaptureIntentTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.functional;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.R;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-public class ImageCaptureIntentTest extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private Intent mIntent;
-
- public ImageCaptureIntentTest() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- }
-
- @LargeTest
- public void testNoExtraOutput() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressDone();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
- Intent resultData = getActivity().getResultData();
- Bitmap bitmap = (Bitmap) resultData.getParcelableExtra("data");
- assertNotNull(bitmap);
- assertTrue(bitmap.getWidth() > 0);
- assertTrue(bitmap.getHeight() > 0);
- }
-
- @LargeTest
- public void testExtraOutput() throws Exception {
- File file = new File(Environment.getExternalStorageDirectory(),
- "test.jpg");
- BufferedInputStream stream = null;
- byte[] jpegData;
-
- try {
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressDone();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
-
- // Verify the jpeg file
- int fileLength = (int) file.length();
- assertTrue(fileLength > 0);
- jpegData = new byte[fileLength];
- stream = new BufferedInputStream(new FileInputStream(file));
- stream.read(jpegData);
- } finally {
- if (stream != null) stream.close();
- file.delete();
- }
-
- Bitmap b = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
- assertTrue(b.getWidth() > 0);
- assertTrue(b.getHeight() > 0);
- }
-
- @LargeTest
- public void testCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testSnapshotCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- private void takePicture() throws Exception {
- getInstrumentation().sendKeySync(
- new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS));
- getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(4000);
- }
-
- private void pressDone() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_done).performClick();
- }
- });
- }
-
- private void pressCancel() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_cancel).performClick();
- }
- });
- }
-}
diff --git a/tests/src/com/android/gallery3d/functional/VideoCaptureIntentTest.java b/tests/src/com/android/gallery3d/functional/VideoCaptureIntentTest.java
deleted file mode 100644
index c8d7bbb1c..000000000
--- a/tests/src/com/android/gallery3d/functional/VideoCaptureIntentTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.functional;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.R;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.database.Cursor;
-import android.media.MediaMetadataRetriever;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Video.VideoColumns;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import java.io.File;
-
-public class VideoCaptureIntentTest extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private static final String TAG = "VideoCaptureIntentTest";
- private Intent mIntent;
- private Uri mVideoUri;
- private File mFile, mFile2;
-
- public VideoCaptureIntentTest() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (mVideoUri != null) {
- ContentResolver resolver = getActivity().getContentResolver();
- Uri query = mVideoUri.buildUpon().build();
- String[] projection = new String[] {VideoColumns.DATA};
-
- Cursor cursor = null;
- try {
- cursor = resolver.query(query, projection, null, null, null);
- if (cursor != null && cursor.moveToFirst()) {
- new File(cursor.getString(0)).delete();
- }
- } finally {
- if (cursor != null) cursor.close();
- }
-
- resolver.delete(mVideoUri, null, null);
- }
- if (mFile != null) mFile.delete();
- if (mFile2 != null) mFile2.delete();
- super.tearDown();
- }
-
- @LargeTest
- public void testNoExtraOutput() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- Intent resultData = getActivity().getResultData();
- mVideoUri = resultData.getData();
- assertNotNull(mVideoUri);
- verify(getActivity(), mVideoUri);
- }
-
- @LargeTest
- public void testExtraOutput() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- }
-
- @LargeTest
- public void testCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testRecordCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testExtraSizeLimit() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- final long sizeLimit = 500000; // bytes
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // use low quality to speed up
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo(5000);
- pressDone();
-
- verify(getActivity(), uri);
- long length = mFile.length();
- Log.v(TAG, "Video size is " + length + " bytes.");
- assertTrue(length > 0);
- assertTrue("Actual size=" + length, length <= sizeLimit);
- }
-
- @LargeTest
- public void testExtraDurationLimit() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- final int durationLimit = 2; // seconds
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo(5000);
- pressDone();
-
- int duration = verify(getActivity(), uri);
- // The duraion should be close to to the limit. The last video duration
- // also has duration, so the total duration may exceeds the limit a
- // little bit.
- Log.v(TAG, "Video length is " + duration + " ms.");
- assertTrue(duration < (durationLimit + 1) * 1000);
- }
-
- @LargeTest
- public void testExtraVideoQuality() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp");
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- setActivity(null);
-
- uri = Uri.fromFile(mFile2);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- assertTrue(mFile.length() <= mFile2.length());
- }
-
- // Verify result code, result data, and the duration.
- private int verify(CameraActivity activity, Uri uri) throws Exception {
- assertTrue(activity.isFinishing());
- assertEquals(Activity.RESULT_OK, activity.getResultCode());
-
- // Verify the video file
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(activity, uri);
- String duration = retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_DURATION);
- assertNotNull(duration);
- int durationValue = Integer.parseInt(duration);
- Log.v(TAG, "Video duration is " + durationValue);
- assertTrue(durationValue > 0);
- return durationValue;
- }
-
- private void recordVideo(int ms) throws Exception {
- getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(ms);
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- // If recording is in progress, stop it. Run these atomically in
- // UI thread.
- CameraActivity activity = getActivity();
- if (activity.isRecording()) {
- activity.findViewById(R.id.shutter_button).performClick();
- }
- }
- });
- }
-
- private void recordVideo() throws Exception {
- recordVideo(2000);
- }
-
- private void pressDone() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_done).performClick();
- }
- });
- }
-
- private void pressCancel() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_cancel).performClick();
- }
- });
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/CameraLatency.java b/tests/src/com/android/gallery3d/stress/CameraLatency.java
deleted file mode 100755
index 2cdc2f1b7..000000000
--- a/tests/src/com/android/gallery3d/stress/CameraLatency.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2009 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.gallery3d.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Instrumentation;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- */
-
-public class CameraLatency extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private String TAG = "CameraLatency";
- private static final int TOTAL_NUMBER_OF_IMAGECAPTURE = 20;
- private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 4000;
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
-
- private long mTotalAutoFocusTime;
- private long mTotalShutterLag;
- private long mTotalShutterToPictureDisplayedTime;
- private long mTotalPictureDisplayedToJpegCallbackTime;
- private long mTotalJpegCallbackFinishTime;
- private long mAvgAutoFocusTime;
- private long mAvgShutterLag = mTotalShutterLag;
- private long mAvgShutterToPictureDisplayedTime;
- private long mAvgPictureDisplayedToJpegCallbackTime;
- private long mAvgJpegCallbackFinishTime;
-
- public CameraLatency() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- public void testImageCapture() {
- Log.v(TAG, "start testImageCapture test");
- Instrumentation inst = getInstrumentation();
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
- try {
- for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) {
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- //skip the first measurement
- if (i != 0) {
- CameraActivity c = getActivity();
-
- // if any of the latency var accessor methods return -1 then the
- // camera is set to a different module other than PhotoModule so
- // skip the shot and try again
- if (c.getAutoFocusTime() != -1) {
- mTotalAutoFocusTime += c.getAutoFocusTime();
- mTotalShutterLag += c.getShutterLag();
- mTotalShutterToPictureDisplayedTime +=
- c.getShutterToPictureDisplayedTime();
- mTotalPictureDisplayedToJpegCallbackTime +=
- c.getPictureDisplayedToJpegCallbackTime();
- mTotalJpegCallbackFinishTime += c.getJpegCallbackFinishTime();
- }
- else {
- i--;
- continue;
- }
- }
- }
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- }
- //ToDO: yslau
- //1) Need to get the baseline from the cupcake so that we can add the
- //failure condition of the camera latency.
- //2) Only count those number with succesful capture. Set the timer to invalid
- //before capture and ignore them if the value is invalid
- int numberofRun = TOTAL_NUMBER_OF_IMAGECAPTURE - 1;
- mAvgAutoFocusTime = mTotalAutoFocusTime / numberofRun;
- mAvgShutterLag = mTotalShutterLag / numberofRun;
- mAvgShutterToPictureDisplayedTime =
- mTotalShutterToPictureDisplayedTime / numberofRun;
- mAvgPictureDisplayedToJpegCallbackTime =
- mTotalPictureDisplayedToJpegCallbackTime / numberofRun;
- mAvgJpegCallbackFinishTime =
- mTotalJpegCallbackFinishTime / numberofRun;
-
- try {
- FileWriter fstream = null;
- fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- BufferedWriter out = new BufferedWriter(fstream);
- out.write("Camera Latency : \n");
- out.write("Number of loop: " + TOTAL_NUMBER_OF_IMAGECAPTURE + "\n");
- out.write("Avg AutoFocus = " + mAvgAutoFocusTime + "\n");
- out.write("Avg mShutterLag = " + mAvgShutterLag + "\n");
- out.write("Avg mShutterToPictureDisplayedTime = "
- + mAvgShutterToPictureDisplayedTime + "\n");
- out.write("Avg mPictureDisplayedToJpegCallbackTime = "
- + mAvgPictureDisplayedToJpegCallbackTime + "\n");
- out.write("Avg mJpegCallbackFinishTime = " +
- mAvgJpegCallbackFinishTime + "\n");
- out.close();
- fstream.close();
- } catch (Exception e) {
- fail("Camera Latency write output to file");
- }
- Log.v(TAG, "The Image capture wait time = " +
- WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- Log.v(TAG, "Avg AutoFocus = " + mAvgAutoFocusTime);
- Log.v(TAG, "Avg mShutterLag = " + mAvgShutterLag);
- Log.v(TAG, "Avg mShutterToPictureDisplayedTime = "
- + mAvgShutterToPictureDisplayedTime);
- Log.v(TAG, "Avg mPictureDisplayedToJpegCallbackTime = "
- + mAvgPictureDisplayedToJpegCallbackTime);
- Log.v(TAG, "Avg mJpegCallbackFinishTime = " + mAvgJpegCallbackFinishTime);
- }
-}
-
diff --git a/tests/src/com/android/gallery3d/stress/CameraStartUp.java b/tests/src/com/android/gallery3d/stress/CameraStartUp.java
deleted file mode 100644
index 3ca163227..000000000
--- a/tests/src/com/android/gallery3d/stress/CameraStartUp.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2009 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.gallery3d.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-
-/**
- * Test cases to measure the camera and video recorder startup time.
- */
-public class CameraStartUp extends InstrumentationTestCase {
-
- private static final int TOTAL_NUMBER_OF_STARTUP = 20;
-
- private String TAG = "CameraStartUp";
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private static int WAIT_TIME_FOR_PREVIEW = 1500; //1.5 second
-
- private long launchCamera() {
- long startupTime = 0;
- try {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- long beforeStart = System.currentTimeMillis();
- Instrumentation inst = getInstrumentation();
- Activity cameraActivity = inst.startActivitySync(intent);
- long cameraStarted = System.currentTimeMillis();
- Thread.sleep(WAIT_TIME_FOR_PREVIEW);
- cameraActivity.finish();
- startupTime = cameraStarted - beforeStart;
- Thread.sleep(1000);
- Log.v(TAG, "camera startup time: " + startupTime);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- fail("Fails to get the output file");
- }
- return startupTime;
- }
-
- private long launchVideo() {
- long startupTime = 0;
-
- try {
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- long beforeStart = System.currentTimeMillis();
- Instrumentation inst = getInstrumentation();
- Activity recorderActivity = inst.startActivitySync(intent);
- long cameraStarted = System.currentTimeMillis();
- recorderActivity.finish();
- startupTime = cameraStarted - beforeStart;
- Log.v(TAG, "Video Startup Time = " + startupTime);
- // wait for 1s to make sure it reach a clean stage
- Thread.sleep(WAIT_TIME_FOR_PREVIEW);
- Log.v(TAG, "video startup time: " + startupTime);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- fail("Fails to launch video output file");
- }
- return startupTime;
- }
-
- private void writeToOutputFile(long totalStartupTime,
- String individualStartupTime, boolean firstStartUp, String Type) throws Exception {
- // TODO (yslau) : Need to integrate the output data with central
- // dashboard
- try {
- FileWriter fstream = null;
- fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- BufferedWriter out = new BufferedWriter(fstream);
- if (firstStartUp) {
- out.write("First " + Type + " Startup: " + totalStartupTime + "\n");
- } else {
- long averageStartupTime = totalStartupTime / (TOTAL_NUMBER_OF_STARTUP -1);
- out.write(Type + "startup time: " + "\n");
- out.write("Number of loop: " + (TOTAL_NUMBER_OF_STARTUP -1) + "\n");
- out.write(individualStartupTime + "\n\n");
- out.write(Type + " average startup time: " + averageStartupTime + " ms\n\n");
- }
- out.close();
- fstream.close();
- } catch (Exception e) {
- fail("Camera write output to file");
- }
- }
-
- public void testLaunchVideo() throws Exception {
- String individualStartupTime;
- individualStartupTime = "Individual Video Startup Time = ";
- long totalStartupTime = 0;
- long startupTime = 0;
- for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) {
- if (i == 0) {
- // Capture the first startup time individually
- long firstStartUpTime = launchVideo();
- writeToOutputFile(firstStartUpTime, "na", true, "Video");
- } else {
- startupTime = launchVideo();
- totalStartupTime += startupTime;
- individualStartupTime += startupTime + " ,";
- }
- }
- Log.v(TAG, "totalStartupTime =" + totalStartupTime);
- writeToOutputFile(totalStartupTime, individualStartupTime, false, "Video");
- }
-
- public void testLaunchCamera() throws Exception {
- String individualStartupTime;
- individualStartupTime = "Individual Camera Startup Time = ";
- long totalStartupTime = 0;
- long startupTime = 0;
- for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) {
- if (i == 0) {
- // Capture the first startup time individually
- long firstStartUpTime = launchCamera();
- writeToOutputFile(firstStartUpTime, "na", true, "Camera");
- } else {
- startupTime = launchCamera();
- totalStartupTime += startupTime;
- individualStartupTime += startupTime + " ,";
- }
- }
- Log.v(TAG, "totalStartupTime =" + totalStartupTime);
- writeToOutputFile(totalStartupTime,
- individualStartupTime, false, "Camera");
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java b/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java
deleted file mode 100755
index d3fb10dad..000000000
--- a/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 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.gallery3d.stress;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import junit.framework.TestSuite;
-
-public class CameraStressTestRunner extends InstrumentationTestRunner {
-
- // Default recorder settings
- public static int mVideoDuration = 20000; // set default to 20 seconds
- public static int mVideoIterations = 1; // set default to 1 video
- public static int mImageIterations = 10; // set default to 10 images
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(ImageCapture.class);
- suite.addTestSuite(VideoCapture.class);
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- return CameraStressTestRunner.class.getClassLoader();
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- String video_iterations = (String) icicle.get("video_iterations");
- String image_iterations = (String) icicle.get("image_iterations");
- String video_duration = (String) icicle.get("video_duration");
-
- if ( video_iterations != null ) {
- mVideoIterations = Integer.parseInt(video_iterations);
- }
- if ( image_iterations != null) {
- mImageIterations = Integer.parseInt(image_iterations);
- }
- if ( video_duration != null) {
- mVideoDuration = Integer.parseInt(video_duration);
- }
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/ImageCapture.java b/tests/src/com/android/gallery3d/stress/ImageCapture.java
deleted file mode 100755
index 5a9ee6a6c..000000000
--- a/tests/src/com/android/gallery3d/stress/ImageCapture.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2009 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.gallery3d.stress;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.stress.CameraStressTestRunner;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.app.Activity;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.ImageCapture \
- * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner
- *
- */
-
-public class ImageCapture extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private String TAG = "ImageCapture";
- private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 1500; //1.5 sedconds
- private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //3 seconds
-
- private TestUtil testUtil = new TestUtil();
-
- // Private intent extras.
- private final static String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
-
- public ImageCapture() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- testUtil.prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- testUtil.closeOutputFile();
- super.tearDown();
- }
-
- public void captureImages(String reportTag, Instrumentation inst) {
- int total_num_of_images = CameraStressTestRunner.mImageIterations;
- Log.v(TAG, "no of images = " + total_num_of_images);
-
- //TODO(yslau): Need to integrate the outoput with the central dashboard,
- //write to a txt file as a temp solution
- boolean memoryResult = false;
- KeyEvent focusEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS);
-
- try {
- testUtil.writeReportHeader(reportTag, total_num_of_images);
- for (int i = 0; i < total_num_of_images; i++) {
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeySync(focusEvent);
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- testUtil.writeResult(i);
- }
- } catch (Exception e) {
- Log.v(TAG, "Got exception: " + e.toString());
- assertTrue("testImageCapture", false);
- }
- }
-
- public void testBackImageCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent();
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureImages("Back Camera Image Capture\n", inst);
- act.finish();
- }
-
- public void testFrontImageCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent();
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureImages("Front Camera Image Capture\n", inst);
- act.finish();
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/ShotToShotLatency.java b/tests/src/com/android/gallery3d/stress/ShotToShotLatency.java
deleted file mode 100644
index 0d5749e7d..000000000
--- a/tests/src/com/android/gallery3d/stress/ShotToShotLatency.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2012 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.gallery3d.stress;
-
-import android.app.Instrumentation;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-import com.android.camera.CameraActivity;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * Junit / Instrumentation test case for measuring camera shot to shot latency
- */
-public class ShotToShotLatency extends ActivityInstrumentationTestCase2<CameraActivity> {
- private String TAG = "ShotToShotLatency";
- private static final int TOTAL_NUMBER_OF_SNAPSHOTS = 250;
- private static final long SNAPSHOT_WAIT = 1000;
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private static final String CAMERA_IMAGE_DIRECTORY =
- Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/";
-
- public ShotToShotLatency() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- private void cleanupLatencyImages() {
- try {
- File sdcard = new File(CAMERA_IMAGE_DIRECTORY);
- File[] pics = null;
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".jpg");
- }
- };
- pics = sdcard.listFiles(filter);
- for (File f : pics) {
- f.delete();
- }
- } catch (SecurityException e) {
- Log.e(TAG, "Security manager access violation: " + e.toString());
- }
- }
-
- private void sleep(long time) {
- try {
- Thread.sleep(time);
- } catch (InterruptedException e) {
- Log.e(TAG, "Sleep InterruptedException " + e.toString());
- }
- }
-
- public void testShotToShotLatency() {
- long sigmaOfDiffFromMeanSquared = 0;
- double mean = 0;
- double standardDeviation = 0;
- ArrayList<Long> captureTimes = new ArrayList<Long>();
- ArrayList<Long> latencyTimes = new ArrayList<Long>();
-
- Log.v(TAG, "start testShotToShotLatency test");
- Instrumentation inst = getInstrumentation();
-
- // Generate data points
- for (int i = 0; i < TOTAL_NUMBER_OF_SNAPSHOTS; i++) {
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- sleep(SNAPSHOT_WAIT);
- CameraActivity c = getActivity();
- if (c.getCaptureStartTime() > 0) {
- captureTimes.add(c.getCaptureStartTime());
- }
- }
-
- // Calculate latencies
- for (int j = 1; j < captureTimes.size(); j++) {
- latencyTimes.add(captureTimes.get(j) - captureTimes.get(j - 1));
- }
-
- // Crunch numbers
- for (long dataPoint : latencyTimes) {
- mean += (double) dataPoint;
- }
- mean /= latencyTimes.size();
-
- for (long dataPoint : latencyTimes) {
- sigmaOfDiffFromMeanSquared += (dataPoint - mean) * (dataPoint - mean);
- }
- standardDeviation = Math.sqrt(sigmaOfDiffFromMeanSquared / latencyTimes.size());
-
- // Report statistics
- File outFile = new File(CAMERA_TEST_OUTPUT_FILE);
- BufferedWriter output = null;
- try {
- output = new BufferedWriter(new FileWriter(outFile, true));
- output.write("Shot to shot latency - mean: " + mean + "\n");
- output.write("Shot to shot latency - standard deviation: " + standardDeviation + "\n");
- cleanupLatencyImages();
- } catch (IOException e) {
- Log.e(TAG, "testShotToShotLatency IOException writing to log " + e.toString());
- } finally {
- try {
- if (output != null) {
- output.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "Error closing file: " + e.toString());
- }
- }
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/SwitchPreview.java b/tests/src/com/android/gallery3d/stress/SwitchPreview.java
deleted file mode 100755
index 3545f3b3e..000000000
--- a/tests/src/com/android/gallery3d/stress/SwitchPreview.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2009 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.gallery3d.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.SwitchPreview \
- * -w com.android.camera.tests/com.android.camera.stress.CameraStressTestRunner
- *
- */
-public class SwitchPreview extends ActivityInstrumentationTestCase2 <CameraActivity>{
- private String TAG = "SwitchPreview";
- private static final int TOTAL_NUMBER_OF_SWITCHING = 200;
- private static final long WAIT_FOR_PREVIEW = 4000;
-
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private BufferedWriter mOut;
- private FileWriter mfstream;
-
- public SwitchPreview() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- getActivity().finish();
- closeOutputFile();
- super.tearDown();
- }
-
- private void prepareOutputFile(){
- try{
- mfstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- mOut = new BufferedWriter(mfstream);
- } catch (Exception e){
- assertTrue("Camera Switch Mode", false);
- }
- }
-
- private void closeOutputFile() {
- try {
- mOut.write("\n");
- mOut.close();
- mfstream.close();
- } catch (Exception e) {
- assertTrue("CameraSwitchMode close output", false);
- }
- }
-
- public void testSwitchMode() {
- //Switching the video and the video recorder mode
- Instrumentation inst = getInstrumentation();
- try{
- mOut.write("Camera Switch Mode:\n");
- mOut.write("No of loops :" + TOTAL_NUMBER_OF_SWITCHING + "\n");
- mOut.write("loop: ");
- for (int i=0; i< TOTAL_NUMBER_OF_SWITCHING; i++) {
- Thread.sleep(WAIT_FOR_PREVIEW);
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- getActivity().startActivity(intent);
- Thread.sleep(WAIT_FOR_PREVIEW);
- intent = new Intent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- getActivity().startActivity(intent);
- mOut.write(" ," + i);
- mOut.flush();
- }
- } catch (Exception e){
- Log.v(TAG, "Got exception", e);
- }
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/TestUtil.java b/tests/src/com/android/gallery3d/stress/TestUtil.java
deleted file mode 100644
index 56ab715f7..000000000
--- a/tests/src/com/android/gallery3d/stress/TestUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.gallery3d.stress;
-
-import android.os.Environment;
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-
-
-/**
- * Collection of utility functions used for the test.
- */
-public class TestUtil {
- public BufferedWriter mOut;
- public FileWriter mfstream;
-
- public TestUtil() {
- }
-
- public void prepareOutputFile() throws Exception {
- String camera_test_output_file =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- mfstream = new FileWriter(camera_test_output_file, true);
- mOut = new BufferedWriter(mfstream);
- }
-
- public void closeOutputFile() throws Exception {
- mOut.write("\n");
- mOut.close();
- mfstream.close();
- }
-
- public void writeReportHeader(String reportTag, int iteration) throws Exception {
- mOut.write(reportTag);
- mOut.write("No of loops :" + iteration + "\n");
- mOut.write("loop: ");
- }
-
- public void writeResult(int iteration) throws Exception {
- mOut.write(" ," + iteration);
- mOut.flush();
- }
-}
diff --git a/tests/src/com/android/gallery3d/stress/VideoCapture.java b/tests/src/com/android/gallery3d/stress/VideoCapture.java
deleted file mode 100755
index 8211badf7..000000000
--- a/tests/src/com/android/gallery3d/stress/VideoCapture.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2010 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.gallery3d.stress;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.stress.TestUtil;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-
-import com.android.gallery3d.stress.CameraStressTestRunner;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.VideoCapture \
- * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner
- *
- */
-
-public class VideoCapture extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private static final long WAIT_FOR_PREVIEW = 1500; //1.5 seconds
- private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //2 seconds
-
- // Private intent extras which control the camera facing.
- private final static String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
-
- private TestUtil testUtil = new TestUtil();
-
- public VideoCapture() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- testUtil.prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- testUtil.closeOutputFile();
- super.tearDown();
- }
-
- public void captureVideos(String reportTag, Instrumentation inst) throws Exception{
- boolean memoryResult = false;
- int total_num_of_videos = CameraStressTestRunner.mVideoIterations;
- int video_duration = CameraStressTestRunner.mVideoDuration;
- testUtil.writeReportHeader(reportTag, total_num_of_videos);
-
- for (int i = 0; i < total_num_of_videos; i++) {
- Thread.sleep(WAIT_FOR_PREVIEW);
- // record a video
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(video_duration);
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- testUtil.writeResult(i);
- }
- }
-
- public void testBackVideoCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureVideos("Back Camera Video Capture\n", inst);
- act.finish();
- }
-
- public void testFrontVideoCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureVideos("Front Camera Video Capture\n", inst);
- act.finish();
- }
-}
diff --git a/tests/src/com/android/gallery3d/unittest/CameraUnitTest.java b/tests/src/com/android/gallery3d/unittest/CameraUnitTest.java
deleted file mode 100644
index b8fb05fc2..000000000
--- a/tests/src/com/android/gallery3d/unittest/CameraUnitTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2010 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.gallery3d.unittest;
-
-import com.android.camera.Util;
-
-import android.graphics.Matrix;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-@SmallTest
-public class CameraUnitTest extends TestCase {
- public void testRoundOrientation() {
- int h = Util.ORIENTATION_HYSTERESIS;
- assertEquals(0, Util.roundOrientation(0, 0));
- assertEquals(0, Util.roundOrientation(359, 0));
- assertEquals(0, Util.roundOrientation(0 + 44 + h, 0));
- assertEquals(90, Util.roundOrientation(0 + 45 + h, 0));
- assertEquals(0, Util.roundOrientation(360 - 44 - h, 0));
- assertEquals(270, Util.roundOrientation(360 - 45 - h, 0));
-
- assertEquals(90, Util.roundOrientation(90, 90));
- assertEquals(90, Util.roundOrientation(90 + 44 + h, 90));
- assertEquals(180, Util.roundOrientation(90 + 45 + h, 90));
- assertEquals(90, Util.roundOrientation(90 - 44 - h, 90));
- assertEquals(0, Util.roundOrientation(90 - 45 - h, 90));
-
- assertEquals(180, Util.roundOrientation(180, 180));
- assertEquals(180, Util.roundOrientation(180 + 44 + h, 180));
- assertEquals(270, Util.roundOrientation(180 + 45 + h, 180));
- assertEquals(180, Util.roundOrientation(180 - 44 - h, 180));
- assertEquals(90, Util.roundOrientation(180 - 45 - h, 180));
-
- assertEquals(270, Util.roundOrientation(270, 270));
- assertEquals(270, Util.roundOrientation(270 + 44 + h, 270));
- assertEquals(0, Util.roundOrientation(270 + 45 + h, 270));
- assertEquals(270, Util.roundOrientation(270 - 44 - h, 270));
- assertEquals(180, Util.roundOrientation(270 - 45 - h, 270));
-
- assertEquals(90, Util.roundOrientation(90, 0));
- assertEquals(180, Util.roundOrientation(180, 0));
- assertEquals(270, Util.roundOrientation(270, 0));
-
- assertEquals(0, Util.roundOrientation(0, 90));
- assertEquals(180, Util.roundOrientation(180, 90));
- assertEquals(270, Util.roundOrientation(270, 90));
-
- assertEquals(0, Util.roundOrientation(0, 180));
- assertEquals(90, Util.roundOrientation(90, 180));
- assertEquals(270, Util.roundOrientation(270, 180));
-
- assertEquals(0, Util.roundOrientation(0, 270));
- assertEquals(90, Util.roundOrientation(90, 270));
- assertEquals(180, Util.roundOrientation(180, 270));
- }
-
- public void testPrepareMatrix() {
- Matrix matrix = new Matrix();
- float[] points;
- int[] expected;
-
- Util.prepareMatrix(matrix, false, 0, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {0, 0, 400, 240, 800, 480, 400, 480, 100, 300};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, false, 90, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {800, 0, 400, 240, 0, 480, 0, 240, 300, 60};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, false, 180, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {800, 480, 400, 240, 0, 0, 400, 0, 700, 180};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, true, 180, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {0, 480, 400, 240, 800, 0, 400, 0, 100, 180};
- matrix.mapPoints(points);
- assertEquals(expected, points);
- }
-
- private void assertEquals(int expected[], float[] actual) {
- for (int i = 0; i < expected.length; i++) {
- assertEquals("Array index " + i + " mismatch", expected[i], Math.round(actual[i]));
- }
- }
-}
diff --git a/tests_camera/Android.mk b/tests_camera/Android.mk
deleted file mode 100644
index f39533a71..000000000
--- a/tests_camera/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SDK_VERSION := 16
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CameraTests
-
-LOCAL_INSTRUMENTATION_FOR := Gallery2
-
-include $(BUILD_PACKAGE)
diff --git a/tests_camera/AndroidManifest.xml b/tests_camera/AndroidManifest.xml
deleted file mode 100644
index 164bbd55c..000000000
--- a/tests_camera/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.camera.tests">
-
- <uses-permission android:name="android.permission.INJECT_EVENTS" />
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="com.android.camera.CameraLaunchPerformance"
- android:targetPackage="com.android.camera"
- android:label="Camera Launch Performance">
- </instrumentation>
-
- <instrumentation android:name="com.android.camera.stress.CameraStressTestRunner"
- android:targetPackage="com.android.camera"
- android:label="Camera stress test runner">
- </instrumentation>
-
- <instrumentation android:name="com.android.camera.CameraTestRunner"
- android:targetPackage="com.android.camera"
- android:label="Camera continuous test runner">
- </instrumentation>
-
- <instrumentation android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.camera"
- android:label="Tests for Camera application."/>
-</manifest>
diff --git a/tests_camera/src/com/android/camera/CameraLaunchPerformance.java b/tests_camera/src/com/android/camera/CameraLaunchPerformance.java
deleted file mode 100644
index fe2b7761a..000000000
--- a/tests_camera/src/com/android/camera/CameraLaunchPerformance.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.test.LaunchPerformanceBase;
-
-/**
- * Instrumentation class for Camera launch performance testing.
- */
-public class CameraLaunchPerformance extends LaunchPerformanceBase {
- @SuppressWarnings("unused")
- private static final String TAG = "CameraLaunchPerformance";
-
- @Override
- public void onCreate(Bundle arguments) {
- super.onCreate(arguments);
- mIntent.setClassName(getTargetContext(),
- "com.android.camera.CameraActivity");
- start();
- }
-
- /**
- * Calls LaunchApp and finish.
- */
- @Override
- public void onStart() {
- super.onStart();
- LaunchApp();
- finish(Activity.RESULT_OK, mResults);
- }
-}
diff --git a/tests_camera/src/com/android/camera/CameraTestRunner.java b/tests_camera/src/com/android/camera/CameraTestRunner.java
deleted file mode 100755
index 96c48a4c8..000000000
--- a/tests_camera/src/com/android/camera/CameraTestRunner.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 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;
-
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-
-import com.android.camera.activity.CameraActivityTest;
-import com.android.camera.functional.CameraTest;
-import com.android.camera.functional.ImageCaptureIntentTest;
-import com.android.camera.functional.VideoCaptureIntentTest;
-import com.android.camera.unittest.CameraUnitTest;
-
-import junit.framework.TestSuite;
-
-
-public class CameraTestRunner extends InstrumentationTestRunner {
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(CameraActivityTest.class);
- suite.addTestSuite(CameraTest.class);
- suite.addTestSuite(ImageCaptureIntentTest.class);
- suite.addTestSuite(VideoCaptureIntentTest.class);
- suite.addTestSuite(CameraUnitTest.class);
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- return CameraTestRunner.class.getClassLoader();
- }
-}
diff --git a/tests_camera/src/com/android/camera/StressTests.java b/tests_camera/src/com/android/camera/StressTests.java
deleted file mode 100755
index 7ed8317cc..000000000
--- a/tests_camera/src/com/android/camera/StressTests.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 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;
-
-import com.android.camera.stress.ImageCapture;
-import com.android.camera.stress.SwitchPreview;
-import com.android.camera.stress.CameraLatency;
-import com.android.camera.stress.CameraStartUp;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Instrumentation Test Runner for all Camera tests.
- *
- * Running all tests:
- *
- * adb shell am instrument \
- * -e class com.android.camera.StressTests \
- * -w com.android.camera.tests/com.android.camera.stress.CameraStressTestRunner
- */
-
-public class StressTests extends TestSuite {
- public static Test suite() {
- TestSuite result = new TestSuite();
- result.addTestSuite(SwitchPreview.class);
- result.addTestSuite(ImageCapture.class);
- result.addTestSuite(CameraLatency.class);
- result.addTestSuite(CameraStartUp.class);
- return result;
- }
-}
diff --git a/tests_camera/src/com/android/camera/UnitTests.java b/tests_camera/src/com/android/camera/UnitTests.java
deleted file mode 100644
index e56a907f0..000000000
--- a/tests_camera/src/com/android/camera/UnitTests.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import android.test.suitebuilder.UnitTestSuiteBuilder;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * TestSuite for all Camera unit tests.
- */
-public class UnitTests extends TestSuite {
-
- public static Test suite() {
- return new UnitTestSuiteBuilder(UnitTests.class)
- .includePackages("com.android.camera.unittest")
- .named("Camera Unit Tests")
- .build();
- }
-}
diff --git a/tests_camera/src/com/android/camera/activity/CameraActivityTest.java b/tests_camera/src/com/android/camera/activity/CameraActivityTest.java
deleted file mode 100644
index eb027e9d3..000000000
--- a/tests_camera/src/com/android/camera/activity/CameraActivityTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 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.activity;
-
-import android.hardware.Camera.Parameters;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.camera.CameraActivity;
-import com.android.camera.CameraHolder;
-import com.android.gallery3d.R;
-
-import static com.google.testing.littlemock.LittleMock.doReturn;
-
-public class CameraActivityTest extends CameraTestCase <CameraActivity> {
- public CameraActivityTest() {
- super(CameraActivity.class);
- }
-
- @LargeTest
- public void testFailToConnect() throws Exception {
- super.internalTestFailToConnect();
- }
-
- @LargeTest
- public void testTakePicture() throws Exception {
- CameraHolder.injectMockCamera(mCameraInfo, mOneMockCamera);
-
- getActivity();
- getInstrumentation().waitForIdleSync();
-
- // Press shutter button to take a picture.
- performClick(R.id.shutter_button);
- getInstrumentation().waitForIdleSync();
-
- // Force the activity to finish.
- getActivity().finish();
- getInstrumentation().waitForIdleSync();
- }
-}
diff --git a/tests_camera/src/com/android/camera/activity/CameraTestCase.java b/tests_camera/src/com/android/camera/activity/CameraTestCase.java
deleted file mode 100644
index 27be3c7d3..000000000
--- a/tests_camera/src/com/android/camera/activity/CameraTestCase.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2012 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.activity;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.hardware.Camera;
-import android.hardware.Camera.AutoFocusCallback;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.PictureCallback;
-import android.hardware.Camera.ShutterCallback;
-import android.test.ActivityInstrumentationTestCase2;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.camera.CameraHolder;
-import com.android.camera.CameraManager.CameraProxy;
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-
-import static com.google.testing.littlemock.LittleMock.mock;
-import static com.google.testing.littlemock.LittleMock.doAnswer;
-import static com.google.testing.littlemock.LittleMock.doReturn;
-import static com.google.testing.littlemock.LittleMock.anyObject;
-import com.google.testing.littlemock.AppDataDirGuesser;
-import com.google.testing.littlemock.ArgumentCaptor;
-import com.google.testing.littlemock.Captor;
-import com.google.testing.littlemock.LittleMock;
-import com.google.testing.littlemock.Mock;
-
-import java.io.File;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-
-
-public class CameraTestCase<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
- protected CameraInfo mCameraInfo[];
- protected CameraProxy mMockCamera[];
- protected CameraInfo mOneCameraInfo[];
- protected CameraProxy mOneMockCamera[];
- private static Parameters mParameters;
- private byte[] mBlankJpeg;
- @Mock private CameraProxy mMockBackCamera;
- @Mock private CameraProxy mMockFrontCamera;
- @Captor private ArgumentCaptor<ShutterCallback> mShutterCallback;
- @Captor private ArgumentCaptor<PictureCallback> mRawPictureCallback;
- @Captor private ArgumentCaptor<PictureCallback> mJpegPictureCallback;
- @Captor private ArgumentCaptor<AutoFocusCallback> mAutoFocusCallback;
- Callable<Object> mAutoFocusCallable = new AutoFocusCallable();
- Callable<Object> mTakePictureCallable = new TakePictureCallable();
-
- private class TakePictureCallable implements Callable<Object> {
- @Override
- public Object call() throws Exception {
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- readBlankJpeg();
- Camera camera = mOneMockCamera[0].getCamera();
- mShutterCallback.getValue().onShutter();
- mRawPictureCallback.getValue().onPictureTaken(null, camera);
- mJpegPictureCallback.getValue().onPictureTaken(mBlankJpeg, camera);
- }
- };
- // Probably need some delay. Make sure shutter callback is called
- // after onShutterButtonFocus(false).
- getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50);
- return null;
- }
- }
-
- private class AutoFocusCallable implements Callable<Object> {
- @Override
- public Object call() throws Exception {
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- Camera camera = mOneMockCamera[0].getCamera();
- mAutoFocusCallback.getValue().onAutoFocus(true, camera);
- }
- };
- // Need some delay. Otherwise, focus callback will be run before
- // onShutterButtonClick
- getActivity().findViewById(R.id.gl_root_view).postDelayed(runnable, 50);
- return null;
- }
- }
-
- public CameraTestCase(Class<T> activityClass) {
- super(activityClass);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- AppDataDirGuesser.setInstance(new AppDataDirGuesser() {
- @Override
- public File guessSuitableDirectoryForGeneratedClasses() {
- return getInstrumentation().getTargetContext().getCacheDir();
- }
- });
- AppDataDirGuesser.getsInstance().guessSuitableDirectoryForGeneratedClasses();
- LittleMock.initMocks(this);
- mCameraInfo = new CameraInfo[2];
- mCameraInfo[0] = new CameraInfo();
- mCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK;
- mCameraInfo[1] = new CameraInfo();
- mCameraInfo[1].facing = CameraInfo.CAMERA_FACING_FRONT;
- mMockCamera = new CameraProxy[2];
- mMockCamera[0] = mMockBackCamera;
- mMockCamera[1] = mMockFrontCamera;
- doReturn(getParameters()).when(mMockCamera[0]).getParameters();
- doReturn(getParameters()).when(mMockCamera[1]).getParameters();
-
- mOneCameraInfo = new CameraInfo[1];
- mOneCameraInfo[0] = new CameraInfo();
- mOneCameraInfo[0].facing = CameraInfo.CAMERA_FACING_BACK;
- mOneMockCamera = new CameraProxy[1];
- mOneMockCamera[0] = mMockBackCamera;
- doReturn(getParameters()).when(mOneMockCamera[0]).getParameters();
-
- // Mock takePicture call.
- doAnswer(mTakePictureCallable).when(mMockBackCamera).takePicture(
- mShutterCallback.capture(), mRawPictureCallback.capture(),
- (PictureCallback) anyObject(), mJpegPictureCallback.capture());
-
- // Mock autoFocus call.
- doAnswer(mAutoFocusCallable).when(mMockBackCamera).autoFocus(
- mAutoFocusCallback.capture());
- }
-
- private void readBlankJpeg() {
- InputStream ins = getActivity().getResources().openRawResource(R.raw.blank);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- int size = 0;
-
- // Read the entire resource into a local byte buffer.
- byte[] buffer = new byte[1024];
- try {
- while((size = ins.read(buffer, 0, 1024)) >= 0){
- outputStream.write(buffer, 0, size);
- }
- } catch (IOException e) {
- // ignore
- } finally {
- Util.closeSilently(ins);
- }
- mBlankJpeg = outputStream.toByteArray();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- CameraHolder.injectMockCamera(null, null);
- }
-
- protected void internalTestFailToConnect() throws Exception {
- CameraHolder.injectMockCamera(mCameraInfo, null);
-
- getActivity();
- Instrumentation inst = getInstrumentation();
- inst.waitForIdleSync();
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER); // close dialog
- }
-
- protected void performClick(final int id) {
- Activity activity = getActivity();
- getInstrumentation().waitForIdleSync();
- assertNotNull(activity.findViewById(id));
- Instrumentation inst = getInstrumentation();
- inst.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- View v = getActivity().findViewById(id);
- float x = (v.getLeft() + v.getRight()) / 2;
- float y = (v.getTop() + v.getBottom()) / 2;
- MotionEvent down = MotionEvent.obtain(0, 0,
- MotionEvent.ACTION_DOWN, x, y, 0, 0, 0, 0, 0, 0, 0);
- MotionEvent up = MotionEvent.obtain(0, 0,
- MotionEvent.ACTION_UP, x, y, 0, 0, 0, 0, 0, 0, 0);
- View parent = (View) v.getParent();
- parent.dispatchTouchEvent(down);
- parent.dispatchTouchEvent(up);
- }
- });
- inst.waitForIdleSync();
- }
-
- protected void assertViewNotExist(int id) {
- Activity activity = getActivity();
- getInstrumentation().waitForIdleSync();
- assertNull(activity.findViewById(id));
- }
-
- protected void assertViewNotVisible(int id) {
- Activity activity = getActivity();
- getInstrumentation().waitForIdleSync();
- View view = activity.findViewById(id);
- assertTrue(view.getVisibility() != View.VISIBLE);
- }
-
- protected static Parameters getParameters() {
- synchronized (CameraTestCase.class) {
- if (mParameters == null) {
- mParameters = android.hardware.Camera.getEmptyParameters();
- mParameters.unflatten("preview-format-values=yuv420sp,yuv420p,yuv422i-yuyv,yuv420p;" +
- "preview-format=yuv420sp;" +
- "preview-size-values=800x480;preview-size=800x480;" +
- "picture-size-values=320x240;picture-size=320x240;" +
- "jpeg-thumbnail-size-values=320x240,0x0;jpeg-thumbnail-width=320;jpeg-thumbnail-height=240;" +
- "jpeg-thumbnail-quality=60;jpeg-quality=95;" +
- "preview-frame-rate-values=30,15;preview-frame-rate=30;" +
- "focus-mode-values=continuous-video,auto,macro,infinity,continuous-picture;focus-mode=auto;" +
- "preview-fps-range-values=(15000,30000);preview-fps-range=15000,30000;" +
- "scene-mode-values=auto,action,night;scene-mode=auto;" +
- "flash-mode-values=off,on,auto,torch;flash-mode=off;" +
- "whitebalance-values=auto,daylight,fluorescent,incandescent;whitebalance=auto;" +
- "effect-values=none,mono,sepia;effect=none;" +
- "zoom-supported=true;zoom-ratios=100,200,400;max-zoom=2;" +
- "picture-format-values=jpeg;picture-format=jpeg;" +
- "min-exposure-compensation=-30;max-exposure-compensation=30;" +
- "exposure-compensation=0;exposure-compensation-step=0.1;" +
- "horizontal-view-angle=40;vertical-view-angle=40;");
- }
- }
- return mParameters;
- }
-}
diff --git a/tests_camera/src/com/android/camera/functional/CameraTest.java b/tests_camera/src/com/android/camera/functional/CameraTest.java
deleted file mode 100644
index 3fdebc030..000000000
--- a/tests_camera/src/com/android/camera/functional/CameraTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 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.functional;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Process;
-import android.provider.MediaStore;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-public class CameraTest extends InstrumentationTestCase {
- @LargeTest
- public void testVideoCaptureIntentFdLeak() throws Exception {
- Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse("file://"
- + Environment.getExternalStorageDirectory().toString()
- + "test_fd_leak.3gp"));
- getInstrumentation().startActivitySync(intent).finish();
- // Test if the fd is closed.
- for (File f: new File("/proc/" + Process.myPid() + "/fd").listFiles()) {
- assertEquals(-1, f.getCanonicalPath().indexOf("test_fd_leak.3gp"));
- }
- }
-
- @LargeTest
- public void testActivityLeak() throws Exception {
- checkActivityLeak(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
- checkActivityLeak(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- }
-
- private void checkActivityLeak(String action) throws Exception {
- final int TEST_COUNT = 5;
- Intent intent = new Intent(action);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- ArrayList<WeakReference<Activity>> refs =
- new ArrayList<WeakReference<Activity>>();
- for (int i = 0; i < TEST_COUNT; i++) {
- Activity activity = getInstrumentation().startActivitySync(intent);
- refs.add(new WeakReference<Activity>(activity));
- activity.finish();
- getInstrumentation().waitForIdleSync();
- activity = null;
- }
- Runtime.getRuntime().gc();
- Runtime.getRuntime().runFinalization();
- Runtime.getRuntime().gc();
- int refCount = 0;
- for (WeakReference<Activity> c: refs) {
- if (c.get() != null) refCount++;
- }
- // If applications are leaking activity, every reference is reachable.
- assertTrue(refCount != TEST_COUNT);
- }
-}
diff --git a/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java b/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java
deleted file mode 100644
index 54ac1b497..000000000
--- a/tests_camera/src/com/android/camera/functional/ImageCaptureIntentTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2011 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.functional;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.R;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-
-public class ImageCaptureIntentTest extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private Intent mIntent;
-
- public ImageCaptureIntentTest() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- }
-
- @LargeTest
- public void testNoExtraOutput() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressDone();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
- Intent resultData = getActivity().getResultData();
- Bitmap bitmap = (Bitmap) resultData.getParcelableExtra("data");
- assertNotNull(bitmap);
- assertTrue(bitmap.getWidth() > 0);
- assertTrue(bitmap.getHeight() > 0);
- }
-
- @LargeTest
- public void testExtraOutput() throws Exception {
- File file = new File(Environment.getExternalStorageDirectory(),
- "test.jpg");
- BufferedInputStream stream = null;
- byte[] jpegData;
-
- try {
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressDone();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_OK, getActivity().getResultCode());
-
- // Verify the jpeg file
- int fileLength = (int) file.length();
- assertTrue(fileLength > 0);
- jpegData = new byte[fileLength];
- stream = new BufferedInputStream(new FileInputStream(file));
- stream.read(jpegData);
- } finally {
- if (stream != null) stream.close();
- file.delete();
- }
-
- Bitmap b = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
- assertTrue(b.getWidth() > 0);
- assertTrue(b.getHeight() > 0);
- }
-
- @LargeTest
- public void testCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testSnapshotCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- takePicture();
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- private void takePicture() throws Exception {
- getInstrumentation().sendKeySync(
- new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS));
- getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(4000);
- }
-
- private void pressDone() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_done).performClick();
- }
- });
- }
-
- private void pressCancel() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_cancel).performClick();
- }
- });
- }
-}
diff --git a/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java b/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java
deleted file mode 100644
index 43e91ca84..000000000
--- a/tests_camera/src/com/android/camera/functional/VideoCaptureIntentTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2011 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.functional;
-
-import com.android.camera.CameraActivity;
-import com.android.gallery3d.R;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.database.Cursor;
-import android.media.MediaMetadataRetriever;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Video.VideoColumns;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import java.io.File;
-
-public class VideoCaptureIntentTest extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private static final String TAG = "VideoCaptureIntentTest";
- private Intent mIntent;
- private Uri mVideoUri;
- private File mFile, mFile2;
-
- public VideoCaptureIntentTest() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (mVideoUri != null) {
- ContentResolver resolver = getActivity().getContentResolver();
- Uri query = mVideoUri.buildUpon().build();
- String[] projection = new String[] {VideoColumns.DATA};
-
- Cursor cursor = null;
- try {
- cursor = resolver.query(query, projection, null, null, null);
- if (cursor != null && cursor.moveToFirst()) {
- new File(cursor.getString(0)).delete();
- }
- } finally {
- if (cursor != null) cursor.close();
- }
-
- resolver.delete(mVideoUri, null, null);
- }
- if (mFile != null) mFile.delete();
- if (mFile2 != null) mFile2.delete();
- super.tearDown();
- }
-
- @LargeTest
- public void testNoExtraOutput() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- Intent resultData = getActivity().getResultData();
- mVideoUri = resultData.getData();
- assertNotNull(mVideoUri);
- verify(getActivity(), mVideoUri);
- }
-
- @LargeTest
- public void testExtraOutput() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- }
-
- @LargeTest
- public void testCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testRecordCancel() throws Exception {
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressCancel();
-
- assertTrue(getActivity().isFinishing());
- assertEquals(Activity.RESULT_CANCELED, getActivity().getResultCode());
- }
-
- @LargeTest
- public void testExtraSizeLimit() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- final long sizeLimit = 500000; // bytes
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // use low quality to speed up
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo(5000);
- pressDone();
-
- verify(getActivity(), uri);
- long length = mFile.length();
- Log.v(TAG, "Video size is " + length + " bytes.");
- assertTrue(length > 0);
- assertTrue("Actual size=" + length, length <= sizeLimit);
- }
-
- @LargeTest
- public void testExtraDurationLimit() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- final int durationLimit = 2; // seconds
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo(5000);
- pressDone();
-
- int duration = verify(getActivity(), uri);
- // The duraion should be close to to the limit. The last video duration
- // also has duration, so the total duration may exceeds the limit a
- // little bit.
- Log.v(TAG, "Video length is " + duration + " ms.");
- assertTrue(duration < (durationLimit + 1) * 1000);
- }
-
- @LargeTest
- public void testExtraVideoQuality() throws Exception {
- mFile = new File(Environment.getExternalStorageDirectory(), "video.tmp");
- mFile2 = new File(Environment.getExternalStorageDirectory(), "video2.tmp");
-
- Uri uri = Uri.fromFile(mFile);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // low quality
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- setActivity(null);
-
- uri = Uri.fromFile(mFile2);
- mIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- mIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // high quality
- setActivityIntent(mIntent);
- getActivity();
-
- recordVideo();
- pressDone();
-
- verify(getActivity(), uri);
- assertTrue(mFile.length() <= mFile2.length());
- }
-
- // Verify result code, result data, and the duration.
- private int verify(CameraActivity activity, Uri uri) throws Exception {
- assertTrue(activity.isFinishing());
- assertEquals(Activity.RESULT_OK, activity.getResultCode());
-
- // Verify the video file
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(activity, uri);
- String duration = retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_DURATION);
- assertNotNull(duration);
- int durationValue = Integer.parseInt(duration);
- Log.v(TAG, "Video duration is " + durationValue);
- assertTrue(durationValue > 0);
- return durationValue;
- }
-
- private void recordVideo(int ms) throws Exception {
- getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(ms);
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- // If recording is in progress, stop it. Run these atomically in
- // UI thread.
- CameraActivity activity = getActivity();
- if (activity.isRecording()) {
- activity.findViewById(R.id.shutter_button).performClick();
- }
- }
- });
- }
-
- private void recordVideo() throws Exception {
- recordVideo(2000);
- }
-
- private void pressDone() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_done).performClick();
- }
- });
- }
-
- private void pressCancel() {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- getActivity().findViewById(R.id.btn_cancel).performClick();
- }
- });
- }
-}
diff --git a/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java b/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java
deleted file mode 100755
index b89b764c3..000000000
--- a/tests_camera/src/com/android/camera/power/ImageAndVideoCapture.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2009 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.power;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Instrumentation;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.content.Intent;
-/**
- * Junit / Instrumentation test case for camera power measurement
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e com.android.camera.power.ImageAndVideoCapture \
- * -w com.android.camera.tests/android.test.InstrumentationTestRunner
- *
- */
-
-public class ImageAndVideoCapture extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private String TAG = "ImageAndVideoCapture";
- private static final int TOTAL_NUMBER_OF_IMAGECAPTURE = 5;
- private static final int TOTAL_NUMBER_OF_VIDEOCAPTURE = 5;
- private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 1500; //1.5 sedconds
- private static final long WAIT_FOR_VIDEO_CAPTURE_TO_BE_TAKEN = 10000; //10 seconds
- private static final long WAIT_FOR_PREVIEW = 1500; //1.5 seconds
- private static final long WAIT_FOR_STABLE_STATE = 2000; //2 seconds
-
- public ImageAndVideoCapture() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @LargeTest
- public void testLaunchCamera() {
- // This test case capture the baseline for the image preview.
- try {
- Thread.sleep(WAIT_FOR_STABLE_STATE);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- assertTrue("testImageCaptureDoNothing", false);
- }
- }
-
- @LargeTest
- public void testCapture5Image() {
- // This test case will use the default camera setting
- Instrumentation inst = getInstrumentation();
- try {
- for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) {
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- }
- Thread.sleep(WAIT_FOR_STABLE_STATE);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- assertTrue("testImageCapture", false);
- }
- }
-
- @LargeTest
- public void testCapture5Videos() {
- // This test case will use the default camera setting
- Instrumentation inst = getInstrumentation();
- try {
- // Switch to the video mode
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- getActivity().startActivity(intent);
- for (int i = 0; i < TOTAL_NUMBER_OF_VIDEOCAPTURE; i++) {
- Thread.sleep(WAIT_FOR_PREVIEW);
- // record a video
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(WAIT_FOR_VIDEO_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(WAIT_FOR_PREVIEW);
- }
- Thread.sleep(WAIT_FOR_STABLE_STATE);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- assertTrue("testVideoCapture", false);
- }
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/CameraLatency.java b/tests_camera/src/com/android/camera/stress/CameraLatency.java
deleted file mode 100755
index 35ff717a1..000000000
--- a/tests_camera/src/com/android/camera/stress/CameraLatency.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2009 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.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Instrumentation;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- */
-
-public class CameraLatency extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private String TAG = "CameraLatency";
- private static final int TOTAL_NUMBER_OF_IMAGECAPTURE = 20;
- private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 4000;
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
-
- private long mTotalAutoFocusTime;
- private long mTotalShutterLag;
- private long mTotalShutterToPictureDisplayedTime;
- private long mTotalPictureDisplayedToJpegCallbackTime;
- private long mTotalJpegCallbackFinishTime;
- private long mAvgAutoFocusTime;
- private long mAvgShutterLag = mTotalShutterLag;
- private long mAvgShutterToPictureDisplayedTime;
- private long mAvgPictureDisplayedToJpegCallbackTime;
- private long mAvgJpegCallbackFinishTime;
-
- public CameraLatency() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- @LargeTest
- public void testImageCapture() {
- Log.v(TAG, "start testImageCapture test");
- Instrumentation inst = getInstrumentation();
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
- try {
- for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) {
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- //skip the first measurement
- if (i != 0) {
- CameraActivity c = getActivity();
-
- // if any of the latency var accessor methods return -1 then the
- // camera is set to a different module other than PhotoModule so
- // skip the shot and try again
- if (c.getAutoFocusTime() != -1) {
- mTotalAutoFocusTime += c.getAutoFocusTime();
- mTotalShutterLag += c.getShutterLag();
- mTotalShutterToPictureDisplayedTime +=
- c.getShutterToPictureDisplayedTime();
- mTotalPictureDisplayedToJpegCallbackTime +=
- c.getPictureDisplayedToJpegCallbackTime();
- mTotalJpegCallbackFinishTime += c.getJpegCallbackFinishTime();
- }
- else {
- i--;
- continue;
- }
- }
- }
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- }
- //ToDO: yslau
- //1) Need to get the baseline from the cupcake so that we can add the
- //failure condition of the camera latency.
- //2) Only count those number with succesful capture. Set the timer to invalid
- //before capture and ignore them if the value is invalid
- int numberofRun = TOTAL_NUMBER_OF_IMAGECAPTURE - 1;
- mAvgAutoFocusTime = mTotalAutoFocusTime / numberofRun;
- mAvgShutterLag = mTotalShutterLag / numberofRun;
- mAvgShutterToPictureDisplayedTime =
- mTotalShutterToPictureDisplayedTime / numberofRun;
- mAvgPictureDisplayedToJpegCallbackTime =
- mTotalPictureDisplayedToJpegCallbackTime / numberofRun;
- mAvgJpegCallbackFinishTime =
- mTotalJpegCallbackFinishTime / numberofRun;
-
- try {
- FileWriter fstream = null;
- fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- BufferedWriter out = new BufferedWriter(fstream);
- out.write("Camera Latency : \n");
- out.write("Number of loop: " + TOTAL_NUMBER_OF_IMAGECAPTURE + "\n");
- out.write("Avg AutoFocus = " + mAvgAutoFocusTime + "\n");
- out.write("Avg mShutterLag = " + mAvgShutterLag + "\n");
- out.write("Avg mShutterToPictureDisplayedTime = "
- + mAvgShutterToPictureDisplayedTime + "\n");
- out.write("Avg mPictureDisplayedToJpegCallbackTime = "
- + mAvgPictureDisplayedToJpegCallbackTime + "\n");
- out.write("Avg mJpegCallbackFinishTime = " +
- mAvgJpegCallbackFinishTime + "\n");
- out.close();
- fstream.close();
- } catch (Exception e) {
- fail("Camera Latency write output to file");
- }
- Log.v(TAG, "The Image capture wait time = " +
- WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- Log.v(TAG, "Avg AutoFocus = " + mAvgAutoFocusTime);
- Log.v(TAG, "Avg mShutterLag = " + mAvgShutterLag);
- Log.v(TAG, "Avg mShutterToPictureDisplayedTime = "
- + mAvgShutterToPictureDisplayedTime);
- Log.v(TAG, "Avg mPictureDisplayedToJpegCallbackTime = "
- + mAvgPictureDisplayedToJpegCallbackTime);
- Log.v(TAG, "Avg mJpegCallbackFinishTime = " + mAvgJpegCallbackFinishTime);
- }
-}
-
diff --git a/tests_camera/src/com/android/camera/stress/CameraStartUp.java b/tests_camera/src/com/android/camera/stress/CameraStartUp.java
deleted file mode 100644
index 94e9a9419..000000000
--- a/tests_camera/src/com/android/camera/stress/CameraStartUp.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2009 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.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-
-/**
- * Test cases to measure the camera and video recorder startup time.
- */
-public class CameraStartUp extends InstrumentationTestCase {
-
- private static final int TOTAL_NUMBER_OF_STARTUP = 20;
-
- private String TAG = "CameraStartUp";
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private static int WAIT_TIME_FOR_PREVIEW = 1500; //1.5 second
-
- private long launchCamera() {
- long startupTime = 0;
- try {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- long beforeStart = System.currentTimeMillis();
- Instrumentation inst = getInstrumentation();
- Activity cameraActivity = inst.startActivitySync(intent);
- long cameraStarted = System.currentTimeMillis();
- Thread.sleep(WAIT_TIME_FOR_PREVIEW);
- cameraActivity.finish();
- startupTime = cameraStarted - beforeStart;
- Thread.sleep(1000);
- Log.v(TAG, "camera startup time: " + startupTime);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- fail("Fails to get the output file");
- }
- return startupTime;
- }
-
- private long launchVideo() {
- long startupTime = 0;
-
- try {
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- long beforeStart = System.currentTimeMillis();
- Instrumentation inst = getInstrumentation();
- Activity recorderActivity = inst.startActivitySync(intent);
- long cameraStarted = System.currentTimeMillis();
- recorderActivity.finish();
- startupTime = cameraStarted - beforeStart;
- Log.v(TAG, "Video Startup Time = " + startupTime);
- // wait for 1s to make sure it reach a clean stage
- Thread.sleep(WAIT_TIME_FOR_PREVIEW);
- Log.v(TAG, "video startup time: " + startupTime);
- } catch (Exception e) {
- Log.v(TAG, "Got exception", e);
- fail("Fails to launch video output file");
- }
- return startupTime;
- }
-
- private void writeToOutputFile(long totalStartupTime,
- String individualStartupTime, boolean firstStartUp, String Type) throws Exception {
- // TODO (yslau) : Need to integrate the output data with central
- // dashboard
- try {
- FileWriter fstream = null;
- fstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- BufferedWriter out = new BufferedWriter(fstream);
- if (firstStartUp) {
- out.write("First " + Type + " Startup: " + totalStartupTime + "\n");
- } else {
- long averageStartupTime = totalStartupTime / (TOTAL_NUMBER_OF_STARTUP -1);
- out.write(Type + "startup time: " + "\n");
- out.write("Number of loop: " + (TOTAL_NUMBER_OF_STARTUP -1) + "\n");
- out.write(individualStartupTime + "\n\n");
- out.write(Type + " average startup time: " + averageStartupTime + " ms\n\n");
- }
- out.close();
- fstream.close();
- } catch (Exception e) {
- fail("Camera write output to file");
- }
- }
-
- @LargeTest
- public void testLaunchVideo() throws Exception {
- String individualStartupTime;
- individualStartupTime = "Individual Video Startup Time = ";
- long totalStartupTime = 0;
- long startupTime = 0;
- for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) {
- if (i == 0) {
- // Capture the first startup time individually
- long firstStartUpTime = launchVideo();
- writeToOutputFile(firstStartUpTime, "na", true, "Video");
- } else {
- startupTime = launchVideo();
- totalStartupTime += startupTime;
- individualStartupTime += startupTime + " ,";
- }
- }
- Log.v(TAG, "totalStartupTime =" + totalStartupTime);
- writeToOutputFile(totalStartupTime, individualStartupTime, false, "Video");
- }
-
- @LargeTest
- public void testLaunchCamera() throws Exception {
- String individualStartupTime;
- individualStartupTime = "Individual Camera Startup Time = ";
- long totalStartupTime = 0;
- long startupTime = 0;
- for (int i = 0; i < TOTAL_NUMBER_OF_STARTUP; i++) {
- if (i == 0) {
- // Capture the first startup time individually
- long firstStartUpTime = launchCamera();
- writeToOutputFile(firstStartUpTime, "na", true, "Camera");
- } else {
- startupTime = launchCamera();
- totalStartupTime += startupTime;
- individualStartupTime += startupTime + " ,";
- }
- }
- Log.v(TAG, "totalStartupTime =" + totalStartupTime);
- writeToOutputFile(totalStartupTime,
- individualStartupTime, false, "Camera");
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java b/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java
deleted file mode 100755
index 4047da0a2..000000000
--- a/tests_camera/src/com/android/camera/stress/CameraStressTestRunner.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 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.stress;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-import junit.framework.TestSuite;
-
-public class CameraStressTestRunner extends InstrumentationTestRunner {
-
- // Default recorder settings
- public static int mVideoDuration = 20000; // set default to 20 seconds
- public static int mVideoIterations = 100; // set default to 100 videos
- public static int mImageIterations = 100; // set default to 100 images
-
- @Override
- public TestSuite getAllTests() {
- TestSuite suite = new InstrumentationTestSuite(this);
- suite.addTestSuite(ImageCapture.class);
- suite.addTestSuite(VideoCapture.class);
- return suite;
- }
-
- @Override
- public ClassLoader getLoader() {
- return CameraStressTestRunner.class.getClassLoader();
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- String video_iterations = (String) icicle.get("video_iterations");
- String image_iterations = (String) icicle.get("image_iterations");
- String video_duration = (String) icicle.get("video_duration");
-
- if ( video_iterations != null ) {
- mVideoIterations = Integer.parseInt(video_iterations);
- }
- if ( image_iterations != null) {
- mImageIterations = Integer.parseInt(image_iterations);
- }
- if ( video_duration != null) {
- mVideoDuration = Integer.parseInt(video_duration);
- }
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/ImageCapture.java b/tests_camera/src/com/android/camera/stress/ImageCapture.java
deleted file mode 100755
index ad06db188..000000000
--- a/tests_camera/src/com/android/camera/stress/ImageCapture.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2009 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.stress;
-
-import com.android.camera.CameraActivity;
-import com.android.camera.stress.CameraStressTestRunner;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.app.Activity;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.ImageCapture \
- * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner
- *
- */
-
-public class ImageCapture extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private String TAG = "ImageCapture";
- private static final long WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN = 1500; //1.5 sedconds
- private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //3 seconds
-
- private TestUtil testUtil = new TestUtil();
-
- // Private intent extras.
- private final static String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
-
- public ImageCapture() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- testUtil.prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- testUtil.closeOutputFile();
- super.tearDown();
- }
-
- public void captureImages(String reportTag, Instrumentation inst) {
- int total_num_of_images = CameraStressTestRunner.mImageIterations;
- Log.v(TAG, "no of images = " + total_num_of_images);
-
- //TODO(yslau): Need to integrate the outoput with the central dashboard,
- //write to a txt file as a temp solution
- boolean memoryResult = false;
- KeyEvent focusEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_FOCUS);
-
- try {
- testUtil.writeReportHeader(reportTag, total_num_of_images);
- for (int i = 0; i < total_num_of_images; i++) {
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeySync(focusEvent);
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- testUtil.writeResult(i);
- }
- } catch (Exception e) {
- Log.v(TAG, "Got exception: " + e.toString());
- assertTrue("testImageCapture", false);
- }
- }
-
- @LargeTest
- public void testBackImageCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent();
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureImages("Back Camera Image Capture\n", inst);
- act.finish();
- }
-
- @LargeTest
- public void testFrontImageCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent();
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureImages("Front Camera Image Capture\n", inst);
- act.finish();
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java b/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java
deleted file mode 100644
index 0c1ef45b9..000000000
--- a/tests_camera/src/com/android/camera/stress/ShotToShotLatency.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2012 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.stress;
-
-import android.app.Instrumentation;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.KeyEvent;
-import com.android.camera.CameraActivity;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * Junit / Instrumentation test case for measuring camera shot to shot latency
- */
-public class ShotToShotLatency extends ActivityInstrumentationTestCase2<CameraActivity> {
- private String TAG = "ShotToShotLatency";
- private static final int TOTAL_NUMBER_OF_SNAPSHOTS = 250;
- private static final long SNAPSHOT_WAIT = 1000;
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private static final String CAMERA_IMAGE_DIRECTORY =
- Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/";
-
- public ShotToShotLatency() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
- private void cleanupLatencyImages() {
- try {
- File sdcard = new File(CAMERA_IMAGE_DIRECTORY);
- File[] pics = null;
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.endsWith(".jpg");
- }
- };
- pics = sdcard.listFiles(filter);
- for (File f : pics) {
- f.delete();
- }
- } catch (SecurityException e) {
- Log.e(TAG, "Security manager access violation: " + e.toString());
- }
- }
-
- private void sleep(long time) {
- try {
- Thread.sleep(time);
- } catch (InterruptedException e) {
- Log.e(TAG, "Sleep InterruptedException " + e.toString());
- }
- }
-
- @LargeTest
- public void testShotToShotLatency() {
- long sigmaOfDiffFromMeanSquared = 0;
- double mean = 0;
- double standardDeviation = 0;
- ArrayList<Long> captureTimes = new ArrayList<Long>();
- ArrayList<Long> latencyTimes = new ArrayList<Long>();
-
- Log.v(TAG, "start testShotToShotLatency test");
- Instrumentation inst = getInstrumentation();
-
- // Generate data points
- for (int i = 0; i < TOTAL_NUMBER_OF_SNAPSHOTS; i++) {
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
- sleep(SNAPSHOT_WAIT);
- CameraActivity c = getActivity();
- if (c.getCaptureStartTime() > 0) {
- captureTimes.add(c.getCaptureStartTime());
- }
- }
-
- // Calculate latencies
- for (int j = 1; j < captureTimes.size(); j++) {
- latencyTimes.add(captureTimes.get(j) - captureTimes.get(j - 1));
- }
-
- // Crunch numbers
- for (long dataPoint : latencyTimes) {
- mean += (double) dataPoint;
- }
- mean /= latencyTimes.size();
-
- for (long dataPoint : latencyTimes) {
- sigmaOfDiffFromMeanSquared += (dataPoint - mean) * (dataPoint - mean);
- }
- standardDeviation = Math.sqrt(sigmaOfDiffFromMeanSquared / latencyTimes.size());
-
- // Report statistics
- File outFile = new File(CAMERA_TEST_OUTPUT_FILE);
- BufferedWriter output = null;
- try {
- output = new BufferedWriter(new FileWriter(outFile, true));
- output.write("Shot to shot latency - mean: " + mean + "\n");
- output.write("Shot to shot latency - standard deviation: " + standardDeviation + "\n");
- cleanupLatencyImages();
- } catch (IOException e) {
- Log.e(TAG, "testShotToShotLatency IOException writing to log " + e.toString());
- } finally {
- try {
- if (output != null) {
- output.close();
- }
- } catch (IOException e) {
- Log.e(TAG, "Error closing file: " + e.toString());
- }
- }
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/SwitchPreview.java b/tests_camera/src/com/android/camera/stress/SwitchPreview.java
deleted file mode 100755
index 86b1b5d99..000000000
--- a/tests_camera/src/com/android/camera/stress/SwitchPreview.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2009 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.stress;
-
-import com.android.camera.CameraActivity;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.SwitchPreview \
- * -w com.android.camera.tests/com.android.camera.stress.CameraStressTestRunner
- *
- */
-public class SwitchPreview extends ActivityInstrumentationTestCase2 <CameraActivity>{
- private String TAG = "SwitchPreview";
- private static final int TOTAL_NUMBER_OF_SWITCHING = 200;
- private static final long WAIT_FOR_PREVIEW = 4000;
-
- private static final String CAMERA_TEST_OUTPUT_FILE =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- private BufferedWriter mOut;
- private FileWriter mfstream;
-
- public SwitchPreview() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- getActivity();
- prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- getActivity().finish();
- closeOutputFile();
- super.tearDown();
- }
-
- private void prepareOutputFile(){
- try{
- mfstream = new FileWriter(CAMERA_TEST_OUTPUT_FILE, true);
- mOut = new BufferedWriter(mfstream);
- } catch (Exception e){
- assertTrue("Camera Switch Mode", false);
- }
- }
-
- private void closeOutputFile() {
- try {
- mOut.write("\n");
- mOut.close();
- mfstream.close();
- } catch (Exception e) {
- assertTrue("CameraSwitchMode close output", false);
- }
- }
-
- @LargeTest
- public void testSwitchMode() {
- //Switching the video and the video recorder mode
- Instrumentation inst = getInstrumentation();
- try{
- mOut.write("Camera Switch Mode:\n");
- mOut.write("No of loops :" + TOTAL_NUMBER_OF_SWITCHING + "\n");
- mOut.write("loop: ");
- for (int i=0; i< TOTAL_NUMBER_OF_SWITCHING; i++) {
- Thread.sleep(WAIT_FOR_PREVIEW);
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- getActivity().startActivity(intent);
- Thread.sleep(WAIT_FOR_PREVIEW);
- intent = new Intent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.setClass(getInstrumentation().getTargetContext(),
- CameraActivity.class);
- getActivity().startActivity(intent);
- mOut.write(" ," + i);
- mOut.flush();
- }
- } catch (Exception e){
- Log.v(TAG, "Got exception", e);
- }
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/TestUtil.java b/tests_camera/src/com/android/camera/stress/TestUtil.java
deleted file mode 100644
index 64e2039f2..000000000
--- a/tests_camera/src/com/android/camera/stress/TestUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.stress;
-
-import android.os.Environment;
-import java.io.FileWriter;
-import java.io.BufferedWriter;
-
-
-/**
- * Collection of utility functions used for the test.
- */
-public class TestUtil {
- public BufferedWriter mOut;
- public FileWriter mfstream;
-
- public TestUtil() {
- }
-
- public void prepareOutputFile() throws Exception {
- String camera_test_output_file =
- Environment.getExternalStorageDirectory().toString() + "/mediaStressOut.txt";
- mfstream = new FileWriter(camera_test_output_file, true);
- mOut = new BufferedWriter(mfstream);
- }
-
- public void closeOutputFile() throws Exception {
- mOut.write("\n");
- mOut.close();
- mfstream.close();
- }
-
- public void writeReportHeader(String reportTag, int iteration) throws Exception {
- mOut.write(reportTag);
- mOut.write("No of loops :" + iteration + "\n");
- mOut.write("loop: ");
- }
-
- public void writeResult(int iteration) throws Exception {
- mOut.write(" ," + iteration);
- mOut.flush();
- }
-}
diff --git a/tests_camera/src/com/android/camera/stress/VideoCapture.java b/tests_camera/src/com/android/camera/stress/VideoCapture.java
deleted file mode 100755
index ec55ccce2..000000000
--- a/tests_camera/src/com/android/camera/stress/VideoCapture.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 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.stress;
-
-import com.android.camera.CameraActivity;
-import com.android.camera.stress.TestUtil;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.provider.MediaStore;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-
-import com.android.camera.stress.CameraStressTestRunner;
-
-/**
- * Junit / Instrumentation test case for camera test
- *
- * Running the test suite:
- *
- * adb shell am instrument \
- * -e class com.android.camera.stress.VideoCapture \
- * -w com.google.android.camera.tests/android.test.InstrumentationTestRunner
- *
- */
-
-public class VideoCapture extends ActivityInstrumentationTestCase2 <CameraActivity> {
- private static final long WAIT_FOR_PREVIEW = 1500; //1.5 seconds
- private static final long WAIT_FOR_SWITCH_CAMERA = 3000; //2 seconds
-
- // Private intent extras which control the camera facing.
- private final static String EXTRAS_CAMERA_FACING =
- "android.intent.extras.CAMERA_FACING";
-
- private TestUtil testUtil = new TestUtil();
-
- public VideoCapture() {
- super(CameraActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- testUtil.prepareOutputFile();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- testUtil.closeOutputFile();
- super.tearDown();
- }
-
- @LargeTest
- public void captureVideos(String reportTag, Instrumentation inst) throws Exception{
- boolean memoryResult = false;
- int total_num_of_videos = CameraStressTestRunner.mVideoIterations;
- int video_duration = CameraStressTestRunner.mVideoDuration;
- testUtil.writeReportHeader(reportTag, total_num_of_videos);
-
- for (int i = 0; i < total_num_of_videos; i++) {
- Thread.sleep(WAIT_FOR_PREVIEW);
- // record a video
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- Thread.sleep(video_duration);
- inst.sendCharacterSync(KeyEvent.KEYCODE_CAMERA);
- testUtil.writeResult(i);
- }
- }
-
- @LargeTest
- public void testBackVideoCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureVideos("Back Camera Video Capture\n", inst);
- act.finish();
- }
-
- @LargeTest
- public void testFrontVideoCapture() throws Exception {
- Instrumentation inst = getInstrumentation();
- Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
-
- intent.setClass(getInstrumentation().getTargetContext(), CameraActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(EXTRAS_CAMERA_FACING,
- android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
- Activity act = inst.startActivitySync(intent);
- Thread.sleep(WAIT_FOR_SWITCH_CAMERA);
- captureVideos("Front Camera Video Capture\n", inst);
- act.finish();
- }
-}
diff --git a/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java b/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java
deleted file mode 100644
index 0b4fc80f6..000000000
--- a/tests_camera/src/com/android/camera/unittest/CameraUnitTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2010 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.unittest;
-
-import com.android.camera.Util;
-
-import android.graphics.Matrix;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-@SmallTest
-public class CameraUnitTest extends TestCase {
- public void testRoundOrientation() {
- int h = Util.ORIENTATION_HYSTERESIS;
- assertEquals(0, Util.roundOrientation(0, 0));
- assertEquals(0, Util.roundOrientation(359, 0));
- assertEquals(0, Util.roundOrientation(0 + 44 + h, 0));
- assertEquals(90, Util.roundOrientation(0 + 45 + h, 0));
- assertEquals(0, Util.roundOrientation(360 - 44 - h, 0));
- assertEquals(270, Util.roundOrientation(360 - 45 - h, 0));
-
- assertEquals(90, Util.roundOrientation(90, 90));
- assertEquals(90, Util.roundOrientation(90 + 44 + h, 90));
- assertEquals(180, Util.roundOrientation(90 + 45 + h, 90));
- assertEquals(90, Util.roundOrientation(90 - 44 - h, 90));
- assertEquals(0, Util.roundOrientation(90 - 45 - h, 90));
-
- assertEquals(180, Util.roundOrientation(180, 180));
- assertEquals(180, Util.roundOrientation(180 + 44 + h, 180));
- assertEquals(270, Util.roundOrientation(180 + 45 + h, 180));
- assertEquals(180, Util.roundOrientation(180 - 44 - h, 180));
- assertEquals(90, Util.roundOrientation(180 - 45 - h, 180));
-
- assertEquals(270, Util.roundOrientation(270, 270));
- assertEquals(270, Util.roundOrientation(270 + 44 + h, 270));
- assertEquals(0, Util.roundOrientation(270 + 45 + h, 270));
- assertEquals(270, Util.roundOrientation(270 - 44 - h, 270));
- assertEquals(180, Util.roundOrientation(270 - 45 - h, 270));
-
- assertEquals(90, Util.roundOrientation(90, 0));
- assertEquals(180, Util.roundOrientation(180, 0));
- assertEquals(270, Util.roundOrientation(270, 0));
-
- assertEquals(0, Util.roundOrientation(0, 90));
- assertEquals(180, Util.roundOrientation(180, 90));
- assertEquals(270, Util.roundOrientation(270, 90));
-
- assertEquals(0, Util.roundOrientation(0, 180));
- assertEquals(90, Util.roundOrientation(90, 180));
- assertEquals(270, Util.roundOrientation(270, 180));
-
- assertEquals(0, Util.roundOrientation(0, 270));
- assertEquals(90, Util.roundOrientation(90, 270));
- assertEquals(180, Util.roundOrientation(180, 270));
- }
-
- public void testPrepareMatrix() {
- Matrix matrix = new Matrix();
- float[] points;
- int[] expected;
-
- Util.prepareMatrix(matrix, false, 0, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {0, 0, 400, 240, 800, 480, 400, 480, 100, 300};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, false, 90, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {800, 0, 400, 240, 0, 480, 0, 240, 300, 60};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, false, 180, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {800, 480, 400, 240, 0, 0, 400, 0, 700, 180};
- matrix.mapPoints(points);
- assertEquals(expected, points);
-
- Util.prepareMatrix(matrix, true, 180, 800, 480);
- points = new float[] {-1000, -1000, 0, 0, 1000, 1000, 0, 1000, -750, 250};
- expected = new int[] {0, 480, 400, 240, 800, 0, 400, 0, 100, 180};
- matrix.mapPoints(points);
- assertEquals(expected, points);
- }
-
- private void assertEquals(int expected[], float[] actual) {
- for (int i = 0; i < expected.length; i++) {
- assertEquals("Array index " + i + " mismatch", expected[i], Math.round(actual[i]));
- }
- }
-}