Adding gcam module to Camera2 app.

Bug: 10430748

Change-Id: I0c53085553cd8505ba376b1518507d36065894f5
diff --git a/res/drawable-mdpi/ic_switch_gcam.png b/res/drawable-mdpi/ic_switch_gcam.png
new file mode 100644
index 0000000..84fe825
--- /dev/null
+++ b/res/drawable-mdpi/ic_switch_gcam.png
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d9fb38c..021fc4e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -510,6 +510,8 @@
     <string name="accessibility_switch_to_panorama">Switch to panorama</string>
     <!-- The button to switch to the Photo Sphere mode. [CHAR LIMIT = NONE] -->
     <string name="accessibility_switch_to_photo_sphere">Switch to Photo Sphere</string>
+    <!-- The button to switch to the high quality mode. [CHAR LIMIT = NONE] -->
+    <string name="accessibility_switch_to_gcam">Switch to high quality</string>
     <!-- The button in review mode indicating that the photo taking, video recording, and panorama saving session should be canceled [CHAR LIMIT = NONE] -->
     <string name="accessibility_review_cancel">Review cancel</string>
     <!-- The button in review mode indicating that the taken photo/video is OK to be attached/uploaded [CHAR LIMIT = NONE] -->
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 46dc2ba..d733964 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -71,6 +71,7 @@
 import com.android.camera.ui.FilmStripView;
 import com.android.camera.util.ApiHelper;
 import com.android.camera.util.CameraUtil;
+import com.android.camera.util.GcamHelper;
 import com.android.camera.util.PhotoSphereHelper;
 import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
 import com.android.camera2.R;
@@ -838,7 +839,8 @@
             // read the module index from the last time the user changed modes
             SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
             moduleIndex = prefs.getInt(PREF_STARTUP_MODULE_INDEX, -1);
-            if (moduleIndex < 0) {
+            if ((moduleIndex == ModuleSwitcher.GCAM_MODULE_INDEX &&
+                    !GcamHelper.hasGcamCapture(this)) || moduleIndex < 0) {
                 moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
             }
         }
@@ -1141,7 +1143,11 @@
             case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX:
                 mCurrentModule = PhotoSphereHelper.createPanoramaModule();
                 break;
-
+            case ModuleSwitcher.GCAM_MODULE_INDEX:
+                // Force immediate release of Camera instance
+                CameraHolder.instance().strongRelease();
+                mCurrentModule = GcamHelper.createGcamModule();
+                break;
             default:
                 // Fall back to photo mode.
                 mCurrentModule = new PhotoModule();
diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java
index 32eae82..e3f2c11 100644
--- a/src/com/android/camera/CameraHolder.java
+++ b/src/com/android/camera/CameraHolder.java
@@ -262,6 +262,12 @@
                     mKeepBeforeTime - now);
             return;
         }
+        strongRelease();
+    }
+
+    public synchronized void strongRelease() {
+        if (mCameraDevice == null) return;
+
         mCameraOpened = false;
         mCameraDevice.release();
         mCameraDevice = null;
diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java
index 9c42a5c..e8ec08d 100644
--- a/src/com/android/camera/MediaSaveService.java
+++ b/src/com/android/camera/MediaSaveService.java
@@ -48,7 +48,7 @@
     // Memory used by the total queued save request, in bytes.
     private long mMemoryUse;
 
-    interface Listener {
+    public interface Listener {
         public void onQueueStatus(boolean full);
     }
 
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 861dead..150b6e8 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -57,6 +57,7 @@
 import com.android.camera.CameraManager.CameraPictureCallback;
 import com.android.camera.CameraManager.CameraProxy;
 import com.android.camera.CameraManager.CameraShutterCallback;
+import com.android.camera.PhotoModule.NamedImages.NamedEntity;
 import com.android.camera.exif.ExifInterface;
 import com.android.camera.exif.ExifTag;
 import com.android.camera.exif.Rational;
@@ -75,6 +76,7 @@
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Vector;
 
 public class PhotoModule
         implements CameraModule,
@@ -721,8 +723,9 @@
                     width = s.height;
                     height = s.width;
                 }
-                String title = mNamedImages.getTitle();
-                long date = mNamedImages.getDate();
+                NamedEntity name = mNamedImages.getNextNameEntity();
+                String title = (name == null) ? null : name.title;
+                long date = (name == null) ? -1 : name.date;
                 if (title == null) {
                     Log.e(TAG, "Unbalanced name/data pair");
                 } else {
@@ -790,41 +793,35 @@
         }
     }
 
-    private static class NamedImages {
-        private ArrayList<NamedEntity> mQueue;
-        private NamedEntity mNamedEntity;
+    /**
+     * This class is just a thread-safe queue for name,date holder objects.
+     */
+    public static class NamedImages {
+        private Vector<NamedEntity> mQueue;
 
         public NamedImages() {
-            mQueue = new ArrayList<NamedEntity>();
+            mQueue = new Vector<NamedEntity>();
         }
 
-        public void nameNewImage(ContentResolver resolver, long date) {
+        public void nameNewImage(long date) {
             NamedEntity r = new NamedEntity();
             r.title = CameraUtil.createJpegName(date);
             r.date = date;
             mQueue.add(r);
         }
 
-        public String getTitle() {
-            if (mQueue.isEmpty()) {
-                mNamedEntity = null;
-                return null;
+        public NamedEntity getNextNameEntity() {
+            synchronized(mQueue) {
+                if (!mQueue.isEmpty()) {
+                    return mQueue.remove(0);
+                }
             }
-            mNamedEntity = mQueue.get(0);
-            mQueue.remove(0);
-
-            return mNamedEntity.title;
+            return null;
         }
 
-        // Must be called after getTitle().
-        public long getDate() {
-            if (mNamedEntity == null) return -1;
-            return mNamedEntity.date;
-        }
-
-        private static class NamedEntity {
-            String title;
-            long date;
+        public static class NamedEntity {
+            public String title;
+            public long date;
         }
     }
 
@@ -893,7 +890,7 @@
                 mRawPictureCallback, mPostViewPictureCallback,
                 new JpegPictureCallback(loc));
 
-        mNamedImages.nameNewImage(mContentResolver, mCaptureStartTime);
+        mNamedImages.nameNewImage(mCaptureStartTime);
 
         mFaceDetectionStarted = false;
         setCameraState(SNAPSHOT_IN_PROGRESS);
diff --git a/src/com/android/camera/ui/ModuleSwitcher.java b/src/com/android/camera/ui/ModuleSwitcher.java
index 69ae3b5..882f6c9 100644
--- a/src/com/android/camera/ui/ModuleSwitcher.java
+++ b/src/com/android/camera/ui/ModuleSwitcher.java
@@ -35,6 +35,7 @@
 import android.widget.LinearLayout;
 
 import com.android.camera.util.CameraUtil;
+import com.android.camera.util.GcamHelper;
 import com.android.camera.util.PhotoSphereHelper;
 import com.android.camera.util.UsageStatistics;
 import com.android.camera2.R;
@@ -50,11 +51,14 @@
     public static final int VIDEO_MODULE_INDEX = 1;
     public static final int WIDE_ANGLE_PANO_MODULE_INDEX = 2;
     public static final int LIGHTCYCLE_MODULE_INDEX = 3;
+    public static final int GCAM_MODULE_INDEX = 4;
+
     private static final int[] DRAW_IDS = {
             R.drawable.ic_switch_camera,
             R.drawable.ic_switch_video,
             R.drawable.ic_switch_pan,
             R.drawable.ic_switch_photosphere,
+            R.drawable.ic_switch_gcam,
     };
 
     public interface ModuleSwitchListener {
@@ -104,6 +108,10 @@
             --numDrawIds;
         }
 
+        if (!GcamHelper.hasGcamCapture(context)) {
+            --numDrawIds;
+        }
+
         int[] drawids = new int[numDrawIds];
         int[] moduleids = new int[numDrawIds];
         int ix = 0;
@@ -111,6 +119,9 @@
             if (i == LIGHTCYCLE_MODULE_INDEX && !PhotoSphereHelper.hasLightCycleCapture(context)) {
                 continue; // not enabled, so don't add to UI
             }
+            if (i == GCAM_MODULE_INDEX && !GcamHelper.hasGcamCapture(context)) {
+                continue; // not enabled, so don't add to UI
+            }
             moduleids[ix] = i;
             drawids[ix++] = DRAW_IDS[i];
         }
@@ -200,6 +211,10 @@
                     item.setContentDescription(getContext().getResources().getString(
                             R.string.accessibility_switch_to_photo_sphere));
                     break;
+                case R.drawable.ic_switch_gcam:
+                    item.setContentDescription(getContext().getResources().getString(
+                            R.string.accessibility_switch_to_gcam));
+                    break;
                 default:
                     break;
             }
diff --git a/src_pd/com/android/camera/util/GcamHelper.java b/src_pd/com/android/camera/util/GcamHelper.java
new file mode 100644
index 0000000..0611955
--- /dev/null
+++ b/src_pd/com/android/camera/util/GcamHelper.java
@@ -0,0 +1,32 @@
+/*
+ * 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.util;
+
+import android.content.Context;
+
+import com.android.camera.CameraModule;
+
+public class GcamHelper {
+
+    public static CameraModule createGcamModule() {
+        return null;
+    }
+
+    public static boolean hasGcamCapture(Context context) {
+        return false;
+    }
+
+}