Merge "Add support for detecting finger orientation." into honeycomb
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 12cf853..0b765fd 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -300,6 +300,17 @@
                     mPaint.setARGB(255, pressureLevel, 128, 255 - pressureLevel);
                     drawOval(canvas, ps.mCoords.x, ps.mCoords.y, ps.mCoords.toolMajor,
                             ps.mCoords.toolMinor, ps.mCoords.orientation, mPaint);
+
+                    // Draw the orientation arrow.
+                    mPaint.setARGB(255, pressureLevel, 255, 0);
+                    float orientationVectorX = (float) (Math.sin(-ps.mCoords.orientation)
+                            * ps.mCoords.toolMajor * 0.7);
+                    float orientationVectorY = (float) (Math.cos(-ps.mCoords.orientation)
+                            * ps.mCoords.toolMajor * 0.7);
+                    canvas.drawLine(
+                            ps.mCoords.x - orientationVectorX, ps.mCoords.y - orientationVectorY,
+                            ps.mCoords.x + orientationVectorX, ps.mCoords.y + orientationVectorY,
+                            mPaint);
                 }
             }
         }
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index f6a8859..6b66791 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -80,6 +80,10 @@
     return sqrtf(x * x + y * y);
 }
 
+inline static int32_t signExtendNybble(int32_t value) {
+    return value >= 8 ? value - 16 : value;
+}
+
 static inline const char* toString(bool value) {
     return value ? "true" : "false";
 }
@@ -1917,6 +1921,8 @@
             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
         } else if (orientationCalibrationString == "interpolated") {
             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else if (orientationCalibrationString == "vector") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
         } else if (orientationCalibrationString != "default") {
             LOGW("Invalid value for touch.orientation.calibration: '%s'",
                     orientationCalibrationString.string());
@@ -2152,6 +2158,9 @@
     case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
         dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
         break;
+    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
+        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
+        break;
     default:
         assert(false);
     }
@@ -2567,6 +2576,19 @@
             case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
                 orientation = in.orientation * mLocked.orientationScale;
                 break;
+            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
+                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
+                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
+                if (c1 != 0 || c2 != 0) {
+                    orientation = atan2f(c1, c2) * 0.5f;
+                    float minorAxisScale = (16.0f - pythag(c1, c2)) / 16.0f;
+                    toolMinor *= minorAxisScale;
+                    touchMinor *= minorAxisScale;
+                } else {
+                    orientation = 0;
+                }
+                break;
+            }
             default:
                 orientation = 0;
             }
@@ -2586,7 +2608,6 @@
             case DISPLAY_ORIENTATION_180: {
                 x = mLocked.surfaceWidth - x;
                 y = mLocked.surfaceHeight - y;
-                orientation = - orientation;
                 break;
             }
             case DISPLAY_ORIENTATION_270: {
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 8c849c4..8b2d40a 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -680,6 +680,7 @@
             ORIENTATION_CALIBRATION_DEFAULT,
             ORIENTATION_CALIBRATION_NONE,
             ORIENTATION_CALIBRATION_INTERPOLATED,
+            ORIENTATION_CALIBRATION_VECTOR,
         };
 
         OrientationCalibration orientationCalibration;