return;
}
- CameraHolder.instance().keep();
closeModule(mCurrentModule);
int oldModuleIndex = mCurrentModeIndex;
+++ /dev/null
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * {@code CameraButtonIntentReceiver} is invoked when the camera button is
- * long-pressed.
- *
- * It is declared in {@code AndroidManifest.xml} to receive the
- * {@code android.intent.action.CAMERA_BUTTON} intent.
- *
- * After making sure we can use the camera hardware, it starts the Camera
- * activity.
- */
-public class CameraButtonIntentReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // Try to get the camera hardware
- CameraHolder holder = CameraHolder.instance();
- ComboPreferences pref = new ComboPreferences(context);
- int cameraId = CameraSettings.readPreferredCameraId(pref);
- if (holder.tryOpen(null, cameraId, null) == null) {
- return;
- }
-
- // We are going to launch the camera, so hold the camera for later use
- holder.keep();
- holder.release();
- Intent i = new Intent(Intent.ACTION_MAIN);
- i.setClass(context, CameraActivity.class);
- i.addCategory(Intent.CATEGORY_LAUNCHER);
- i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- context.startActivity(i);
- }
-}
+++ /dev/null
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.camera;
-
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.android.camera.app.CameraManager;
-import com.android.camera.app.CameraManager.CameraProxy;
-import com.android.camera.app.CameraManagerFactory;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-
-import static com.android.camera.util.CameraUtil.Assert;
-
-/**
- * The class is used to hold an {@code android.hardware.Camera} instance.
- *
- * <p>The {@code open()} and {@code release()} calls are similar to the ones
- * in {@code android.hardware.Camera}. The difference is if {@code keep()} is
- * called before {@code release()}, CameraHolder will try to hold the {@code
- * android.hardware.Camera} instance for a while, so if {@code open()} is
- * called soon after, we can avoid the cost of {@code open()} in {@code
- * android.hardware.Camera}.
- *
- * <p>This is used in switching between different modules.
- */
-public class CameraHolder {
- private static final String TAG = "CameraHolder";
- private static final int KEEP_CAMERA_TIMEOUT = 3000; // 3 seconds
- private CameraProxy mCameraDevice;
- private long mKeepBeforeTime; // Keep the Camera before this time.
- private final Handler mHandler;
- private boolean mCameraOpened; // true if camera is opened
- private final int mNumberOfCameras;
- private int mCameraId = -1; // current camera id
- private int mBackCameraId = -1;
- private int mFrontCameraId = -1;
- private final CameraInfo[] mInfo;
- private static CameraProxy mMockCamera[];
- private static CameraInfo mMockCameraInfo[];
-
- /* Debug double-open issue */
- private static final boolean DEBUG_OPEN_RELEASE = true;
- private static class OpenReleaseState {
- long time;
- int id;
- String device;
- String[] stack;
- }
- private static ArrayList<OpenReleaseState> sOpenReleaseStates =
- new ArrayList<OpenReleaseState>();
- private static SimpleDateFormat sDateFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH:mm:ss.SSS");
-
- private static synchronized void collectState(int id, CameraProxy device) {
- OpenReleaseState s = new OpenReleaseState();
- s.time = System.currentTimeMillis();
- s.id = id;
- if (device == null) {
- s.device = "(null)";
- } else {
- s.device = device.toString();
- }
-
- StackTraceElement[] stack = Thread.currentThread().getStackTrace();
- String[] lines = new String[stack.length];
- for (int i = 0; i < stack.length; i++) {
- lines[i] = stack[i].toString();
- }
- s.stack = lines;
-
- if (sOpenReleaseStates.size() > 10) {
- sOpenReleaseStates.remove(0);
- }
- sOpenReleaseStates.add(s);
- }
-
- private static synchronized void dumpStates() {
- for (int i = sOpenReleaseStates.size() - 1; i >= 0; i--) {
- OpenReleaseState s = sOpenReleaseStates.get(i);
- String date = sDateFormat.format(new Date(s.time));
- Log.d(TAG, "State " + i + " at " + date);
- Log.d(TAG, "mCameraId = " + s.id + ", mCameraDevice = " + s.device);
- Log.d(TAG, "Stack:");
- for (int j = 0; j < s.stack.length; j++) {
- Log.d(TAG, " " + s.stack[j]);
- }
- }
- }
-
- // We store the camera parameters when we actually open the device,
- // so we can restore them in the subsequent open() requests by the user.
- // This prevents the parameters set by PhotoModule used by VideoModule
- // inadvertently.
- private Parameters mParameters;
-
- // Use a singleton.
- private static CameraHolder sHolder;
- public static synchronized CameraHolder instance() {
- if (sHolder == null) {
- sHolder = new CameraHolder();
- }
- return sHolder;
- }
-
- private static final int RELEASE_CAMERA = 1;
- private class MyHandler extends Handler {
- MyHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case RELEASE_CAMERA:
- synchronized (CameraHolder.this) {
- // In 'CameraHolder.open', the 'RELEASE_CAMERA' message
- // will be removed if it is found in the queue. However,
- // there is a chance that this message has been handled
- // before being removed. So, we need to add a check
- // here:
- if (!mCameraOpened) release();
- }
- break;
- }
- }
- }
-
- public static void injectMockCamera(CameraInfo[] info, CameraProxy[] camera) {
- mMockCameraInfo = info;
- mMockCamera = camera;
- sHolder = new CameraHolder();
- }
-
- private CameraHolder() {
- HandlerThread ht = new HandlerThread("CameraHolder");
- ht.start();
- mHandler = new MyHandler(ht.getLooper());
- if (mMockCameraInfo != null) {
- mNumberOfCameras = mMockCameraInfo.length;
- mInfo = mMockCameraInfo;
- } else {
- mNumberOfCameras = android.hardware.Camera.getNumberOfCameras();
- mInfo = new CameraInfo[mNumberOfCameras];
- for (int i = 0; i < mNumberOfCameras; i++) {
- mInfo[i] = new CameraInfo();
- android.hardware.Camera.getCameraInfo(i, mInfo[i]);
- }
- }
-
- // get the first (smallest) back and first front camera id
- for (int i = 0; i < mNumberOfCameras; i++) {
- if (mBackCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_BACK) {
- mBackCameraId = i;
- } else if (mFrontCameraId == -1 && mInfo[i].facing == CameraInfo.CAMERA_FACING_FRONT) {
- mFrontCameraId = i;
- }
- }
- }
-
- public int getNumberOfCameras() {
- return mNumberOfCameras;
- }
-
- public CameraInfo[] getCameraInfo() {
- return mInfo;
- }
-
- public synchronized CameraProxy open(
- Handler handler, int cameraId,
- CameraManager.CameraOpenCallback cb) {
- if (DEBUG_OPEN_RELEASE) {
- collectState(cameraId, mCameraDevice);
- if (mCameraOpened) {
- Log.e(TAG, "double open");
- dumpStates();
- }
- }
- Assert(!mCameraOpened);
- if (mCameraDevice != null && mCameraId != cameraId) {
- mCameraDevice.release(true);
- mCameraDevice = null;
- mCameraId = -1;
- }
- if (mCameraDevice == null) {
- Log.v(TAG, "open camera " + cameraId);
- if (mMockCameraInfo == null) {
- mCameraDevice = CameraManagerFactory
- .getAndroidCameraManager().cameraOpenOld(handler, cameraId, cb);
- } else {
- if (mMockCamera != null) {
- mCameraDevice = mMockCamera[cameraId];
- } else {
- Log.e(TAG, "MockCameraInfo found, but no MockCamera provided.");
- mCameraDevice = null;
- }
- }
- if (mCameraDevice == null) {
- Log.e(TAG, "fail to connect Camera:" + mCameraId + ", aborting.");
- return null;
- }
- mCameraId = cameraId;
- mParameters = mCameraDevice.getParameters();
- } else {
- if (!mCameraDevice.reconnectOld(handler, cb)) {
- Log.e(TAG, "fail to reconnect Camera:" + mCameraId + ", aborting.");
- return null;
- }
- mCameraDevice.setParameters(mParameters);
- }
- mCameraOpened = true;
- mHandler.removeMessages(RELEASE_CAMERA);
- mKeepBeforeTime = 0;
- return mCameraDevice;
- }
-
- /**
- * Tries to open the hardware camera. If the camera is being used or
- * unavailable then return {@code null}.
- */
- public synchronized CameraProxy tryOpen(
- Handler handler, int cameraId, CameraManager.CameraOpenCallback cb) {
- return (!mCameraOpened ? open(handler, cameraId, cb) : null);
- }
-
- public synchronized void release() {
- if (DEBUG_OPEN_RELEASE) {
- collectState(mCameraId, mCameraDevice);
- }
-
- if (mCameraDevice == null) return;
-
- strongRelease();
- }
-
- public synchronized void strongRelease() {
- if (mCameraDevice == null) return;
-
- mCameraOpened = false;
- mCameraDevice.release(true);
- mCameraDevice = null;
- // We must set this to null because it has a reference to Camera.
- // Camera has references to the listeners.
- mParameters = null;
- mCameraId = -1;
- }
-
- public void keep() {
- keep(KEEP_CAMERA_TIMEOUT);
- }
-
- public synchronized void keep(int time) {
- // We allow mCameraOpened in either state for the convenience of the
- // calling activity. The activity may not have a chance to call open()
- // before the user switches to another activity.
- mKeepBeforeTime = System.currentTimeMillis() + time;
- }
-
- public int getBackCameraId() {
- return mBackCameraId;
- }
-
- public int getFrontCameraId() {
- return mFrontCameraId;
- }
-}
* com.android.camera.app.CameraProvider#requestCamera(int)}. The camera
* will be returned through {@link
* #onCameraAvailable(com.android.camera.app.CameraManager.CameraProxy)}
- * when it's available.
+ * when it's available. This is a no-op when there's no back camera
+ * available.
*/
protected void requestBackCamera() {
- mCameraProvider.requestCamera(mCameraProvider.getFirstBackCameraId());
+ int backCameraId = mCameraProvider.getFirstBackCameraId();
+ if (backCameraId != -1) {
+ mCameraProvider.requestCamera(backCameraId);
+ }
+ }
+
+ /**
+ * Releases the back camera through {@link CameraProvider}.
+ * This calls {@link
+ * com.android.camera.app.CameraProvider#releaseCamera(int)}.
+ * This is a no-op when there's no back camera available.
+ */
+ protected void releaseBackCamera() {
+ int backCameraId = mCameraProvider.getFirstBackCameraId();
+ if (backCameraId != -1) {
+ mCameraProvider.releaseCamera(backCameraId);
+ }
}
}
import android.media.CamcorderProfile;
import android.util.Log;
+import com.android.camera.app.AppController;
import com.android.camera.settings.SettingsManager;
import com.android.camera.util.ApiHelper;
import com.android.camera.util.CameraUtil;
private static final String TAG = "CameraSettings";
+ private final AppController mActivityController;
private final Context mContext;
private final Parameters mParameters;
private final CameraInfo[] mCameraInfo;
private final int mCameraId;
private final SettingsManager mSettingsManager;
- public CameraSettings(CameraActivity activity, Parameters parameters,
+ public CameraSettings(AppController app, Parameters parameters,
int cameraId, CameraInfo[] cameraInfo) {
- mContext = (Context) activity;
+ mActivityController = app;
+ mContext = app.getAndroidContext();
mParameters = parameters;
mCameraId = cameraId;
mCameraInfo = cameraInfo;
- mSettingsManager = activity.getSettingsManager();
+ mSettingsManager = mActivityController.getSettingsManager();
}
public PreferenceGroup getPreferenceGroup(int preferenceRes) {
removePreference(group, cameraHdr.getKey());
}
- int frontCameraId = CameraHolder.instance().getFrontCameraId();
+ int frontCameraId = mActivityController.getCameraProvider().getFirstFrontCameraId();
boolean isFrontCamera = (frontCameraId == mCameraId);
if (cameraHdrPlus != null && (!ApiHelper.HAS_CAMERA_HDR_PLUS ||
!GcamHelper.hasGcamCapture() || isFrontCamera)) {
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package com.android.camera;
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.SharedPreferencesBackupHelper;
-import android.content.Context;
+import android.hardware.Camera.CameraInfo;
-public class CameraBackupAgent extends BackupAgentHelper {
- private static final String CAMERA_BACKUP_KEY = "camera_prefs";
+import com.android.camera.app.CameraManager.CameraProxy;
- public void onCreate () {
- Context context = getApplicationContext();
- String prefNames[] = ComboPreferences.getSharedPreferencesNames(context);
+/**
+ * The class is kept to make sure the tests can build.
+ */
+@Deprecated
+public class CameraTestDevice {
+
+ public static void injectMockCamera(CameraInfo[] info, CameraProxy[] camera) {
+ }
- addHelper(CAMERA_BACKUP_KEY, new SharedPreferencesBackupHelper(context, prefNames));
+ private CameraTestDevice() {
}
}
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;
+import com.android.camera.app.AppController;
+
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
-import com.android.camera.util.UsageStatistics;
-
public class ComboPreferences implements
SharedPreferences,
OnSharedPreferenceChangeListener {
movePrefFrom(prefMap, CameraSettings.KEY_VIDEO_EFFECT, src);
}
- public static String[] getSharedPreferencesNames(Context context) {
- int numOfCameras = CameraHolder.instance().getNumberOfCameras();
+ public static String[] getSharedPreferencesNames(AppController app) {
+ int numOfCameras = app.getCameraProvider().getNumberOfCameras();
String prefNames[] = new String[numOfCameras + 1];
- prefNames[0] = getGlobalSharedPreferencesName(context);
+ prefNames[0] = getGlobalSharedPreferencesName(app.getAndroidContext());
for (int i = 0; i < numOfCameras; i++) {
- prefNames[i + 1] = getLocalSharedPreferencesName(context, i);
+ prefNames[i + 1] = getLocalSharedPreferencesName(app.getAndroidContext(), i);
}
return prefNames;
}
return;
}
// Check if the back camera exists
- int backCameraId = CameraHolder.instance().getBackCameraId();
+ int backCameraId = mAppController.getCameraProvider().getFirstBackCameraId();
if (backCameraId == -1) {
// If there is no back camera, do not show the prompt.
return;
}
if (mParameters.getMaxNumDetectedFaces() > 0) {
mFaceDetectionStarted = true;
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ CameraInfo info = mAppController.getCameraProvider().getCameraInfo()[mCameraId];
mUI.onStartFaceDetection(mDisplayOrientation,
(info.facing == CameraInfo.CAMERA_FACING_FRONT));
mCameraDevice.setFaceDetectionCallback(mHandler, mUI);
if (mFocusManager != null) {
mFocusManager.removeMessages();
} else {
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ CameraInfo info = mAppController.getCameraProvider().getCameraInfo()[mCameraId];
mMirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
String[] defaultFocusModes = mActivity.getResources().getStringArray(
R.array.pref_camera_focusmode_default_array);
import android.hardware.Camera.Size;
import android.location.Location;
import android.net.Uri;
-import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import com.android.camera.CameraActivity;
import com.android.camera.CameraDisabledException;
-import com.android.camera.CameraHolder;
-import com.android.camera.app.CameraManager;
-import com.android.camera.app.CameraManagerFactory;
import com.android.camera2.R;
import java.io.Closeable;
}
}
- public static CameraManager.CameraProxy openCamera(
- Activity activity, final int cameraId,
- Handler handler, final CameraManager.CameraOpenCallback cb) {
- try {
- throwIfCameraDisabled(activity);
- return CameraHolder.instance().open(handler, cameraId, cb);
- } catch (CameraDisabledException ex) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- cb.onCameraDisabled(cameraId);
- }
- });
- }
- return null;
- }
-
public static void showErrorAndFinish(final Activity activity, int msgId) {
DialogInterface.OnClickListener buttonListener =
new DialogInterface.OnClickListener() {
package com.android.camera.activity;
-import android.hardware.Camera.Parameters;
import android.test.suitebuilder.annotation.LargeTest;
import com.android.camera.CameraActivity;
-import com.android.camera.CameraHolder;
+import com.android.camera.CameraTestDevice;
import com.android.gallery3d.R;
import static com.google.testing.littlemock.LittleMock.doReturn;
@LargeTest
public void testTakePicture() throws Exception {
- CameraHolder.injectMockCamera(mCameraInfo, mOneMockCamera);
+ CameraTestDevice.injectMockCamera(mCameraInfo, mOneMockCamera);
getActivity();
getInstrumentation().waitForIdleSync();
import android.view.MotionEvent;
import android.view.View;
-import com.android.camera.CameraHolder;
+import com.android.camera.CameraTestDevice;
import com.android.camera.app.CameraManager.CameraProxy;
import com.android.camera.util.CameraUtil;
import com.android.gallery3d.R;
@Override
protected void tearDown() throws Exception {
super.tearDown();
- CameraHolder.injectMockCamera(null, null);
+ CameraTestDevice.injectMockCamera(null, null);
}
protected void internalTestFailToConnect() throws Exception {
- CameraHolder.injectMockCamera(mCameraInfo, null);
+ CameraTestDevice.injectMockCamera(mCameraInfo, null);
getActivity();
Instrumentation inst = getInstrumentation();