Merge "Add AssistUtils" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 72b5ca4..835e836 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23419,6 +23419,7 @@
 
   public final class PowerManager {
     method public boolean isDeviceIdleMode();
+    method public boolean isIgnoringBatteryOptimizations(java.lang.String);
     method public boolean isInteractive();
     method public boolean isPowerSaveMode();
     method public deprecated boolean isScreenOn();
@@ -30536,6 +30537,7 @@
     field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+    field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
diff --git a/api/system-current.txt b/api/system-current.txt
index 6ef78d0..e3978cb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25341,6 +25341,7 @@
 
   public final class PowerManager {
     method public boolean isDeviceIdleMode();
+    method public boolean isIgnoringBatteryOptimizations(java.lang.String);
     method public boolean isInteractive();
     method public boolean isPowerSaveMode();
     method public boolean isScreenBrightnessBoosted();
@@ -32752,6 +32753,7 @@
     field public static final java.lang.String ACTION_CHANGE_DEFAULT_DIALER = "android.telecom.action.CHANGE_DEFAULT_DIALER";
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE";
+    field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
     field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 02e26a5..903411e 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -28,7 +28,6 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.LogWriter;
-import android.util.Pair;
 import android.util.SparseArray;
 import android.view.View;
 import android.view.ViewGroup;
@@ -1005,13 +1004,20 @@
                 outFragment.getExitTransition());
     }
 
-    private static Transition getSharedElementTransition(Fragment inFragment, Fragment outFragment,
-            boolean isBack) {
+    private static TransitionSet getSharedElementTransition(Fragment inFragment,
+            Fragment outFragment, boolean isBack) {
         if (inFragment == null || outFragment == null) {
             return null;
         }
-        return cloneTransition(isBack ? outFragment.getSharedElementReturnTransition() :
-                inFragment.getSharedElementEnterTransition());
+        Transition transition = cloneTransition(isBack
+                ? outFragment.getSharedElementReturnTransition()
+                : inFragment.getSharedElementEnterTransition());
+        if (transition == null) {
+            return null;
+        }
+        TransitionSet transitionSet = new TransitionSet();
+        transitionSet.addTransition(transition);
+        return transitionSet;
     }
 
     private static ArrayList<View> captureExitingViews(Transition exitTransition,
@@ -1070,7 +1076,7 @@
      * capturing the final state of the Transition.</p>
      */
     private ArrayList<View> addTransitionTargets(final TransitionState state,
-            final Transition enterTransition, final Transition sharedElementTransition,
+            final Transition enterTransition, final TransitionSet sharedElementTransition,
             final Transition overallTransition, final View container,
             final Fragment inFragment, final Fragment outFragment,
             final ArrayList<View> hiddenFragmentViews, final boolean isBack,
@@ -1094,11 +1100,8 @@
                         if (sharedElementTransition != null) {
                             namedViews = mapSharedElementsIn(state, isBack, inFragment);
                             removeTargets(sharedElementTransition, sharedElementTargets);
-                            sharedElementTargets.clear();
-                            sharedElementTargets.add(state.nonExistentView);
-                            sharedElementTargets.addAll(namedViews.values());
-
-                            addTargets(sharedElementTransition, sharedElementTargets);
+                            setSharedElementTargets(sharedElementTransition,
+                                    state.nonExistentView, namedViews, sharedElementTargets);
 
                             setEpicenterIn(namedViews, state);
 
@@ -1241,8 +1244,8 @@
             Fragment outFragment = firstOutFragments.get(containerId);
 
             Transition enterTransition = getEnterTransition(inFragment, isBack);
-            Transition sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
-                    isBack);
+            TransitionSet sharedElementTransition =
+                    getSharedElementTransition(inFragment, outFragment, isBack);
             Transition exitTransition = getExitTransition(outFragment, isBack);
 
             if (enterTransition == null && sharedElementTransition == null &&
@@ -1256,9 +1259,8 @@
             ArrayList<View> sharedElementTargets = new ArrayList<View>();
             if (sharedElementTransition != null) {
                 namedViews = remapSharedElements(state, outFragment, isBack);
-                sharedElementTargets.add(state.nonExistentView);
-                sharedElementTargets.addAll(namedViews.values());
-                addTargets(sharedElementTransition, sharedElementTargets);
+                setSharedElementTargets(sharedElementTransition,
+                        state.nonExistentView, namedViews, sharedElementTargets);
 
                 // Notify the start of the transition.
                 SharedElementCallback callback = isBack ?
@@ -1294,8 +1296,8 @@
             if (transition != null) {
                 ArrayList<View> hiddenFragments = new ArrayList<View>();
                 ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
-                        sharedElementTransition, transition, sceneRoot, inFragment, outFragment,
-                        hiddenFragments, isBack, sharedElementTargets);
+                        sharedElementTransition, transition, sceneRoot, inFragment,
+                        outFragment, hiddenFragments, isBack, sharedElementTargets);
 
                 transition.setNameOverrides(state.nameOverrides);
                 // We want to exclude hidden views later, so we need a non-null list in the
@@ -1307,12 +1309,74 @@
                 // Remove the view targeting after the transition starts
                 removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
                         enterTransition, enteringViews, exitTransition, exitingViews,
-                        sharedElementTransition, sharedElementTargets, transition, hiddenFragments);
+                        sharedElementTransition, sharedElementTargets, transition,
+                        hiddenFragments);
             }
         }
     }
 
     /**
+     * Finds all children of the shared elements and sets the wrapping TransitionSet
+     * targets to point to those. It also limits transitions that have no targets to the
+     * specific shared elements. This allows developers to target child views of the
+     * shared elements specifically, but this doesn't happen by default.
+     */
+    private static void setSharedElementTargets(TransitionSet transition,
+            View nonExistentView, ArrayMap<String, View> namedViews,
+            ArrayList<View> sharedElementTargets) {
+        sharedElementTargets.clear();
+        sharedElementTargets.addAll(namedViews.values());
+
+        final List<View> views = transition.getTargets();
+        views.clear();
+        final int count = sharedElementTargets.size();
+        for (int i = 0; i < count; i++) {
+            final View view = sharedElementTargets.get(i);
+            bfsAddViewChildren(views, view);
+        }
+        sharedElementTargets.add(nonExistentView);
+        addTargets(transition, sharedElementTargets);
+    }
+
+    /**
+     * Uses a breadth-first scheme to add startView and all of its children to views.
+     * It won't add a child if it is already in views.
+     */
+    private static void bfsAddViewChildren(final List<View> views, final View startView) {
+        final int startIndex = views.size();
+        if (containedBeforeIndex(views, startView, startIndex)) {
+            return; // This child is already in the list, so all its children are also.
+        }
+        views.add(startView);
+        for (int index = startIndex; index < views.size(); index++) {
+            final View view = views.get(index);
+            if (view instanceof ViewGroup) {
+                ViewGroup viewGroup = (ViewGroup) view;
+                final int childCount =  viewGroup.getChildCount();
+                for (int childIndex = 0; childIndex < childCount; childIndex++) {
+                    final View child = viewGroup.getChildAt(childIndex);
+                    if (!containedBeforeIndex(views, child, startIndex)) {
+                        views.add(child);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Does a linear search through views for view, limited to maxIndex.
+     */
+    private static boolean containedBeforeIndex(final List<View> views, final View view,
+            final int maxIndex) {
+        for (int i = 0; i < maxIndex; i++) {
+            if (views.get(i) == view) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * After the transition has started, remove all targets that we added to the transitions
      * so that the transitions are left in a clean state.
      */
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 970623a..83ce087 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2248,6 +2248,7 @@
             //@hide: VOICE_INTERACTION_MANAGER_SERVICE,
             //@hide: BACKUP_SERVICE,
             DROPBOX_SERVICE,
+            //@hide: DEVICE_IDLE_CONTROLLER,
             DEVICE_POLICY_SERVICE,
             UI_MODE_SERVICE,
             DOWNLOAD_SERVICE,
@@ -2874,6 +2875,13 @@
     public static final String DROPBOX_SERVICE = "dropbox";
 
     /**
+     * System service name for the DeviceIdleController.  There is no Java API for this.
+     * @see #getSystemService
+     * @hide
+     */
+    public static final String DEVICE_IDLE_CONTROLLER = "deviceidle";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.app.admin.DevicePolicyManager} for working with global
      * device policy management.
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index b69ca88..921e9f1 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1109,13 +1109,13 @@
     /**
      * <p>The correction coefficients to correct for this camera device's
      * radial and tangential lens distortion.</p>
-     * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+     * <p>Four radial distortion coefficients <code>[kappa_0, kappa_1, kappa_2,
      * kappa_3]</code> and two tangential distortion coefficients
      * <code>[kappa_4, kappa_5]</code> that can be used to correct the
      * lens's geometric distortion with the mapping equations:</p>
-     * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     * <pre><code> x_c = x_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
      *        kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
-     *  y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     *  y_c = y_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
      *        kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
      * </code></pre>
      * <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3bb2fdb..479583c 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2671,13 +2671,13 @@
     /**
      * <p>The correction coefficients to correct for this camera device's
      * radial and tangential lens distortion.</p>
-     * <p>Three radial distortion coefficients <code>[kappa_1, kappa_2,
+     * <p>Four radial distortion coefficients <code>[kappa_0, kappa_1, kappa_2,
      * kappa_3]</code> and two tangential distortion coefficients
      * <code>[kappa_4, kappa_5]</code> that can be used to correct the
      * lens's geometric distortion with the mapping equations:</p>
-     * <pre><code> x_c = x_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     * <pre><code> x_c = x_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
      *        kappa_4 * (2 * x_i * y_i) + kappa_5 * ( r^2 + 2 * x_i^2 )
-     *  y_c = y_i * ( 1 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
+     *  y_c = y_i * ( kappa_0 + kappa_1 * r^2 + kappa_2 * r^4 + kappa_3 * r^6 ) +
      *        kappa_5 * (2 * x_i * y_i) + kappa_4 * ( r^2 + 2 * y_i^2 )
      * </code></pre>
      * <p>Here, <code>[x_c, y_c]</code> are the coordinates to sample in the
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 8512b23..a1ebe6a 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -2053,8 +2053,10 @@
                 requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
 
         // Overwrite the capture intent to make sure a good value is set.
-        Surface[] surfaces = (Surface[])outputSurfaces.toArray();
-        if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(surfaces[0])) {
+        Iterator<Surface> iterator = outputSurfaces.iterator();
+        Surface firstSurface = iterator.next();
+        Surface secondSurface = null;
+        if (outputSurfaces.size() == 1 && SurfaceUtils.isSurfaceForHwVideoEncoder(firstSurface)) {
             singleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
                     CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
         } else {
@@ -2071,19 +2073,20 @@
                     requestMetadata, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE);
             doubleTargetRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT,
                     CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
-            doubleTargetRequestBuilder.addTarget(surfaces[0]);
-            doubleTargetRequestBuilder.addTarget(surfaces[1]);
+            doubleTargetRequestBuilder.addTarget(firstSurface);
+            secondSurface = iterator.next();
+            doubleTargetRequestBuilder.addTarget(secondSurface);
             doubleTargetRequestBuilder.setPartOfCHSRequestList(/*partOfCHSList*/true);
             // Make sure singleTargetRequestBuilder contains only recording surface for
             // preview + recording case.
-            Surface recordingSurface = surfaces[0];
+            Surface recordingSurface = firstSurface;
             if (!SurfaceUtils.isSurfaceForHwVideoEncoder(recordingSurface)) {
-                recordingSurface = surfaces[1];
+                recordingSurface = secondSurface;
             }
             singleTargetRequestBuilder.addTarget(recordingSurface);
         } else {
             // Single output case: either recording or preview.
-            singleTargetRequestBuilder.addTarget(surfaces[0]);
+            singleTargetRequestBuilder.addTarget(firstSurface);
         }
 
         // Generate the final request list.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 7a1aa1e..6ef1cd0 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -392,6 +392,8 @@
     final IPowerManager mService;
     final Handler mHandler;
 
+    IDeviceIdleController mIDeviceIdleController;
+
     /**
      * {@hide}
      */
@@ -892,6 +894,25 @@
     }
 
     /**
+     * Return whether the given application package name is on the device's power whitelist.
+     * Apps can be placed on the whitelist through the settings UI invoked by
+     * {@link android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}.
+     */
+    public boolean isIgnoringBatteryOptimizations(String packageName) {
+        synchronized (this) {
+            if (mIDeviceIdleController == null) {
+                mIDeviceIdleController = IDeviceIdleController.Stub.asInterface(
+                        ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
+            }
+        }
+        try {
+            return mIDeviceIdleController.isPowerSaveWhitelistApp(packageName);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Turn off the device.
      *
      * @param confirm If true, shows a shutdown confirmation dialog.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e335f6d..dfd72c2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -579,13 +579,14 @@
     /**
      * Activity Action: Show screen for controlling which apps can ignore battery optimizations.
      * <p>
-     * In some cases, a matching Activity may not exist, so ensure you
-     * safeguard against this.
-     * <p>
-     * Input: The Intent's data URI specifies the application package name
+     * Input: Optionally, the Intent's data URI specifies the application package name
      * to be shown, with the "package" scheme.  That is "package:com.my.app".
      * <p>
      * Output: Nothing.
+     * <p>
+     * You can use {@link android.os.PowerManager#isIgnoringBatteryOptimizations
+     * PowerManager.isIgnoringBatteryOptimizations()} to determine if an application is
+     * already ignoring optimizations.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS =
diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java
index c40f11f..93a156b 100644
--- a/core/java/android/text/style/TtsSpan.java
+++ b/core/java/android/text/style/TtsSpan.java
@@ -165,7 +165,7 @@
 
     /**
      * The text associated with this span is a series of characters that have to
-     * be read verbatim. The engine will attempt to ready out any character like
+     * be read verbatim. The engine will attempt to read out any character like
      * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
      * Also accepts the arguments {@link #ARG_GENDER},
      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
diff --git a/core/java/android/transition/Explode.java b/core/java/android/transition/Explode.java
index 788676a..3445ef2 100644
--- a/core/java/android/transition/Explode.java
+++ b/core/java/android/transition/Explode.java
@@ -90,7 +90,7 @@
         float startY = endY + mTempLoc[1];
 
         return TranslationAnimationCreator.createAnimation(view, endValues, bounds.left, bounds.top,
-                startX, startY, endX, endY, sDecelerate);
+                startX, startY, endX, endY, sDecelerate, this);
     }
 
     @Override
@@ -119,7 +119,7 @@
         endY += mTempLoc[1];
 
         return TranslationAnimationCreator.createAnimation(view, startValues,
-                viewPosX, viewPosY, startX, startY, endX, endY, sAccelerate);
+                viewPosX, viewPosY, startX, startY, endX, endY, sAccelerate, this);
     }
 
     private void calculateOut(View sceneRoot, Rect bounds, int[] outVector) {
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
index be1d907..9063b43 100644
--- a/core/java/android/transition/Slide.java
+++ b/core/java/android/transition/Slide.java
@@ -231,7 +231,7 @@
         float startY = mSlideCalculator.getGoneY(sceneRoot, view);
         return TranslationAnimationCreator
                 .createAnimation(view, endValues, position[0], position[1],
-                        startX, startY, endX, endY, sDecelerate);
+                        startX, startY, endX, endY, sDecelerate, this);
     }
 
     @Override
@@ -247,6 +247,6 @@
         float endY = mSlideCalculator.getGoneY(sceneRoot, view);
         return TranslationAnimationCreator
                 .createAnimation(view, startValues, position[0], position[1],
-                        startX, startY, endX, endY, sAccelerate);
+                        startX, startY, endX, endY, sAccelerate, this);
     }
 }
diff --git a/core/java/android/transition/TranslationAnimationCreator.java b/core/java/android/transition/TranslationAnimationCreator.java
index de71fd7..1554975 100644
--- a/core/java/android/transition/TranslationAnimationCreator.java
+++ b/core/java/android/transition/TranslationAnimationCreator.java
@@ -22,6 +22,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.graphics.Path;
+import android.transition.Transition.TransitionListener;
 import android.view.View;
 
 /**
@@ -48,7 +49,8 @@
      * a previous interruption, in which case it moves from the current position to (endX, endY).
      */
     static Animator createAnimation(View view, TransitionValues values, int viewPosX, int viewPosY,
-            float startX, float startY, float endX, float endY, TimeInterpolator interpolator) {
+            float startX, float startY, float endX, float endY, TimeInterpolator interpolator,
+            Transition transition) {
         float terminalX = view.getTranslationX();
         float terminalY = view.getTranslationY();
         int[] startPosition = (int[]) values.view.getTag(R.id.transitionPosition);
@@ -73,13 +75,15 @@
 
         TransitionPositionListener listener = new TransitionPositionListener(view, values.view,
                 startPosX, startPosY, terminalX, terminalY);
+        transition.addListener(listener);
         anim.addListener(listener);
         anim.addPauseListener(listener);
         anim.setInterpolator(interpolator);
         return anim;
     }
 
-    private static class TransitionPositionListener extends AnimatorListenerAdapter {
+    private static class TransitionPositionListener extends AnimatorListenerAdapter implements
+            TransitionListener {
 
         private final View mViewInHierarchy;
         private final View mMovingView;
@@ -117,8 +121,6 @@
 
         @Override
         public void onAnimationEnd(Animator animator) {
-            mMovingView.setTranslationX(mTerminalX);
-            mMovingView.setTranslationY(mTerminalY);
         }
 
         @Override
@@ -134,6 +136,28 @@
             mMovingView.setTranslationX(mPausedX);
             mMovingView.setTranslationY(mPausedY);
         }
+
+        @Override
+        public void onTransitionStart(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            mMovingView.setTranslationX(mTerminalX);
+            mMovingView.setTranslationY(mTerminalY);
+        }
+
+        @Override
+        public void onTransitionCancel(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionPause(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(Transition transition) {
+        }
     }
 
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0df8ea9..fd3ee4f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -56,6 +56,8 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManagerGlobal;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -95,6 +97,7 @@
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Checkable;
+import android.widget.FrameLayout;
 import android.widget.ScrollBarDrawable;
 
 import static android.os.Build.VERSION_CODES.*;
@@ -4274,23 +4277,33 @@
                             PROVIDER_BACKGROUND));
                     break;
                 case R.styleable.View_foreground:
-                    setForeground(a.getDrawable(attr));
+                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                        setForeground(a.getDrawable(attr));
+                    }
                     break;
                 case R.styleable.View_foregroundGravity:
-                    setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
+                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                        setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY));
+                    }
                     break;
                 case R.styleable.View_foregroundTintMode:
-                    setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                        setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+                    }
                     break;
                 case R.styleable.View_foregroundTint:
-                    setForegroundTintList(a.getColorStateList(attr));
+                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                        setForegroundTintList(a.getColorStateList(attr));
+                    }
                     break;
                 case R.styleable.View_foregroundInsidePadding:
-                    if (mForegroundInfo == null) {
-                        mForegroundInfo = new ForegroundInfo();
+                    if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) {
+                        if (mForegroundInfo == null) {
+                            mForegroundInfo = new ForegroundInfo();
+                        }
+                        mForegroundInfo.mInsidePadding = a.getBoolean(attr,
+                                mForegroundInfo.mInsidePadding);
                     }
-                    mForegroundInfo.mInsidePadding = a.getBoolean(attr,
-                            mForegroundInfo.mInsidePadding);
                     break;
                 case R.styleable.View_scrollIndicators:
                     final int scrollIndicators =
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index bd45007..f18b7ac 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -80,12 +80,18 @@
 
     /**
      * The interpolator of the underlying Animator object. By default, we don't set the interpolator
-     * on the Animator and just use its default interpolator. If the interpolator is set to a
-     * non-null value on this Animator, then we use the interpolator that it was set to.
+     * on the Animator and just use its default interpolator. If the interpolator is ever set on
+     * this Animator, then we use the interpolator that it was set to.
      */
     private TimeInterpolator mInterpolator;
 
     /**
+     * A flag indicating whether the interpolator has been set on this object. If not, we don't set
+     * the interpolator on the underlying Animator, but instead just use its default interpolator.
+     */
+    private boolean mInterpolatorSet = false;
+
+    /**
      * Listener for the lifecycle events of the underlying ValueAnimator object.
      */
     private Animator.AnimatorListener mListener = null;
@@ -332,6 +338,7 @@
      * @return This object, allowing calls to methods in this class to be chained.
      */
     public ViewPropertyAnimator setInterpolator(TimeInterpolator interpolator) {
+        mInterpolatorSet = true;
         mInterpolator = interpolator;
         return this;
     }
@@ -342,7 +349,7 @@
      * @return The timing interpolator for this animation.
      */
     public TimeInterpolator getInterpolator() {
-        if (mInterpolator != null) {
+        if (mInterpolatorSet) {
             return mInterpolator;
         } else {
             // Just return the default from ValueAnimator, since that's what we'd get if
@@ -890,7 +897,7 @@
         if (mDurationSet) {
             animator.setDuration(mDuration);
         }
-        if (mInterpolator != null) {
+        if (mInterpolatorSet) {
             animator.setInterpolator(mInterpolator);
         }
         animator.start();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a434a13..65c064b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -289,6 +289,8 @@
     <protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
     <protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
 
+    <protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" />
+
     <protected-broadcast
         android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
 
diff --git a/data/fonts/DroidSansMono.ttf b/data/fonts/DroidSansMono.ttf
index 4085cee..b7bf5b4 100644
--- a/data/fonts/DroidSansMono.ttf
+++ b/data/fonts/DroidSansMono.ttf
Binary files differ
diff --git a/docs/html/training/tv/publishing/checklist.jd b/docs/html/training/tv/publishing/checklist.jd
index 865a89b..6259721 100644
--- a/docs/html/training/tv/publishing/checklist.jd
+++ b/docs/html/training/tv/publishing/checklist.jd
@@ -67,12 +67,12 @@
 
 <li>
   Eliminate requirements for unsupported hardware in your app.
-  <p>See <a href="training/tv/start/hardware.html#declare-hardware-requirements">Declaring hardware requirements for TV</a>.</p>
+  <p>See <a href="{@docRoot}training/tv/start/hardware.html#declare-hardware-requirements">Declaring hardware requirements for TV</a>.</p>
 </li>
 
 <li>
   Ensure permissions do not imply hardware requirements
-  <p>See <a href="training/tv/start/hardware.html#hardware-permissions">Declaring permissions that imply hardware features</a>.</p>
+  <p>See <a href="{@docRoot}training/tv/start/hardware.html#hardware-permissions">Declaring permissions that imply hardware features</a>.</p>
 </li>
 
 </ol>
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index b93424d..2de60fd 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -624,7 +624,7 @@
             int keySizeBits,
             KeyGenParameterSpec spec) {
         // Constraints:
-        // 1. Key must be authorized for signing.
+        // 1. Key must be authorized for signing without user authentication.
         // 2. Signature digest must be one of key's authorized digests.
         // 3. For RSA keys, the digest output size must not exceed modulus size minus space needed
         //    for RSA PKCS#1 signature padding (about 29 bytes: minimum 10 bytes of padding + 15--19
@@ -636,6 +636,10 @@
             // Key not authorized for signing
             return null;
         }
+        if (spec.isUserAuthenticationRequired()) {
+            // Key not authorized for use without user authentication
+            return null;
+        }
         if (!spec.isDigestsSpecified()) {
             // Key not authorized for any digests -- can't sign
             return null;
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_alpha_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_alpha_animation.xml
new file mode 100644
index 0000000..21caab4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_disable_alpha_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
new file mode 100644
index 0000000..a914687c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_disable_bar01_0_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.680404663086,3.53039550781 c 0.0,0.0 -0.01416015625,0.00492858886719 -0.01416015625,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151519775391,-0.00492858886719 0.0151519775391,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
+        android:valueTo="M 0.680404663086,3.53039550781 c 0.0,0.0 20.0110015869,20.0110015869 20.0110015869,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0100097656,-20.0110015869 -20.0100097656,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
new file mode 100644
index 0000000..3c60c013
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_disable_mask_1_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="pathData"
+        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
+        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 20.4531555176,20.4530792236 20.4531555176,20.4530792236 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -20.4531402588,-20.4530487061 -20.4531402588,-20.4530487061 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_alpha_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_alpha_animation.xml
new file mode 100644
index 0000000..21caab4
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_alpha_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:valueType="floatType"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
new file mode 100644
index 0000000..8d3296e
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_mask_1_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="pathData"
+        android:valueFrom="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z"
+        android:valueTo="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 19.8804626465,19.8695220947 19.8804626465,19.8695220947 c 0.0,0.0 -1.41999816895,1.40995788574 -1.41999816895,1.40995788574 c 0.0,0.0 -19.8804473877,-19.8694915771 -19.8804473877,-19.8694915771 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
new file mode 100644
index 0000000..2626499
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_dnd_total_silence_disable_outer_ring_merged_animation.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 -0.0141754150391,0.00492858886719 -0.014175415039,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151672363281,-0.00492858886719 0.0151672363281,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 3.0,1.0 c 0.0,0.0 -6.0,0.0 -6.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 6.0,0.0 6.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-6.0 c -3.30000305176,0.0 -6.0,2.69999694824 -6.0,6.0 c 0.0,3.30000305176 2.69999694824,6.0 6.0,6.0 c 3.30000305176,0.0 6.0,-2.69999694824 6.0,-6.0 c 0.0,-3.30000305176 -2.60000610352,-6.0 -6.0,-6.0 Z"
+        android:valueTo="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 20.0109863281,20.0110015869 20.0109863281,20.0110015869 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 -20.0099945068,-20.0110015869 -20.0099945068,-20.0110015869 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 5.0,1.0 c 0.0,0.0 -10.0,0.0 -10.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 10.0,0.0 10.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-10.0 c -5.52000427246,0.0 -10.0,4.47999572754 -10.0,10.0 c 0.0,5.52000427246 4.47999572754,10.0 10.0,10.0 c 5.52000427246,0.0 10.0,-4.47999572754 10.0,-10.0 c 0.0,-5.52000427246 -4.47999572754,-10.0 -10.0,-10.0 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_disable.xml b/packages/SystemUI/res/drawable/ic_dnd_disable.xml
new file mode 100644
index 0000000..ba4692a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_dnd_disable.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_dnd_disable"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
+    <group
+        android:name="dnd_icon"
+        android:translateX="12"
+        android:translateY="12" >
+        <clip-path
+            android:name="mask_1"
+            android:pathData="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z" />
+        <group
+            android:name="bar01"
+            android:translateX="-12"
+            android:translateY="-12" >
+            <path
+                android:name="bar01_0"
+                android:pathData="M 0.680404663086,3.53039550781 c 0.0,0.0 -0.01416015625,0.00492858886719 -0.01416015625,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151519775391,-0.00492858886719 0.0151519775391,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z"
+                android:fillColor="#FFFFFFFF" />
+        </group>
+        <group
+            android:name="circle" >
+            <path
+                android:name="icon_center_merged"
+                android:pathData="M 5.0,1.0 c 0.0,0.0 -10.0,0.0 -10.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 10.0,0.0 10.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-10.0 c -5.52000427246,0.0 -10.0,4.47999572754 -10.0,10.0 c 0.0,5.52000427246 4.47999572754,10.0 10.0,10.0 c 5.52000427246,0.0 10.0,-4.47999572754 10.0,-10.0 c 0.0,-5.52000427246 -4.47999572754,-10.0 -10.0,-10.0 Z"
+                android:fillColor="#FFFFFFFF" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
new file mode 100644
index 0000000..13ed767
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_dnd_disable_animation.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_dnd_disable" >
+    <target
+        android:name="mask_1"
+        android:animation="@anim/ic_dnd_disable_mask_1_animation" />
+    <target
+        android:name="bar01_0"
+        android:animation="@anim/ic_dnd_disable_bar01_0_animation" />
+    <target
+        android:name="ic_dnd_disable"
+        android:animation="@anim/ic_dnd_disable_alpha_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml
new file mode 100644
index 0000000..1a33255
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="ic_dnd_total_silence_disable"
+    android:width="24dp"
+    android:viewportWidth="24"
+    android:height="24dp"
+    android:viewportHeight="24" >
+    <group
+        android:name="tot_silence"
+        android:translateX="12"
+        android:translateY="12" >
+        <clip-path
+            android:name="mask_1"
+            android:pathData="M -9.67768859863,-9.82725524902 c 0.0,0.0 -7.8091583252,7.18409729004 -7.8091583252,7.18409729004 c 0.0,0.0 20.9320983887,20.9321136475 20.9320983887,20.9321136475 c 0.0,0.0 15.041595459,-15.0416717529 15.041595459,-15.0416717529 c 0.0,0.0 -20.5361938477,-20.536239624 -20.5361938477,-20.536239624 c 0.0,0.0 -6.20835876465,6.05171203613 -6.20835876465,6.05171203613 c 0.0,0.0 0.219390869141,0.219299316406 0.219390869141,0.219299316406 c 0.0,0.0 -1.41998291016,1.40998840332 -1.41998291016,1.40998840332 c 0.0,0.0 -0.219390869141,-0.219299316406 -0.219390869141,-0.219299316406 Z" />
+        <group
+            android:name="icon_shape" >
+            <path
+                android:name="outer_ring_merged"
+                android:pathData="M 0.0,-10.0 c -5.5,0.0 -10.0,4.5 -10.0,10.0 c 0.0,5.5 4.5,10.0 10.0,10.0 c 5.5,0.0 10.0,-4.5 10.0,-10.0 c 0.0,-5.5 -4.5,-10.0 -10.0,-10.0 Z M 0.0,8.5 c -4.69999694824,0.0 -8.5,-3.80000305176 -8.5,-8.5 c 0.0,-4.69999694824 3.80000305176,-8.5 8.5,-8.5 c 4.69999694824,0.0 8.5,3.80000305176 8.5,8.5 c 0.0,4.69999694824 -3.80000305176,8.5 -8.5,8.5 Z M -11.3195953369,-8.46960449219 c 0.0,0.0 -0.0141754150391,0.00492858886719 -0.014175415039,0.00492858886719 c 0.0,0.0 1.41400146484,-1.41400146484 1.41400146484,-1.41400146484 c 0.0,0.0 0.0151672363281,-0.00492858886719 0.0151672363281,-0.00492858886719 c 0.0,0.0 -1.41499328613,1.41400146484 -1.41499328613,1.41400146484 Z M 3.0,1.0 c 0.0,0.0 -6.0,0.0 -6.0,0.0 c 0.0,0.0 0.0,-2.0 0.0,-2.0 c 0.0,0.0 6.0,0.0 6.0,0.0 c 0.0,0.0 0.0,2.0 0.0,2.0 Z M 0.0,-6.0 c -3.30000305176,0.0 -6.0,2.69999694824 -6.0,6.0 c 0.0,3.30000305176 2.69999694824,6.0 6.0,6.0 c 3.30000305176,0.0 6.0,-2.69999694824 6.0,-6.0 c 0.0,-3.30000305176 -2.60000610352,-6.0 -6.0,-6.0 Z"
+                android:fillColor="#FFFFFFFF" />
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
new file mode 100644
index 0000000..c0b2d69
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_dnd_total_silence_disable_animation.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_dnd_total_silence_disable" >
+    <target
+        android:name="mask_1"
+        android:animation="@anim/ic_dnd_total_silence_disable_mask_1_animation" />
+    <target
+        android:name="outer_ring_merged"
+        android:animation="@anim/ic_dnd_total_silence_disable_outer_ring_merged_animation" />
+    <target
+        android:name="ic_dnd_total_silence_disable"
+        android:animation="@anim/ic_dnd_total_silence_disable_alpha_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a6313ad..37601884 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -164,7 +164,7 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_tile_height">88dp</dimen>
-    <dimen name="qs_tile_icon_size">28dp</dimen>
+    <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
     <dimen name="qs_tile_divider_height">1dp</dimen>
     <dimen name="qs_panel_padding">16dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f00fed5..c06b34f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -371,7 +371,6 @@
         @Override
         public void onDeviceProvisioned() {
             sendUserPresentBroadcast();
-            updateInputRestricted();
         }
 
         @Override
@@ -947,7 +946,7 @@
      * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
      */
     public boolean isInputRestricted() {
-        return mShowing || mNeedToReshowWhenReenabled || shouldWaitForProvisioning();
+        return mShowing || mNeedToReshowWhenReenabled;
     }
 
     private void updateInputRestricted() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index f4d6f04..f97f519 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -38,6 +38,7 @@
 
 /** Quick settings tile: Do not disturb **/
 public class DndTile extends QSTile<QSTile.BooleanState> {
+
     private static final Intent ZEN_SETTINGS =
             new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
 
@@ -47,6 +48,14 @@
     private static final String ACTION_SET_VISIBLE = "com.android.systemui.dndtile.SET_VISIBLE";
     private static final String EXTRA_VISIBLE = "visible";
 
+    private static final QSTile.Icon TOTAL_SILENCE =
+            ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
+
+    private final AnimationIcon mDisable =
+            new AnimationIcon(R.drawable.ic_dnd_disable_animation);
+    private final AnimationIcon mDisableTotalSilence =
+            new AnimationIcon(R.drawable.ic_dnd_total_silence_disable_animation);
+
     private final ZenModeController mController;
     private final DndDetailAdapter mDetailAdapter;
 
@@ -89,6 +98,8 @@
 
     @Override
     public void handleClick() {
+        mDisable.setAllowAnimation(true);
+        mDisableTotalSilence.setAllowAnimation(true);
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
         if (mState.value) {
             mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
@@ -114,7 +125,7 @@
                         R.string.accessibility_quick_settings_dnd_priority_on);
                 break;
             case Global.ZEN_MODE_NO_INTERRUPTIONS:
-                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
+                state.icon = TOTAL_SILENCE;
                 state.label = mContext.getString(R.string.quick_settings_dnd_none_label);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_dnd_none_on);
@@ -126,7 +137,7 @@
                         R.string.accessibility_quick_settings_dnd_alarms_on);
                 break;
             default:
-                state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_off);
+                state.icon = TOTAL_SILENCE.equals(state.icon) ? mDisableTotalSilence : mDisable;
                 state.label = mContext.getString(R.string.quick_settings_dnd_label);
                 state.contentDescription =  mContext.getString(
                         R.string.accessibility_quick_settings_dnd_off);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index ff7b37f..9e0b08b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -114,14 +114,21 @@
             return;
         }
         ArraySet<String> blockList = StatusBarIconController.getIconBlacklist(newValue);
-        mBlockAirplane = blockList.contains(SLOT_AIRPLANE);
-        mBlockMobile = blockList.contains(SLOT_MOBILE);
-        mBlockWifi = blockList.contains(SLOT_WIFI);
-        mBlockEthernet = blockList.contains(SLOT_ETHERNET);
+        boolean blockAirplane = blockList.contains(SLOT_AIRPLANE);
+        boolean blockMobile = blockList.contains(SLOT_MOBILE);
+        boolean blockWifi = blockList.contains(SLOT_WIFI);
+        boolean blockEthernet = blockList.contains(SLOT_ETHERNET);
 
-        // Re-register to get new callbacks.
-        mNC.removeSignalCallback(SignalClusterView.this);
-        mNC.addSignalCallback(SignalClusterView.this);
+        if (blockAirplane != mBlockAirplane || blockMobile != mBlockMobile
+                || blockEthernet != mBlockEthernet || blockWifi != mBlockWifi) {
+            mBlockAirplane = blockAirplane;
+            mBlockMobile = blockMobile;
+            mBlockEthernet = blockEthernet;
+            mBlockWifi = blockWifi;
+            // Re-register to get new callbacks.
+            mNC.removeSignalCallback(this);
+            mNC.addSignalCallback(this);
+        }
     }
 
     public void setNetworkController(NetworkControllerImpl nc) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b689d13..69198ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -812,12 +812,7 @@
         signalClusterQs.setNetworkController(mNetworkController);
         final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
         if (isAPhone) {
-            mNetworkController.addEmergencyListener(new NetworkControllerImpl.EmergencyListener() {
-                @Override
-                public void setEmergencyCallsOnly(boolean emergencyOnly) {
-                    mHeader.setShowEmergencyCallsOnly(emergencyOnly);
-                }
-            });
+            mNetworkController.addEmergencyListener(mHeader);
         }
 
         mFlashlightController = new FlashlightController(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index dfc6924..a81f06e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -45,6 +45,7 @@
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.UserInfoController;
 
@@ -54,7 +55,8 @@
  * The view to manage the header area in the expanded status bar.
  */
 public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener,
-        BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback {
+        BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback,
+        EmergencyListener {
 
     private boolean mExpanded;
     private boolean mListening;
@@ -527,7 +529,8 @@
         return true;
     }
 
-    public void setShowEmergencyCallsOnly(boolean show) {
+    @Override
+    public void setEmergencyCallsOnly(boolean show) {
         boolean changed = show != mShowEmergencyCallsOnly;
         if (changed) {
             mShowEmergencyCallsOnly = show;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 686e24c..0aa0b4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -34,6 +34,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
 
 import java.io.PrintWriter;
 import java.util.BitSet;
@@ -43,6 +44,7 @@
 public class MobileSignalController extends SignalController<
         MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
     private final TelephonyManager mPhone;
+    private final SubscriptionDefaults mDefaults;
     private final String mNetworkNameDefault;
     private final String mNetworkNameSeparator;
     @VisibleForTesting
@@ -67,13 +69,15 @@
     // need listener lists anymore.
     public MobileSignalController(Context context, Config config, boolean hasMobileData,
             TelephonyManager phone, CallbackHandler callbackHandler,
-            NetworkControllerImpl networkController, SubscriptionInfo info, Looper receiverLooper) {
+            NetworkControllerImpl networkController, SubscriptionInfo info,
+            SubscriptionDefaults defaults, Looper receiverLooper) {
         super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
                 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
                 networkController);
         mNetworkToIconLookup = new SparseArray<>();
         mConfig = config;
         mPhone = phone;
+        mDefaults = defaults;
         mSubscriptionInfo = info;
         mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(),
                 receiverLooper);
@@ -290,7 +294,7 @@
     }
 
     private void updateDataSim() {
-        int defaultDataSub = SubscriptionManager.getDefaultDataSubId();
+        int defaultDataSub = mDefaults.getDefaultDataSubId();
         if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
             mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index e8957f9..18b5820 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -71,6 +71,7 @@
     private final ConnectivityManager mConnectivityManager;
     private final SubscriptionManager mSubscriptionManager;
     private final boolean mHasMobileDataFeature;
+    private final SubscriptionDefaults mSubDefaults;
     private Config mConfig;
 
     // Subcontrollers.
@@ -124,7 +125,8 @@
                 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
                 new CallbackHandler(),
                 new AccessPointControllerImpl(context, bgLooper),
-                new MobileDataControllerImpl(context));
+                new MobileDataControllerImpl(context),
+                new SubscriptionDefaults());
         mReceiverHandler.post(mRegisterListeners);
     }
 
@@ -134,13 +136,15 @@
             SubscriptionManager subManager, Config config, Looper bgLooper,
             CallbackHandler callbackHandler,
             AccessPointControllerImpl accessPointController,
-            MobileDataControllerImpl mobileDataController) {
+            MobileDataControllerImpl mobileDataController,
+            SubscriptionDefaults defaultsHandler) {
         mContext = context;
         mConfig = config;
         mReceiverHandler = new Handler(bgLooper);
         mCallbackHandler = callbackHandler;
 
         mSubscriptionManager = subManager;
+        mSubDefaults = defaultsHandler;
         mConnectivityManager = connectivityManager;
         mHasMobileDataFeature =
                 mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
@@ -233,7 +237,7 @@
     }
 
     private MobileSignalController getDataController() {
-        int dataSubId = SubscriptionManager.getDefaultDataSubId();
+        int dataSubId = mSubDefaults.getDefaultDataSubId();
         if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
             if (DEBUG) Log.e(TAG, "No data sim selected");
             return mDefaultSignalController;
@@ -251,17 +255,19 @@
     }
 
     public boolean isEmergencyOnly() {
-        int voiceSubId = SubscriptionManager.getDefaultVoiceSubId();
+        int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
         if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
             for (MobileSignalController mobileSignalController :
                                             mMobileSignalControllers.values()) {
-                if (!mobileSignalController.isEmergencyOnly()) {
+                if (!mobileSignalController.getState().isEmergency) {
+                    if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag);
                     return false;
                 }
             }
         }
         if (mMobileSignalControllers.containsKey(voiceSubId)) {
-            return mMobileSignalControllers.get(voiceSubId).isEmergencyOnly();
+            if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
+            return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
         }
         if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
         // Something is wrong, better assume we can't make calls...
@@ -375,6 +381,11 @@
         if (!mListening) {
             return;
         }
+        doUpdateMobileControllers();
+    }
+
+    @VisibleForTesting
+    void doUpdateMobileControllers() {
         List<SubscriptionInfo> subscriptions = mSubscriptionManager.getActiveSubscriptionInfoList();
         if (subscriptions == null) {
             subscriptions = Collections.emptyList();
@@ -389,6 +400,7 @@
         }
         setCurrentSubscriptions(subscriptions);
         updateNoSims();
+        recalculateEmergency();
     }
 
     @VisibleForTesting
@@ -425,7 +437,7 @@
             } else {
                 MobileSignalController controller = new MobileSignalController(mContext, mConfig,
                         mHasMobileDataFeature, mPhone, mCallbackHandler,
-                        this, subscriptions.get(i), mReceiverHandler.getLooper());
+                        this, subscriptions.get(i), mSubDefaults, mReceiverHandler.getLooper());
                 mMobileSignalControllers.put(subId, controller);
                 if (subscriptions.get(i).getSimSlotIndex() == 0) {
                     mDefaultSignalController = controller;
@@ -708,7 +720,7 @@
                 null, 0, 0, "");
         mMobileSignalControllers.put(id, new MobileSignalController(mContext,
                 mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info,
-                mReceiverHandler.getLooper()));
+                mSubDefaults, mReceiverHandler.getLooper()));
         return info;
     }
 
@@ -735,6 +747,16 @@
         void setEmergencyCallsOnly(boolean emergencyOnly);
     }
 
+    public static class SubscriptionDefaults {
+        public int getDefaultVoiceSubId() {
+            return SubscriptionManager.getDefaultVoiceSubId();
+        }
+
+        public int getDefaultDataSubId() {
+            return SubscriptionManager.getDefaultDataSubId();
+        }
+    }
+
     @VisibleForTesting
     static class Config {
         boolean showAtLeast3G = false;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 441bb16..30c08cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -36,6 +36,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
 
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
@@ -66,6 +67,7 @@
     protected TelephonyManager mMockTm;
     protected Config mConfig;
     protected CallbackHandler mCallbackHandler;
+    protected SubscriptionDefaults mMockSubDefaults;
 
     protected int mSubId;
 
@@ -79,6 +81,7 @@
         mMockTm = mock(TelephonyManager.class);
         mMockSm = mock(SubscriptionManager.class);
         mMockCm = mock(ConnectivityManager.class);
+        mMockSubDefaults = mock(SubscriptionDefaults.class);
         mNetCapabilities = new NetworkCapabilities();
         when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
         when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn(
@@ -92,25 +95,39 @@
         mCallbackHandler = mock(CallbackHandler.class);
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
+                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mMockSubDefaults);
         setupNetworkController();
+
+        // Trigger blank callbacks to always get the current state (some tests don't trigger
+        // changes from default state).
+        mNetworkController.addSignalCallback(null);
+        mNetworkController.addEmergencyListener(null);
     }
 
     protected void setupNetworkController() {
         // For now just pretend to be the data sim, so we can test that too.
         mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        SubscriptionInfo subscription = mock(SubscriptionInfo.class);
-        List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
-        when(subscription.getSubscriptionId()).thenReturn(mSubId);
-        subs.add(subscription);
-        mNetworkController.setCurrentSubscriptions(subs);
+        setDefaultSubId(mSubId);
+        setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
-        mMobileSignalController.getState().dataSim = true;
         mPhoneStateListener = mMobileSignalController.mPhoneStateListener;
+    }
 
-        // Trigger blank callbacks to always get the current state (some tests don't trigger
-        // changes from default state).
-        mNetworkController.addSignalCallback(null);
+    protected void setDefaultSubId(int subId) {
+        when(mMockSubDefaults.getDefaultDataSubId()).thenReturn(subId);
+        when(mMockSubDefaults.getDefaultVoiceSubId()).thenReturn(subId);
+    }
+
+    protected void setSubscriptions(int... subIds) {
+        List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
+        for (int subId : subIds) {
+            SubscriptionInfo subscription = mock(SubscriptionInfo.class);
+            when(subscription.getSubscriptionId()).thenReturn(subId);
+            subs.add(subscription);
+        }
+        when(mMockSm.getActiveSubscriptionInfoList()).thenReturn(subs);
+        mNetworkController.doUpdateMobileControllers();
     }
 
     protected NetworkControllerImpl setUpNoMobileData() {
@@ -119,7 +136,7 @@
               = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                         mConfig, Looper.getMainLooper(), mCallbackHandler,
                         mock(AccessPointControllerImpl.class),
-                        mock(MobileDataControllerImpl.class));
+                        mock(MobileDataControllerImpl.class), mMockSubDefaults);
 
       setupNetworkController();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 15752e1de..e60e0a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -77,7 +77,7 @@
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
                 Mockito.mock(AccessPointControllerImpl.class),
-                Mockito.mock(MobileDataControllerImpl.class));
+                Mockito.mock(MobileDataControllerImpl.class), mMockSubDefaults);
         setupNetworkController();
 
         setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 2df1980..168aebe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -21,7 +21,6 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
 import android.os.Looper;
-import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
@@ -30,6 +29,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.systemui.R;
 
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
 import java.util.ArrayList;
@@ -43,7 +43,8 @@
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
+                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mMockSubDefaults);
         setupNetworkController();
 
         verifyLastMobileDataIndicators(false, 0, 0);
@@ -57,13 +58,33 @@
         verifyHasNoSims(true);
     }
 
+    public void testEmergencyOnly() {
+        setupDefaultSignal();
+        mNetworkController.recalculateEmergency();
+        verifyEmergencyOnly(false);
+
+        mMobileSignalController.getState().isEmergency = true;
+        mNetworkController.recalculateEmergency();
+        verifyEmergencyOnly(true);
+    }
+
+    public void testEmergencyOnlyNoSubscriptions() {
+        setupDefaultSignal();
+        mNetworkController.recalculateEmergency();
+        verifyEmergencyOnly(false);
+
+        setSubscriptions();
+        verifyEmergencyOnly(true);
+    }
+
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
         Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
-                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
+                mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class),
+                mMockSubDefaults);
         setupNetworkController();
 
         // No Subscriptions.
@@ -418,4 +439,11 @@
               TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][strength] /* strengthIcon */,
               DEFAULT_ICON /* typeIcon */);
     }
+
+    private void verifyEmergencyOnly(boolean isEmergencyOnly) {
+        ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
+        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
+                emergencyOnly.capture());
+        assertEquals(isEmergencyOnly, (boolean) emergencyOnly.getValue());
+    }
 }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index ad34b37..6eba3f6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -95,8 +95,6 @@
 
     private static final boolean COMPRESS_TIME = false;
 
-    public static final String SERVICE_NAME = "deviceidle";
-
     private static final String ACTION_STEP_IDLE_STATE =
             "com.android.server.device_idle.STEP_IDLE_STATE";
 
@@ -636,7 +634,7 @@
             mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
         }
 
-        publishBinderService(SERVICE_NAME, new BinderService());
+        publishBinderService(Context.DEVICE_IDLE_CONTROLLER, new BinderService());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 81ef4d5..e009455 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -338,7 +338,7 @@
         mNetworkStats = checkNotNull(networkStats, "missing networkStats");
         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(ServiceManager.getService(
-                DeviceIdleController.SERVICE_NAME));
+                Context.DEVICE_IDLE_CONTROLLER));
         mTime = checkNotNull(time, "missing TrustedTime");
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 837570b..75b8278 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -196,7 +196,7 @@
 
             mAppWidgetManager = getContext().getSystemService(AppWidgetManager.class);
             mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
-                    ServiceManager.getService(DeviceIdleController.SERVICE_NAME));
+                    ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
             mBatteryStats = IBatteryStats.Stub.asInterface(
                     ServiceManager.getService(BatteryStats.SERVICE_NAME));
             mDisplayManager = (DisplayManager) getContext().getSystemService(
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 368e137..0cd8c19 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -124,6 +124,16 @@
             "android.telecom.action.CHANGE_DEFAULT_DIALER";
 
     /**
+     * Broadcast intent action indicating that the current default dialer has changed.
+     * The string extra {@link #EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME} will contain the
+     * name of the package that the default dialer was changed to.
+     *
+     * @see #EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME
+     */
+    public static final String ACTION_DEFAULT_DIALER_CHANGED =
+            "android.telecom.action.DEFAULT_DIALER_CHANGED";
+
+    /**
      * Extra value used to provide the package name for {@link #ACTION_CHANGE_DEFAULT_DIALER}.
      */
     public static final String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME =
@@ -774,6 +784,31 @@
     }
 
     /**
+     * Used to set the default dialer package.
+     *
+     * @param packageName to set the default dialer to..
+     *
+     * @result {@code true} if the default dialer was successfully changed, {@code false} if
+     *         the specified package does not correspond to an installed dialer, or is already
+     *         the default dialer.
+     *
+     * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * Requires permission: {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
+     *
+     * @hide
+     */
+    public boolean setDefaultDialer(String packageName) {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().setDefaultDialer(packageName);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException attempting to set the default dialer.", e);
+        }
+        return false;
+    }
+
+    /**
      * Used to determine the dialer package that is preloaded on the system partition.
      *
      * @return package name for the system dialer package or null if no system dialer is preloaded.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index da0c547..7303298 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -232,6 +232,34 @@
      */
     public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
 
+    /**
+     * Flag specifying whether an additional (client initiated) intent needs to be sent on System
+     * update
+     * @hide
+     */
+    public static final String KEY_CI_ACTION_ON_SYS_UPDATE_BOOL = "ci_action_on_sys_update_bool";
+
+    /**
+     * Intent to be sent for the additional action on System update
+     * @hide
+     */
+    public static final String KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING =
+            "ci_action_on_sys_update_intent_string";
+
+    /**
+     * Extra to be included in the intent sent for additional action on System update
+     * @hide
+     */
+    public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING =
+            "ci_action_on_sys_update_extra_string";
+
+    /**
+     * Value of extra included in intent sent for additional action on System update
+     * @hide
+     */
+    public static final String KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING =
+            "ci_action_on_sys_update_extra_val_string";
+
     // These variables are used by the MMS service and exposed through another API, {@link
     // SmsManager}. The variable names and string values are copied from there.
     public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -304,6 +332,10 @@
         sDefaults.putInt(KEY_VVM_PORT_NUMBER_INT, 0);
         sDefaults.putString(KEY_VVM_TYPE_STRING, "");
         sDefaults.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING, "");
+        sDefaults.putBoolean(KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, false);
+        sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, "");
+        sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, "");
+        sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, "");
 
         // MMS defaults
         sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 94cbabf..2f0bf39 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -32,15 +32,18 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.graphics.BitmapFactory;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.graphics.Bitmap;
+import android.provider.Settings;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -60,6 +63,7 @@
     static final String KEY_CONFIGURATION = "configuration";
 
     ActivityManager mAm;
+    PowerManager mPower;
     AlarmManager mAlarm;
     Configuration mOverrideConfig;
     int mSecondUser;
@@ -158,8 +162,9 @@
 
         Log.i(TAG, "Referrer: " + getReferrer());
 
-        mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
-        mAlarm = (AlarmManager)getSystemService(ALARM_SERVICE);
+        mAm = getSystemService(ActivityManager.class);
+        mPower = getSystemService(PowerManager.class);
+        mAlarm = getSystemService(AlarmManager.class);
         if (savedInstanceState != null) {
             mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
             if (mOverrideConfig != null) {
@@ -445,7 +450,7 @@
                 new MenuItem.OnMenuItemClickListener() {
             @Override public boolean onMenuItemClick(MenuItem item) {
                 Intent intent = new Intent(Intent.ACTION_MAIN);
-                intent.putExtra("gulp", new int[1024*1024]);
+                intent.putExtra("gulp", new int[1024 * 1024]);
                 startActivity(intent);
                 return true;
             }
@@ -457,6 +462,17 @@
                 return true;
             }
         });
+        menu.add("Ignore battery optimizations").setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
+            @Override public boolean onMenuItemClick(MenuItem item) {
+                Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
+                if (!mPower.isIgnoringBatteryOptimizations(getPackageName())) {
+                    intent.setData(Uri.fromParts("package", getPackageName(), null));
+                }
+                startActivity(intent);
+                return true;
+            }
+        });
         return true;
     }