Merge "Fix a race condition in SeekBarVolumizer." into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 672eb4d9..015c035 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19262,7 +19262,6 @@
     method public boolean hasCarrierPhase();
     method public boolean hasCarrierPhaseUncertainty();
     method public boolean hasSnrInDb();
-    method public boolean isPseudorangeRateCorrected();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
     field public static final int ADR_STATE_RESET = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index 91d6292..7412908 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20433,7 +20433,6 @@
     method public boolean hasCarrierPhase();
     method public boolean hasCarrierPhaseUncertainty();
     method public boolean hasSnrInDb();
-    method public boolean isPseudorangeRateCorrected();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4
     field public static final int ADR_STATE_RESET = 2; // 0x2
@@ -25721,9 +25720,11 @@
 
   public class ScoredNetwork implements android.os.Parcelable {
     ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve);
+    ctor public ScoredNetwork(android.net.NetworkKey, android.net.RssiCurve, boolean);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.ScoredNetwork> CREATOR;
+    field public final boolean meteredHint;
     field public final android.net.NetworkKey networkKey;
     field public final android.net.RssiCurve rssiCurve;
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 55d6ecd..34c14d4 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19292,7 +19292,6 @@
     method public boolean hasCarrierPhase();
     method public boolean hasCarrierPhaseUncertainty();
     method public boolean hasSnrInDb();
-    method public boolean isPseudorangeRateCorrected();
     method public void reset();
     method public void resetCarrierCycles();
     method public void resetCarrierFrequencyHz();
@@ -19310,7 +19309,6 @@
     method public void setCn0DbHz(double);
     method public void setConstellationType(int);
     method public void setMultipathIndicator(int);
-    method public void setPseudorangeRateCorrected(boolean);
     method public void setPseudorangeRateMetersPerSecond(double);
     method public void setPseudorangeRateUncertaintyMetersPerSecond(double);
     method public void setReceivedSvTimeNanos(long);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a0a599e..cc1d68e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -744,7 +744,7 @@
     Activity mParent;
     boolean mCalled;
     /*package*/ boolean mResumed;
-    private boolean mStopped;
+    /*package*/ boolean mStopped;
     boolean mFinished;
     boolean mStartedActivity;
     private boolean mDestroyed;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 060ac5e..93c668d1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -379,6 +379,33 @@
                         ? "no component name" : componentName.toShortString())
                 + "}";
         }
+
+        public String getStateString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("ActivityClientRecord{");
+            sb.append("paused=").append(paused);
+            sb.append(", stopped=").append(stopped);
+            sb.append(", hideForNow=").append(hideForNow);
+            sb.append(", startsNotResumed=").append(startsNotResumed);
+            sb.append(", isForward=").append(isForward);
+            sb.append(", pendingConfigChanges=").append(pendingConfigChanges);
+            sb.append(", onlyLocalRequest=").append(onlyLocalRequest);
+            sb.append(", preserveWindow=").append(mPreserveWindow);
+            if (activity != null) {
+                sb.append(", Activity{");
+                sb.append("resumed=").append(activity.mResumed);
+                sb.append(", stopped=").append(activity.mStopped);
+                sb.append(", finished=").append(activity.isFinishing());
+                sb.append(", destroyed=").append(activity.isDestroyed());
+                sb.append(", startedActivity=").append(activity.mStartedActivity);
+                sb.append(", temporaryPause=").append(activity.mTemporaryPause);
+                sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
+                sb.append(", visibleBehind=").append(activity.mVisibleBehind);
+                sb.append("}");
+            }
+            sb.append("}");
+            return sb.toString();
+        }
     }
 
     final class ProviderClientRecord {
@@ -3752,9 +3779,10 @@
                     return;
                 }
                 RuntimeException e = new RuntimeException(
-                        "Performing stop of activity that is not resumed: "
+                        "Performing stop of activity that is already stopped: "
                         + r.intent.getComponent().toShortString());
                 Slog.e(TAG, e.getMessage(), e);
+                Slog.e(TAG, r.getStateString());
             }
 
             if (info != null) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1e288de..e9d0846 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3197,6 +3197,7 @@
         }
 
         private void resetStandardTemplateWithActions(RemoteViews big) {
+            big.setViewVisibility(R.id.actions_container, View.GONE);
             big.setViewVisibility(R.id.actions, View.GONE);
             big.removeAllViews(R.id.actions);
 
@@ -3218,6 +3219,7 @@
 
             int N = mActions.size();
             if (N > 0) {
+                big.setViewVisibility(R.id.actions_container, View.VISIBLE);
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
                 if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
                 for (int i=0; i<N; i++) {
diff --git a/core/java/android/net/ScoredNetwork.java b/core/java/android/net/ScoredNetwork.java
index 2dfb061..8582150 100644
--- a/core/java/android/net/ScoredNetwork.java
+++ b/core/java/android/net/ScoredNetwork.java
@@ -43,6 +43,16 @@
     public final RssiCurve rssiCurve;
 
     /**
+     * A boolean value that indicates whether or not the network is believed to be metered.
+     *
+     * <p>A network can be classified as metered if the user would be
+     * sensitive to heavy data usage on that connection due to monetary costs,
+     * data limitations or battery/performance issues. A typical example would
+     * be a wifi connection where the user would be charged for usage.
+     */
+    public final boolean meteredHint;
+
+    /**
      * Construct a new {@link ScoredNetwork}.
      *
      * @param networkKey the {@link NetworkKey} uniquely identifying this network.
@@ -54,8 +64,26 @@
      *     the scorer may choose to issue an out-of-band update at any time.
      */
     public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve) {
+        this(networkKey, rssiCurve, false /* meteredHint */);
+    }
+
+    /**
+     * Construct a new {@link ScoredNetwork}.
+     *
+     * @param networkKey the {@link NetworkKey} uniquely identifying this network.
+     * @param rssiCurve the {@link RssiCurve} representing the scores for this network based on the
+     *     RSSI. This field is optional, and may be skipped to represent a network which the scorer
+     *     has opted not to score at this time. Passing a null value here is strongly preferred to
+     *     not returning any {@link ScoredNetwork} for a given {@link NetworkKey} because it
+     *     indicates to the system not to request scores for this network in the future, although
+     *     the scorer may choose to issue an out-of-band update at any time.
+     * @param meteredHint A boolean value indicating whether or not the network is believed to be
+     *     metered.
+     */
+    public ScoredNetwork(NetworkKey networkKey, RssiCurve rssiCurve, boolean meteredHint) {
         this.networkKey = networkKey;
         this.rssiCurve = rssiCurve;
+        this.meteredHint = meteredHint;
     }
 
     private ScoredNetwork(Parcel in) {
@@ -65,6 +93,7 @@
         } else {
             rssiCurve = null;
         }
+        meteredHint = in.readByte() != 0;
     }
 
     @Override
@@ -81,6 +110,7 @@
         } else {
             out.writeByte((byte) 0);
         }
+        out.writeByte((byte) (meteredHint ? 1 : 0));
     }
 
     @Override
@@ -90,18 +120,20 @@
 
         ScoredNetwork that = (ScoredNetwork) o;
 
-        return Objects.equals(networkKey, that.networkKey) &&
-                Objects.equals(rssiCurve, that.rssiCurve);
+        return Objects.equals(networkKey, that.networkKey)
+            && Objects.equals(rssiCurve, that.rssiCurve)
+            && Objects.equals(meteredHint, that.meteredHint);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(networkKey, rssiCurve);
+        return Objects.hash(networkKey, rssiCurve, meteredHint);
     }
 
     @Override
     public String toString() {
-        return "ScoredNetwork[key=" + networkKey + ",score=" + rssiCurve + "]";
+        return "ScoredNetwork[key=" + networkKey + ",score=" + rssiCurve
+            + ",meteredHint=" + meteredHint + "]";
     }
 
     public static final Parcelable.Creator<ScoredNetwork> CREATOR =
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8a1a8c5..5060350 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9646,7 +9646,10 @@
     }
 
     boolean canShare() {
-        return canCopy() && isDeviceProvisioned();
+        if (!getContext().canStartActivityForResult() || !isDeviceProvisioned()) {
+            return false;
+        }
+        return canCopy();
     }
 
     boolean isDeviceProvisioned() {
@@ -9669,16 +9672,10 @@
     }
 
     boolean canProcessText() {
-        if (!getContext().canStartActivityForResult() || getId() == View.NO_ID
-                || hasPasswordTransformationMethod()) {
+        if (getId() == View.NO_ID) {
             return false;
         }
-
-        if (mText.length() > 0 && hasSelection() && mEditor != null) {
-            return true;
-        }
-
-        return false;
+        return canShare();
     }
 
     boolean canSelectAllText() {
diff --git a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
index cbf17a4..ec8cd71 100644
--- a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
+++ b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java
@@ -37,6 +37,8 @@
 import android.print.mockservice.PrinterDiscoverySessionCallbacks;
 import android.print.mockservice.StubbablePrinterDiscoverySession;
 
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -253,6 +255,7 @@
     /**
      * test IPrintManager.getPrintJobInfo
      */
+    @LargeTest
     public void testGetPrintJobInfo() throws Exception {
         startPrinting();
 
@@ -274,6 +277,7 @@
     /**
      * test IPrintManager.getPrintJobInfos
      */
+    @LargeTest
     public void testGetPrintJobInfos() throws Exception {
         startPrinting();
 
@@ -301,6 +305,7 @@
     /**
      * test IPrintManager.print
      */
+    @LargeTest
     public void testPrint() throws Exception {
         final String name = "dummy print job";
 
@@ -354,6 +359,7 @@
     /**
      * test IPrintManager.cancelPrintJob
      */
+    @LargeTest
     public void testCancelPrintJob() throws Exception {
         startPrinting();
 
@@ -377,6 +383,7 @@
     /**
      * test IPrintManager.restartPrintJob
      */
+    @LargeTest
     public void testRestartPrintJob() throws Exception {
         startPrinting();
 
@@ -399,6 +406,7 @@
     /**
      * test IPrintManager.addPrintJobStateChangeListener
      */
+    @MediumTest
     public void testAddPrintJobStateChangeListener() throws Exception {
         final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
 
@@ -424,6 +432,7 @@
     /**
      * test IPrintManager.removePrintJobStateChangeListener
      */
+    @MediumTest
     public void testRemovePrintJobStateChangeListener() throws Exception {
         final IPrintJobStateChangeListener listener = createMockIPrintJobStateChangeListener();
 
@@ -447,6 +456,7 @@
     /**
      * test IPrintManager.addPrintServicesChangeListener
      */
+    @MediumTest
     public void testAddPrintServicesChangeListener() throws Exception {
         final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
 
@@ -465,6 +475,7 @@
     /**
      * test IPrintManager.removePrintServicesChangeListener
      */
+    @MediumTest
     public void testRemovePrintServicesChangeListener() throws Exception {
         final IPrintServicesChangeListener listener = createMockIPrintServicesChangeListener();
 
@@ -488,6 +499,7 @@
     /**
      * test IPrintManager.getPrintServices
      */
+    @MediumTest
     public void testGetPrintServices() throws Exception {
         List<PrintServiceInfo> printServices = mIPrintManager.getPrintServices(
                 PrintManager.ALL_SERVICES, mUserId);
@@ -509,6 +521,7 @@
     /**
      * test IPrintManager.setPrintServiceEnabled
      */
+    @MediumTest
     public void testSetPrintServiceEnabled() throws Exception {
         final ComponentName printService = mIPrintManager.getPrintServices(
                 PrintManager.ALL_SERVICES, mUserId).get(0).getComponentName();
@@ -548,6 +561,7 @@
     /**
      * test IPrintManager.createPrinterDiscoverySession
      */
+    @MediumTest
     public void testCreatePrinterDiscoverySession() throws Exception {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
@@ -573,6 +587,7 @@
     /**
      * test IPrintManager.startPrinterDiscovery
      */
+    @LargeTest
     public void testStartPrinterDiscovery() throws Exception {
         startPrinting();
 
@@ -615,6 +630,7 @@
     /**
      * test IPrintManager.stopPrinterDiscovery
      */
+    @MediumTest
     public void testStopPrinterDiscovery() throws Exception {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
@@ -638,6 +654,7 @@
     /**
      * test IPrintManager.validatePrinters
      */
+    @LargeTest
     public void testValidatePrinters() throws Exception {
         startPrinting();
 
@@ -678,6 +695,7 @@
     /**
      * test IPrintManager.startPrinterStateTracking
      */
+    @LargeTest
     public void testStartPrinterStateTracking() throws Exception {
         startPrinting();
 
@@ -699,6 +717,7 @@
     /**
      * test IPrintManager.getCustomPrinterIcon
      */
+    @LargeTest
     public void testGetCustomPrinterIcon() throws Exception {
         startPrinting();
 
@@ -720,6 +739,7 @@
     /**
      * test IPrintManager.stopPrinterStateTracking
      */
+    @LargeTest
     public void testStopPrinterStateTracking() throws Exception {
         startPrinting();
 
@@ -746,6 +766,7 @@
     /**
      * test IPrintManager.destroyPrinterDiscoverySession
      */
+    @MediumTest
     public void testDestroyPrinterDiscoverySession() throws Exception {
         final IPrinterDiscoveryObserver listener = createMockIPrinterDiscoveryObserver();
 
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 11fecfb..a7eb73f 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -47,7 +47,6 @@
     private double mCarrierPhaseUncertainty;
     private int mMultipathIndicator;
     private double mSnrInDb;
-    private boolean mPseudorangeRateCorrected;
 
     // The following enumerations must be in sync with the values declared in gps.h
 
@@ -440,25 +439,6 @@
     }
 
     /**
-     * See {@link #getPseudorangeRateMetersPerSecond()} for more details.
-     *
-     * @return {@code true} if {@link #getPseudorangeRateMetersPerSecond()} contains a corrected
-     *         value, {@code false} if it contains an uncorrected value.
-     */
-    public boolean isPseudorangeRateCorrected() {
-        return mPseudorangeRateCorrected;
-    }
-
-    /**
-     * Sets whether the pseudorange corrected.
-     * @hide
-     */
-    @TestApi
-    public void setPseudorangeRateCorrected(boolean value) {
-        mPseudorangeRateCorrected = value;
-    }
-
-    /**
      * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
      * The uncertainty is represented as an absolute (single sided) value.
      */
@@ -813,7 +793,6 @@
             gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
             gnssMeasurement.mMultipathIndicator = parcel.readInt();
             gnssMeasurement.mSnrInDb = parcel.readDouble();
-            gnssMeasurement.mPseudorangeRateCorrected = (parcel.readByte() != 0);
 
             return gnssMeasurement;
         }
@@ -845,7 +824,6 @@
         parcel.writeDouble(mCarrierPhaseUncertainty);
         parcel.writeInt(mMultipathIndicator);
         parcel.writeDouble(mSnrInDb);
-        parcel.writeByte((byte) (mPseudorangeRateCorrected ? 1 : 0));
     }
 
     @Override
@@ -880,10 +858,6 @@
                 mPseudorangeRateMetersPerSecond,
                 "PseudorangeRateUncertaintyMetersPerSecond",
                 mPseudorangeRateUncertaintyMetersPerSecond));
-        builder.append(String.format(
-                format,
-                "PseudorangeRateIsCorrected",
-                isPseudorangeRateCorrected()));
 
         builder.append(String.format(
                 format,
@@ -943,7 +917,6 @@
         resetCarrierPhaseUncertainty();
         setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
         resetSnrInDb();
-        setPseudorangeRateCorrected(false);
     }
 
     private void setFlag(int flag) {
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index ac255c8..e5c0f27 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -286,18 +286,11 @@
             navigationMessage.setSvid(parcel.readInt());
             navigationMessage.setMessageId(parcel.readInt());
             navigationMessage.setSubmessageId(parcel.readInt());
-
             int dataLength = parcel.readInt();
             byte[] data = new byte[dataLength];
             parcel.readByteArray(data);
             navigationMessage.setData(data);
-
-            if (parcel.dataAvail() >= Integer.SIZE) {
-                int status = parcel.readInt();
-                navigationMessage.setStatus(status);
-            } else {
-                navigationMessage.setStatus(STATUS_UNKNOWN);
-            }
+            navigationMessage.setStatus(parcel.readInt());
 
             return navigationMessage;
         }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d179171..3c42161 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1076,9 +1076,6 @@
      * <p>
      * This method has no effect if the device implements a fixed volume policy
      * as indicated by {@link #isVolumeFixed()}.
-     * <p>From N onward, stream mute changes that would toggle Do Not Disturb are not allowed unless
-     * the app has been granted Do Not Disturb Access.
-     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
      * <p>
      * This method was deprecated in API level 22. Prior to API level 22 this
      * method had significantly different behavior and should be used carefully.
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 75195c4..7460201 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -43,6 +43,7 @@
             android:singleLine="true"
             android:ellipsize="start"
             android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
+            android:textIsSelectable="true"
             android:imeOptions="actionSend|flagNoExtractUi" />
 
     <FrameLayout
@@ -62,6 +63,7 @@
                 android:paddingBottom="12dp"
                 android:id="@+id/remote_input_send"
                 android:src="@drawable/ic_send"
+                android:contentDescription="@*android:string/ime_action_send"
                 android:tint="@color/remote_input_send"
                 android:tintMode="src_in"
                 android:background="@drawable/ripple_drawable" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 8f1517d..bb4a771 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1107,6 +1107,7 @@
                         });
                         a.start();
                         guts.setExposed(true);
+                        row.closeRemoteInput();
                         mStackScroller.onHeightChanged(null, true /* needsAnimation */);
                         mNotificationGutsExposed = guts;
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 246f15e..22bb8eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -579,6 +579,11 @@
         }
     }
 
+    public void closeRemoteInput() {
+        mPrivateLayout.closeRemoteInput();
+        mPublicLayout.closeRemoteInput();
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 3b87577..c2df292 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -69,6 +69,9 @@
     private View mHeadsUpChild;
     private HybridNotificationView mSingleLineView;
 
+    private RemoteInputView mExpandedRemoteInput;
+    private RemoteInputView mHeadsUpRemoteInput;
+
     private NotificationViewWrapper mContractedWrapper;
     private NotificationViewWrapper mExpandedWrapper;
     private NotificationViewWrapper mHeadsUpWrapper;
@@ -743,15 +746,19 @@
 
         View bigContentView = mExpandedChild;
         if (bigContentView != null) {
-            applyRemoteInput(bigContentView, entry, hasRemoteInput);
+            mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput);
+        } else {
+            mExpandedRemoteInput = null;
         }
         View headsUpContentView = mHeadsUpChild;
         if (headsUpContentView != null) {
-            applyRemoteInput(headsUpContentView, entry, hasRemoteInput);
+            mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput);
+        } else {
+            mHeadsUpRemoteInput = null;
         }
     }
 
-    private void applyRemoteInput(View view, NotificationData.Entry entry, boolean hasRemoteInput) {
+    private RemoteInputView applyRemoteInput(View view, NotificationData.Entry entry, boolean hasRemoteInput) {
         View actionContainerCandidate = view.findViewById(
                 com.android.internal.R.id.actions_container);
         if (actionContainerCandidate instanceof FrameLayout) {
@@ -777,7 +784,20 @@
                     color = mContext.getColor(R.color.default_remote_input_background);
                 }
                 riv.setBackgroundColor(color);
+
+                return riv;
             }
+            return existing;
+        }
+        return null;
+    }
+
+    public void closeRemoteInput() {
+        if (mHeadsUpRemoteInput != null) {
+            mHeadsUpRemoteInput.close();
+        }
+        if (mExpandedRemoteInput != null) {
+            mExpandedRemoteInput.close();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index eb5b57e..95f26d4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -16,24 +16,42 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.LayoutRes;
 import android.app.StatusBarManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.media.session.MediaSessionLegacyHelper;
+import android.net.Uri;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.util.AttributeSet;
+import android.view.ActionMode;
+import android.view.InputQueue;
 import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.MotionEvent;
+import android.view.SurfaceHolder;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.widget.FrameLayout;
 
+import com.android.internal.view.FloatingActionMode;
+import com.android.internal.widget.FloatingToolbar;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -57,6 +75,13 @@
     private final Paint mTransparentSrcPaint = new Paint();
     private FalsingManager mFalsingManager;
 
+    // Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
+    // DecorView, but since this is a special window we have to roll our own.
+    private View mFloatingActionModeOriginatingView;
+    private ActionMode mFloatingActionMode;
+    private FloatingToolbar mFloatingToolbar;
+    private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
+
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setMotionEventSplittingEnabled(false);
@@ -301,5 +326,341 @@
             a.recycle();
         }
     }
+
+    @Override
+    public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
+            int type) {
+        if (type == ActionMode.TYPE_FLOATING) {
+            return startActionMode(originalView, callback, type);
+        }
+        return super.startActionModeForChild(originalView, callback, type);
+    }
+
+    private ActionMode createFloatingActionMode(
+            View originatingView, ActionMode.Callback2 callback) {
+        if (mFloatingActionMode != null) {
+            mFloatingActionMode.finish();
+        }
+        cleanupFloatingActionModeViews();
+        final FloatingActionMode mode =
+                new FloatingActionMode(mContext, callback, originatingView);
+        mFloatingActionModeOriginatingView = originatingView;
+        mFloatingToolbarPreDrawListener =
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        mode.updateViewLocationInWindow();
+                        return true;
+                    }
+                };
+        return mode;
+    }
+
+    private void setHandledFloatingActionMode(ActionMode mode) {
+        mFloatingActionMode = mode;
+        mFloatingToolbar = new FloatingToolbar(mContext, mFakeWindow);
+        ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar);
+        mFloatingActionMode.invalidate();  // Will show the floating toolbar if necessary.
+        mFloatingActionModeOriginatingView.getViewTreeObserver()
+                .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
+    }
+
+    private void cleanupFloatingActionModeViews() {
+        if (mFloatingToolbar != null) {
+            mFloatingToolbar.dismiss();
+            mFloatingToolbar = null;
+        }
+        if (mFloatingActionModeOriginatingView != null) {
+            if (mFloatingToolbarPreDrawListener != null) {
+                mFloatingActionModeOriginatingView.getViewTreeObserver()
+                        .removeOnPreDrawListener(mFloatingToolbarPreDrawListener);
+                mFloatingToolbarPreDrawListener = null;
+            }
+            mFloatingActionModeOriginatingView = null;
+        }
+    }
+
+    private ActionMode startActionMode(
+            View originatingView, ActionMode.Callback callback, int type) {
+        ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
+        ActionMode mode = createFloatingActionMode(originatingView, wrappedCallback);
+        if (mode != null && wrappedCallback.onCreateActionMode(mode, mode.getMenu())) {
+            setHandledFloatingActionMode(mode);
+        } else {
+            mode = null;
+        }
+        return mode;
+    }
+
+    private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
+        private final ActionMode.Callback mWrapped;
+
+        public ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
+            mWrapped = wrapped;
+        }
+
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            return mWrapped.onCreateActionMode(mode, menu);
+        }
+
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            requestFitSystemWindows();
+            return mWrapped.onPrepareActionMode(mode, menu);
+        }
+
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return mWrapped.onActionItemClicked(mode, item);
+        }
+
+        public void onDestroyActionMode(ActionMode mode) {
+            mWrapped.onDestroyActionMode(mode);
+            if (mode == mFloatingActionMode) {
+                cleanupFloatingActionModeViews();
+                mFloatingActionMode = null;
+            }
+            requestFitSystemWindows();
+        }
+
+        @Override
+        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+            if (mWrapped instanceof ActionMode.Callback2) {
+                ((ActionMode.Callback2) mWrapped).onGetContentRect(mode, view, outRect);
+            } else {
+                super.onGetContentRect(mode, view, outRect);
+            }
+        }
+    }
+
+    /**
+     * Minimal window to satisfy FloatingToolbar.
+     */
+    private Window mFakeWindow = new Window(mContext) {
+        @Override
+        public void takeSurface(SurfaceHolder.Callback2 callback) {
+        }
+
+        @Override
+        public void takeInputQueue(InputQueue.Callback callback) {
+        }
+
+        @Override
+        public boolean isFloating() {
+            return false;
+        }
+
+        @Override
+        public void alwaysReadCloseOnTouchAttr() {
+        }
+
+        @Override
+        public void setContentView(@LayoutRes int layoutResID) {
+        }
+
+        @Override
+        public void setContentView(View view) {
+        }
+
+        @Override
+        public void setContentView(View view, ViewGroup.LayoutParams params) {
+        }
+
+        @Override
+        public void addContentView(View view, ViewGroup.LayoutParams params) {
+        }
+
+        @Override
+        public void clearContentView() {
+        }
+
+        @Override
+        public View getCurrentFocus() {
+            return null;
+        }
+
+        @Override
+        public LayoutInflater getLayoutInflater() {
+            return null;
+        }
+
+        @Override
+        public void setTitle(CharSequence title) {
+        }
+
+        @Override
+        public void setTitleColor(@ColorInt int textColor) {
+        }
+
+        @Override
+        public void openPanel(int featureId, KeyEvent event) {
+        }
+
+        @Override
+        public void closePanel(int featureId) {
+        }
+
+        @Override
+        public void togglePanel(int featureId, KeyEvent event) {
+        }
+
+        @Override
+        public void invalidatePanelMenu(int featureId) {
+        }
+
+        @Override
+        public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
+            return false;
+        }
+
+        @Override
+        public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
+            return false;
+        }
+
+        @Override
+        public void closeAllPanels() {
+        }
+
+        @Override
+        public boolean performContextMenuIdentifierAction(int id, int flags) {
+            return false;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+        }
+
+        @Override
+        public void setBackgroundDrawable(Drawable drawable) {
+        }
+
+        @Override
+        public void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
+        }
+
+        @Override
+        public void setFeatureDrawableUri(int featureId, Uri uri) {
+        }
+
+        @Override
+        public void setFeatureDrawable(int featureId, Drawable drawable) {
+        }
+
+        @Override
+        public void setFeatureDrawableAlpha(int featureId, int alpha) {
+        }
+
+        @Override
+        public void setFeatureInt(int featureId, int value) {
+        }
+
+        @Override
+        public void takeKeyEvents(boolean get) {
+        }
+
+        @Override
+        public boolean superDispatchKeyEvent(KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchTouchEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchTrackballEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public boolean superDispatchGenericMotionEvent(MotionEvent event) {
+            return false;
+        }
+
+        @Override
+        public View getDecorView() {
+            return StatusBarWindowView.this;
+        }
+
+        @Override
+        public View peekDecorView() {
+            return null;
+        }
+
+        @Override
+        public Bundle saveHierarchyState() {
+            return null;
+        }
+
+        @Override
+        public void restoreHierarchyState(Bundle savedInstanceState) {
+        }
+
+        @Override
+        protected void onActive() {
+        }
+
+        @Override
+        public void setChildDrawable(int featureId, Drawable drawable) {
+        }
+
+        @Override
+        public void setChildInt(int featureId, int value) {
+        }
+
+        @Override
+        public boolean isShortcutKey(int keyCode, KeyEvent event) {
+            return false;
+        }
+
+        @Override
+        public void setVolumeControlStream(int streamType) {
+        }
+
+        @Override
+        public int getVolumeControlStream() {
+            return 0;
+        }
+
+        @Override
+        public int getStatusBarColor() {
+            return 0;
+        }
+
+        @Override
+        public void setStatusBarColor(@ColorInt int color) {
+        }
+
+        @Override
+        public int getNavigationBarColor() {
+            return 0;
+        }
+
+        @Override
+        public void setNavigationBarColor(@ColorInt int color) {
+        }
+
+        @Override
+        public void setDecorCaptionShade(int decorCaptionShade) {
+        }
+
+        @Override
+        public void setResizingCaptionDrawable(Drawable drawable) {
+        }
+
+        @Override
+        public void onMultiWindowChanged() {
+        }
+
+        @Override
+        public void reportActivityRelaunched() {
+        }
+    };
+
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 29b0f4b..3a0336b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -29,8 +29,10 @@
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -44,6 +46,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.stack.LongPressCancelable;
 
 /**
  * Host for the remote input.
@@ -64,6 +67,7 @@
     private RemoteInputController mController;
 
     private NotificationData.Entry mEntry;
+    private LongPressCancelable mLongPressCancelable;
 
     public RemoteInputView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -226,6 +230,30 @@
         updateSendButton();
     }
 
+    public void close() {
+        mEditText.defocusIfNeeded();
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            if (mLongPressCancelable == null) {
+                ViewParent p = getParent();
+                while (p != null) {
+                    if (p instanceof LongPressCancelable) {
+                        mLongPressCancelable = (LongPressCancelable) p;
+                        break;
+                    }
+                    p = p.getParent();
+                }
+            }
+            if (mLongPressCancelable != null) {
+                mLongPressCancelable.requestDisallowLongPress();
+            }
+        }
+        return super.onInterceptTouchEvent(ev);
+    }
+
     /**
      * An EditText that changes appearance based on whether it's focusable and becomes
      * un-focusable whenever the user navigates away from it or it becomes invisible.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java
new file mode 100644
index 0000000..05f0c07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/LongPressCancelable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 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
+ */
+
+package com.android.systemui.statusbar.stack;
+
+/**
+ * Interface for container layouts that listen for long presses. A child that
+ * wants to handle long press can use this to cancel the parents long press logic.
+ */
+public interface LongPressCancelable {
+    /**
+     * Request that the view does not perform long press for the current touch.
+     */
+    void requestDisallowLongPress();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 59ec6112..686a712 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -83,7 +83,7 @@
 public class NotificationStackScrollLayout extends ViewGroup
         implements SwipeHelper.Callback, ExpandHelper.Callback, ScrollAdapter,
         ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener,
-        SettingsIconRowListener {
+        SettingsIconRowListener, LongPressCancelable {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -2627,6 +2627,11 @@
         }
     }
 
+    @Override
+    public void requestDisallowLongPress() {
+        removeLongPressCallback();
+    }
+
     public void removeLongPressCallback() {
         mSwipeHelper.removeLongPressCallback();
     }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d4dd505..8310c97 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -597,7 +597,7 @@
         if (sharedAccounts == null || sharedAccounts.length == 0) return;
         Account[] accounts = getAccountsAsUser(null, userId, mContext.getOpPackageName());
         int parentUserId = UserManager.isSplitSystemUser()
-                ? mUserManager.getUserInfo(userId).restrictedProfileParentId
+                ? getUserManager().getUserInfo(userId).restrictedProfileParentId
                 : UserHandle.USER_SYSTEM;
         if (parentUserId < 0) {
             Log.w(TAG, "User " + userId + " has shared accounts, but no parent user");
@@ -1061,7 +1061,7 @@
         for (UserInfo user : users) {
             if (user.isRestricted() && (parentUserId == user.restrictedProfileParentId)) {
                 addSharedAccountAsUser(account, user.id);
-                if (mUserManager.isUserUnlocked(user.id)) {
+                if (getUserManager().isUserUnlocked(user.id)) {
                     mMessageHandler.sendMessage(mMessageHandler.obtainMessage(
                             MESSAGE_COPY_SHARED_ACCOUNT, parentUserId, user.id, account));
                 }
@@ -1270,7 +1270,7 @@
                          * Owner or system user account was renamed, rename the account for
                          * those users with which the account was shared.
                          */
-                        List<UserInfo> users = mUserManager.getUsers(true);
+                        List<UserInfo> users = getUserManager().getUsers(true);
                         for (UserInfo user : users) {
                             if (user.isRestricted()
                                     && (user.restrictedProfileParentId == parentUserId)) {
@@ -1286,7 +1286,7 @@
     }
 
     private boolean canHaveProfile(final int parentUserId) {
-        final UserInfo userInfo = mUserManager.getUserInfo(parentUserId);
+        final UserInfo userInfo = getUserManager().getUserInfo(parentUserId);
         return userInfo != null && userInfo.canHaveProfile();
     }
 
@@ -1477,7 +1477,7 @@
             int parentUserId = accounts.userId;
             if (canHaveProfile(parentUserId)) {
                 // Remove from any restricted profiles that are sharing this account.
-                List<UserInfo> users = mUserManager.getUsers(true);
+                List<UserInfo> users = getUserManager().getUsers(true);
                 for (UserInfo user : users) {
                     if (user.isRestricted() && parentUserId == (user.restrictedProfileParentId)) {
                         removeSharedAccountAsUser(account, user.id, callingUid);
@@ -4730,7 +4730,7 @@
                 || callingUid == Process.myUid()) {
             return unfiltered;
         }
-        UserInfo user = mUserManager.getUserInfo(userAccounts.userId);
+        UserInfo user = getUserManager().getUserInfo(userAccounts.userId);
         if (user != null && user.isRestricted()) {
             String[] packages = mPackageManager.getPackagesForUid(callingUid);
             // If any of the packages is a white listed package, return the full set,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5320221..b4df689 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1290,7 +1290,7 @@
             // Check if the ringer mode handles this adjustment. If it does we don't
             // need to adjust the volume further.
             final int result = checkForRingerModeChange(aliasIndex, direction, step,
-                    streamState.mIsMuted, caller);
+                    streamState.mIsMuted);
             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
             // If suppressing a volume adjustment in silent mode, display the UI hint
             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
@@ -3361,8 +3361,7 @@
      * adjusting volume. If so, this will set the proper ringer mode and volume
      * indices on the stream states.
      */
-    private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
-            String caller) {
+    private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted) {
         final boolean isTv = mPlatformType == AudioSystem.PLATFORM_TELEVISION;
         int result = FLAG_ADJUST_VOLUME;
         int ringerMode = getRingerModeInternal();
@@ -3451,11 +3450,6 @@
             break;
         }
 
-        if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
-                && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
-            throw new SecurityException("Not allowed to change Do Not Disturb state");
-        }
-
         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
 
         mPrevVolDirection = direction;