Mirror the preview for front-facing cameras. do not merge

Now overlay does ROT_90 before FLIP_V or FLIP_H. It should be FLIP_V
or FLIP_H first. The formula should be changed after overlay is fixed.

bug:3059865
Change-Id: Ie4366bf7f1fcac7383e8dfc74b1b865997bbbcc6
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 6ff5a40..275e2eb 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -779,9 +779,9 @@
      * Set the clockwise rotation of preview display in degrees. This affects
      * the preview frames and the picture displayed after snapshot. This method
      * is useful for portrait mode applications. Note that preview display of
-     * front-facing cameras is flipped horizontally, that is, the image is
-     * reflected along the central vertical axis of the camera sensor. So the
-     * users can see themselves as looking into a mirror.
+     * front-facing cameras is flipped horizontally before the rotation, that
+     * is, the image is reflected along the central vertical axis of the camera
+     * sensor. So the users can see themselves as looking into a mirror.
      *
      * This does not affect the order of byte array passed in {@link
      * PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 964700b..e6d84ba 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -83,6 +83,18 @@
 enum {
     CAMERA_CMD_START_SMOOTH_ZOOM     = 1,
     CAMERA_CMD_STOP_SMOOTH_ZOOM      = 2,
+    // Set the clockwise rotation of preview display (setPreviewDisplay) in
+    // degrees. This affects the preview frames and the picture displayed after
+    // snapshot. This method is useful for portrait mode applications. Note that
+    // preview display of front-facing cameras is flipped horizontally before
+    // the rotation, that is, the image is reflected along the central vertical
+    // axis of the camera sensor. So the users can see themselves as looking
+    // into a mirror.
+    //
+    // This does not affect the order of byte array of CAMERA_MSG_PREVIEW_FRAME,
+    // CAMERA_MSG_VIDEO_FRAME, CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE,
+    // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during
+    // preview.
     CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3,
 };
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 58209fd..121819a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -150,7 +150,10 @@
         LOGE("Fail to open camera hardware (id=%d)", cameraId);
         return NULL;
     }
-    client = new Client(this, cameraClient, hardware, cameraId, callingPid);
+    CameraInfo info;
+    HAL_getCameraInfo(cameraId, &info);
+    client = new Client(this, cameraClient, hardware, cameraId, info.facing,
+                        info.orientation, callingPid);
     mClient[cameraId] = client;
     LOG1("CameraService::connect X");
     return client;
@@ -292,7 +295,7 @@
 CameraService::Client::Client(const sp<CameraService>& cameraService,
         const sp<ICameraClient>& cameraClient,
         const sp<CameraHardwareInterface>& hardware,
-        int cameraId, int clientPid) {
+        int cameraId, int cameraFacing, int cameraOrientation, int clientPid) {
     int callingPid = getCallingPid();
     LOG1("Client::Client E (pid %d)", callingPid);
 
@@ -300,6 +303,8 @@
     mCameraClient = cameraClient;
     mHardware = hardware;
     mCameraId = cameraId;
+    mCameraFacing = cameraFacing;
+    mCameraOrientation = cameraOrientation;
     mClientPid = clientPid;
     mUseOverlay = mHardware->useOverlay();
     mMsgEnabled = 0;
@@ -318,7 +323,7 @@
 
     // Callback is disabled by default
     mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
-    mOrientation = 0;
+    mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
     mOrientationChanged = false;
     cameraService->setCameraBusy(cameraId);
     cameraService->loadSound();
@@ -823,22 +828,10 @@
         if (mHardware->previewEnabled()) {
             return INVALID_OPERATION;
         }
-        switch (arg1) {
-            case 0:
-                orientation = ISurface::BufferHeap::ROT_0;
-                break;
-            case 90:
-                orientation = ISurface::BufferHeap::ROT_90;
-                break;
-            case 180:
-                orientation = ISurface::BufferHeap::ROT_180;
-                break;
-            case 270:
-                orientation = ISurface::BufferHeap::ROT_270;
-                break;
-            default:
-                return BAD_VALUE;
-        }
+        // Mirror the preview if the camera is front-facing.
+        orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
+        if (orientation == -1) return BAD_VALUE;
+
         if (mOrientation != orientation) {
             mOrientation = orientation;
             if (mOverlayRef != 0) mOrientationChanged = true;
@@ -1204,6 +1197,31 @@
     client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
 }
 
+int CameraService::Client::getOrientation(int degrees, bool mirror) {
+    if (!mirror) {
+        if (degrees == 0) return 0;
+        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
+        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
+        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
+    } else {  // mirror (horizontal flip)
+        // Now overlay does ROT_90 before FLIP_V or FLIP_H. It should be FLIP_V
+        // or FLIP_H first.
+        // TODO: change this after overlay is fixed.
+        if (degrees == 0) {           // FLIP_H and ROT_0
+            return HAL_TRANSFORM_FLIP_H;
+        } else if (degrees == 90) {   // FLIP_H and ROT_90
+            return HAL_TRANSFORM_ROT_90 | HAL_TRANSFORM_FLIP_V;
+        } else if (degrees == 180) {  // FLIP_H and ROT_180
+            return HAL_TRANSFORM_FLIP_V;
+        } else if (degrees == 270) {  // FLIP_H and ROT_270
+            return HAL_TRANSFORM_ROT_90 | HAL_TRANSFORM_FLIP_H;
+        }
+    }
+    LOGE("Invalid setDisplayOrientation degrees=%d", degrees);
+    return -1;
+}
+
+
 // ----------------------------------------------------------------------------
 
 static const int kDumpLockRetries = 50;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8f0ed75..0dec2ab 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -108,6 +108,8 @@
                                        const sp<ICameraClient>& cameraClient,
                                        const sp<CameraHardwareInterface>& hardware,
                                        int cameraId,
+                                       int cameraFacing,
+                                       int mCameraOrientation,
                                        int clientPid);
                                 ~Client();
 
@@ -153,10 +155,14 @@
                                     const sp<IMemoryHeap>& heap,
                                     size_t offset, size_t size);
 
+        int                     getOrientation(int orientation, bool mirror);
+
         // these are initialized in the constructor.
         sp<CameraService>               mCameraService;  // immutable after constructor
         sp<ICameraClient>               mCameraClient;
         int                             mCameraId;       // immutable after constructor
+        int                             mCameraFacing;   // immutable after constructor
+        int                             mCameraOrientation;  // immutable after constructor
         pid_t                           mClientPid;
         sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()
         bool                            mUseOverlay;     // immutable after constructor