summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml13
-rw-r--r--res/layout/camera.xml27
-rw-r--r--res/layout/camera_filmstrip.xml20
-rw-r--r--res/layout/new_photo_module.xml44
-rw-r--r--res/layout/new_video_module.xml53
-rw-r--r--src/com/android/camera/NewCameraActivity.java346
-rw-r--r--src/com/android/camera/NewCameraModule.java76
-rw-r--r--src/com/android/camera/NewPhotoMenu.java247
-rw-r--r--src/com/android/camera/NewPhotoModule.java2005
-rw-r--r--src/com/android/camera/NewPhotoUI.java879
-rw-r--r--src/com/android/camera/NewPreviewGestures.java358
-rw-r--r--src/com/android/camera/NewVideoMenu.java190
-rw-r--r--src/com/android/camera/NewVideoModule.java2344
-rw-r--r--src/com/android/camera/NewVideoUI.java724
-rw-r--r--src/com/android/camera/data/CameraDataAdapter.java424
-rw-r--r--src/com/android/camera/ui/FaceView.java9
-rw-r--r--src/com/android/camera/ui/FilmStripGestureRecognizer.java107
-rw-r--r--src/com/android/camera/ui/FilmStripView.java830
-rw-r--r--src/com/android/camera/ui/NewCameraRootView.java91
19 files changed, 1 insertions, 8786 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0cdaf991f..d5a5ef9fa 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -284,19 +284,6 @@
android:configChanges="keyboardHidden|orientation|screenSize"
android:theme="@style/Theme.Gallery.Dialog"/>
- <activity android:name="com.android.camera.NewCameraActivity"
- android:taskAffinity="com.android.camera.NewCameraActivity"
- android:theme="@style/Theme.Camera"
- android:label="@string/camera_label"
- android:configChanges="orientation|screenSize|keyboardHidden"
- android:clearTaskOnLaunch="true"
- android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
<activity android:name="com.android.camera.CameraActivity"
android:taskAffinity="com.android.camera.CameraActivity"
android:label="@string/camera_label"
diff --git a/res/layout/camera.xml b/res/layout/camera.xml
deleted file mode 100644
index b4ec436c6..000000000
--- a/res/layout/camera.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <!-- NewCameraRootView needs to be in a FrameLayout to set margins
- in the layout parameters. -->
- <com.android.camera.ui.NewCameraRootView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/camera_app_root"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- </com.android.camera.ui.NewCameraRootView>
-</FrameLayout>
diff --git a/res/layout/camera_filmstrip.xml b/res/layout/camera_filmstrip.xml
deleted file mode 100644
index 26fc3f030..000000000
--- a/res/layout/camera_filmstrip.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<com.android.camera.ui.FilmStripView
-xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/filmstrip_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
diff --git a/res/layout/new_photo_module.xml b/res/layout/new_photo_module.xml
deleted file mode 100644
index 70a7579b7..000000000
--- a/res/layout/new_photo_module.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- This layout is shared by phone and tablet in both landscape and portrait
- orientation. The purpose of having this layout is to eventually not manually
- recreate views when the orientation changes, by migrating the views that do not
- need to be recreated in onConfigurationChanged from old photo_module to this
- layout. -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center">
- <TextureView
- android:id="@+id/preview_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <ViewStub android:id="@+id/face_view_stub"
- android:inflatedId="@+id/face_view"
- android:layout="@layout/face_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"/>
- <com.android.camera.ui.RenderOverlay
- android:id="@+id/render_overlay"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <include layout="@layout/camera_controls"
- android:layout_gravity="center"
- style="@style/CameraControls"/>
-</merge> \ No newline at end of file
diff --git a/res/layout/new_video_module.xml b/res/layout/new_video_module.xml
deleted file mode 100644
index 9eb3e84e2..000000000
--- a/res/layout/new_video_module.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<!-- This layout is shared by phone and tablet in landscape orientation. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="match_parent"
- android:layout_width="match_parent">
- <TextureView
- android:id="@+id/preview_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <FrameLayout android:id="@+id/preview_border"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone"
- android:background="@drawable/ic_snapshot_border" />
- <com.android.camera.ui.RenderOverlay
- android:id="@+id/render_overlay"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect"
- style="@style/ViewfinderLabelLayout">
- <include layout="@layout/viewfinder_labels_video" android:id="@+id/labels" />
- </com.android.camera.ui.RotateLayout>
- <ImageView android:id="@+id/review_image"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:visibility="gone"
- android:background="@android:color/black"/>
- <ImageView
- android:id="@+id/btn_play"
- style="@style/ReviewControlIcon"
- android:layout_centerInParent="true"
- android:src="@drawable/ic_gallery_play_big"
- android:visibility="gone"
- android:onClick="onReviewPlayClicked"/>
-
- <include layout="@layout/camera_controls"
- android:layout_gravity="center"
- style="@style/CameraControls"/>
-</merge>
diff --git a/src/com/android/camera/NewCameraActivity.java b/src/com/android/camera/NewCameraActivity.java
deleted file mode 100644
index e8d2157da..000000000
--- a/src/com/android/camera/NewCameraActivity.java
+++ /dev/null
@@ -1,346 +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.Activity;
-import android.content.ComponentName;
-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.os.Bundle;
-import android.os.IBinder;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.OrientationEventListener;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.camera.data.CameraDataAdapter;
-import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
-import com.android.camera.ui.FilmStripView;
-import com.android.camera.ui.NewCameraRootView;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.util.LightCycleHelper;
-
-public class NewCameraActivity extends Activity
- implements CameraSwitchListener {
- public static final int PHOTO_MODULE_INDEX = 0;
- public static final int VIDEO_MODULE_INDEX = 1;
- public static final int PANORAMA_MODULE_INDEX = 2;
- public static final int LIGHTCYCLE_MODULE_INDEX = 3;
- 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";
-
- private CameraDataAdapter mDataAdapter;
- private int mCurrentModuleIndex;
- private NewCameraModule mCurrentModule;
- private View mRootView;
- private FilmStripView mFilmStripView;
- private int mResultCodeForTesting;
- private Intent mResultDataForTesting;
- private OnScreenHint mStorageHint;
- private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
- private PhotoModule mController;
- private boolean mAutoRotateScreen;
- private boolean mSecureCamera;
- private int mLastRawOrientation;
- private MyOrientationEventListener mOrientationListener;
- 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;
- }};
-
- public MediaSaveService getMediaSaveService() {
- return mMediaSaveService;
- }
-
- 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() {
- mMediaSaveService.setListener(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)) {
- mSecureCamera = true;
- // Use a new album when this is started from the lock screen.
- //TODO: sSecureAlbumId++;
- } else if (ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
- mSecureCamera = true;
- } else {
- mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
- }
- /*TODO: if (mSecureCamera) {
- IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
- registerReceiver(mScreenOffReceiver, filter);
- if (sScreenOffReceiver == null) {
- sScreenOffReceiver = new ScreenOffReceiver();
- getApplicationContext().registerReceiver(sScreenOffReceiver, filter);
- }
- }*/
- LayoutInflater inflater = getLayoutInflater();
- View rootLayout = inflater.inflate(R.layout.camera, null, false);
- mRootView = rootLayout.findViewById(R.id.camera_app_root);
- mDataAdapter = new CameraDataAdapter(
- new ColorDrawable(getResources().getColor(R.color.photo_placeholder)));
- mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
- // Set up the camera preview first so the preview shows up ASAP.
- mDataAdapter.setCameraPreviewInfo(rootLayout,
- FilmStripView.ImageData.SIZE_FULL, FilmStripView.ImageData.SIZE_FULL);
- mFilmStripView.setDataAdapter(mDataAdapter);
- mCurrentModule = new NewPhotoModule();
- mCurrentModule.init(this, mRootView);
- mOrientationListener = new MyOrientationEventListener(this);
- bindMediaSaveService();
- }
-
- 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();
-
- // The loading is done in background and will update the filmstrip later.
- mDataAdapter.requestLoad(getContentResolver());
- }
-
- @Override
- public void onDestroy() {
- unbindMediaSaveService();
- super.onDestroy();
- }
-
- @Override
- public void onConfigurationChanged(Configuration config) {
- super.onConfigurationChanged(config);
- mCurrentModule.onConfigurationChanged(config);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- //if (mFilmStripView.isInCameraFullscreen()) {
- // return mCurrentModule.dispatchTouchEvent(m);
- //}
- return mFilmStripView.dispatchTouchEvent(m);
- }
- 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 VIDEO_MODULE_INDEX:
- mCurrentModule = new NewVideoModule();
- break;
- case PHOTO_MODULE_INDEX:
- mCurrentModule = new NewPhotoModule();
- break;
- /* TODO:
- case PANORAMA_MODULE_INDEX:
- mCurrentModule = new PanoramaModule();
- break;
- case LIGHTCYCLE_MODULE_INDEX:
- mCurrentModule = LightCycleHelper.createPanoramaModule();
- break; */
- default:
- break;
- }
-
- openModule(mCurrentModule);
- mCurrentModule.onOrientationChanged(mLastRawOrientation);
- if (mMediaSaveService != null) {
- mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
- }
- }
-
- private void openModule(NewCameraModule module) {
- module.init(this, mRootView);
- module.onResumeBeforeSuper();
- module.onResumeAfterSuper();
- ((NewCameraRootView) mRootView).cameraModuleChanged();
- }
-
- private void closeModule(NewCameraModule module) {
- module.onPauseBeforeSuper();
- module.onPauseAfterSuper();
- ((ViewGroup) mRootView).removeAllViews();
- }
-
- @Override
- public void onShowSwitcherPopup() {
- }
-}
diff --git a/src/com/android/camera/NewCameraModule.java b/src/com/android/camera/NewCameraModule.java
deleted file mode 100644
index 061cc6cca..000000000
--- a/src/com/android/camera/NewCameraModule.java
+++ /dev/null
@@ -1,76 +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.Intent;
-import android.content.res.Configuration;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-
-public interface NewCameraModule {
-
- public void init(NewCameraActivity activity, View frame);
-
- public void onFullScreenChanged(boolean full);
-
- 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 boolean dispatchTouchEvent(MotionEvent m);
-
- public void onPreviewTextureCopied();
-
- public void onCaptureTextureCopied();
-
- public void onUserInteraction();
-
- public boolean updateStorageHintOnResume();
-
- public void updateCameraAppView();
-
- public boolean needsSwitcher();
-
- public boolean needsPieMenu();
-
- public void onOrientationChanged(int orientation);
-
- public void onShowSwitcherPopup();
-
- public void onMediaSaveServiceConnected(MediaSaveService s);
-}
diff --git a/src/com/android/camera/NewPhotoMenu.java b/src/com/android/camera/NewPhotoMenu.java
deleted file mode 100644
index 962df0f9a..000000000
--- a/src/com/android/camera/NewPhotoMenu.java
+++ /dev/null
@@ -1,247 +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.hardware.Camera.Parameters;
-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.TimerSettingPopup;
-import com.android.gallery3d.R;
-
-public class NewPhotoMenu extends PieController
- implements MoreSettingPopup.Listener,
- TimerSettingPopup.Listener,
- ListPrefSettingPopup.Listener {
- private static String TAG = "CAM_photomenu";
-
- private static final int POS_HDR = 0;
- private static final int POS_EXP = 1;
- private static final int POS_MORE = 2;
- private static final int POS_FLASH = 3;
- private static final int POS_SWITCH = 4;
- private static final int POS_WB = 1;
- private static final int POS_SET = 2;
-
- private final String mSettingOff;
-
- private NewPhotoUI mUI;
- private String[] mOtherKeys;
- // First level popup
- private MoreSettingPopup mPopup;
- // Second level popup
- private AbstractSettingPopup mSecondPopup;
- private NewCameraActivity mActivity;
-
- public NewPhotoMenu(NewCameraActivity activity, NewPhotoUI 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;
- mSecondPopup = null;
- PieItem item = null;
- // flash
- if (group.findPreference(CameraSettings.KEY_FLASH_MODE) != null) {
- item = makeItem(CameraSettings.KEY_FLASH_MODE, POS_FLASH, 5);
- mRenderer.addItem(item);
- }
- // exposure compensation
- item = makeItem(CameraSettings.KEY_EXPOSURE, POS_EXP, 5);
- mRenderer.addItem(item);
- // camera switcher
- if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) {
- item = makeItem(R.drawable.ic_switch_photo_facing_holo_light);
- item.setPosition(POS_SWITCH, 5);
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- // Find the index of next camera.
- ListPreference camPref = mPreferenceGroup
- .findPreference(CameraSettings.KEY_CAMERA_ID);
- if (camPref != null) {
- int index = camPref.findIndexOfValue(camPref.getValue());
- CharSequence[] values = camPref.getEntryValues();
- index = (index + 1) % values.length;
- int newCameraId = Integer
- .parseInt((String) values[index]);
- mListener.onCameraPickerClicked(newCameraId);
- }
- }
- });
- mRenderer.addItem(item);
- }
- // hdr
- if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) {
- item = makeItem(R.drawable.ic_hdr);
- item.setPosition(POS_HDR, 5);
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- // Find the index of next camera.
- ListPreference pref = mPreferenceGroup
- .findPreference(CameraSettings.KEY_CAMERA_HDR);
- if (pref != null) {
- // toggle hdr value
- int index = (pref.findIndexOfValue(pref.getValue()) + 1) % 2;
- pref.setValueIndex(index);
- onSettingChanged(pref);
- }
- }
- });
- mRenderer.addItem(item);
- }
-
- // more settings
- PieItem more = makeItem(R.drawable.ic_settings_holo_light);
- more.setPosition(POS_MORE, 5);
- mRenderer.addItem(more);
- // white balance
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE, POS_WB, 5);
- more.addItem(item);
- // settings popup
- mOtherKeys = new String[] {
- CameraSettings.KEY_SCENE_MODE,
- CameraSettings.KEY_RECORD_LOCATION,
- CameraSettings.KEY_PICTURE_SIZE,
- CameraSettings.KEY_FOCUS_MODE,
- CameraSettings.KEY_TIMER,
- CameraSettings.KEY_TIMER_SOUND_EFFECTS,
- };
- item = makeItem(R.drawable.ic_settings_holo_light);
- item.setPosition(POS_SET, 5);
- item.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(PieItem item) {
- if (mPopup == null) {
- initializePopup();
- }
- mUI.showPopup(mPopup);
- }
- });
- more.addItem(item);
- }
-
- @Override
- public void reloadPreferences() {
- super.reloadPreferences();
- if (mPopup != null) {
- mPopup.reloadPreference();
- }
- }
-
- @Override
- // Hit when an item in the second-level popup gets selected
- public void onListPrefChanged(ListPreference pref) {
- if (mPopup != null && mSecondPopup != null) {
- mUI.dismissPopup(true);
- mPopup.reloadPreference();
- }
- onSettingChanged(pref);
- }
-
- @Override
- public void overrideSettings(final String ... keyvalues) {
- super.overrideSettings(keyvalues);
- if (mPopup == null) initializePopup();
- mPopup.overrideSettings(keyvalues);
- }
-
- 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 (mSecondPopup != null) {
- mSecondPopup = null;
- if (topPopupOnly) mUI.showPopup(mPopup);
- }
- }
-
- // 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);
- }
-
- @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 (mSecondPopup != null) return;
-
- LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- if (CameraSettings.KEY_TIMER.equals(pref.getKey())) {
- TimerSettingPopup timerPopup = (TimerSettingPopup) inflater.inflate(
- R.layout.timer_setting_popup, null, false);
- timerPopup.initialize(pref);
- timerPopup.setSettingChangedListener(this);
- mUI.dismissPopup(true);
- mSecondPopup = timerPopup;
- } else {
- ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate(
- R.layout.list_pref_setting_popup, null, false);
- basic.initialize(pref);
- basic.setSettingChangedListener(this);
- mUI.dismissPopup(true);
- mSecondPopup = basic;
- }
- mUI.showPopup(mSecondPopup);
- }
-}
diff --git a/src/com/android/camera/NewPhotoModule.java b/src/com/android/camera/NewPhotoModule.java
deleted file mode 100644
index 659e2be19..000000000
--- a/src/com/android/camera/NewPhotoModule.java
+++ /dev/null
@@ -1,2005 +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.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-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.PictureCallback;
-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.MotionEvent;
-import android.view.OrientationEventListener;
-import android.view.SurfaceHolder;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.camera.CameraManager.CameraProxy;
-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.CropExtras;
-import com.android.gallery3d.filtershow.FilterShowActivity;
-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.Collections;
-import java.util.Formatter;
-import java.util.List;
-
-public class NewPhotoModule
- implements NewCameraModule,
- 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 NewCameraActivity mActivity;
- private CameraProxy mCameraDevice;
- private int mCameraId;
- private Parameters mParameters;
- private boolean mPaused;
-
- private NewPhotoUI mUI;
-
- // -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 ShutterCallback mShutterCallback = new ShutterCallback();
- 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) {
- // TODO: Commenting out the line below for now. need to get it working
- // mActivity.addSecureAlbumItemIfNeeded(false, uri);
- Util.broadcastNewPicture(mActivity, 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(NewCameraActivity activity, View parent) {
- mActivity = activity;
- mUI = new NewPhotoUI(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;
- }
-
- 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) {
- setLocationPreference(RecordLocationPreference.VALUE_ON);
- }
- })
- .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) {
- setLocationPreference(RecordLocationPreference.VALUE_OFF);
- }
- })
- .show();
- }
-
- 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();
-
- 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.setPreviewDisplayAsync(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.setFaceDetectionListener(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.setFaceDetectionListener(null);
- mCameraDevice.stopFaceDetection();
- mUI.clearFaces();
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mCameraState == SWITCHING_CAMERA) return true;
- return mUI.dispatchTouchEvent(m);
- }
-
- private final class ShutterCallback
- implements android.hardware.Camera.ShutterCallback {
- @Override
- public void onShutter() {
- mShutterCallbackTime = System.currentTimeMillis();
- mShutterLag = mShutterCallbackTime - mCaptureStartTime;
- Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
- }
- }
-
- private final class PostViewPictureCallback implements PictureCallback {
- @Override
- public void onPictureTaken(
- byte [] data, android.hardware.Camera camera) {
- mPostViewPictureCallbackTime = System.currentTimeMillis();
- Log.v(TAG, "mShutterToPostViewCallbackTime = "
- + (mPostViewPictureCallbackTime - mShutterCallbackTime)
- + "ms");
- }
- }
-
- private final class RawPictureCallback implements PictureCallback {
- @Override
- public void onPictureTaken(
- byte [] rawData, android.hardware.Camera camera) {
- mRawPictureCallbackTime = System.currentTimeMillis();
- Log.v(TAG, "mShutterToRawCallbackTime = "
- + (mRawPictureCallbackTime - mShutterCallbackTime) + "ms");
- }
- }
-
- private final class JpegPictureCallback implements PictureCallback {
- Location mLocation;
-
- public JpegPictureCallback(Location loc) {
- mLocation = loc;
- }
-
- @Override
- public void onPictureTaken(
- final byte [] jpegData, final android.hardware.Camera camera) {
- if (mPaused) {
- return;
- }
- if (mSceneMode == Util.SCENE_MODE_HDR) {
- mUI.showSwitcher();
- //TODO: mActivity.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");
-
- /*TODO:
- // 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 (ApiHelper.HAS_SURFACE_TEXTURE && !mIsImageCaptureIntent
- && mActivity.mShowCameraAppView) {
- // Finish capture animation
- ((CameraScreenNail) mActivity.mCameraScreenNail).animateSlide();
- } */
- 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 android.hardware.Camera.AutoFocusCallback {
- @Override
- public void onAutoFocus(
- boolean focused, android.hardware.Camera 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 android.hardware.Camera.AutoFocusMoveCallback {
- @Override
- public void onAutoFocusMoving(
- boolean moving, android.hardware.Camera 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.FOCUSING:
- case PhotoController.SWITCHING_CAMERA:
- mUI.enableGestures(false);
- break;
- case PhotoController.IDLE:
- mUI.enableGestures(true);
- break;
- }
- }
-
- private void animateFlash() {
- /* //TODO:
- // 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 (ApiHelper.HAS_SURFACE_TEXTURE && !mIsImageCaptureIntent
- && mActivity.mShowCameraAppView) {
- // Start capture animation.
- ((CameraScreenNail) mActivity.mCameraScreenNail).animateFlash(mDisplayRotation);
- } */
- }
-
- @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) {
- animateFlash();
- }
-
- // Set rotation and gps data.
- int orientation = (360 - mDisplayRotation) % 360;
- // 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.takePicture2(mShutterCallback, mRawPictureCallback,
- mPostViewPictureCallback, new JpegPictureCallback(loc),
- mCameraState, mFocusManager.getFocusState());
-
- if (!animateBefore) {
- animateFlash();
- }
-
- mNamedImages.nameNewImage(mContentResolver, mCaptureStartTime);
-
- mFaceDetectionStarted = false;
- setCameraState(SNAPSHOT_IN_PROGRESS);
- 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(FilterShowActivity.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) {
- if (mSceneMode == Util.SCENE_MODE_HDR) {
- mUI.hideSwitcher();
- //TODO: mActivity.setSwipingEnabled(false);
- }
- 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 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()
- && ActivityBase.isFirstStartAfterScreenOn()) {
- ActivityBase.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 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(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.setFaceDetectionListener(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.setPreviewTextureAsync((SurfaceTexture) st);
- }
-
- Log.v(TAG, "startPreview");
- mCameraDevice.startPreviewAsync();
- 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.
- List<Integer> frameRates = mParameters.getSupportedPreviewFrameRates();
- if (frameRates != null) {
- Integer max = Collections.max(frameRates);
- mParameters.setPreviewFrameRate(max);
- }
-
- 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
- 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(
- (AutoFocusMoveCallback) mAutoFocusMoveCallback);
- } else {
- mCameraDevice.setAutoFocusMoveCallback(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)
- || ActivityBase.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, 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 boolean needsSwitcher() {
- return !mIsImageCaptureIntent;
- }
-
- @Override
- public boolean needsPieMenu() {
- return true;
- }
-
- @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;
- }
- }
-/* 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() {}
-
- @Override
- public void onFullScreenChanged(boolean full) {
- /* //TODO:
- mUI.onFullScreenChanged(full);
- if (ApiHelper.HAS_SURFACE_TEXTURE) {
- if (mActivity.mCameraScreenNail != null) {
- ((CameraScreenNail) mActivity.mCameraScreenNail).setFullScreen(full);
- }
- return;
- } */
- }
-
-}
diff --git a/src/com/android/camera/NewPhotoUI.java b/src/com/android/camera/NewPhotoUI.java
deleted file mode 100644
index d1470b2b6..000000000
--- a/src/com/android/camera/NewPhotoUI.java
+++ /dev/null
@@ -1,879 +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.graphics.Matrix;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.Camera.Face;
-import android.hardware.Camera.FaceDetectionListener;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.MotionEvent;
-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.CameraSwitcher.CameraSwitchListener;
-import com.android.camera.ui.CountDownView;
-import com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
-import com.android.camera.ui.CameraSwitcher;
-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.io.IOException;
-import java.util.List;
-
-public class NewPhotoUI implements PieListener,
- NewPreviewGestures.SingleTapListener,
- NewPreviewGestures.CancelEventListener,
- FocusUI, TextureView.SurfaceTextureListener,
- LocationManager.Listener,
- FaceDetectionListener,
- NewPreviewGestures.SwipeListener {
-
- private static final String TAG = "CAM_UI";
- private static final int UPDATE_TRANSFORM_MATRIX = 1;
- private NewCameraActivity mActivity;
- private PhotoController mController;
- private NewPreviewGestures 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 NewPhotoMenu mMenu;
- private CameraSwitcher mSwitcher;
- private View mCameraControls;
-
- // Small indicators which show the camera settings in the viewfinder.
- private ImageView mExposureIndicator;
- private ImageView mFlashIndicator;
- private ImageView mSceneIndicator;
- private ImageView mHdrIndicator;
- // A view group that contains all the small indicators.
- private View 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 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);
- }
- }
- };
-
- public NewPhotoUI(NewCameraActivity activity, PhotoController controller, View parent) {
- mActivity = activity;
- mController = controller;
- mRootView = parent;
-
- mActivity.getLayoutInflater().inflate(R.layout.new_photo_module,
- (ViewGroup) mRootView, true);
- mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_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(0);
- 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 = mRootView.findViewById(R.id.camera_controls);
- }
-
- 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 = mRootView.findViewById(R.id.on_screen_indicators);
- mExposureIndicator = (ImageView) mOnScreenIndicators.findViewById(R.id.menu_exposure_indicator);
- mFlashIndicator = (ImageView) mOnScreenIndicators.findViewById(R.id.menu_flash_indicator);
- mSceneIndicator = (ImageView) mOnScreenIndicators.findViewById(R.id.menu_scenemode_indicator);
- mHdrIndicator = (ImageView) mOnScreenIndicators.findViewById(R.id.menu_hdr_indicator);
- }
-
- public void onCameraOpened(PreferenceGroup prefGroup, ComboPreferences prefs,
- Camera.Parameters params, OnPreferenceChangedListener listener) {
- if (mPieRenderer == null) {
- mPieRenderer = new PieRenderer(mActivity);
- mPieRenderer.setPieListener(this);
- }
-
- if (mMenu == null) {
- mMenu = new NewPhotoMenu(mActivity, this, mPieRenderer);
- mMenu.setListener(listener);
- }
- mMenu.initialize(prefGroup);
-
- if (mZoomRenderer == null) {
- mZoomRenderer = new ZoomRenderer(mActivity);
- }
- mRenderOverlay.addRenderer(mPieRenderer);
- mRenderOverlay.addRenderer(mZoomRenderer);
-
- if (mGestures == null) {
- // this will handle gesture disambiguation and dispatching
- mGestures = new NewPreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer,
- this);
- mGestures.setCancelEventListener(this);
- }
- mGestures.clearTouchReceivers();
- mGestures.setRenderOverlay(mRenderOverlay);
- mGestures.addTouchReceiver(mMenuButton);
- mGestures.addTouchReceiver(mBlocker);
- // make sure to add touch targets for image capture
- if (mController.isImageCaptureIntent()) {
- if (mReviewCancelButton != null) {
- mGestures.addTouchReceiver(mReviewCancelButton);
- }
- if (mReviewDoneButton != null) {
- mGestures.addTouchReceiver(mReviewDoneButton);
- }
- }
- mRenderOverlay.requestLayout();
-
- initializeZoom(params);
- updateOnScreenIndicators(params, prefs);
- }
-
- 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);
- 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);
- hideSwitcher();
- mShutterButton.setVisibility(View.GONE);
- }
-
- public void showUI() {
- mCameraControls.setVisibility(View.VISIBLE);
- showSwitcher();
- mShutterButton.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 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,
- ComboPreferences prefs) {
- if (params == null) return;
- updateSceneOnScreenIndicator(params.getSceneMode());
- updateExposureOnScreenIndicator(params,
- CameraSettings.readExposure(prefs));
- updateFlashOnScreenIndicator(params.getFlashMode());
- updateHdrOnScreenIndicator(params.getSceneMode());
- }
-
- private void updateExposureOnScreenIndicator(Camera.Parameters params, int value) {
- if (mExposureIndicator == null) {
- return;
- }
- int id = 0;
- float step = params.getExposureCompensationStep();
- value = (int) Math.round(value * step);
- 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);
- }
-
- private 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)) {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_on);
- } else {
- mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_off);
- }
- }
- }
-
- private void updateSceneOnScreenIndicator(String value) {
- if (mSceneIndicator == null) {
- return;
- }
- if ((value == null) || Parameters.SCENE_MODE_AUTO.equals(value)
- || Parameters.SCENE_MODE_HDR.equals(value)) {
- mSceneIndicator.setImageResource(R.drawable.ic_indicator_sce_off);
- } else {
- mSceneIndicator.setImageResource(R.drawable.ic_indicator_sce_on);
- }
- }
-
- private void updateHdrOnScreenIndicator(String value) {
- if (mHdrIndicator == null) {
- return;
- }
- if ((value != null) && Parameters.SCENE_MODE_HDR.equals(value)) {
- mHdrIndicator.setImageResource(R.drawable.ic_indicator_hdr_on);
- } else {
- mHdrIndicator.setImageResource(R.drawable.ic_indicator_hdr_off);
- }
- }
-
- public void setCameraState(int state) {
- }
-
- // Gestures and touch events
-
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mPopup != null || mSwitcher.showsPopup()) {
- boolean handled = mRootView.dispatchTouchEvent(m);
- if (!handled && mPopup != null) {
- dismissPopup(false);
- }
- return handled;
- } else if (mGestures != null && mRenderOverlay != null) {
- if (mGestures.dispatchTouch(m)) {
- return true;
- } else {
- return mRootView.dispatchTouchEvent(m);
- }
- }
- return true;
- }
-
- @Override
- public void onTouchEventCancelled(MotionEvent cancelEvent) {
- mRootView.dispatchTouchEvent(cancelEvent);
- }
-
- 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 onFullScreenChanged(boolean full) {
- if (mFaceView != null) {
- mFaceView.setBlockDraw(!full);
- }
- if (mPopup != null) {
- dismissPopup(false, full);
- }
- if (mGestures != null) {
- mGestures.setEnabled(full);
- }
- if (mRenderOverlay != null) {
- // this can not happen in capture mode
- mRenderOverlay.setVisibility(full ? View.VISIBLE : View.GONE);
- }
- if (mPieRenderer != null) {
- mPieRenderer.setBlockFocus(!full);
- }
- setShowMenu(full);
- if (mBlocker != null) {
- mBlocker.setVisibility(full ? View.VISIBLE : View.GONE);
- }
- if (!full && 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(true);
- 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(boolean topPopupOnly) {
- dismissPopup(topPopupOnly, true);
- }
-
- private void dismissPopup(boolean topOnly, boolean fullScreen) {
- if (fullScreen) {
- showUI();
- mBlocker.setVisibility(View.VISIBLE);
- }
- setShowMenu(fullScreen);
- if (mPopup != null) {
- ((FrameLayout) mRootView).removeView(mPopup);
- mPopup = null;
- }
- mMenu.popupDismissed(topOnly);
- }
-
- 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(false);
- ret = true;
- }
- return ret;
- }
-
- protected void showPostCaptureAlert() {
- mOnScreenIndicators.setVisibility(View.GONE);
- mMenuButton.setVisibility(View.GONE);
- Util.fadeIn(mReviewDoneButton);
- mShutterButton.setVisibility(View.INVISIBLE);
- Util.fadeIn(mReviewRetakeButton);
- }
-
- protected void hidePostCaptureAlert() {
- mOnScreenIndicators.setVisibility(View.VISIBLE);
- mMenuButton.setVisibility(View.VISIBLE);
- Util.fadeOut(mReviewDoneButton);
- mShutterButton.setVisibility(View.VISIBLE);
- Util.fadeOut(mReviewRetakeButton);
- }
-
- 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) {
- //TODO: mActivity.cancelActivityTouchHandling();
- //TODO: mActivity.setSwipingEnabled(false);
- if (mFaceView != null) {
- mFaceView.setBlockDraw(true);
- }
- }
-
- @Override
- public void onPieClosed() {
- //TODO: mActivity.setSwipingEnabled(true);
- if (mFaceView != null) {
- mFaceView.setBlockDraw(false);
- }
- }
-
- 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();
-
- 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, android.hardware.Camera camera) {
- mFaceView.setFaces(faces);
- }
-
- @Override
- public void onSwipe(int direction) {
- if (direction == PreviewGestures.DIR_UP) {
- openMenu();
- }
- }
-}
diff --git a/src/com/android/camera/NewPreviewGestures.java b/src/com/android/camera/NewPreviewGestures.java
deleted file mode 100644
index 2718e55ae..000000000
--- a/src/com/android/camera/NewPreviewGestures.java
+++ /dev/null
@@ -1,358 +0,0 @@
-package com.android.camera;
-
-/*
- * 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.
- */
-
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.View;
-import android.view.ViewConfiguration;
-
-import com.android.camera.PreviewGestures.SwipeListener;
-import com.android.camera.ui.PieRenderer;
-import com.android.camera.ui.RenderOverlay;
-import com.android.camera.ui.ZoomRenderer;
-import com.android.gallery3d.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class NewPreviewGestures
- implements ScaleGestureDetector.OnScaleGestureListener {
-
- private static final String TAG = "CAM_gestures";
-
- private static final long TIMEOUT_PIE = 200;
- private static final int MSG_PIE = 1;
- private static final int MODE_NONE = 0;
- private static final int MODE_PIE = 1;
- private static final int MODE_ZOOM = 2;
- private static final int MODE_MODULE = 3;
- private static final int MODE_ALL = 4;
- private static final int MODE_SWIPE = 5;
-
- 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 NewCameraActivity mActivity;
- private SingleTapListener mTapListener;
- private CancelEventListener mCancelEventListener;
- private RenderOverlay mOverlay;
- private PieRenderer mPie;
- private ZoomRenderer mZoom;
- private MotionEvent mDown;
- private MotionEvent mCurrent;
- private ScaleGestureDetector mScale;
- private List<View> mReceivers;
- private int mMode;
- private int mSlop;
- private int mTapTimeout;
- private boolean mEnabled;
- private boolean mZoomOnly;
- private int mOrientation;
- private int[] mLocation;
- private SwipeListener mSwipeListener;
-
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (msg.what == MSG_PIE) {
- mMode = MODE_PIE;
- openPie();
- cancelActivityTouchHandling(mDown);
- }
- }
- };
-
- public interface SingleTapListener {
- public void onSingleTapUp(View v, int x, int y);
- }
-
- public interface CancelEventListener {
- public void onTouchEventCancelled(MotionEvent cancelEvent);
- }
-
- interface SwipeListener {
- public void onSwipe(int direction);
- }
-
- public NewPreviewGestures(NewCameraActivity ctx, SingleTapListener tapListener,
- ZoomRenderer zoom, PieRenderer pie, SwipeListener swipe) {
- mActivity = ctx;
- mTapListener = tapListener;
- mPie = pie;
- mZoom = zoom;
- mMode = MODE_ALL;
- mScale = new ScaleGestureDetector(ctx, this);
- mSlop = (int) ctx.getResources().getDimension(R.dimen.pie_touch_slop);
- mTapTimeout = ViewConfiguration.getTapTimeout();
- mEnabled = true;
- mLocation = new int[2];
- mSwipeListener = swipe;
- }
-
- public void setCancelEventListener(CancelEventListener listener) {
- mCancelEventListener = listener;
- }
-
- public void setRenderOverlay(RenderOverlay overlay) {
- mOverlay = overlay;
- }
-
- public void setOrientation(int orientation) {
- mOrientation = orientation;
- }
-
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- if (!enabled) {
- cancelPie();
- }
- }
-
- public void setZoomOnly(boolean zoom) {
- mZoomOnly = zoom;
- }
-
- public void addTouchReceiver(View v) {
- if (mReceivers == null) {
- mReceivers = new ArrayList<View>();
- }
- mReceivers.add(v);
- }
-
- public void clearTouchReceivers() {
- if (mReceivers != null) {
- mReceivers.clear();
- }
- }
-
- public boolean dispatchTouch(MotionEvent m) {
- if (!mEnabled) {
- return false;
- }
- mCurrent = m;
- if (MotionEvent.ACTION_DOWN == m.getActionMasked()) {
- if (checkReceivers(m)) {
- mMode = MODE_MODULE;
- return false;
- } else {
- mMode = MODE_ALL;
- mDown = MotionEvent.obtain(m);
- if (mPie != null && mPie.showsItems()) {
- mMode = MODE_PIE;
- return sendToPie(m);
- }
- if (mPie != null && !mZoomOnly) {
- mHandler.sendEmptyMessageDelayed(MSG_PIE, TIMEOUT_PIE);
- }
- if (mZoom != null) {
- mScale.onTouchEvent(m);
- }
- // make sure this is ok
- return false;
- }
- } else if (mMode == MODE_NONE) {
- return false;
- } else if (mMode == MODE_SWIPE) {
- if (MotionEvent.ACTION_UP == m.getActionMasked()) {
- mSwipeListener.onSwipe(getSwipeDirection(m));
- }
- return true;
- } else if (mMode == MODE_PIE) {
- if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) {
- sendToPie(makeCancelEvent(m));
- if (mZoom != null) {
- onScaleBegin(mScale);
- }
- } else {
- return sendToPie(m);
- }
- return true;
- } else if (mMode == MODE_ZOOM) {
- mScale.onTouchEvent(m);
- if (!mScale.isInProgress() && MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) {
- mMode = MODE_NONE;
- onScaleEnd(mScale);
- }
- return true;
- } else if (mMode == MODE_MODULE) {
- return false;
- } else {
- // didn't receive down event previously;
- // assume module wasn't initialzed and ignore this event.
- if (mDown == null) {
- return true;
- }
- if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) {
- if (!mZoomOnly) {
- cancelPie();
- sendToPie(makeCancelEvent(m));
- }
- if (mZoom != null) {
- mScale.onTouchEvent(m);
- onScaleBegin(mScale);
- }
- } else if ((mMode == MODE_ZOOM) && !mScale.isInProgress()
- && MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) {
- // user initiated and stopped zoom gesture without zooming
- mScale.onTouchEvent(m);
- onScaleEnd(mScale);
- }
- // not zoom or pie mode and no timeout yet
- if (mZoom != null) {
- boolean res = mScale.onTouchEvent(m);
- if (mScale.isInProgress()) {
- cancelPie();
- cancelActivityTouchHandling(m);
- return res;
- }
- }
- if (MotionEvent.ACTION_UP == m.getActionMasked()) {
- cancelPie();
- cancelActivityTouchHandling(m);
- // must have been tap
- if (m.getEventTime() - mDown.getEventTime() < mTapTimeout) {
- mTapListener.onSingleTapUp(null,
- (int) mDown.getX() - mOverlay.getWindowPositionX(),
- (int) mDown.getY() - mOverlay.getWindowPositionY());
- return true;
- } else {
- return false;
- }
- } else if (MotionEvent.ACTION_MOVE == m.getActionMasked()) {
- if ((Math.abs(m.getX() - mDown.getX()) > mSlop)
- || Math.abs(m.getY() - mDown.getY()) > mSlop) {
- // moved too far and no timeout yet, no focus or pie
- cancelPie();
- int dir = getSwipeDirection(m);
- if (dir == DIR_LEFT) {
- mMode = MODE_MODULE;
- return false;
- } else {
- cancelActivityTouchHandling(m);
- mMode = MODE_NONE;
- }
- }
- }
- return false;
- }
- }
-
- private boolean checkReceivers(MotionEvent m) {
- if (mReceivers != null) {
- for (View receiver : mReceivers) {
- if (isInside(m, receiver)) {
- return true;
- }
- }
- }
- return false;
- }
-
- // left tests for finger moving right to left
- private int getSwipeDirection(MotionEvent m) {
- float dx = 0;
- float dy = 0;
- switch (mOrientation) {
- case 0:
- dx = m.getX() - mDown.getX();
- dy = m.getY() - mDown.getY();
- break;
- case 90:
- dx = - (m.getY() - mDown.getY());
- dy = m.getX() - mDown.getX();
- break;
- case 180:
- dx = -(m.getX() - mDown.getX());
- dy = m.getY() - mDown.getY();
- break;
- case 270:
- dx = m.getY() - mDown.getY();
- dy = m.getX() - mDown.getX();
- break;
- }
- if (dx < 0 && (Math.abs(dy) / -dx < 2)) return DIR_LEFT;
- if (dx > 0 && (Math.abs(dy) / dx < 2)) return DIR_RIGHT;
- if (dy > 0) return DIR_DOWN;
- return DIR_UP;
- }
-
- private boolean isInside(MotionEvent evt, View v) {
- v.getLocationInWindow(mLocation);
- return (v.getVisibility() == View.VISIBLE
- && evt.getX() >= mLocation[0] && evt.getX() < mLocation[0] + v.getWidth()
- && evt.getY() >= mLocation[1] && evt.getY() < mLocation[1] + v.getHeight());
- }
-
- public void cancelActivityTouchHandling(MotionEvent m) {
- if (mCancelEventListener != null) {
- mCancelEventListener.onTouchEventCancelled(makeCancelEvent(m));
- }
- }
-
- private MotionEvent makeCancelEvent(MotionEvent m) {
- MotionEvent c = MotionEvent.obtain(m);
- c.setAction(MotionEvent.ACTION_CANCEL);
- return c;
- }
-
- private void openPie() {
- mDown.offsetLocation(-mOverlay.getWindowPositionX(),
- -mOverlay.getWindowPositionY());
- mOverlay.directDispatchTouch(mDown, mPie);
- }
-
- private void cancelPie() {
- mHandler.removeMessages(MSG_PIE);
- }
-
- private boolean sendToPie(MotionEvent m) {
- m.offsetLocation(-mOverlay.getWindowPositionX(),
- -mOverlay.getWindowPositionY());
- return mOverlay.directDispatchTouch(m, mPie);
- }
-
- @Override
- public boolean onScale(ScaleGestureDetector detector) {
- return mZoom.onScale(detector);
- }
-
- @Override
- public boolean onScaleBegin(ScaleGestureDetector detector) {
- if (mMode != MODE_ZOOM) {
- mMode = MODE_ZOOM;
- cancelActivityTouchHandling(mCurrent);
- }
- if (mCurrent.getActionMasked() != MotionEvent.ACTION_MOVE) {
- return mZoom.onScaleBegin(detector);
- } else {
- return true;
- }
- }
-
- @Override
- public void onScaleEnd(ScaleGestureDetector detector) {
- if (mCurrent.getActionMasked() != MotionEvent.ACTION_MOVE) {
- mZoom.onScaleEnd(detector);
- }
- }
-}
-
diff --git a/src/com/android/camera/NewVideoMenu.java b/src/com/android/camera/NewVideoMenu.java
deleted file mode 100644
index 1dec27a47..000000000
--- a/src/com/android/camera/NewVideoMenu.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.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 NewVideoMenu extends PieController
- implements MoreSettingPopup.Listener,
- ListPrefSettingPopup.Listener,
- TimeIntervalPopup.Listener {
-
- private static String TAG = "CAM_VideoMenu";
- private static final int POS_WB = 1;
- private static final int POS_SET = 2;
- private static final int POS_FLASH = 3;
- private static final int POS_SWITCH = 4;
-
- private NewVideoUI 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 NewCameraActivity mActivity;
-
- public NewVideoMenu(NewCameraActivity activity, NewVideoUI 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 = makeItem(CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE, POS_FLASH, 5);
- mRenderer.addItem(item);
- item = makeItem(CameraSettings.KEY_WHITE_BALANCE, POS_WB, 5);
- mRenderer.addItem(item);
- // camera switcher
- item = makeItem(R.drawable.ic_switch_video_facing_holo_light);
- item.setPosition(POS_SWITCH, 5);
- 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]);
- mListener.onCameraPickerClicked(newCameraId);
- }
- }
- });
- 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.setPosition(POS_SET, 5);
- 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);
- }
-
- @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/NewVideoModule.java b/src/com/android/camera/NewVideoModule.java
deleted file mode 100644
index 6ff8bbf18..000000000
--- a/src/com/android/camera/NewVideoModule.java
+++ /dev/null
@@ -1,2344 +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.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.PictureCallback;
-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.Video;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-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.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 NewVideoModule implements NewCameraModule,
- 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 HIDE_SURFACE_VIEW = 10;
-
- 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";
-
- private static final int MIN_THUMB_SIZE = 64;
- // module fields
- private NewCameraActivity mActivity;
- private boolean mPaused;
- private int mCameraId;
- private Parameters mParameters;
-
- private Boolean mCameraOpened = false;
-
- 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;
-
- 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 VideoNamer mVideoNamer;
- private Surface mSurface;
- private int mPendingSwitchCameraId;
- private boolean mOpenCameraFail;
- private boolean mCameraDisabled;
- private final Handler mHandler = new MainHandler();
- private NewVideoUI 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 MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
- new MediaSaveService.OnMediaSavedListener() {
- @Override
- public void onMediaSaved(Uri uri) {
- if (uri != null) {
- Util.broadcastNewPicture(mActivity, uri);
- }
- }
- };
-
-
- protected class CameraOpenThread extends Thread {
- @Override
- public void run() {
- openCamera();
- }
- }
-
- private void openCamera() {
- try {
- synchronized(mCameraOpened) {
- if (!mCameraOpened) {
- mCameraDevice = Util.openCamera(mActivity, mCameraId);
- mCameraOpened = true;
- }
- }
- 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(NewCameraActivity activity, View root) {
- mActivity = activity;
- mUI = new NewVideoUI(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);
- new Thread(new Runnable() {
- @Override
- public void run() {
- startPreview();
- }
- }).start();
-
- 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);
-
- // 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(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(getLowVideoQuality()));
- }
- }
-
- @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
- private static int getLowVideoQuality() {
- if (ApiHelper.HAS_FINE_RESOLUTION_QUALITY_LEVELS) {
- return CamcorderProfile.QUALITY_480P;
- } else {
- return CamcorderProfile.QUALITY_LOW;
- }
- }
-
-
- @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) {
- doReturnToCaller(true);
- }
-
- @OnClickAttr
- public void onReviewCancelClicked(View v) {
- stopVideoRecording();
- doReturnToCaller(false);
- }
-
- 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.
- // TODO: need to get the capture animation to work
- // ((CameraScreenNail) mActivity.mCameraScreenNail).animateCapture(mDisplayRotation);
- }
- }
- }
-
- 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 defaultQuality = CameraSettings.getDefaultVideoQuality(mCameraId,
- mActivity.getResources().getString(R.string.pref_video_quality_default));
- String videoQuality =
- mPreferences.getString(CameraSettings.KEY_VIDEO_QUALITY,
- defaultQuality);
- 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 = getLowVideoQuality();
- }
- } 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();
- }
-
- 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();
- new Thread(new Runnable() {
- @Override
- public void run() {
- startPreview();
- }
- }).start();
- } 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);
-
- mVideoNamer = new VideoNamer();
- 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 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");
-
- mCameraDevice.setErrorCallback(mErrorCallback);
- if (mPreviewing == true) {
- stopPreview();
- if (effectsActive() && mEffectsRecorder != null) {
- mEffectsRecorder.release();
- mEffectsRecorder = null;
- }
- }
-
- setDisplayOrientation();
- mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation);
- setCameraParameters();
-
- try {
- if (!effectsActive()) {
- SurfaceTexture surfaceTexture = mUI.getSurfaceTexture();
- if (surfaceTexture == null) {
- return; // The texture has been destroyed (pause, etc)
- }
- mCameraDevice.setPreviewTextureAsync(surfaceTexture);
- mCameraDevice.startPreviewAsync();
- mPreviewing = true;
- onPreviewStarted();
- } else {
- initializeEffectsPreview();
- mEffectsRecorder.startPreview();
- mPreviewing = true;
- onPreviewStarted();
- }
- } catch (Throwable ex) {
- closeCamera();
- throw new RuntimeException("startPreview failed", ex);
- } finally {
- mActivity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- 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);
- synchronized(mCameraOpened) {
- if (mCameraOpened) {
- CameraHolder.instance().release();
- }
- mCameraOpened = false;
- }
- 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();
- clearVideoNamer();
- }
-
- 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;
- // 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.setPreviewDisplayAsync(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.startPreviewAsync();
- 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();
- mCameraDevice.waitDone();
- 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(7);
- mCurrentVideoValues.put(Video.Media.TITLE, title);
- mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, filename);
- mCurrentVideoValues.put(Video.Media.DATE_TAKEN, dateTaken);
- 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());
- }
- mVideoNamer.prepareUri(mContentResolver, mCurrentVideoValues);
- mVideoFilename = tmpPath;
- Log.v(TAG, "New video filename: " + mVideoFilename);
- }
-
- private boolean addVideoToMediaStore() {
- boolean fail = false;
- if (mVideoFileDescriptor == null) {
- mCurrentVideoValues.put(Video.Media.SIZE,
- new File(mCurrentVideoFilename).length());
- long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
- if (duration > 0) {
- if (mCaptureTimeLapse) {
- duration = getTimeLapseVideoLength(duration);
- }
- mCurrentVideoValues.put(Video.Media.DURATION, duration);
- } else {
- Log.w(TAG, "Video duration <= 0 : " + duration);
- }
- try {
- mCurrentVideoUri = mVideoNamer.getUri();
- //TODO: mActivity.addSecureAlbumItemIfNeeded(true, mCurrentVideoUri);
-
- // Rename the video file to the final name. This avoids other
- // apps reading incomplete data. We need to do it after the
- // above mVideoNamer.getUri() call, so we are certain that the
- // previous insert to MediaProvider is completed.
- String finalName = mCurrentVideoValues.getAsString(
- Video.Media.DATA);
- if (new File(mCurrentVideoFilename).renameTo(new File(finalName))) {
- mCurrentVideoFilename = finalName;
- }
-
- mContentResolver.update(mCurrentVideoUri, mCurrentVideoValues
- , null, null);
- mActivity.sendBroadcast(new Intent(Util.ACTION_NEW_VIDEO,
- mCurrentVideoUri));
- } 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);
- mCurrentVideoUri = null;
- mCurrentVideoFilename = null;
- fail = true;
- } finally {
- Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
- }
- }
- mCurrentVideoValues = null;
- return fail;
- }
-
- private void deleteCurrentVideo() {
- // Remove the video and the uri if the uri is not passed in by intent.
- if (mCurrentVideoFilename != null) {
- deleteVideoFile(mCurrentVideoFilename);
- mCurrentVideoFilename = null;
- if (mCurrentVideoUri != null) {
- mContentResolver.delete(mCurrentVideoUri, null, null);
- mCurrentVideoUri = null;
- }
- }
- mActivity.updateStorageSpaceAndHint();
- }
-
- 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");
- // TODO: mActivity.setSwipingEnabled(false);
-
- mActivity.updateStorageSpaceAndHint();
- if (mActivity.getStorageSpace() <= Storage.LOW_STORAGE_THRESHOLD) {
- Log.v(TAG, "Storage issue, ignore the start request");
- 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 void showCaptureResult() {
- 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);
- 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");
- //TODO: 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 addVideoToMediaStore 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) {
- if (addVideoToMediaStore()) fail = true;
- }
- }
- // always release media recorder if no effects running
- if (!effectsActive()) {
- releaseMediaRecorder();
- if (!mPaused) {
- mCameraDevice.lock();
- mCameraDevice.waitDone();
- 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);
- 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 && !addVideoToMediaStore()) {
- 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();
- clearVideoNamer();
- }
- } 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);
- }
- }
-
- 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
- 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);
- }
-
- // 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();
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mSwitchingCamera) return true;
- return mUI.dispatchTouchEvent(m);
- }
-
- 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) {
- // TODO: ((CameraScreenNail) mActivity.mCameraScreenNail).animateCapture(mDisplayRotation);
- } 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 onFullScreenChanged(boolean full) {
- mUI.onFullScreenChanged(full);
- }
-
- private final class JpegPictureCallback implements PictureCallback {
- Location mLocation;
-
- public JpegPictureCallback(Location loc) {
- mLocation = loc;
- }
-
- @Override
- public void onPictureTaken(byte [] jpegData, android.hardware.Camera 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, mOnMediaSavedListener, 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();
- }
-
- private void clearVideoNamer() {
- if (mVideoNamer != null) {
- mVideoNamer.finish();
- mVideoNamer = null;
- }
- }
-
- private static class VideoNamer extends Thread {
- private boolean mRequestPending;
- private ContentResolver mResolver;
- private ContentValues mValues;
- private boolean mStop;
- private Uri mUri;
-
- // Runs in main thread
- public VideoNamer() {
- start();
- }
-
- // Runs in main thread
- public synchronized void prepareUri(
- ContentResolver resolver, ContentValues values) {
- mRequestPending = true;
- mResolver = resolver;
- mValues = new ContentValues(values);
- notifyAll();
- }
-
- // Runs in main thread
- public synchronized Uri getUri() {
- // wait until the request is done.
- while (mRequestPending) {
- try {
- wait();
- } catch (InterruptedException ex) {
- // ignore.
- }
- }
- Uri uri = mUri;
- mUri = null;
- return uri;
- }
-
- // Runs in namer thread
- @Override
- public synchronized void run() {
- while (true) {
- if (mStop) break;
- if (!mRequestPending) {
- try {
- wait();
- } catch (InterruptedException ex) {
- // ignore.
- }
- continue;
- }
- cleanOldUri();
- generateUri();
- mRequestPending = false;
- notifyAll();
- }
- cleanOldUri();
- }
-
- // Runs in main thread
- public synchronized void finish() {
- mStop = true;
- notifyAll();
- }
-
- // Runs in namer thread
- private void generateUri() {
- Uri videoTable = Uri.parse("content://media/external/video/media");
- mUri = mResolver.insert(videoTable, mValues);
- }
-
- // Runs in namer thread
- private void cleanOldUri() {
- if (mUri == null) return;
- mResolver.delete(mUri, null, null);
- mUri = null;
- }
- }
-
- @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 boolean needsSwitcher() {
- return !mIsVideoCaptureIntent;
- }
-
- @Override
- public boolean needsPieMenu() {
- return true;
- }
-
- @Override
- public void onShowSwitcherPopup() {
- mUI.onShowSwitcherPopup();
- }
-
- @Override
- public void onMediaSaveServiceConnected(MediaSaveService s) {
- // do nothing.
- }
-}
diff --git a/src/com/android/camera/NewVideoUI.java b/src/com/android/camera/NewVideoUI.java
deleted file mode 100644
index a14dae3d3..000000000
--- a/src/com/android/camera/NewVideoUI.java
+++ /dev/null
@@ -1,724 +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.graphics.Bitmap;
-import android.graphics.Matrix;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.MotionEvent;
-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.CameraSwitcher;
-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.camera.ui.CameraSwitcher.CameraSwitchListener;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-
-import java.util.List;
-
-public class NewVideoUI implements PieRenderer.PieListener,
- NewPreviewGestures.SingleTapListener,
- NewPreviewGestures.SwipeListener, SurfaceTextureListener,
- SurfaceHolder.Callback {
- private final static String TAG = "CAM_VideoUI";
- private static final int UPDATE_TRANSFORM_MATRIX = 1;
- // module fields
- private NewCameraActivity 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 NewVideoMenu mVideoMenu;
- private View mCameraControls;
- private AbstractSettingPopup mPopup;
- private ZoomRenderer mZoomRenderer;
- private NewPreviewGestures mGestures;
- private View mMenuButton;
- private View mBlocker;
- private View mOnScreenIndicators;
- private ImageView mFlashIndicator;
- private RotateLayout mRecordingTimeRect;
- private final Object mLock = new Object();
- private SurfaceTexture mSurfaceTexture;
- private VideoController mController;
- private int mZoomMax;
- private List<Integer> mZoomRatios;
-
- 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 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 NewVideoUI(NewCameraActivity activity, VideoController controller, View parent) {
- mActivity = activity;
- mController = controller;
- mRootView = parent;
- mActivity.getLayoutInflater().inflate(R.layout.new_video_module, (ViewGroup) mRootView, true);
- mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
- mTextureView.setSurfaceTextureListener(this);
- mRootView.addOnLayoutChangeListener(mLayoutListener);
- mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
- mSwitcher = (CameraSwitcher) mRootView.findViewById(R.id.camera_switcher);
- mSwitcher.setCurrentIndex(1);
- mSwitcher.setSwitchListener((CameraSwitchListener) mActivity);
- initializeMiscControls();
- initializeControlByIntent();
- initializeOverlay();
- }
-
-
- 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 = mActivity.findViewById(R.id.camera_controls);
- mOnScreenIndicators = mActivity.findViewById(R.id.on_screen_indicators);
- mFlashIndicator = (ImageView) mActivity.findViewById(R.id.menu_flash_indicator);
- 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();
- }
- }
-
- public void hideUI() {
- mCameraControls.setVisibility(View.INVISIBLE);
- hideSwitcher();
- mShutterButton.setVisibility(View.GONE);
- }
-
- public void showUI() {
- mCameraControls.setVisibility(View.VISIBLE);
- showSwitcher();
- mShutterButton.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) {
- if (mGestures != null) {
- mGestures.setOrientation(orientation);
- }
- // 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 NewVideoMenu(mActivity, this, mPieRenderer);
- mPieRenderer.setPieListener(this);
- }
- mRenderOverlay.addRenderer(mPieRenderer);
- if (mZoomRenderer == null) {
- mZoomRenderer = new ZoomRenderer(mActivity);
- }
- mRenderOverlay.addRenderer(mZoomRenderer);
- if (mGestures == null) {
- mGestures = new NewPreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer, this);
- }
- mGestures.setRenderOverlay(mRenderOverlay);
- mGestures.clearTouchReceivers();
- mGestures.addTouchReceiver(mMenuButton);
- mGestures.addTouchReceiver(mBlocker);
- if (mController.isVideoCaptureIntent()) {
- if (mReviewCancelButton != null) {
- mGestures.addTouchReceiver(mReviewCancelButton);
- }
- if (mReviewDoneButton != null) {
- mGestures.addTouchReceiver(mReviewDoneButton);
- }
- if (mReviewPlayButton != null) {
- mGestures.addTouchReceiver(mReviewPlayButton);
- }
- }
- }
-
- 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) {
- if (param == null) return;
- String value = param.getFlashMode();
- 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);
- }
- }
- }
-
- 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) {
- 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) {
- // TODO: mActivity.cancelActivityTouchHandling();
- // mActivity.setSwipingEnabled(false);
- }
-
- @Override
- public void onPieClosed() {
- // TODO: mActivity.setSwipingEnabled(true);
- }
-
- 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 onFullScreenChanged(boolean full) {
- if (mGestures != null) {
- mGestures.setEnabled(full);
- }
- if (mPopup != null) {
- dismissPopup(false, full);
- }
- if (mRenderOverlay != null) {
- // this can not happen in capture mode
- mRenderOverlay.setVisibility(full ? View.VISIBLE : View.GONE);
- }
- setShowMenu(full);
- if (mBlocker != null) {
- // this can not happen in capture mode
- mBlocker.setVisibility(full ? View.VISIBLE : View.GONE);
- }
- }
-
- public void initializePopup(PreferenceGroup pref) {
- mVideoMenu.initialize(pref);
- }
-
- public void initializeZoom(Parameters param) {
- if (param == null || !param.isZoomSupported()) return;
- 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;
- }
-
- // Gestures and touch events
-
- public boolean dispatchTouchEvent(MotionEvent m) {
- if (mPopup != null || mSwitcher.showsPopup()) {
- boolean handled = mRootView.dispatchTouchEvent(m);
- if (!handled && mPopup != null) {
- dismissPopup(false);
- }
- return handled;
- } else if (mGestures != null && mRenderOverlay != null) {
- if (mGestures.dispatchTouch(m)) {
- return true;
- } else {
- return mRootView.dispatchTouchEvent(m);
- }
- }
- return true;
- }
- public void setRecordingTime(String text) {
- mRecordingTimeView.setText(text);
- }
-
- public void setRecordingTimeTextColor(int color) {
- mRecordingTimeView.setTextColor(color);
- }
-
- public boolean isVisible() {
- return mTextureView.getVisibility() == View.VISIBLE;
- }
-
- 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() {
- }
- }
-
- @Override
- public void onSwipe(int direction) {
- if (direction == PreviewGestures.DIR_UP) {
- openMenu();
- }
- }
-
- public SurfaceTexture 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;
- }
-
- // SurfaceTexture callbacks
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- synchronized (mLock) {
- mSurfaceTexture = surface;
- mLock.notifyAll();
- }
- }
-
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- mSurfaceTexture = null;
- mController.stopPreview();
- 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/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
deleted file mode 100644
index d1dad3ffb..000000000
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ /dev/null
@@ -1,424 +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.Drawable;
-import android.os.AsyncTask;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.camera.Storage;
-import com.android.camera.ui.FilmStripView;
-import com.android.camera.ui.FilmStripView.ImageData;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A FilmStripDataProvider that provide data in the camera folder.
- *
- * The given view for camera preview won't be added until the preview info
- * has been set by setCameraPreviewInfo(int, int).
- */
-public class CameraDataAdapter implements FilmStripView.DataAdapter {
- private static final String TAG = CameraDataAdapter.class.getSimpleName();
-
- private static final int DEFAULT_DECODE_SIZE = 3000;
- private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" };
-
- private List<LocalData> mImages;
-
- private Listener mListener;
- private View mCameraPreviewView;
- private Drawable mPlaceHolder;
-
- private int mSuggestedWidth = DEFAULT_DECODE_SIZE;
- private int mSuggestedHeight = DEFAULT_DECODE_SIZE;
-
- public CameraDataAdapter(Drawable placeHolder) {
- mPlaceHolder = placeHolder;
- }
-
- public void setCameraPreviewInfo(View cameraPreview, int width, int height) {
- mCameraPreviewView = cameraPreview;
- addOrReplaceCameraData(buildCameraImageData(width, height));
- }
-
- public void requestLoad(ContentResolver resolver) {
- QueryTask qtask = new QueryTask();
- qtask.execute(resolver);
- }
-
- @Override
- public int getTotalNumber() {
- return mImages.size();
- }
-
- @Override
- public ImageData getImageData(int id) {
- if (id >= mImages.size()) return null;
- return mImages.get(id);
- }
-
- @Override
- public void suggestSize(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 (dataID >= mImages.size() || dataID < 0) {
- return null;
- }
-
- return mImages.get(dataID).getView(
- c, mSuggestedWidth, mSuggestedHeight, mPlaceHolder);
- }
-
- @Override
- public void setListener(Listener listener) {
- mListener = listener;
- if (mImages != null) mListener.onDataLoaded();
- }
-
- private LocalData buildCameraImageData(int width, int height) {
- LocalData d = new CameraPreviewData(width, height);
- return d;
- }
-
- private void addOrReplaceCameraData(LocalData data) {
- if (mImages == null) mImages = new ArrayList<LocalData>();
- if (mImages.size() == 0) {
- // No data at all.
- mImages.add(0, data);
- if (mListener != null) mListener.onDataLoaded();
- return;
- }
-
- LocalData first = mImages.get(0);
- if (first.getType() == ImageData.TYPE_CAMERA_PREVIEW) {
- // Replace the old camera data.
- mImages.set(0, data);
- if (mListener != null) {
- mListener.onDataUpdated(new StatusReporter() {
- @Override
- public boolean isDataRemoved(int id) {
- return false;
- }
-
- @Override
- public boolean isDataUpdated(int id) {
- if (id == 0) return true;
- return false;
- }
- });
- }
- } else {
- // Add a new camera data.
- mImages.add(0, data);
- if (mListener != null) {
- mListener.onDataLoaded();
- }
- }
- }
-
- private class QueryTask extends AsyncTask<ContentResolver, Void, List<LocalData>> {
- @Override
- protected List<LocalData> doInBackground(ContentResolver... resolver) {
- List<LocalData> l = null;
- Cursor c = resolver[0].query(
- Images.Media.EXTERNAL_CONTENT_URI,
- LocalPhotoData.QUERY_PROJECTION,
- MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalPhotoData.QUERY_ORDER);
- if (c == null) return null;
-
- // build up the list.
- l = new ArrayList<LocalData>();
- c.moveToFirst();
- while (!c.isLast()) {
- LocalData data = LocalPhotoData.buildFromCursor(c);
- if (data != null) {
- l.add(data);
- } else {
- Log.e(TAG, "Error decoding file:"
- + c.getString(LocalPhotoData.COL_DATA));
- }
- c.moveToNext();
- }
- c.close();
- return l;
- }
-
- @Override
- protected void onPostExecute(List<LocalData> l) {
- boolean changed = (l != mImages);
- LocalData cameraData = null;
- if (mImages != null && mImages.size() > 0) {
- cameraData = mImages.get(0);
- if (cameraData.getType() != ImageData.TYPE_CAMERA_PREVIEW) cameraData = null;
- }
-
- mImages = l;
- if (cameraData != null) {
- l.add(0, cameraData);
- if (mListener != null) {
- mListener.onDataUpdated(new StatusReporter() {
- @Override
- public boolean isDataRemoved(int id) {
- return false;
- }
-
- @Override
- public boolean isDataUpdated(int id) {
- if (id == 0) return false;
- return true;
- }
- });
- }
- } else {
- // both might be null.
- if (changed) mListener.onDataLoaded();
- }
- }
- }
-
- private abstract static class LocalData implements FilmStripView.ImageData {
- public int id;
- public String title;
- public String mimeType;
- public String path;
- // width and height should be adjusted according to orientation.
- public int width;
- public int height;
- public int supportedAction;
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public boolean isActionSupported(int action) {
- return false;
- }
-
- @Override
- public abstract int getType();
-
- abstract View getView(Context c, int width, int height, Drawable placeHolder);
- }
-
- private class CameraPreviewData extends LocalData {
- CameraPreviewData(int w, int h) {
- width = w;
- height = h;
- }
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public int getType() {
- return ImageData.TYPE_CAMERA_PREVIEW;
- }
-
- @Override
- View getView(Context c, int width, int height, Drawable placeHolder) {
- return mCameraPreviewView;
- }
- }
-
- private static class LocalPhotoData extends LocalData {
- static final String QUERY_ORDER = ImageColumns.DATE_TAKEN + " DESC, "
- + ImageColumns._ID + " DESC";
- static final String[] QUERY_PROJECTION = {
- ImageColumns._ID, // 0, int
- ImageColumns.TITLE, // 1, string
- ImageColumns.MIME_TYPE, // 2, tring
- 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
- ImageColumns.SIZE // 9, int
- };
-
- private static final int COL_ID = 0;
- private static final int COL_TITLE = 1;
- private static final int COL_MIME_TYPE = 2;
- private static final int COL_DATE_TAKEN = 3;
- private static final int COL_DATE_MODIFIED = 4;
- private static final int COL_DATA = 5;
- private static final int COL_ORIENTATION = 6;
- private static final int COL_WIDTH = 7;
- private static final int COL_HEIGHT = 8;
- private static final int COL_SIZE = 9;
-
-
- // 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 LocalPhotoData buildFromCursor(Cursor c) {
- LocalPhotoData d = new LocalPhotoData();
- d.id = c.getInt(COL_ID);
- d.title = c.getString(COL_TITLE);
- d.mimeType = c.getString(COL_MIME_TYPE);
- 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.v(TAG, "warning! zero dimension for "
- + d.path + ":" + d.width + "x" + d.height);
- Dimension dim = decodeDimension(d.path);
- if (dim != null) {
- d.width = dim.width;
- d.height = dim.height;
- } else {
- Log.v(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
- View getView(Context c,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
- ImageView v = new ImageView(c);
- v.setImageDrawable(placeHolder);
-
- v.setScaleType(ImageView.ScaleType.FIT_XY);
- LoadBitmapTask task = new LoadBitmapTask(v, decodeWidth, decodeHeight);
- task.execute();
- return v;
- }
-
-
- @Override
- public String toString() {
- return "LocalPhotoData:" + ",data=" + path + ",mimeType=" + mimeType
- + "," + width + "x" + height + ",orientation=" + orientation;
- }
-
- @Override
- public int getType() {
- return TYPE_PHOTO;
- }
-
- private static Dimension decodeDimension(String path) {
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inJustDecodeBounds = true;
- Bitmap b = BitmapFactory.decodeFile(path, opts);
- if (b == null) return null;
- Dimension d = new Dimension();
- d.width = opts.outWidth;
- d.height = opts.outHeight;
- return d;
- }
-
- private static class Dimension {
- public int width;
- public int height;
- }
-
- private class LoadBitmapTask extends AsyncTask<Void, Void, Bitmap> {
- private ImageView mView;
- private int mDecodeWidth;
- private int mDecodeHeight;
-
- public LoadBitmapTask(ImageView v, int decodeWidth, int decodeHeight) {
- mView = 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()) return null;
- b = BitmapFactory.decodeFile(path, opts);
- if (orientation != 0) {
- if (isCancelled()) return null;
- Matrix m = new Matrix();
- m.setRotate((float) orientation);
- b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
- }
- return b;
- }
-
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- if (bitmap == null) {
- Log.e(TAG, "Cannot decode bitmap file:" + path);
- return;
- }
- mView.setScaleType(ImageView.ScaleType.FIT_XY);
- mView.setImageBitmap(bitmap);
- }
- }
- }
-}
diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java
index 9840b1544..f4dd823d1 100644
--- a/src/com/android/camera/ui/FaceView.java
+++ b/src/com/android/camera/ui/FaceView.java
@@ -33,15 +33,13 @@ import android.view.View;
import com.android.camera.CameraActivity;
import com.android.camera.CameraScreenNail;
-import com.android.camera.NewPhotoUI;
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,
- NewPhotoUI.SurfaceTextureSizeChangedListener {
+ implements FocusIndicator, Rotatable {
private static final String TAG = "CAM FaceView";
private final boolean LOGV = false;
// The value for android.hardware.Camera.setDisplayOrientation.
@@ -97,11 +95,6 @@ public class FaceView extends View
mPaint.setStrokeWidth(res.getDimension(R.dimen.face_circle_stroke));
}
- 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;
diff --git a/src/com/android/camera/ui/FilmStripGestureRecognizer.java b/src/com/android/camera/ui/FilmStripGestureRecognizer.java
deleted file mode 100644
index f0e2534d3..000000000
--- a/src/com/android/camera/ui/FilmStripGestureRecognizer.java
+++ /dev/null
@@ -1,107 +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);
- 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 boolean onTouchEvent(MotionEvent event) {
- return mGestureDetector.onTouchEvent(event) || mScaleDetector.onTouchEvent(event);
- }
-
- 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 0a19effb2..000000000
--- a/src/com/android/camera/ui/FilmStripView.java
+++ /dev/null
@@ -1,830 +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.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Scroller;
-
-public class FilmStripView extends ViewGroup {
- private static final String TAG = FilmStripView.class.getSimpleName();
- private static final int BUFFER_SIZE = 5;
- // Horizontal padding of children.
- private static final int H_PADDING = 50;
- // Duration to go back to the first.
- private static final int DURATION_BACK_ANIM = 500;
- private static final int DURATION_SCROLL_TO_FILMSTRIP = 350;
- private static final int DURATION_GEOMETRY_ADJUST = 200;
- private static final float FILM_STRIP_SCALE = 0.6f;
- private static final float MAX_SCALE = 1f;
-
- private Context mContext;
- private FilmStripGestureRecognizer mGestureRecognizer;
- private DataAdapter mDataAdapter;
- private final Rect mDrawArea = new Rect();
-
- private int mCurrentInfo;
- private float mScale;
- private GeometryAnimator mGeometryAnimator;
- private int mCenterPosition = -1;
- private ViewInfo[] mViewInfo = new ViewInfo[BUFFER_SIZE];
-
- // 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 mCenterPosition is not adjusted with the orientation.
- // Set this to true when onSizeChanged is called to make sure we adjust
- // mCenterPosition accordingly.
- private boolean mAnchorPending;
-
- public interface ImageData {
- public static final int TYPE_NONE = 0;
- public static final int TYPE_CAMERA_PREVIEW = 1;
- public static final int TYPE_PHOTO = 2;
- public static final int TYPE_VIDEO = 3;
- public static final int TYPE_PHOTOSPHERE = 4;
-
- // 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 = 2;
-
- // SIZE_FULL means disgard the width or height when deciding the view size
- // of this ImageData, just use full screen size.
- public static final int SIZE_FULL = -2;
-
- // The values returned by getWidth() and getHeight() will be used for layout.
- public int getWidth();
- public int getHeight();
- public int getType();
- public boolean isActionSupported(int action);
- }
-
- public interface DataAdapter {
- public interface StatusReporter {
- public boolean isDataRemoved(int id);
- public boolean isDataUpdated(int id);
- }
-
- 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(StatusReporter reporter);
- public void onDataInserted(int dataID);
- public void onDataRemoved(int dataID);
- }
-
- public int getTotalNumber();
- public View getView(Context context, int id);
- public ImageData getImageData(int id);
- public void suggestSize(int w, int h);
-
- public void setListener(Listener listener);
- }
-
- // 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 float mOffsetY;
-
- public ViewInfo(int id, View v) {
- v.setPivotX(0f);
- v.setPivotY(0f);
- mDataID = id;
- mView = v;
- mLeftPosition = -1;
- mOffsetY = 0;
- }
-
- public int getID() {
- return mDataID;
- }
-
- public void setLeftPosition(int pos) {
- mLeftPosition = pos;
- }
-
- public int getLeftPosition() {
- return mLeftPosition;
- }
-
- public float getOffsetY() {
- return mOffsetY;
- }
-
- public void setOffsetY(float offset) {
- mOffsetY = offset;
- }
-
- 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
- + mOffsetY);
- layoutAt(left, top);
- mView.setScaleX(scale);
- mView.setScaleY(scale);
- }
- }
-
- public FilmStripView(Context context) {
- super(context);
- init(context);
- }
-
- public FilmStripView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public FilmStripView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
-
- private void init(Context context) {
- mCurrentInfo = (BUFFER_SIZE - 1) / 2;
- // 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;
- mGeometryAnimator = new GeometryAnimator(context);
- mGestureRecognizer =
- new FilmStripGestureRecognizer(context, new MyGestureReceiver());
- }
-
- public float getScale() {
- return mScale;
- }
-
- public boolean isAnchoredTo(int id) {
- if (mViewInfo[mCurrentInfo].getID() == id
- && mViewInfo[mCurrentInfo].getCenterX() == mCenterPosition) {
- return true;
- }
- return false;
- }
-
- public 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 (mGeometryAnimator.hasNewGeometry()) {
- layoutChildren();
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- int boundWidth = MeasureSpec.getSize(widthMeasureSpec);
- int boundHeight = MeasureSpec.getSize(heightMeasureSpec);
- if (mDataAdapter != null) {
- mDataAdapter.suggestSize(boundWidth / 2, boundHeight / 2);
- }
-
- int wMode = View.MeasureSpec.EXACTLY;
- int hMode = View.MeasureSpec.EXACTLY;
-
- for (int i = 0; i < mViewInfo.length; i++) {
- ViewInfo info = mViewInfo[i];
- if (mViewInfo[i] == null) continue;
-
- int imageWidth = mDataAdapter.getImageData(info.getID()).getWidth();
- int imageHeight = mDataAdapter.getImageData(info.getID()).getHeight();
- if (imageWidth == ImageData.SIZE_FULL) imageWidth = boundWidth;
- if (imageHeight == ImageData.SIZE_FULL) imageHeight = boundHeight;
-
- int scaledWidth = boundWidth;
- int scaledHeight = boundHeight;
-
- if (imageWidth * scaledHeight > scaledWidth * imageHeight) {
- scaledHeight = imageHeight * scaledWidth / imageWidth;
- } else {
- scaledWidth = imageWidth * scaledHeight / imageHeight;
- }
- scaledWidth += H_PADDING * 2;
- mViewInfo[i].getView().measure(
- View.MeasureSpec.makeMeasureSpec(scaledWidth, wMode)
- , View.MeasureSpec.makeMeasureSpec(scaledHeight, hMode));
- }
- setMeasuredDimension(boundWidth, boundHeight);
- }
-
- private int findTheNearestView(int pointX) {
-
- int nearest = 0;
- // find the first non-null ViewInfo.
- for (; 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) {
- View v = mDataAdapter.getView(mContext, dataID);
- if (v == null) return null;
- v.setPadding(H_PADDING, 0, H_PADDING, 0);
- ViewInfo info = new ViewInfo(dataID, v);
- addView(info.getView());
- return info;
- }
-
- // We try to keep the one closest to the center of the screen at position mCurrentInfo.
- private void stepIfNeeded() {
- int nearest = findTheNearestView(mCenterPosition);
- // no change made.
- if (nearest == -1 || nearest == mCurrentInfo) return;
-
- int adjust = nearest - mCurrentInfo;
- if (adjust > 0) {
- for (int k = 0; k < adjust; k++) {
- if (mViewInfo[k] != null) {
- removeView(mViewInfo[k].getView());
- }
- }
- 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--) {
- if (mViewInfo[k] != null) {
- removeView(mViewInfo[k].getView());
- }
- }
- 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);
- }
- }
- }
-
- // Don't go out of bound.
- private void adjustCenterPosition() {
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr == null) return;
-
- if (curr.getID() == 0 && mCenterPosition < curr.getCenterX()) {
- mCenterPosition = curr.getCenterX();
- mGeometryAnimator.stopScroll();
- }
- if (curr.getID() == mDataAdapter.getTotalNumber() - 1
- && mCenterPosition > curr.getCenterX()) {
- mCenterPosition = curr.getCenterX();
- mGeometryAnimator.stopScroll();
- }
- }
-
- private void layoutChildren() {
- if (mAnchorPending) {
- mCenterPosition = mViewInfo[mCurrentInfo].getCenterX();
- mAnchorPending = false;
- }
-
- if (mGeometryAnimator.hasNewGeometry()) {
- mCenterPosition = mGeometryAnimator.getNewPosition();
- mScale = mGeometryAnimator.getNewScale();
- }
-
- adjustCenterPosition();
-
- mViewInfo[mCurrentInfo].layoutIn(mDrawArea, mCenterPosition, mScale);
-
- // images on the left
- for (int infoID = mCurrentInfo - 1; infoID >= 0; infoID--) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr != null) {
- ViewInfo next = mViewInfo[infoID + 1];
- curr.setLeftPosition(
- next.getLeftPosition() - curr.getView().getMeasuredWidth());
- curr.layoutIn(mDrawArea, mCenterPosition, mScale);
- }
- }
-
- // images on the right
- for (int infoID = mCurrentInfo + 1; infoID < BUFFER_SIZE; infoID++) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr != null) {
- ViewInfo prev = mViewInfo[infoID - 1];
- curr.setLeftPosition(
- prev.getLeftPosition() + prev.getView().getMeasuredWidth());
- curr.layoutIn(mDrawArea, mCenterPosition, mScale);
- }
- }
-
- stepIfNeeded();
- invalidate();
- }
-
- @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();
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (w == oldw && h == oldh) return;
- if (mViewInfo[mCurrentInfo] != null && mScale == 1f
- && isAnchoredTo(mViewInfo[mCurrentInfo].getID())) {
- mAnchorPending = true;
- }
- }
-
- public void setDataAdapter(DataAdapter adapter) {
- mDataAdapter = adapter;
- mDataAdapter.suggestSize(getMeasuredWidth(), getMeasuredHeight());
- mDataAdapter.setListener(new DataAdapter.Listener() {
- @Override
- public void onDataLoaded() {
- reload();
- }
-
- @Override
- public void onDataUpdated(DataAdapter.StatusReporter reporter) {
- update(reporter);
- }
-
- @Override
- public void onDataInserted(int dataID) {
- }
-
- @Override
- public void onDataRemoved(int dataID) {
- }
- });
- }
-
- public boolean isInCameraFullscreen() {
- return (isAnchoredTo(0) && mScale == 1f
- && getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (isInCameraFullscreen()) return false;
- return true;
- }
-
- @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.StatusReporter 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)) {
- mCenterPosition = -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;
-
- int currentData = 0;
- int currentLeft = 0;
- mViewInfo[mCurrentInfo] = buildInfoFromData(currentData);
- mViewInfo[mCurrentInfo].setLeftPosition(currentLeft);
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW
- && currentLeft == 0) {
- // we are in camera mode by default.
- mGeometryAnimator.lockPosition(currentLeft);
- }
- 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();
- }
-
- // GeometryAnimator controls all the geometry animations. It passively
- // tells the geometry information on demand.
- private class GeometryAnimator implements
- 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 mCanStopScale;
-
- private boolean mIsPositionLocked;
- private int mLockedPosition;
-
- private Runnable mPostAction;
-
- GeometryAnimator(Context context) {
- mScroller = new Scroller(context);
- mHasNewPosition = false;
- mScaleAnimator = new ValueAnimator();
- mScaleAnimator.addUpdateListener(GeometryAnimator.this);
- mScaleAnimator.addListener(GeometryAnimator.this);
- mDecelerateInterpolator = new DecelerateInterpolator();
- mCanStopScroll = true;
- mCanStopScale = true;
- mHasNewScale = false;
- }
-
- 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 hasNewGeometry() before getting the new scale value.
- float getNewScale() {
- if (!mHasNewScale) return mScale;
- mHasNewScale = false;
- return mNewScale;
- }
-
- // Always call hasNewGeometry() before getting the new position value.
- int getNewPosition() {
- if (mIsPositionLocked) return mLockedPosition;
- if (!mHasNewPosition) return mCenterPosition;
- return mScroller.getCurrX();
- }
-
- void lockPosition(int pos) {
- mIsPositionLocked = true;
- mLockedPosition = pos;
- }
-
- void unlockPosition() {
- if (mIsPositionLocked) {
- // only when the position is previously locked we set the current
- // position to make it consistent.
- mCenterPosition = mLockedPosition;
- mIsPositionLocked = false;
- }
- }
-
- void fling(int velocityX, int minX, int maxX) {
- if (!stopScroll() || mIsPositionLocked) return;
- mScroller.fling(mCenterPosition, 0, velocityX, 0, minX, maxX, 0, 0);
- }
-
- boolean stopScroll() {
- if (!mCanStopScroll) return false;
- mScroller.forceFinished(true);
- mHasNewPosition = false;
- return true;
- }
-
- boolean stopScale() {
- if (!mCanStopScale) return false;
- mScaleAnimator.cancel();
- mHasNewScale = false;
- return true;
- }
-
- void stop() {
- stopScroll();
- stopScale();
- }
-
- void scrollTo(int position, int duration, boolean interruptible) {
- if (!stopScroll() || mIsPositionLocked) return;
- mCanStopScroll = interruptible;
- stopScroll();
- mScroller.startScroll(mCenterPosition, 0, position - mCenterPosition,
- 0, duration);
- }
-
- void scrollTo(int position, int duration) {
- scrollTo(position, duration, true);
- }
-
- void scaleTo(float scale, int duration, boolean interruptible) {
- if (!stopScale()) return;
- mCanStopScale = interruptible;
- mScaleAnimator.setDuration(duration);
- mScaleAnimator.setFloatValues(mScale, scale);
- mScaleAnimator.setInterpolator(mDecelerateInterpolator);
- mScaleAnimator.start();
- mHasNewScale = true;
- }
-
- void scaleTo(float scale, int duration) {
- scaleTo(scale, duration, true);
- }
-
- void setPostAction(Runnable act) {
- mPostAction = act;
- }
-
- @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) {
- if (mPostAction != null) {
- mPostAction.run();
- mPostAction = null;
- }
- mCanStopScale = true;
- }
-
- @Override
- public void onAnimationCancel(Animator anim) {
- mPostAction = null;
- }
-
- @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) {
- return false;
- }
-
- @Override
- public boolean onDoubleTap(float x, float y) {
- return false;
- }
-
- @Override
- public boolean onDown(float x, float y) {
- mGeometryAnimator.stop();
- return true;
- }
-
- @Override
- public boolean onScroll(float x, float y, float dx, float dy) {
- int deltaX = (int) (dx / mScale);
- if (deltaX > 0 && isInCameraFullscreen()) {
- mGeometryAnimator.unlockPosition();
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- }
-
- mCenterPosition += deltaX;
-
- // Vertical part. Promote or demote.
- int scaledDeltaY = (int) (dy / mScale);
-
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null) continue;
- Rect hitRect = new Rect();
- View v = mViewInfo[i].getView();
- v.getHitRect(hitRect);
- if (hitRect.contains((int) x, (int) y)) {
- ImageData data = mDataAdapter.getImageData(mViewInfo[i].getID());
- if ((data.isActionSupported(ImageData.ACTION_DEMOTE) && dy > 0)
- || (data.isActionSupported(ImageData.ACTION_PROMOTE) && dy < 0)) {
- mViewInfo[i].setOffsetY(mViewInfo[i].getOffsetY() - dy);
- }
- break;
- }
- }
-
- layoutChildren();
- return true;
- }
-
- @Override
- public boolean onFling(float velocityX, float velocityY) {
- float scaledVelocityX = velocityX / mScale;
- if (isInCameraFullscreen() && scaledVelocityX < 0) {
- mGeometryAnimator.unlockPosition();
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- }
- ViewInfo info = mViewInfo[mCurrentInfo];
- int w = getWidth();
- if (info == null) return true;
- mGeometryAnimator.fling((int) -scaledVelocityX,
- // estimation of possible length on the left
- info.getLeftPosition() - info.getID() * w * 2,
- // estimation of possible length on the right
- info.getLeftPosition()
- + (mDataAdapter.getTotalNumber() - info.getID()) * w * 2);
- layoutChildren();
- return true;
- }
-
- @Override
- public boolean onScaleBegin(float focusX, float focusY) {
- if (isInCameraFullscreen()) return false;
- mScaleTrend = 1f;
- return true;
- }
-
- @Override
- public boolean onScale(float focusX, float focusY, float scale) {
- if (isInCameraFullscreen()) return false;
-
- mScaleTrend = mScaleTrend * 0.5f + scale * 0.5f;
- mScale *= scale;
- if (mScale <= FILM_STRIP_SCALE) mScale = FILM_STRIP_SCALE;
- if (mScale >= MAX_SCALE) mScale = MAX_SCALE;
- layoutChildren();
- return true;
- }
-
- @Override
- public void onScaleEnd() {
- if (mScaleTrend >= 1f) {
- if (mScale != 1f) {
- mGeometryAnimator.scaleTo(1f, DURATION_GEOMETRY_ADJUST, false);
- }
-
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW) {
- if (isAnchoredTo(0)) {
- mGeometryAnimator.lockPosition(mViewInfo[mCurrentInfo].getCenterX());
- } else {
- mGeometryAnimator.scrollTo(
- mViewInfo[mCurrentInfo].getCenterX(),
- DURATION_GEOMETRY_ADJUST, false);
- mGeometryAnimator.setPostAction(mLockPositionRunnable);
- }
- }
- } else {
- // Scale down to film strip mode.
- if (mScale == FILM_STRIP_SCALE) {
- mGeometryAnimator.unlockPosition();
- return;
- }
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- mGeometryAnimator.setPostAction(mUnlockPositionRunnable);
- }
- }
-
- private Runnable mLockPositionRunnable = new Runnable() {
- @Override
- public void run() {
- mGeometryAnimator.lockPosition(mViewInfo[mCurrentInfo].getCenterX());
- }
- };
-
- private Runnable mUnlockPositionRunnable = new Runnable() {
- @Override
- public void run() {
- mGeometryAnimator.unlockPosition();
- }
- };
- }
-}
diff --git a/src/com/android/camera/ui/NewCameraRootView.java b/src/com/android/camera/ui/NewCameraRootView.java
deleted file mode 100644
index a507b147c..000000000
--- a/src/com/android/camera/ui/NewCameraRootView.java
+++ /dev/null
@@ -1,91 +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.Gravity;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-
-public class NewCameraRootView extends FrameLayout
- implements RotatableLayout.RotationListener {
-
- private int mOffset = 0;
- public NewCameraRootView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- }
-
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- super.fitSystemWindows(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;
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- if (insets.bottom > 0) {
- mOffset = insets.bottom;
- } else if (insets.right > 0) {
- mOffset = insets.right;
- }
- Configuration config = getResources().getConfiguration();
- if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
- lp.setMargins(0, 0, 0, mOffset);
- } else if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- lp.setMargins(0, 0, mOffset, 0);
- }
- CameraControls controls = (CameraControls) findViewById(R.id.camera_controls);
- if (controls != null) {
- controls.setRotationListener(this);
- controls.adjustControlsToRightPosition();
- }
- return true;
- }
-
- public void cameraModuleChanged() {
- CameraControls controls = (CameraControls) findViewById(R.id.camera_controls);
- if (controls != null) {
- controls.setRotationListener(this);
- controls.adjustControlsToRightPosition();
- }
- }
-
- @Override
- public void onRotation(int rotation) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- int b = lp.bottomMargin;
- int t = lp.topMargin;
- int l = lp.leftMargin;
- int r = lp.rightMargin;
- rotation = (rotation + 360) % 360;
- if (rotation == 90) {
- lp.setMargins(b, l, t, r);
- } else if (rotation == 270) {
- lp.setMargins(t, r, b, l);
- } else if (rotation == 180) {
- lp.setMargins(r, b, l, t);
- }
- }
-}