Merge "Move zen mode constants and code to framework" into lmp-dev
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index f4e4671..25417ed 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -92,21 +92,27 @@
      */
     public static Animator loadAnimator(Resources resources, Theme theme, int id)
             throws NotFoundException {
+        return loadAnimator(resources, theme, id, 1);
+    }
+
+    /** @hide */
+    public static Animator loadAnimator(Resources resources, Theme theme, int id,
+            float pathErrorScale) throws NotFoundException {
 
         XmlResourceParser parser = null;
         try {
             parser = resources.getAnimation(id);
-            return createAnimatorFromXml(resources, theme, parser);
+            return createAnimatorFromXml(resources, theme, parser, pathErrorScale);
         } catch (XmlPullParserException ex) {
             Resources.NotFoundException rnf =
                     new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
+                            Integer.toHexString(id));
             rnf.initCause(ex);
             throw rnf;
         } catch (IOException ex) {
             Resources.NotFoundException rnf =
                     new Resources.NotFoundException("Can't load animation resource ID #0x" +
-                    Integer.toHexString(id));
+                            Integer.toHexString(id));
             rnf.initCause(ex);
             throw rnf;
         } finally {
@@ -177,7 +183,7 @@
                         }
                         if (animator == null) {
                             animator = createAnimatorFromXml(context.getResources(),
-                                    context.getTheme(), parser);
+                                    context.getTheme(), parser, 1f);
                         }
 
                         if (animator == null) {
@@ -248,9 +254,11 @@
      * @param arrayAnimator Incoming typed array for Animator's attributes.
      * @param arrayObjectAnimator Incoming typed array for Object Animator's
      *            attributes.
+     * @param pixelSize The relative pixel size, used to calculate the
+     *                  maximum error for path animations.
      */
     private static void parseAnimatorFromTypeArray(ValueAnimator anim,
-            TypedArray arrayAnimator, TypedArray arrayObjectAnimator) {
+            TypedArray arrayAnimator, TypedArray arrayObjectAnimator, float pixelSize) {
         long duration = arrayAnimator.getInt(R.styleable.Animator_duration, 300);
 
         long startDelay = arrayAnimator.getInt(R.styleable.Animator_startOffset, 0);
@@ -303,7 +311,7 @@
         }
 
         if (arrayObjectAnimator != null) {
-            setupObjectAnimator(anim, arrayObjectAnimator, getFloats);
+            setupObjectAnimator(anim, arrayObjectAnimator, getFloats, pixelSize);
         }
     }
 
@@ -351,9 +359,11 @@
      * @param anim The target Animator which will be updated.
      * @param arrayObjectAnimator TypedArray for the ObjectAnimator.
      * @param getFloats True if the value type is float.
+     * @param pixelSize The relative pixel size, used to calculate the
+     *                  maximum error for path animations.
      */
     private static void setupObjectAnimator(ValueAnimator anim, TypedArray arrayObjectAnimator,
-            boolean getFloats) {
+            boolean getFloats, float pixelSize) {
         ObjectAnimator oa = (ObjectAnimator) anim;
         String pathData = arrayObjectAnimator.getString(R.styleable.PropertyAnimator_pathData);
 
@@ -370,7 +380,8 @@
                         + " propertyXName or propertyYName is needed for PathData");
             } else {
                 Path path = PathParser.createPathFromPathData(pathData);
-                PathKeyframes keyframeSet = KeyframeSet.ofPath(path);
+                float error = 0.5f * pixelSize; // max half a pixel error
+                PathKeyframes keyframeSet = KeyframeSet.ofPath(path, error);
                 Keyframes xKeyframes;
                 Keyframes yKeyframes;
                 if (getFloats) {
@@ -487,13 +498,15 @@
         }
     }
 
-    private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser)
+    private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
+            float pixelSize)
             throws XmlPullParserException, IOException {
-        return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0);
+        return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0,
+                pixelSize);
     }
 
     private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser,
-            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering)
+            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize)
             throws XmlPullParserException, IOException {
 
         Animator anim = null;
@@ -513,9 +526,9 @@
             String name = parser.getName();
 
             if (name.equals("objectAnimator")) {
-                anim = loadObjectAnimator(res, theme, attrs);
+                anim = loadObjectAnimator(res, theme, attrs, pixelSize);
             } else if (name.equals("animator")) {
-                anim = loadAnimator(res, theme, attrs, null);
+                anim = loadAnimator(res, theme, attrs, null, pixelSize);
             } else if (name.equals("set")) {
                 anim = new AnimatorSet();
                 TypedArray a;
@@ -526,7 +539,8 @@
                 }
                 int ordering = a.getInt(R.styleable.AnimatorSet_ordering,
                         TOGETHER);
-                createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering);
+                createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
+                        pixelSize);
                 a.recycle();
             } else {
                 throw new RuntimeException("Unknown animator name: " + parser.getName());
@@ -556,11 +570,11 @@
 
     }
 
-    private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs)
-            throws NotFoundException {
+    private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs,
+            float pathErrorScale) throws NotFoundException {
         ObjectAnimator anim = new ObjectAnimator();
 
-        loadAnimator(res, theme, attrs, anim);
+        loadAnimator(res, theme, attrs, anim, pathErrorScale);
 
         return anim;
     }
@@ -575,7 +589,7 @@
      *            ObjectAnimator
      */
     private static ValueAnimator loadAnimator(Resources res, Theme theme,
-            AttributeSet attrs, ValueAnimator anim)
+            AttributeSet attrs, ValueAnimator anim, float pathErrorScale)
             throws NotFoundException {
 
         TypedArray arrayAnimator = null;
@@ -601,7 +615,7 @@
             anim = new ValueAnimator();
         }
 
-        parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator);
+        parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale);
 
         final int resID =
                 arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0);
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index fc9bbb1..8d15db2 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -154,6 +154,10 @@
         return new PathKeyframes(path);
     }
 
+    public static PathKeyframes ofPath(Path path, float error) {
+        return new PathKeyframes(path, error);
+    }
+
     /**
      * Sets the TypeEvaluator to be used when calculating animated values. This object
      * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 9f49194..43fa3f0 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -599,17 +599,18 @@
                 mOriginalAlphas.put(view, view.getAlpha());
             }
             view.setAlpha(0f);
-            view.setTransitionAlpha(0f);
         }
     }
 
-    protected void showViews(ArrayList<View> views) {
+    protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) {
         int count = views.size();
         for (int i = 0; i < count; i++) {
             View view = views.get(i);
             Float alpha = mOriginalAlphas.remove(view);
             if (alpha != null) {
                 view.setAlpha(alpha);
+            }
+            if (setTransitionAlpha) {
                 view.setTransitionAlpha(1f);
             }
         }
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index f38c108..9c7728e 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -240,7 +240,7 @@
         if (!mIsCanceled) {
             mIsCanceled = true;
             if (getViewsTransition() == null || mIsViewsTransitionStarted) {
-                showViews(mSharedElements);
+                showViews(mSharedElements, true);
             } else {
                 mTransitioningViews.addAll(mSharedElements);
             }
@@ -300,7 +300,7 @@
         // Now start shared element transition
         ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState,
                 mSharedElementNames);
-        showViews(mSharedElements);
+        showViews(mSharedElements, true);
         scheduleSetSharedElementEnd(sharedElementSnapshots);
         ArrayList<SharedElementOriginalState> originalImageViewState =
                 setSharedElementState(sharedElementState, sharedElementSnapshots);
@@ -411,7 +411,7 @@
                     @Override
                     public void onTransitionStart(Transition transition) {
                         mEnterViewsTransition = transition;
-                        showViews(mTransitioningViews);
+                        showViews(mTransitioningViews, false);
                         super.onTransitionStart(transition);
                     }
 
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 982bbc4..e85ec63 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -126,8 +126,8 @@
     }
 
     public void resetViews() {
-        showViews(mTransitioningViews);
-        showViews(mSharedElements);
+        showViews(mTransitioningViews, true);
+        showViews(mSharedElements, true);
         mIsHidden = true;
         if (!mIsReturning && getDecor() != null) {
             getDecor().suppressLayout(false);
@@ -296,7 +296,7 @@
                     transition.removeListener(this);
                     exitTransitionComplete();
                     if (mIsHidden) {
-                        showViews(mTransitioningViews);
+                        showViews(mTransitioningViews, true);
                     }
                     if (mSharedElementBundle != null) {
                         delayCancel();
@@ -323,7 +323,7 @@
                     transition.removeListener(this);
                     sharedElementTransitionComplete();
                     if (mIsHidden) {
-                        showViews(mSharedElements);
+                        showViews(mSharedElements, true);
                     }
                 }
             });
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index aa724f0..3a91d1a 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -16,6 +16,7 @@
 
 package android.service.notification;
 
+import android.annotation.SystemApi;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Parcel;
@@ -28,6 +29,7 @@
  *
  * @hide
  */
+@SystemApi
 public class Condition implements Parcelable {
 
     public static final String SCHEME = "condition";
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 326412f..03ee726 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -17,6 +17,7 @@
 package android.service.notification;
 
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.app.INotificationManager;
 import android.app.Service;
 import android.content.Context;
@@ -44,6 +45,7 @@
  *
  * @hide
  */
+@SystemApi
 public abstract class ConditionProviderService extends Service {
     private final String TAG = ConditionProviderService.class.getSimpleName()
             + "[" + getClass().getSimpleName() + "]";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8a1d5af..bf2d09b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2773,7 +2773,7 @@
         android:description="@string/permdesc_bindNotificationListenerService"
         android:protectionLevel="signature" />
 
-    <!-- Must be required by an {@link
+    <!-- @SystemApi Must be required by a {@link
          android.service.notification.ConditionProviderService},
          to ensure that only the system can bind to it.
          @hide -->
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index ba22550..e5e2f18 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -252,6 +252,7 @@
             throws XmlPullParserException, IOException {
 
         int eventType = parser.getEventType();
+        float pathErrorScale = 1;
         while (eventType != XmlPullParser.END_DOCUMENT) {
             if (eventType == XmlPullParser.START_TAG) {
                 final String tagName = parser.getName();
@@ -261,9 +262,11 @@
                     int drawableRes = a.getResourceId(
                             R.styleable.AnimatedVectorDrawable_drawable, 0);
                     if (drawableRes != 0) {
-                        mAnimatedVectorState.mVectorDrawable = (VectorDrawable) res.getDrawable(
+                        VectorDrawable vectorDrawable = (VectorDrawable) res.getDrawable(
                                 drawableRes, theme).mutate();
-                        mAnimatedVectorState.mVectorDrawable.setAllowCaching(false);
+                        vectorDrawable.setAllowCaching(false);
+                        pathErrorScale = vectorDrawable.getPixelSize();
+                        mAnimatedVectorState.mVectorDrawable = vectorDrawable;
                     }
                     a.recycle();
                 } else if (TARGET.equals(tagName)) {
@@ -275,7 +278,8 @@
                     int id = a.getResourceId(
                             R.styleable.AnimatedVectorDrawableTarget_animation, 0);
                     if (id != 0) {
-                        Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id);
+                        Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id,
+                                pathErrorScale);
                         setupAnimatorsForTarget(target, objectAnimator);
                     }
                     a.recycle();
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 042da5b..a07ccc4 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -368,6 +368,29 @@
         }
     }
 
+    /**
+     * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension.
+     * This is used to calculate the path animation accuracy.
+     *
+     * @hide
+     */
+    public float getPixelSize() {
+        if (mVectorState == null && mVectorState.mVPathRenderer == null ||
+                mVectorState.mVPathRenderer.mBaseWidth == 0 ||
+                mVectorState.mVPathRenderer.mBaseHeight == 0 ||
+                mVectorState.mVPathRenderer.mViewportHeight == 0 ||
+                mVectorState.mVPathRenderer.mViewportWidth == 0) {
+            return 1; // fall back to 1:1 pixel mapping.
+        }
+        float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth;
+        float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight;
+        float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth;
+        float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight;
+        float scaleX = viewportWidth / intrinsicWidth;
+        float scaleY = viewportHeight / intrinsicHeight;
+        return Math.min(scaleX, scaleY);
+    }
+
     /** @hide */
     public static VectorDrawable create(Resources resources, int rid) {
         try {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
index b86e67c..a9fdc86 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java
@@ -23,7 +23,6 @@
 import android.text.TextUtils.TruncateAt;
 import android.view.Gravity;
 import android.view.View;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -41,7 +40,7 @@
  *               truncate.
  *   Second line: ellipsis if necessary
  */
-public class QSDualTileLabel extends FrameLayout {
+public class QSDualTileLabel extends LinearLayout {
 
     private final Context mContext;
     private final TextView mFirstLine;
@@ -54,6 +53,7 @@
     public QSDualTileLabel(Context context) {
         super(context);
         mContext = context;
+        setOrientation(LinearLayout.VERTICAL);
 
         mHorizontalPaddingPx = mContext.getResources()
                 .getDimensionPixelSize(R.dimen.qs_dual_tile_padding_horizontal);
@@ -70,13 +70,13 @@
         mFirstLineCaret.setScaleType(ImageView.ScaleType.MATRIX);
         mFirstLineCaret.setClickable(false);
         firstLineLayout.addView(mFirstLineCaret);
-        addView(firstLineLayout, newFrameLayoutParams());
+        addView(firstLineLayout, newLinearLayoutParams());
 
         mSecondLine = initTextView();
         mSecondLine.setPadding(mHorizontalPaddingPx, 0, mHorizontalPaddingPx, 0);
         mSecondLine.setEllipsize(TruncateAt.END);
         mSecondLine.setVisibility(GONE);
-        addView(mSecondLine, newFrameLayoutParams());
+        addView(mSecondLine, newLinearLayoutParams());
 
         addOnLayoutChangeListener(new OnLayoutChangeListener() {
             @Override
@@ -89,7 +89,7 @@
         });
     }
 
-    private static LayoutParams newFrameLayoutParams() {
+    private static LayoutParams newLinearLayoutParams() {
         final LayoutParams lp =
                 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         lp.gravity = Gravity.CENTER_HORIZONTAL;