Made the Chronometer able to count downwards

Bug: 26862188
Change-Id: I3a4a34ffccdbcbcb8001b1894ce47bb75b11821d
diff --git a/api/current.txt b/api/current.txt
index abc9e9a..2ccf5067 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -423,6 +423,7 @@
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
+    field public static final int countDown = 16844060; // 0x101051c
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -46069,7 +46070,9 @@
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
+    method public boolean isCountDown();
     method public void setBase(long);
+    method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
     method public void setOnChronometerTickListener(android.widget.Chronometer.OnChronometerTickListener);
     method public void start();
diff --git a/api/system-current.txt b/api/system-current.txt
index 4e7157d..c40b4f29 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -518,6 +518,7 @@
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
+    field public static final int countDown = 16844060; // 0x101051c
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -49170,7 +49171,9 @@
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
+    method public boolean isCountDown();
     method public void setBase(long);
+    method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
     method public void setOnChronometerTickListener(android.widget.Chronometer.OnChronometerTickListener);
     method public void start();
diff --git a/api/test-current.txt b/api/test-current.txt
index 3878fbf..4b6b9be 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -423,6 +423,7 @@
     field public static final int controlX2 = 16843774; // 0x10103fe
     field public static final int controlY1 = 16843773; // 0x10103fd
     field public static final int controlY2 = 16843775; // 0x10103ff
+    field public static final int countDown = 16844060; // 0x101051c
     field public static final int country = 16843962; // 0x10104ba
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
@@ -46086,7 +46087,9 @@
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
+    method public boolean isCountDown();
     method public void setBase(long);
+    method public void setCountDown(boolean);
     method public void setFormat(java.lang.String);
     method public void setOnChronometerTickListener(android.widget.Chronometer.OnChronometerTickListener);
     method public void start();
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 4d707e3..3421790 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -19,15 +19,14 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.os.Handler;
-import android.os.Message;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
 import android.widget.RemoteViews.RemoteView;
 
+import com.android.internal.R;
+
 import java.util.Formatter;
 import java.util.IllegalFormatException;
 import java.util.Locale;
@@ -37,11 +36,17 @@
  * <p>
  * You can give it a start time in the {@link SystemClock#elapsedRealtime} timebase,
  * and it counts up from that, or if you don't give it a base time, it will use the
- * time at which you call {@link #start}.  By default it will display the current
+ * time at which you call {@link #start}.
+ *
+ * <p>The timer can also count downward towards the base time by
+ * setting {@link #setCountDown(boolean)} to true.
+ *
+ *  <p>By default it will display the current
  * timer value in the form "MM:SS" or "H:MM:SS", or you can use {@link #setFormat}
  * to format the timer value into an arbitrary string.
  *
  * @attr ref android.R.styleable#Chronometer_format
+ * @attr ref android.R.styleable#Chronometer_countDown
  */
 @RemoteView
 public class Chronometer extends TextView {
@@ -72,6 +77,7 @@
     private StringBuilder mFormatBuilder;
     private OnChronometerTickListener mOnChronometerTickListener;
     private StringBuilder mRecycle = new StringBuilder(8);
+    private boolean mCountDown;
     
     /**
      * Initialize this Chronometer object.
@@ -102,7 +108,8 @@
 
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, com.android.internal.R.styleable.Chronometer, defStyleAttr, defStyleRes);
-        setFormat(a.getString(com.android.internal.R.styleable.Chronometer_format));
+        setFormat(a.getString(R.styleable.Chronometer_format));
+        setCountDown(a.getBoolean(R.styleable.Chronometer_countDown, false));
         a.recycle();
 
         init();
@@ -114,6 +121,27 @@
     }
 
     /**
+     * Set this view to count down to the base instead of counting up from it.
+     *
+     * @param countDown whether this view should count down
+     *
+     * @see #setBase(long)
+     */
+    @android.view.RemotableViewMethod
+    public void setCountDown(boolean countDown) {
+        mCountDown = countDown;
+    }
+
+    /**
+     * @return whether this view counts down
+     *
+     * @see #setCountDown(boolean)
+     */
+    public boolean isCountDown() {
+        return mCountDown;
+    }
+
+    /**
      * Set the time that the count-up timer is in reference to.
      *
      * @param base Use the {@link SystemClock#elapsedRealtime} time base.
@@ -226,9 +254,17 @@
 
     private synchronized void updateText(long now) {
         mNow = now;
-        long seconds = now - mBase;
+        long seconds = mCountDown ? mBase - now : now - mBase;
         seconds /= 1000;
+        boolean negative = false;
+        if (seconds < 0) {
+            seconds = -seconds;
+            negative = true;
+        }
         String text = DateUtils.formatElapsedTime(mRecycle, seconds);
+        if (negative) {
+            text = getResources().getString(R.string.negative_duration, text);
+        }
 
         if (mFormat != null) {
             Locale loc = Locale.getDefault();
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4480944..2ab95412 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3539,6 +3539,9 @@
              If no format string is specified, the Chronometer will simply display
              "MM:SS" or "H:MM:SS". -->
         <attr name="format" format="string" localization="suggested" />
+        <!-- Specifies whether this Chronometer counts down or counts up from the base.
+              If not specified this is false and the Chronometer counts up. -->
+        <attr name="countDown" format="boolean" />
     </declare-styleable>
     <declare-styleable name="CompoundButton">
         <!-- Indicates the initial checked state of this button. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 13812630..dbaa737 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2702,6 +2702,7 @@
     <public type="attr" name="hotSpotY" />
     <public type="attr" name="version" />
     <public type="attr" name="backupInForeground" />
+    <public type="attr" name="countDown" />
 
     <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
     <public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index da88146..3e9a6ca 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4230,4 +4230,7 @@
     <!-- View application info for a target. -->
     <string name="app_info">App info</string>
 
+    <!-- The representation of a time duration when negative. An example is -1:14. This can be used with a countdown timer for example.-->
+    <string name="negative_duration">\u2212<xliff:g id="time" example="1:14">%1$s</xliff:g></string>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9950884..a7a9292 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2541,4 +2541,5 @@
   <java-symbol type="string" name="carrier_app_dialog_not_now" />
   <java-symbol type="string" name="carrier_app_notification_title" />
   <java-symbol type="string" name="carrier_app_notification_text" />
+  <java-symbol type="string" name="negative_duration" />
 </resources>