Add forced sound for panorama mode.

bug:5538024
Change-Id: I59b662a0cc53471ba905391c016c78ebd9ae1d73
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index 43d33a8..7a7cf78 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -26,6 +26,7 @@
 import com.android.camera.OnClickAttr;
 import com.android.camera.R;
 import com.android.camera.ShutterButton;
+import com.android.camera.SoundPlayer;
 import com.android.camera.Storage;
 import com.android.camera.Thumbnail;
 import com.android.camera.Util;
@@ -37,6 +38,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -54,6 +56,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.Menu;
@@ -65,6 +69,7 @@
 import android.widget.TextView;
 
 import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
 import java.io.File;
 import java.util.List;
 
@@ -96,6 +101,8 @@
     // Ratio of nanosecond to second
     private static final float NS2S = 1.0f / 1000000000.0f;
 
+    private static final String VIDEO_RECORD_SOUND = "/system/media/audio/ui/VideoRecord.ogg";
+
     private boolean mPausing;
 
     private View mPanoLayout;
@@ -158,6 +165,8 @@
     private float[] mTransformMatrix;
     private float mHorizontalViewAngle;
 
+    private SoundPlayer mRecordSound;
+
     // Prefer FOCUS_MODE_INFINITY to FOCUS_MODE_CONTINUOUS_VIDEO because of
     // getting a better image quality by the former.
     private String mTargetFocusMode = Parameters.FOCUS_MODE_INFINITY;
@@ -704,9 +713,11 @@
         // right now.
         switch (mCaptureState) {
             case CAPTURE_STATE_VIEWFINDER:
+                if (mRecordSound != null) mRecordSound.play();
                 startCapture();
                 break;
             case CAPTURE_STATE_MOSAIC:
+                if (mRecordSound != null) mRecordSound.play();
                 stopCapture(false);
         }
     }
@@ -890,6 +901,34 @@
         mMosaicFrameProcessor.initialize();
     }
 
+    private void initSoundRecorder() {
+        // Construct sound player; use enforced sound output if necessary
+        File recordSoundFile = new File(VIDEO_RECORD_SOUND);
+        try {
+            ParcelFileDescriptor recordSoundParcel =
+                    ParcelFileDescriptor.open(recordSoundFile,
+                            ParcelFileDescriptor.MODE_READ_ONLY);
+            AssetFileDescriptor recordSoundAsset =
+                    new AssetFileDescriptor(recordSoundParcel, 0,
+                                            AssetFileDescriptor.UNKNOWN_LENGTH);
+            if (SystemProperties.get("ro.camera.sound.forced", "0").equals("0")) {
+                mRecordSound = new SoundPlayer(recordSoundAsset, false);
+            } else {
+                mRecordSound = new SoundPlayer(recordSoundAsset, true);
+            }
+        } catch (java.io.FileNotFoundException e) {
+            Log.e(TAG, "System video record sound not found");
+            mRecordSound = null;
+        }
+    }
+
+    private void releaseSoundRecorder() {
+        if (mRecordSound != null) {
+            mRecordSound.release();
+            mRecordSound = null;
+        }
+    }
+
     @Override
     protected void onPause() {
         super.onPause();
@@ -908,6 +947,7 @@
         }
 
         releaseCamera();
+        releaseSoundRecorder();
         mMosaicView.onPause();
         clearMosaicFrameProcessorIfNeeded();
         mOrientationEventListener.disable();
@@ -922,6 +962,8 @@
         mCaptureState = CAPTURE_STATE_VIEWFINDER;
         setupCamera();
 
+        initSoundRecorder();
+
         // Camera must be initialized before MosaicFrameProcessor is initialized. The preview size
         // has to be decided by camera device.
         initMosaicFrameProcessorIfNeeded();