Merge "SnapdragonCamera: Remove the Video Flash option" into camera-SnapdragonCamera.lnx.2.0
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index fecc7d1..62e0a41 100755
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -614,7 +614,7 @@
 
     <!-- Default picture quality setting. See
          pref_camera_jpegquality_entryvalues for possible values -->
-    <string name="pref_camera_jpegquality_default" translatable="false">85</string>
+    <string name="pref_camera_jpegquality_default" translatable="false">100</string>
 
     <!-- Default Picture format setting. Do not translate. -->
     <string name="pref_camera_picture_format_default">jpeg</string>
@@ -1012,7 +1012,7 @@
 
     <string name="pref_camera2_makeup_title" translatable="true">Makeup</string>
 
-    <string name="pref_camera2_noise_reduction_default" translatable="false">off</string>
+    <string name="pref_camera2_noise_reduction_default" translatable="false">high-quality</string>
     <string name="pref_camera2_noise_reduction_title" translatable="true">Noise Reduction</string>
 
     <string name="pref_camera2_noise_reduction_entry_off" translatable="true">@string/pref_camera_noise_reduction_entry_off</string>
@@ -1180,7 +1180,7 @@
     <string name="pref_camera2_video_quality_default" translatable="false">1920x1080</string>
 
     <string name="pref_camera2_zsl_title" translatable="true">ZSL</string>
-    <string name="pref_camera2_zsl_default" translatable="false">@string/pref_camera2_zsl_entryvalue_disable</string>
+    <string name="pref_camera2_zsl_default" translatable="false">@string/pref_camera2_zsl_entryvalue_hal_zsl</string>
     <string name="pref_camera2_zsl_entry_disable" translatable="true">Off</string>
     <string name="pref_camera2_zsl_entry_app_zsl" translatable="true">APP-ZSL</string>
     <string name="pref_camera2_zsl_entry_hal_zsl" translatable="true">HAL-ZSL</string>
@@ -1219,7 +1219,7 @@
     <string name="pref_camera2_afmode_value_edof" translatable="false">5</string>
 
     <string name="pref_camera2_exposure_metering_title" translatable="true">ExposureMetering</string>
-    <string name="pref_camera2_exposure_metering_default" translatable="true">0</string>
+    <string name="pref_camera2_exposure_metering_default" translatable="true">1</string>
     <string name="pref_camera2_exposure_metering_entry_frame_average" translatable="false">FrameAverage</string>
     <string name="pref_camera2_exposure_metering_entry_center_weighted" translatable="false">CenterWeighted</string>
     <string name="pref_camera2_exposure_metering_entry_spot_meteting" translatable="false">SpotMeteting</string>
diff --git a/res/xml/capture_preferences.xml b/res/xml/capture_preferences.xml
index 5f3ff3e..0337f3e 100755
--- a/res/xml/capture_preferences.xml
+++ b/res/xml/capture_preferences.xml
@@ -250,11 +250,11 @@
         camera:title="@string/pref_camera_dis_title"/>
 
     <ListPreference
-        camera:defaultValue="@string/pref_camera_noise_reduction_default"
+        camera:defaultValue="@string/pref_camera2_noise_reduction_default"
         camera:entries="@array/pref_camera2_noise_reduction_entries"
         camera:entryValues="@array/pref_camera2_noise_reduction_entryvalues"
         camera:key="pref_camera2_noise_reduction_key"
-        camera:title="@string/pref_camera_noise_reduction_title"/>
+        camera:title="@string/pref_camera2_noise_reduction_title"/>
 
     <IconListPreference
         camera:defaultValue="@string/pref_camera_video_flashmode_default"
diff --git a/res/xml/setting_menu_preferences.xml b/res/xml/setting_menu_preferences.xml
index c496971..af1b390 100755
--- a/res/xml/setting_menu_preferences.xml
+++ b/res/xml/setting_menu_preferences.xml
@@ -207,14 +207,14 @@
             android:title="@string/pref_camera_dis_title" />
 
         <ListPreference
-            android:defaultValue="@string/pref_camera_noise_reduction_default"
+            android:defaultValue="@string/pref_camera2_noise_reduction_default"
             android:entries="@array/pref_camera2_noise_reduction_entries"
             android:entryValues="@array/pref_camera2_noise_reduction_entryvalues"
             android:icon="@drawable/noise_reduction"
             android:key="pref_camera2_noise_reduction_key"
             android:layout="@layout/preference"
             android:summary="%s"
-            android:title="@string/pref_camera_noise_reduction_title" />
+            android:title="@string/pref_camera2_noise_reduction_title" />
 
         <ListPreference
             android:defaultValue="@string/pref_camera_videoencoder_default"
diff --git a/res/xml/video_preferences.xml b/res/xml/video_preferences.xml
old mode 100644
new mode 100755
index 3fafddd..66e2e05
--- a/res/xml/video_preferences.xml
+++ b/res/xml/video_preferences.xml
@@ -151,8 +151,8 @@
             camera:entryValues="@array/pref_camera_hfr_entryvalues"/>
     <ListPreference
             camera:key="pref_camera_noise_reduction_key"
-            camera:defaultValue="@string/pref_camera_noise_reduction_default"
-            camera:title="@string/pref_camera_noise_reduction_title"
+            camera:defaultValue="@string/pref_camera2_noise_reduction_default"
+            camera:title="@string/pref_camera2_noise_reduction_title"
             camera:entries="@array/pref_camera_noise_reduction_entries"
             camera:entryValues="@array/pref_camera_noise_reduction_entryvalues"/>
     <ListPreference
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
old mode 100644
new mode 100755
index cad136c..e16d37e
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ b/src/com/android/camera/AndroidCameraManagerImpl.java
@@ -39,8 +39,6 @@
 import android.os.Message;
 import android.util.Log;
 import android.view.SurfaceHolder;
-import android.hardware.Camera.CameraDataCallback;
-import android.hardware.Camera.CameraMetaDataCallback;
 import com.android.camera.util.ApiHelper;
 import android.os.ConditionVariable;
 import java.lang.reflect.Method;
@@ -95,7 +93,6 @@
     private static final int ENABLE_SHUTTER_SOUND =    501;
     private static final int SET_DISPLAY_ORIENTATION = 502;
     // Histogram
-    private static final int SET_HISTOGRAM_MODE =    601;
     private static final int SEND_HISTOGRAM_DATA =   602;
     //LONGSHOT
     private static final int SET_LONGSHOT = 701;
@@ -390,10 +387,6 @@
                         mParametersIsDirty = true;
                         return;
 
-                    case SET_HISTOGRAM_MODE:
-                        CameraWrapper.setHistogramMode(mCamera, (CameraDataCallback) msg.obj);
-                        break;
-
                     case SEND_HISTOGRAM_DATA:
                         CameraWrapper.sendHistogramData(mCamera);
                         break;
@@ -402,10 +395,6 @@
                         CameraWrapper.setLongshot(mCamera, (Boolean) msg.obj);
                         break;
 
-                    case SET_AUTO_HDR_MODE:
-                        CameraWrapper.setMetadataCb(mCamera, (CameraMetaDataCallback) msg.obj);
-                        break;
-
                     default:
                         throw new RuntimeException("Invalid CameraProxy message=" + msg.what);
                 }
@@ -504,11 +493,6 @@
         }
 
         @Override
-        public void setMetadataCb(CameraMetaDataCallback cb){
-            mCameraHandler.obtainMessage(SET_AUTO_HDR_MODE, cb).sendToTarget();
-        }
-
-        @Override
         public void setPreviewTexture(SurfaceTexture surfaceTexture) {
             mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture).sendToTarget();
         }
@@ -663,10 +647,6 @@
         }
 
         @Override
-        public void setHistogramMode(CameraDataCallback cb) {
-            mCameraHandler.obtainMessage(SET_HISTOGRAM_MODE, cb).sendToTarget();
-        }
-        @Override
         public void sendHistogramData() {
             mCameraHandler.sendEmptyMessage(SEND_HISTOGRAM_DATA);
         }
diff --git a/src/com/android/camera/CameraManager.java b/src/com/android/camera/CameraManager.java
old mode 100644
new mode 100755
index b93e718..d3ef929
--- a/src/com/android/camera/CameraManager.java
+++ b/src/com/android/camera/CameraManager.java
@@ -25,8 +25,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.view.SurfaceHolder;
-import android.hardware.Camera.CameraDataCallback;
-import android.hardware.Camera.CameraMetaDataCallback;
 /**
  * An interface which provides possible camera device operations.
  *
@@ -175,12 +173,6 @@
         public void release();
 
         /**
-         * Sets the metadata cb
-         * @cb Metadata callback object
-        */
-        public void setMetadataCb (CameraMetaDataCallback cb);
-
-        /**
          * Reconnects to the camera device.
          * @see android.hardware.Camera#reconnect()
          *
@@ -367,12 +359,6 @@
          */
         public void enableShutterSound(boolean enable);
         /**
-         * Set histogram Mode
-         *
-         * @param cb   cameraDataCallback to use
-         */
-        public void setHistogramMode(CameraDataCallback cb);
-        /**
          * Send the Histogram Data.
          *
         */
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 608e119..5ec6f5b 100755
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -182,7 +182,7 @@
     private static final int CANCEL_TOUCH_FOCUS_DELAY = PersistUtil.getCancelTouchFocusDelay();
     private static final int OPEN_CAMERA = 0;
     private static final int CANCEL_TOUCH_FOCUS = 1;
-    private static final int MAX_NUM_CAM = 6;
+    private static final int MAX_NUM_CAM = 16;
     private String DEPTH_CAM_ID;
     private static final MeteringRectangle[] ZERO_WEIGHT_3A_REGION = new MeteringRectangle[]{
             new MeteringRectangle(0, 0, 0, 0, 0)};
@@ -390,6 +390,8 @@
             new CaptureResult.Key<>("org.quic.camera.isDepthFocus.isDepthFocus", byte.class);
     private static final CaptureRequest.Key<Byte> capture_burst_fps =
             new CaptureRequest.Key<>("org.quic.camera.BurstFPS.burstfps", byte.class);
+    private static final CaptureRequest.Key<Byte> custom_noise_reduction =
+            new CaptureRequest.Key<>("org.quic.camera.CustomNoiseReduction.CustomNoiseReduction", byte.class);
 
     private boolean mIsDepthFocus = false;
     private boolean[] mTakingPicture = new boolean[MAX_NUM_CAM];
@@ -497,6 +499,9 @@
     private HeifWriter mInitHeifWriter;
     private OutputConfiguration mHeifOutput;
     private HeifImage mHeifImage;
+    private HeifWriter mLiveShotInitHeifWriter;
+    private OutputConfiguration mLiveShotOutput;
+    private HeifImage mLiveShotImage;
     private NamedImages mNamedImages;
     private ContentResolver mContentResolver;
     private byte[] mLastJpegData;
@@ -542,7 +547,7 @@
     private static final int STATS_DATA = 768;
     public static int statsdata[] = new int[STATS_DATA];
 
-    public static int statsview_scale = 1;
+    private boolean mInTAF = false;
 
     // BG stats
     private static final int BGSTATS_DATA = 64*48;
@@ -847,7 +852,7 @@
                             for (int wi = 0; wi < 10; wi++)
                             {
                                 index               = 10*(int)(el/64) + 48*10*hi + 48*10*10*(el%64) + wi;
-                                bg_statsdata[480*(639-(int)(index/480))+(index%480)] = Color.argb(255, r, g, b);
+                                bg_statsdata[index] = Color.argb(255, r, g, b);
                             }
                         }
                     }
@@ -886,7 +891,7 @@
                             for (int wi = 0; wi < 10; wi++)
                             {
                                 index               = 10*(int)(el/64) + 48*10*hi + 48*10*10*(el%64) + wi;
-                                be_statsdata[480*(639-(int)(index/480))+(index%480)] = Color.argb(255, r, g, b);
+                                be_statsdata[index] = Color.argb(255, r, g, b);
                             }
                         }
                     }
@@ -1845,6 +1850,7 @@
         Log.d(TAG, "takePicture");
         mUI.enableShutter(false);
         if (mSettingsManager.isZSLInHALEnabled()&&
+                !isFlashOn(getMainCameraId())&&
                 mPreviewCaptureResult.get(CaptureResult.CONTROL_AE_STATE) !=
                         CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED) {
             takeZSLPictureInHAL();
@@ -2071,6 +2077,7 @@
         if (null == mActivity || null == mCameraDevice[id]
                 || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
             warningToast("Camera is not ready yet to take a picture.");
+            mInTAF = false;
             return;
         }
         try {
@@ -2080,6 +2087,7 @@
 
             mControlAFMode = CaptureRequest.CONTROL_AF_MODE_AUTO;
             applySettingsForAutoFocus(builder, id);
+            builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
             mState[id] = STATE_WAITING_TOUCH_FOCUS;
             applyFlash(builder, id);//apply flash mode and AEmode for this temp builder
             mCaptureSession[id].capture(builder.build(), mCaptureCallback, mCameraHandler);
@@ -2124,7 +2132,10 @@
         mIsRefocus = false;
         if (isDeepZoom()) mSupportZoomCapture = false;
         try {
-            if (null == mActivity || null == mCameraDevice[id]) {
+            if (null == mActivity || null == mCameraDevice[id]
+                    || !checkSessionAndBuilder(mCaptureSession[id], mPreviewRequestBuilder[id])) {
+                mUI.enableShutter(true);
+                mLongshotActive = false;
                 warningToast("Camera is not ready yet to take a picture.");
                 return;
             }
@@ -2138,12 +2149,12 @@
                 captureBuilder.set(CaptureRequest.CONTROL_ENABLE_ZSL, false);
             }
 
+            applySettingsForJpegInformation(captureBuilder, id);
+            applyAFRegions(captureBuilder, id);
+            applyAERegions(captureBuilder, id);
+            applySettingsForCapture(captureBuilder, id);
             if (!mLongshoting) {
-                applySettingsForJpegInformation(captureBuilder, id);
-                applyAFRegions(captureBuilder, id);
-                applyAERegions(captureBuilder, id);
                 VendorTagUtil.setCdsMode(captureBuilder, 2);// CDS 0-OFF, 1-ON, 2-AUTO
-                applySettingsForCapture(captureBuilder, id);
                 applyCaptureMFNR(captureBuilder);
             }
             applyCaptureBurstFps(captureBuilder);
@@ -2172,12 +2183,14 @@
                     NamedEntity name = mNamedImages.getNextNameEntity();
                     String title = (name == null) ? null : name.title;
                     long date = (name == null) ? -1 : name.date;
-                    String path = Storage.generateFilepath(title, "heif");
+                    String pictureFormat = mLongshotActive? "heifs":"heif";
+                    String path = Storage.generateFilepath(title, pictureFormat);
                     String value = mSettingsManager.getValue(SettingsManager.KEY_JPEG_QUALITY);
                     int quality = getQualityNumber(value);
                     int orientation = CameraUtil.getJpegRotation(id,mOrientation);
+                    int imageCount = mLongshotActive? MAX_IMAGEREADERS*2 : 1;
                     HeifWriter writer = createHEIFEncoder(path,mPictureSize.getWidth(),mPictureSize.getHeight(),
-                            orientation,quality);
+                            orientation,imageCount,quality);
                     if (writer != null) {
                         mHeifImage = new HeifImage(writer,path,title,date,orientation,quality);
                         Surface input = writer.getInputSurface();
@@ -2305,6 +2318,24 @@
             @Override
             public void onCaptureSequenceCompleted(CameraCaptureSession session, int
                             sequenceId, long frameNumber) {
+                if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+                    if (mHeifImage != null) {
+                        try {
+                            mHeifOutput.removeSurface(mHeifImage.getInputSurface());
+                            session.updateOutputConfiguration(mHeifOutput);
+                            mHeifImage.getWriter().stop(3000);
+                            mHeifImage.getWriter().close();
+                            mActivity.getMediaSaveService().addHEIFImage(mHeifImage.getPath(),
+                                    mHeifImage.getTitle(),mHeifImage.getDate(),null,mPictureSize.getWidth(),mPictureSize.getHeight(),
+                                    mHeifImage.getOrientation(),null,mContentResolver,mOnMediaSavedListener,mHeifImage.getQuality(),"heifs");
+                            mHeifImage = null;
+                        } catch (TimeoutException | IllegalStateException e) {
+                            e.printStackTrace();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
                 if(mLongshotActive) {
                     captureStillPicture(getMainCameraId());
                 } else {
@@ -2318,6 +2349,7 @@
     private void captureStillPictureForLongshot(CaptureRequest.Builder captureBuilder, int id) throws CameraAccessException{
         List<CaptureRequest> burstList = new ArrayList<>();
         for (int i = 0; i < MAX_IMAGEREADERS*2; i++) {
+            burstList.add(mPreviewRequestBuilder[id].build());
             burstList.add(captureBuilder.build());
         }
         mCaptureSession[id].captureBurst(burstList, mLongshotCallBack, mCaptureCallbackHandler);
@@ -2405,7 +2437,33 @@
             applyVideoSnapshot(captureBuilder, id);
             applyZoom(captureBuilder, id);
 
-            captureBuilder.addTarget(mVideoSnapshotImageReader.getSurface());
+            if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+                long captureTime = System.currentTimeMillis();
+                mNamedImages.nameNewImage(captureTime);
+                NamedEntity name = mNamedImages.getNextNameEntity();
+                String title = (name == null) ? null : name.title;
+                long date = (name == null) ? -1 : name.date;
+                String path = Storage.generateFilepath(title, "heif");
+                String value = mSettingsManager.getValue(SettingsManager.KEY_JPEG_QUALITY);
+                int quality = getQualityNumber(value);
+                int orientation = CameraUtil.getJpegRotation(id,mOrientation);
+                HeifWriter writer = createHEIFEncoder(path,mVideoSize.getWidth(),
+                        mVideoSize.getHeight(),orientation,1,quality);
+                if (writer != null) {
+                    mLiveShotImage = new HeifImage(writer,path,title,date,orientation,quality);
+                    Surface input = writer.getInputSurface();
+                    mLiveShotOutput.addSurface(input);
+                    try{
+                        mCurrentSession.updateOutputConfiguration(mLiveShotOutput);
+                        captureBuilder.addTarget(input);
+                        writer.start();
+                    } catch (IllegalStateException | IllegalArgumentException e) {
+                        e.printStackTrace();
+                    }
+                }
+            } else {
+                captureBuilder.addTarget(mVideoSnapshotImageReader.getSurface());
+            }
             // send snapshot stream together with preview and video stream for snapshot request
             // stream is the surface for the app
             Surface surface = getPreviewSurfaceForSession(id);
@@ -2439,6 +2497,27 @@
                         public void onCaptureSequenceCompleted(CameraCaptureSession session, int
                                 sequenceId, long frameNumber) {
                             Log.d(TAG, "captureVideoSnapshot onCaptureSequenceCompleted: " + id);
+                            if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+                                if (mLiveShotImage != null) {
+                                    try {
+                                        mLiveShotOutput.removeSurface(mLiveShotImage.getInputSurface());
+                                        mCurrentSession.updateOutputConfiguration(mLiveShotOutput);
+                                        mLiveShotImage.getWriter().stop(3000);
+                                        mLiveShotImage.getWriter().close();
+                                        mActivity.getMediaSaveService().addHEIFImage(mLiveShotImage.getPath(),
+                                                mLiveShotImage.getTitle(),mLiveShotImage.getDate(),
+                                                null,mVideoSize.getWidth(),mVideoSize.getHeight(),
+                                                mLiveShotImage.getOrientation(),null,
+                                                mContentResolver,mOnMediaSavedListener,
+                                                mLiveShotImage.getQuality(),"heif");
+                                        mLiveShotImage = null;
+                                    } catch (TimeoutException | IllegalStateException e) {
+                                        e.printStackTrace();
+                                    } catch (Exception e) {
+                                        e.printStackTrace();
+                                    }
+                                }
+                            }
                         }
                     }, mCaptureCallbackHandler);
         } catch (CameraAccessException e) {
@@ -2489,6 +2568,15 @@
         CameraManager manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
         try {
             String[] cameraIdList = manager.getCameraIdList();
+            //inti heifWriter and get input surface
+            if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+                String tmpPath = mActivity.getCacheDir().getPath() + "/" + "heif.tmp";
+                if (mInitHeifWriter != null) {
+                    mInitHeifWriter.close();
+                }
+                mInitHeifWriter = createHEIFEncoder(tmpPath, mPictureSize.getWidth(),
+                        mPictureSize.getHeight(), 0,1, 85);
+            }
             for (int i = 0; i < cameraIdList.length; i++) {
                 String cameraId = cameraIdList[i];
 
@@ -2521,16 +2609,6 @@
                 }
                 mCameraId[i] = cameraId;
 
-                //inti heifWriter and get input surface
-                if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
-                    String tmpPath = mActivity.getCacheDir().getPath() + "/" + "heif.tmp";
-                    if (mInitHeifWriter != null) {
-                        mInitHeifWriter.close();
-                    }
-                    mInitHeifWriter = createHEIFEncoder(tmpPath, mPictureSize.getWidth(),
-                            mPictureSize.getHeight(), 0, 85);
-                }
-
                 if (isClearSightOn()) {
                     if(i == getMainCameraId()) {
                         ClearSightImageProcessor.getInstance().init(map, mActivity,
@@ -2575,6 +2653,10 @@
                                     image.close();
                                     return;
                                 }
+                                if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+                                    image.close();
+                                    return;
+                                }
                                 if (isMpoOn()) {
                                     mMpoSaveHandler.obtainMessage(
                                             MpoSaveHandler.MSG_NEW_IMG, mCamId, 0, image).sendToTarget();
@@ -2621,7 +2703,7 @@
 
                         if (mSaveRaw) {
                             mRawImageReader[i] = ImageReader.newInstance(mSupportedRawPictureSize.getWidth(),
-                                    mSupportedRawPictureSize.getHeight(), ImageFormat.RAW10, PersistUtil.getLongshotShotLimit());
+                                    mSupportedRawPictureSize.getHeight(), ImageFormat.RAW10, MAX_IMAGEREADERS);
                             mRawImageReader[i].setOnImageAvailableListener(listener, mImageAvailableHandler);
                         }
                     }
@@ -2636,13 +2718,13 @@
     }
 
     public static HeifWriter createHEIFEncoder(String path, int width, int height,
-                                        int orientation, int quality) {
+                                        int orientation, int imageCount, int quality) {
         HeifWriter heifWriter = null;
         try {
             HeifWriter.Builder builder =
                     new HeifWriter.Builder(path, width, height, HeifWriter.INPUT_MODE_SURFACE);
             builder.setQuality(quality);
-            builder.setMaxImages(1);
+            builder.setMaxImages(imageCount);
             builder.setPrimaryIndex(0);
             builder.setRotation(orientation);
             builder.setGridEnabled(true);
@@ -2659,6 +2741,12 @@
         if (mVideoSnapshotImageReader != null) {
             mVideoSnapshotImageReader.close();
         }
+        if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT) {
+            String tmpPath = mActivity.getCacheDir().getPath() + "/" + "liveshot_heif.tmp";
+            mLiveShotInitHeifWriter = createHEIFEncoder(tmpPath,mVideoSize.getWidth(),
+                    mVideoSize.getHeight(),0, 1,85);
+            return;
+        }
         mVideoSnapshotImageReader = ImageReader.newInstance(mVideoSnapshotSize.getWidth(),
                 mVideoSnapshotSize.getHeight(), ImageFormat.JPEG, 2);
         mVideoSnapshotImageReader.setOnImageAvailableListener(
@@ -2950,6 +3038,8 @@
     }
 
     private void applySettingsForJpegInformation(CaptureRequest.Builder builder, int id) {
+        if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT)
+            return;
         Location location = mLocationManager.getCurrentLocation();
         if(location != null) {
             // make copy so that we don't alter the saved location since we may re-use it
@@ -3114,6 +3204,7 @@
         }
         closeCamera();
         resetAudioMute();
+        mUI.releaseSoundPool();
         mUI.showPreviewCover();
         if (mUI.getGLCameraPreview() != null) {
             mUI.getGLCameraPreview().onPause();
@@ -3316,6 +3407,14 @@
 
     }
 
+    private void loadSoundPoolResource() {
+        String timer = mSettingsManager.getValue(SettingsManager.KEY_TIMER);
+        int seconds = Integer.parseInt(timer);
+        if (seconds > 0) {
+            mUI.initCountDownView();
+        }
+    }
+
     @Override
     public void onResumeAfterSuper() {
         Log.d(TAG, "onResume " + getCameraMode());
@@ -3333,6 +3432,7 @@
         setDisplayOrientation();
         startBackgroundThread();
         openProcessors();
+        loadSoundPoolResource();
         Message msg = Message.obtain();
         msg.what = OPEN_CAMERA;
         if (isBackCamera()) {
@@ -3666,9 +3766,8 @@
         mUI.setFocusPosition(x, y);
         x = newXY[0];
         y = newXY[1];
-        if (!mIsDepthFocus) {
-            mUI.onFocusStarted();
-        }
+        mInTAF = true;
+        mUI.onFocusStarted();
         if (isBackCamera()) {
             switch (getCameraMode()) {
                 case DUAL_MODE:
@@ -4192,7 +4291,7 @@
             } catch (IllegalStateException e) {
                 e.printStackTrace();
             }
-            if (!mFrameProcessor.isFrameListnerEnabled() && !startMediaRecorder()) {
+            if ((!mFrameProcessor.isFrameListnerEnabled() && !startMediaRecorder()) || !mIsRecordingVideo) {
                 mUI.showUIafterRecording();
                 releaseMediaRecorder();
                 mFrameProcessor.setVideoOutputSurface(null);
@@ -4229,7 +4328,16 @@
             List<Surface> outputSurfaces, CameraCaptureSession.StateCallback listener,
             Handler handler, CaptureRequest initialRequest) throws CameraAccessException {
         List<OutputConfiguration> outConfigurations = new ArrayList<>(outputSurfaces.size());
-        outputSurfaces.add(mVideoSnapshotImageReader.getSurface());
+        if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT &&
+                mLiveShotInitHeifWriter != null) {
+            mLiveShotOutput = new OutputConfiguration(
+                    mLiveShotInitHeifWriter.getInputSurface());
+            mLiveShotOutput.enableSurfaceSharing();
+            outConfigurations.add(mLiveShotOutput);
+        } else {
+            outputSurfaces.add(mVideoSnapshotImageReader.getSurface());
+        }
+
         for (Surface surface : outputSurfaces) {
             outConfigurations.add(new OutputConfiguration(surface));
         }
@@ -4281,6 +4389,13 @@
         for (Surface surface : outputSurfaces) {
             outConfigurations.add(new OutputConfiguration(surface));
         }
+        if (mSettingsManager.getSavePictureFormat() == SettingsManager.HEIF_FORMAT &&
+                mLiveShotInitHeifWriter != null) {
+            mLiveShotOutput = new OutputConfiguration(
+                    mLiveShotInitHeifWriter.getInputSurface());
+            mLiveShotOutput .enableSurfaceSharing();
+            outConfigurations.add(mLiveShotOutput);
+        }
         Method method_setSessionParameters = null;
         Method method_createCaptureSession = null;
         Object sessionConfig = null;
@@ -4387,6 +4502,7 @@
                         mHighSpeedFPSRange);
             }
 
+
             if (ApiHelper.isAndroidPOrHigher()) {
                 if (mHighSpeedCapture && ((int) mHighSpeedFPSRange.getUpper() > NORMAL_SESSION_MAX_FPS)) {
                     CaptureRequest initialRequest = mVideoRequestBuilder.build();
@@ -4597,6 +4713,10 @@
         if (mHighSpeedCapture) {
             mVideoPausePreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
                     mHighSpeedFPSRange);
+        } else {
+            mHighSpeedFPSRange = new Range(30, 30);
+            mVideoPausePreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
+                    mHighSpeedFPSRange);
         }
         if (!mHighSpeedCapture || !((int)mHighSpeedFPSRange.getUpper() > NORMAL_SESSION_MAX_FPS)) {
             applyVideoCommentSettings(mVideoPausePreviewRequestBuilder, cameraId);
@@ -4631,11 +4751,19 @@
     }
 
     private void applyCaptureMFNR(CaptureRequest.Builder builder) {
-        int noiseReduMode = (isMFNREnabled() ? CameraMetadata.NOISE_REDUCTION_MODE_HIGH_QUALITY :
+        boolean isMfnrEnable = isMFNREnabled();
+        int noiseReduMode = (isMfnrEnable ? CameraMetadata.NOISE_REDUCTION_MODE_HIGH_QUALITY :
                 CameraMetadata.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
-        Log.v(TAG, "applyCaptureMFNR mfnrEnable :" + isMFNREnabled() + ", noiseReduMode :"
+        Log.v(TAG, "applyCaptureMFNR mfnrEnable :" + isMfnrEnable + ", noiseReduMode :"
                 + noiseReduMode);
         builder.set(CaptureRequest.NOISE_REDUCTION_MODE, noiseReduMode);
+        if (isMfnrEnable) {
+            try {
+                builder.set(custom_noise_reduction, (byte)0x01);
+            } catch (IllegalArgumentException e) {
+                Log.w(TAG, "cannot find vendor tag: " + custom_noise_reduction.toString());
+            }
+        }
     }
 
     private void applyCaptureBurstFps(CaptureRequest.Builder builder) {
@@ -4912,7 +5040,11 @@
         setEndOfStream(false, true);
         mFrameProcessor.setVideoOutputSurface(null);
         mFrameProcessor.onClose();
+        if (mLiveShotInitHeifWriter != null) {
+            mLiveShotInitHeifWriter.close();
+        }
         closePreviewSession();
+        mIsRecordingVideo = false;
         try {
             mMediaRecorder.setOnErrorListener(null);
             mMediaRecorder.setOnInfoListener(null);
@@ -4936,7 +5068,6 @@
         mUI.showRecordingUI(false, false);
         mUI.enableShutter(true);
 
-        mIsRecordingVideo = false;
         if (mIntentMode == INTENT_MODE_VIDEO) {
             if (isQuickCapture()) {
                 onRecordingDone(true);
@@ -6248,6 +6379,7 @@
         }
         if (mCropRegion[id] == null) {
             Log.d(TAG, "crop region is null at " + id);
+            mInTAF = false;
             return;
         }
         Point p = mUI.getSurfaceViewSize();
@@ -6277,6 +6409,7 @@
         if (DEBUG) {
             Log.v(TAG, "cancelTouchFocus " + id);
         }
+        mInTAF = false;
         mState[id] = STATE_PREVIEW;
         mControlAFMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
         setAFModeToPreview(id, mControlAFMode);
@@ -6331,31 +6464,33 @@
     }
 
     private void updateFocusStateChange(CaptureResult result) {
-        final Integer resultAFState = result.get(CaptureResult.CONTROL_AF_STATE);
+        Integer resultAFState = result.get(CaptureResult.CONTROL_AF_STATE);
         if (resultAFState == null) return;
         try {
             Byte isDepthFocus = result.get(CaptureModule.is_depth_focus);
-            if(DEBUG) Log.d(TAG, "isDepthFocus is " + isDepthFocus);
-            if (isDepthFocus != null && isDepthFocus == 1) {
-                mIsDepthFocus = true;
-            } else {
-                mIsDepthFocus = false;
+            if (isDepthFocus != null) {
+                if (isDepthFocus == 1) {
+                    mIsDepthFocus = true;
+                } else {
+                    mIsDepthFocus = false;
+                }
             }
+            if(DEBUG) Log.d(TAG, "isDepthFocus is " + mIsDepthFocus + ", inTAF is " + mInTAF);
         } catch (IllegalArgumentException e) {
             mIsDepthFocus = false;
             if (DEBUG) e.printStackTrace();
         }
 
-        // If focus started then don't return
-        if (mIsDepthFocus && mLastResultAFState == CaptureResult.CONTROL_AF_STATE_INACTIVE) {
-            return;
+        if (mIsDepthFocus && !mInTAF) {
+            resultAFState = CaptureResult.CONTROL_AF_STATE_INACTIVE;
         }
+        final Integer afState = resultAFState;
         // Report state change when AF state has changed.
         if (resultAFState != mLastResultAFState && mFocusStateListener != null) {
             mActivity.runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    mFocusStateListener.onFocusStatusUpdate(resultAFState);
+                    mFocusStateListener.onFocusStatusUpdate(afState);
                 }
             });
         }
diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java
index c4952eb..8b72d92 100755
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -1545,8 +1545,17 @@
         showUIAfterCountDown();
     }
 
-    public void startCountDown(int sec, boolean playSound) {
+    public void initCountDownView() {
         if (mCountDownView == null) initializeCountDown();
+    }
+
+    public void releaseSoundPool() {
+        if (mCountDownView != null) {
+            mCountDownView.releaseSoundPool();
+        }
+    }
+
+    public void startCountDown(int sec, boolean playSound) {
         mCountDownView.startCountDown(sec, playSound);
         hideUIWhileCountDown();
     }
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 672b973..e84c328 100755
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -324,8 +324,6 @@
                     : null;
 
     private final CameraErrorCallback mErrorCallback = new CameraErrorCallback();
-    private final StatsCallback mStatsCallback = new StatsCallback();
-    private final MetaDataCallback mMetaDataCallback = new MetaDataCallback();
     private long mFocusStartTime;
     private long mShutterCallbackTime;
     private long mPostViewPictureCallbackTime;
@@ -1144,69 +1142,6 @@
             }
         }
     }
-    private final class StatsCallback
-           implements android.hardware.Camera.CameraDataCallback {
-            @Override
-        public void onCameraData(int [] data, android.hardware.Camera camera) {
-            //if(!mPreviewing || !mHiston || !mFirstTimeInitialized){
-            if(!mHiston || !mFirstTimeInitialized){
-                return;
-            }
-            /*The first element in the array stores max hist value . Stats data begin from second value*/
-            synchronized(statsdata) {
-                System.arraycopy(data,0,statsdata,0,STATS_DATA);
-            }
-            mActivity.runOnUiThread(new Runnable() {
-                public void run() {
-                    if(mGraphView != null)
-                        mGraphView.PreviewChanged();
-                }
-           });
-        }
-    }
-
-    private final class MetaDataCallback
-           implements android.hardware.Camera.CameraMetaDataCallback{
-        @Override
-        public void onCameraMetaData (byte[] data, android.hardware.Camera camera) {
-            int metadata[] = new int[3];
-            if (data.length >= 12) {
-                for (int i =0;i<3;i++) {
-                    metadata[i] = byteToInt( (byte []) data, i*4);
-                }
-                /* Checking if the meta data is for auto HDR */
-                if (metadata[0] == 3) {
-                    if (metadata[2] == 1) {
-                        mAutoHdrEnable = true;
-                        mActivity.runOnUiThread(new Runnable() {
-                            public void run() {
-                                if (mDrawAutoHDR != null)
-                                    mDrawAutoHDR.AutoHDR();
-                            }
-                        });
-                    }
-                    else {
-                        mAutoHdrEnable = false;
-                        mActivity.runOnUiThread(new Runnable() {
-                            public void run() {
-                                if (mDrawAutoHDR != null)
-                                    mDrawAutoHDR.AutoHDR();
-                            }
-                        });
-                    }
-                }
-            }
-        }
-
-        private int byteToInt (byte[] b, int offset) {
-            int value = 0;
-            for (int i = 0; i < 4; i++) {
-                int shift = (4 - 1 - i) * 8;
-                value += (b[(3-i) + offset] & 0x000000FF) << shift;
-            }
-            return value;
-        }
-    }
 
     private final class PostViewPictureCallback
             implements CameraPictureCallback {
@@ -1706,7 +1641,6 @@
         if(mHiston) {
             if (mSnapshotMode != CameraInfoWrapper.CAMERA_SUPPORT_MODE_ZSL) {
                 mHiston = false;
-                mCameraDevice.setHistogramMode(null);
             }
             mActivity.runOnUiThread(new Runnable() {
                 public void run() {
@@ -3579,7 +3513,6 @@
                     }
                 });
                 mParameters.setSceneMode("asd");
-                mCameraDevice.setMetadataCb(mMetaDataCallback);
             }
             else {
                 mAutoHdrEnable = false;
@@ -3681,7 +3614,6 @@
                         }
                     }
                 });
-                mCameraDevice.setHistogramMode(mStatsCallback);
                 mHiston = true;
             } else {
                 mHiston = false;
@@ -3691,7 +3623,6 @@
                              mGraphView.setVisibility(View.INVISIBLE);
                          }
                     });
-                mCameraDevice.setHistogramMode(null);
             }
         }
 
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 0eb7c51..edf176c 100755
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -38,6 +38,11 @@
 import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.media.MediaRecorder;
 import android.media.CamcorderProfile;
 import android.preference.PreferenceManager;
@@ -1156,36 +1161,66 @@
         ArrayList<String> supported = new ArrayList<String>();
         supported.add("off");
         ListPreference videoQuality = mPreferenceGroup.findPreference(KEY_VIDEO_QUALITY);
-        if (videoQuality == null) return supported;
+        ListPreference videoEncoder = mPreferenceGroup.findPreference(KEY_VIDEO_ENCODER);
+        if (videoQuality == null || videoEncoder == null) return supported;
         String videoSizeStr = videoQuality.getValue();
+        int videoEncoderNum = SettingTranslation.getVideoEncoder(videoEncoder.getValue());
+        VideoCapabilities videoCapabilities = null;
+        boolean findVideoEncoder = false;
         if (videoSizeStr != null) {
             Size videoSize = parseSize(videoSizeStr);
+            MediaCodecList allCodecs = new MediaCodecList(MediaCodecList.ALL_CODECS);
+            for (MediaCodecInfo info : allCodecs.getCodecInfos()) {
+                if (!info.isEncoder() || info.getName().contains("google")) continue;
+                for (String type : info.getSupportedTypes()) {
+                    if ((videoEncoderNum == MediaRecorder.VideoEncoder.MPEG_4_SP && type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4))
+                            || (videoEncoderNum == MediaRecorder.VideoEncoder.H263 && type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263))
+                            || (videoEncoderNum == MediaRecorder.VideoEncoder.H264 && type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC))
+                            || (videoEncoderNum == MediaRecorder.VideoEncoder.HEVC && type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC))) {
+                        CodecCapabilities codecCapabilities = info.getCapabilitiesForType(type);
+                        videoCapabilities = codecCapabilities.getVideoCapabilities();
+                        findVideoEncoder = true;
+                        break;
+                    }
+                }
+                if (findVideoEncoder) break;
+            }
+
             try {
                 Range[] range = getSupportedHighSpeedVideoFPSRange(mCameraId, videoSize);
                 for (Range r : range) {
                     // To support HFR for both preview and recording,
                     // minmal FPS needs to be equal to maximum FPS
-                    if ((int) r.getUpper() == (int)r.getLower()) {
-                        supported.add("hfr" + String.valueOf(r.getUpper()));
-                        supported.add("hsr" + String.valueOf(r.getUpper()));
+                    if ((int) r.getUpper() == (int) r.getLower()) {
+                        if (videoCapabilities != null) {
+                            if (videoCapabilities.areSizeAndRateSupported(
+                                    videoSize.getWidth(), videoSize.getHeight(), (int) r.getUpper())) {
+                                supported.add("hfr" + String.valueOf(r.getUpper()));
+                                supported.add("hsr" + String.valueOf(r.getUpper()));
+                            }
+                        }
                     }
                 }
             } catch (IllegalArgumentException ex) {
                 Log.w(TAG, "HFR is not supported for this resolution " + ex);
             }
-            if ( mExtendedHFRSize != null && mExtendedHFRSize.length >= 3 ) {
-                for( int i=0; i < mExtendedHFRSize.length; i+=3 ) {
-                    String item = "hfr" + mExtendedHFRSize[i+2];
-                    if ( !supported.contains(item)
+            if (mExtendedHFRSize != null && mExtendedHFRSize.length >= 3) {
+                for (int i = 0; i < mExtendedHFRSize.length; i += 3) {
+                    String item = "hfr" + mExtendedHFRSize[i + 2];
+                    if (!supported.contains(item)
                             && videoSize.getWidth() <= mExtendedHFRSize[i]
-                            && videoSize.getHeight() <= mExtendedHFRSize[i+1] ) {
-                        supported.add(item);
-                        supported.add("hsr"+mExtendedHFRSize[i+2]);
+                            && videoSize.getHeight() <= mExtendedHFRSize[i + 1]) {
+                        if (videoCapabilities != null) {
+                            if (videoCapabilities.areSizeAndRateSupported(
+                                    videoSize.getWidth(), videoSize.getHeight(), mExtendedHFRSize[i + 2])) {
+                                supported.add(item);
+                                supported.add("hsr" + mExtendedHFRSize[i + 2]);
+                            }
+                        }
                     }
                 }
             }
         }
-
         return supported;
     }
 
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 65b700f..1f5671c 100755
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -146,6 +146,8 @@
 
             if (mimeType.equalsIgnoreCase("heif")){
                 values.put(ImageColumns.DISPLAY_NAME, title + ".heic");
+            } else if(mimeType.equalsIgnoreCase("heifs")){
+                values.put(ImageColumns.DISPLAY_NAME, title + ".heics");
             } else {
                 values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
             }
@@ -271,10 +273,13 @@
 
     public static String generateFilepath(String title, String pictureFormat) {
         if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg")
-                || pictureFormat.equalsIgnoreCase("heif")) {
+                || pictureFormat.equalsIgnoreCase("heif")
+                || pictureFormat.equalsIgnoreCase("heifs")) {
             String suffix = ".jpg";
             if (pictureFormat.equalsIgnoreCase("heif")) {
                 suffix = ".heic";
+            }else if(pictureFormat.equalsIgnoreCase("heifs")) {
+                suffix = ".heics";
             }
             if (isSaveSDCard() && SDCard.instance().isWriteable()) {
                 return SDCard.instance().getDirectory() + '/' + title + suffix;
diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java
index de14dec..69e2ecd 100755
--- a/src/com/android/camera/imageprocessor/PostProcessor.java
+++ b/src/com/android/camera/imageprocessor/PostProcessor.java
@@ -722,9 +722,6 @@
             mZSLQueue = new ZSLQueue(mController);
         }
         mMaxRequiredImageNum = MAX_REQUIRED_IMAGE_NUM;
-        if(mController.isLongShotSettingEnabled()) {
-            mMaxRequiredImageNum = Math.max(MAX_REQUIRED_IMAGE_NUM, PersistUtil.getLongshotShotLimit()+2);
-        }
         mPendingContinuousRequestCount = 0;
     }
 
diff --git a/src/com/android/camera/imageprocessor/filter/BlurbusterFilter.java b/src/com/android/camera/imageprocessor/filter/BlurbusterFilter.java
index 4ec2fe3..d8d0a3e 100644
--- a/src/com/android/camera/imageprocessor/filter/BlurbusterFilter.java
+++ b/src/com/android/camera/imageprocessor/filter/BlurbusterFilter.java
@@ -154,8 +154,8 @@
 
     static {
         try {
-            System.loadLibrary("jni_blurbuster");
-            mIsSupported = true;
+            //System.loadLibrary("jni_blurbuster");
+            mIsSupported = false;
         }catch(UnsatisfiedLinkError e) {
             Log.d(TAG, e.toString());
             mIsSupported = false;
diff --git a/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java b/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java
index 4682e39..41bd036 100644
--- a/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java
+++ b/src/com/android/camera/imageprocessor/filter/ChromaflashFilter.java
@@ -252,8 +252,8 @@
 
     static {
         try {
-            System.loadLibrary("jni_chromaflash");
-            mIsSupported = true;
+            //System.loadLibrary("jni_chromaflash");
+            mIsSupported = false;
         }catch(UnsatisfiedLinkError e) {
             Log.d(TAG, e.toString());
             mIsSupported = false;
diff --git a/src/com/android/camera/imageprocessor/filter/SharpshooterFilter.java b/src/com/android/camera/imageprocessor/filter/SharpshooterFilter.java
index 611949f..f35d3be 100644
--- a/src/com/android/camera/imageprocessor/filter/SharpshooterFilter.java
+++ b/src/com/android/camera/imageprocessor/filter/SharpshooterFilter.java
@@ -179,8 +179,8 @@
 
     static {
         try {
-            System.loadLibrary("jni_sharpshooter");
-            mIsSupported = true;
+            //System.loadLibrary("jni_sharpshooter");
+            mIsSupported = false;
         }catch(UnsatisfiedLinkError e) {
             Log.d(TAG, e.toString());
             mIsSupported = false;
diff --git a/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java b/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java
index 25c1670..0c588b9 100755
--- a/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java
+++ b/src/com/android/camera/imageprocessor/filter/UbifocusFilter.java
@@ -327,8 +327,8 @@
 
     static {
         try {
-            System.loadLibrary("jni_ubifocus");
-            mIsSupported = true;
+            //System.loadLibrary("jni_ubifocus");
+            mIsSupported = false;
         }catch(UnsatisfiedLinkError e) {
             mIsSupported = false;
         }
diff --git a/src/com/android/camera/ui/CountDownView.java b/src/com/android/camera/ui/CountDownView.java
index 7e1f28d..d9d0244 100755
--- a/src/com/android/camera/ui/CountDownView.java
+++ b/src/com/android/camera/ui/CountDownView.java
@@ -67,6 +67,15 @@
         }
     }
 
+    public void releaseSoundPool() {
+        if (mSoundPool != null) {
+            mSoundPool.unload(R.raw.beep_once);
+            mSoundPool.unload(R.raw.beep_twice);
+            mSoundPool.release();
+            mSoundPool = null;
+        }
+    }
+
     public boolean isCountingDown() {
         return mRemainingSecs > 0;
     };
diff --git a/src_wrapper/org/codeaurora/snapcam/wrapper/CameraWrapper.java b/src_wrapper/org/codeaurora/snapcam/wrapper/CameraWrapper.java
old mode 100644
new mode 100755
index 6739686..8078a38
--- a/src_wrapper/org/codeaurora/snapcam/wrapper/CameraWrapper.java
+++ b/src_wrapper/org/codeaurora/snapcam/wrapper/CameraWrapper.java
@@ -46,45 +46,9 @@
 import android.util.Log;
 import android.view.SurfaceHolder;
 
-import android.hardware.Camera.CameraMetaDataCallback;
-import android.hardware.Camera.CameraDataCallback;
-
 public class CameraWrapper extends Wrapper{
 
     private static Method method_setMetadataCb = null;
-    public static final void setMetadataCb(Camera camera, CameraMetaDataCallback cb){
-        if ( DEBUG ){
-            Log.e(TAG, "" + Camera.class + " no setMetadataCb");
-            return;
-        }
-        try{
-            if ( method_setMetadataCb == null ){
-                method_setMetadataCb = Camera.class.getMethod("setMetadataCb",
-                        android.hardware.Camera.CameraMetaDataCallback.class);
-            }
-            method_setMetadataCb.invoke(camera, cb);
-        }catch (Exception exception){
-            exception.printStackTrace();
-        }
-    }
-
-
-    private static Method method_setHistogramMode = null;
-    public static final void setHistogramMode(Camera camera, CameraDataCallback cb) {
-        if ( DEBUG ){
-            Log.e(TAG, "" + Camera.class + " no setHistogramMode");
-            return;
-        }
-        try{
-            if ( method_setHistogramMode == null ){
-                method_setHistogramMode = Camera.class.getMethod("setHistogramMode",
-                        CameraDataCallback.class);
-            }
-            method_setHistogramMode.invoke(camera, cb);
-        }catch (Exception exception){
-            exception.printStackTrace();
-        }
-    }
 
     private static Method method_sendHistogramData = null;
     public static final void sendHistogramData(Camera camera){
diff --git a/version.mk b/version.mk
index d461f0d..51006fd 100755
--- a/version.mk
+++ b/version.mk
@@ -40,7 +40,7 @@
 # base_version_build is 3 digits and auto-increment for fixing CR.
 base_version_major := 2
 base_version_minor := 02
-base_version_build := 017
+base_version_build := 019
 
 #####################################################
 #####################################################