touchpad.py: Require single clicks in all quadrants.

can assign click number for each quadrant by
number_to_quadrant argument.
for SMT, operator cannot test each quadrant.
Just assign number_to_quadrant argument to 0.

BUG=chrome-os-partner:18528
TEST=manually, add four quadrants single click test

Change-Id: Ia463496819a70d7ac5322c27dfd3cfe97996a1f9
Reviewed-on: https://gerrit.chromium.org/gerrit/51294
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
Commit-Queue: Heng-ruey Hsu <henryhsu@chromium.org>
Tested-by: Heng-ruey Hsu <henryhsu@chromium.org>
diff --git a/py/test/pytests/touchpad.py b/py/test/pytests/touchpad.py
index 153afa2..445b5ca 100644
--- a/py/test/pytests/touchpad.py
+++ b/py/test/pytests/touchpad.py
@@ -99,19 +99,63 @@
 # The layout contains one div for touchpad touch and scroll,
 # one table for left/right click, and one div for countdown timer.
 _HTML_TOUCHPAD = '''
-<div id="%s" style="position: relative; width: 100%%; height: 80%%;"></div>
-<table style="width: 100%%;">
+<div id="%s" style="position: relative; width: 100%%; height: 60%%;"></div>
+<table style="width: 100%%; height: 30%%;">
   <tbody>
     <tr>
-      <td style="width: 50%%;" id="left-text-cell"></td>
-      <td style="width: 50%%;" id="right-text-cell"></td>
-    </tr>
-    <tr>
-      <td>
-        <div id="left-circle" class="touchpad-test-circle-untested"></div>
+      <td style="width: 65%%;">
+        <table id="quadrant_table" style="width: 100%%;">
+          <tbody>
+            <tr>
+              <td>
+                <div id="quadrant2" class="touchpad-test-sector-untested" align="center">
+                  Click Left-Top Corner
+                  <div id="quadrant2_count" align="center">0/3</div>
+                </div>
+              </td>
+              <td>
+                <div id="quadrant1" class="touchpad-test-sector-untested" align="center">
+                  Click Right-Top Corner
+                  <div id="quadrant1_count" align="center">0/3</div>
+                </div>
+              </td>
+            </tr>
+            <tr>
+              <td>
+                <div id="quadrant3" class="touchpad-test-sector-untested" align="center">
+                  Click Left-Bottom Corner
+                  <div id="quadrant3_count" align="center">0/3</div>
+                </div>
+              </td>
+              <td>
+                <div id="quadrant4" class="touchpad-test-sector-untested" align="center">
+                  Click Right-Bottom Corner
+                  <div id="quadrant4_count" align="center">0/3</div>
+                </div>
+              </td>
+            </tr>
+          </tbody>
+        </table>
       </td>
       <td>
-        <div id="right-circle" class="touchpad-test-circle-untested"></div>
+        <table style="width: 100%%;">
+          <tbody>
+            <tr>
+              <td align="right" valign="center">
+                <div id="left-circle" class="touchpad-test-circle-untested"></div>
+              </td>
+              <td align="left" valign="center">
+                <div id="left-text-cell"></div>
+              </td>
+              <td align="right" valign="center">
+                <div id="right-circle" class="touchpad-test-circle-untested"></div>
+              </td>
+              <td align="left" valign="center">
+                <div id="right-text-cell"></div>
+              </td>
+            </tr>
+          </tbody>
+        </table>
       </td>
     </tr>
   </tbody>
@@ -138,17 +182,17 @@
     .touchpad-test-circle-untested {
       border: 3px solid gray;
       border-radius: 50%;
-      width: 30px; height: 30px;
+      width: 20px; height: 20px;
       box-sizing: border-box; }
     .touchpad-test-circle-down {
       border: 3px solid yellow;
       border-radius: 50%;
-      width: 30px; height: 30px;
+      width: 20px; height: 20px;
       box-sizing: border-box; }
     .touchpad-test-circle-tested {
       border: 3px solid green;
       border-radius: 50%;
-      width: 30px; height: 30px;
+      width: 20px; height: 20px;
       box-sizing: border-box; }
 '''
 _X_SEGMENTS = 5
@@ -166,6 +210,27 @@
   Down = "1"
 
 
+class Quadrant:
+  '''
+  The class is to update quadrant information according to x_ratio and y_ratio
+  Quadrant 1 is Right-Top Corner
+  Quadrant 2 is Left-Top Corner
+  Quadrant 3 is Left-Bottom Corner
+  Quadrant 4 is Right-Bottom Corner
+  '''
+  def __init__(self):
+    self.quadrant = 0
+
+  def UpdateQuadrant(self, x_ratio, y_ratio):
+    if x_ratio >= 0.5 and y_ratio < 0.5:
+      self.quadrant = 1
+    elif x_ratio < 0.5 and y_ratio < 0.5:
+      self.quadrant = 2
+    elif x_ratio < 0.5 and y_ratio >= 0.5:
+      self.quadrant = 3
+    elif x_ratio >= 0.5 and y_ratio >= 0.5:
+      self.quadrant = 4
+
 class MoveEvent:
   '''The class to store touchpad move event.'''
   def __init__(self):
@@ -241,12 +306,14 @@
     self.monitor_process: the evtest process to get touchpad input.
         This should get terminated when test stops.
     self.touchpad_event_path: The path of input device like /dev/input/event1.
+    self.quadrant: This represents the current quadrant of mouse.
   '''
   ARGS = [
     Arg('touchpad_event_id', int, 'Touchpad input event id. The test will probe'
         ' for event id if it is not given.', default=None, optional=True),
     Arg('timeout_secs', int, 'Timeout for the test.', default=20),
-    Arg('number_to_click', int, 'Target number to click.', default=10)
+    Arg('number_to_click', int, 'Target number to click.', default=10),
+    Arg('number_to_quadrant', int, 'Target number to click for each quadrant.', default=0)
   ]
 
   def setUp(self):
@@ -256,7 +323,7 @@
     self.ui.AppendCSS(_TOUCHPAD_TEST_DEFAULT_CSS)
     self.template.SetState(_HTML_TOUCHPAD)
     self.ui.CallJSFunction('setupTouchpadTest', _ID_CONTAINER,
-        _X_SEGMENTS, _Y_SEGMENTS, self.args.number_to_click)
+        _X_SEGMENTS, _Y_SEGMENTS, self.args.number_to_click, self.args.number_to_quadrant)
 
     # Initialize properties
     self.x_max = None
@@ -266,6 +333,7 @@
     self.click_event = ClickEvent()
     self.touchpad_has_right_btn = False
     self.monitor_process = None
+    self.quadrant = Quadrant()
     if self.args.touchpad_event_id is None:
       self.touchpad_event_path = self.ProbeEventSource()
     else:
@@ -457,6 +525,10 @@
       x_ratio = float(self.move_event.x) / float(self.x_max)
     if self.move_event.y:
       y_ratio = float(self.move_event.y) / float(self.y_max)
+
+    if self.move_event.x and self.move_event.y:
+      self.quadrant.UpdateQuadrant(x_ratio, y_ratio)
+
     if self.move_event.scroll and self.move_event.y:
       self.MarkScrollSectorTested(y_ratio)
     elif self.move_event.x and self.move_event.y:
@@ -486,10 +558,10 @@
     '''
     if up_down == UpDown.Up:
       logging.info('mark single click up')
-      self.ui.CallJSFunction('markSingleClickUp')
+      self.ui.CallJSFunction('markSingleClickUp', self.quadrant.quadrant)
     elif up_down == UpDown.Down:
       logging.info('mark single click down')
-      self.ui.CallJSFunction('markSingleClickDown')
+      self.ui.CallJSFunction('markSingleClickDown', self.quadrant.quadrant)
 
   def DrawDoubleClick(self, up_down):
     '''
diff --git a/py/test/pytests/touchpad_static/touchpad.js b/py/test/pytests/touchpad_static/touchpad.js
index 3e6746f..bebd131 100644
--- a/py/test/pytests/touchpad_static/touchpad.js
+++ b/py/test/pytests/touchpad_static/touchpad.js
@@ -9,15 +9,18 @@
  * @param {int} xSegments
  * @param {int} ySegments
  * @param {int} countTarget
+ * @param {int} quadCountTarget
  */
-TouchpadTest = function(container, xSegments, ySegments, countTarget) {
+TouchpadTest = function(container, xSegments, ySegments, countTarget, quadCountTarget) {
   this.container = container;
   this.xSegments = xSegments;
   this.ySegments = ySegments;
   this.leftCount = 0;
   this.rightCount = 0;
   this.countTarget = countTarget;
-
+  this.quadCountTarget = quadCountTarget;
+  this.quadrant_count = {};
+  this.quadrant_total_count = 0;
 };
 
 /**
@@ -26,10 +29,11 @@
  * @param {int} xSegments
  * @param {int} ySegments
  * @param {int} countTarget
+ * @param {int} quadCountTarget
  */
-function setupTouchpadTest(container, xSegments, ySegments, countTarget) {
+function setupTouchpadTest(container, xSegments, ySegments, countTarget, quadCountTarget) {
   window.touchpadTest = new TouchpadTest(container, xSegments, ySegments,
-                                         countTarget);
+                                         countTarget, quadCountTarget);
   window.touchpadTest.init();
 }
 
@@ -65,6 +69,17 @@
   table.appendChild(tableBody);
   $(this.container).appendChild(table);
   this.updateCircleCountText();
+
+  /* This is for SMT test, operator cannot click for each quadrant */
+  if (this.quadCountTarget == 0) {
+    var element = document.getElementById('quadrant_table');
+    if (element) {
+      element.style.display = "none";
+    }
+    for (i = 1; i <= 4; i++) {
+      window.touchpadTest.markQuadrantSectorTested(i);
+    }
+  }
 };
 
 /**
@@ -95,6 +110,19 @@
 };
 
 /**
+ * Marks the given quadrant sector as "tested" on the test ui.
+ * @param {int} quadrant
+ */
+TouchpadTest.prototype.markQuadrantSectorTested = function(quadrant) {
+  var id = "quadrant" + quadrant;
+  var element = document.getElementById(id);
+  if (element) {
+    element.className = "touchpad-test-sector-tested";
+  }
+  this.checkTestComplete();
+};
+
+/**
  * Marks the given circle as "tested" on the test ui.
  * @param {string} id
  */
@@ -135,6 +163,37 @@
 };
 
 /**
+ * Adds a mark to quadrant.
+ * @param {int} quad
+ */
+TouchpadTest.prototype.updateQuadrant = function(quad) {
+  if (!this.quadrant_count[quad]) {
+    this.quadrant_count[quad] = 0;
+  }
+  if (this.quadrant_count[quad] < this.quadCountTarget) {
+    this.quadrant_count[quad] = this.quadrant_count[quad] + 1;
+    this.quadrant_total_count = this.quadrant_total_count + 1;
+  }
+  if (this.quadrant_count[quad] == this.quadCountTarget) {
+    window.touchpadTest.markQuadrantSectorTested(quad);
+  }
+};
+
+/**
+ * Update the number of click for each quadrant
+ * @param {int} quad
+ */
+TouchpadTest.prototype.updateQuadrantCount = function(quad) {
+  var id = "quadrant" + quad + "_count";
+  var element = document.getElementById(id);
+
+  if (element) {
+    element.innerHTML= this.quadrant_count[quad].toString() + " / "
+      + this.quadCountTarget.toString();
+  }
+};
+
+/**
  * Marks the given circle as "down" on the test ui.
  * @param {string} id
  */
@@ -152,7 +211,8 @@
 TouchpadTest.prototype.checkTestComplete = function() {
   if ((this.getClassArray("touchpad-test-sector-untested").length == 0) &&
       (this.leftCount == this.countTarget) &&
-      (this.rightCount == this.countTarget)) {
+      (this.rightCount == this.countTarget) &&
+      (this.quadrant_total_count == this.quadCountTarget * 4)) {
     window.test.pass();
   }
 };
@@ -244,18 +304,23 @@
 
 /**
  * Marks single click as down.
+ * @param {int} quadrant
  */
-function markSingleClickDown() {
+function markSingleClickDown(quadrant) {
   window.touchpadTest.markCircleDown("left-circle");
 }
 
 /**
  * Marks single click as tested.
+ * @param {int} quadrant
  */
-function markSingleClickUp() {
+function markSingleClickUp(quadrant) {
   window.touchpadTest.updateLeftCount();
   window.touchpadTest.updateCircleCountText();
   window.touchpadTest.markCircleTested("left-circle");
+
+  window.touchpadTest.updateQuadrant(quadrant);
+  window.touchpadTest.updateQuadrantCount(quadrant);
 }
 
 /**