Merge "Some fixes in ConnectivityService event logging" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 7fe5728..00a2b7a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30330,7 +30330,7 @@
 
 package android.printservice {
 
-  public class CustomPrinterIconCallback {
+  public final class CustomPrinterIconCallback {
     method public boolean onCustomPrinterIconLoaded(android.graphics.drawable.Icon);
   }
 
diff --git a/api/system-current.txt b/api/system-current.txt
index f725731..697166d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -26111,9 +26111,10 @@
     field public static final int IPCE_IPMGR_PROVISIONING_FAIL = 4097; // 0x1001
     field public static final int IPCE_IPMGR_PROVISIONING_OK = 4096; // 0x1000
     field public static final int IPCE_IPRM_BASE = 0; // 0x0
-    field public static final int IPCE_IPRM_MESSAGE_RECEIVED = 1; // 0x1
-    field public static final int IPCE_IPRM_PROBE_RESULT = 0; // 0x0
-    field public static final int IPCE_IPRM_REACHABILITY_LOST = 2; // 0x2
+    field public static final int IPCE_IPRM_NUD_FAILED = 2; // 0x2
+    field public static final int IPCE_IPRM_PROBE_FAILURE = 1; // 0x1
+    field public static final int IPCE_IPRM_PROBE_STARTED = 0; // 0x0
+    field public static final int IPCE_IPRM_PROVISIONING_LOST = 3; // 0x3
     field public static final int IPCE_NETMON_BASE = 2048; // 0x800
     field public static final int IPCE_NETMON_CHECK_RESULT = 2049; // 0x801
     field public static final int IPCE_NETMON_STATE_CHANGE = 2048; // 0x800
@@ -26128,35 +26129,20 @@
     field public final java.lang.String ifName;
   }
 
-  public final class IpReachabilityMonitorLostEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
+  public final class IpReachabilityEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
     method public int describeContents();
-    method public static void logEvent(java.lang.String);
+    method public static void logNudFailed(java.lang.String);
+    method public static void logProbeEvent(java.lang.String, int);
+    method public static void logProvisioningLost(java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorLostEvent> CREATOR;
+    field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityEvent> CREATOR;
+    field public static final int NUD_FAILED = 512; // 0x200
+    field public static final int PROBE = 256; // 0x100
+    field public static final int PROVISIONING_LOST = 768; // 0x300
+    field public final int eventType;
     field public final java.lang.String ifName;
   }
 
-  public final class IpReachabilityMonitorMessageEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    method public int describeContents();
-    method public static void logEvent(java.lang.String, java.lang.String, int, int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorMessageEvent> CREATOR;
-    field public final java.lang.String destination;
-    field public final java.lang.String ifName;
-    field public final int msgType;
-    field public final int nudState;
-  }
-
-  public final class IpReachabilityMonitorProbeEvent extends android.net.metrics.IpConnectivityEvent implements android.os.Parcelable {
-    method public int describeContents();
-    method public static void logEvent(java.lang.String, java.lang.String, boolean);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.metrics.IpReachabilityMonitorProbeEvent> CREATOR;
-    field public final java.lang.String destination;
-    field public final java.lang.String ifName;
-    field public final boolean success;
-  }
-
 }
 
 package android.net.nsd {
@@ -32829,7 +32815,7 @@
 
 package android.printservice {
 
-  public class CustomPrinterIconCallback {
+  public final class CustomPrinterIconCallback {
     method public boolean onCustomPrinterIconLoaded(android.graphics.drawable.Icon);
   }
 
diff --git a/api/test-current.txt b/api/test-current.txt
index 88031cf..d5ecfd1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -30402,7 +30402,7 @@
 
 package android.printservice {
 
-  public class CustomPrinterIconCallback {
+  public final class CustomPrinterIconCallback {
     method public boolean onCustomPrinterIconLoaded(android.graphics.drawable.Icon);
   }
 
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 424d355..2f7c550 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -126,6 +126,19 @@
     public static final String META_HOME_ALTERNATE = "android.app.home.alternate";
 
     /**
+     * Result for IActivityManager.startVoiceActivity: active session is currently hidden.
+     * @hide
+     */
+    public static final int START_VOICE_HIDDEN_SESSION = -10;
+
+    /**
+     * Result for IActivityManager.startVoiceActivity: active session does not match
+     * the requesting token.
+     * @hide
+     */
+    public static final int START_VOICE_NOT_ACTIVE_SESSION = -9;
+
+    /**
      * Result for IActivityManager.startActivity: trying to start a background user
      * activity that shouldn't be displayed for all users.
      * @hide
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 4fca69a..95ea2a5 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1797,7 +1797,7 @@
         if (res >= ActivityManager.START_SUCCESS) {
             return;
         }
-        
+
         switch (res) {
             case ActivityManager.START_INTENT_NOT_RESOLVED:
             case ActivityManager.START_CLASS_NOT_FOUND:
@@ -1820,6 +1820,15 @@
             case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                 throw new SecurityException(
                         "Starting under voice control not allowed for: " + intent);
+            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
+                throw new IllegalStateException(
+                        "Session calling startVoiceActivity does not match active session");
+            case ActivityManager.START_VOICE_HIDDEN_SESSION:
+                throw new IllegalStateException(
+                        "Cannot start voice activity on a hidden session");
+            case ActivityManager.START_CANCELED:
+                throw new AndroidRuntimeException("Activity could not be started for "
+                        + intent);
             default:
                 throw new AndroidRuntimeException("Unknown error code "
                         + res + " when starting " + intent);
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index c84a0dc..602d950 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -24,7 +24,7 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 import android.util.Log;
-import static android.util.TimeUtils.formatForLogging;
+import static android.util.TimeUtils.formatDuration;
 
 import java.util.ArrayList;
 
@@ -760,15 +760,27 @@
                         " setRequiresDeviceIdle is an error.");
             }
             JobInfo job = new JobInfo(this);
-            if (job.intervalMillis != job.getIntervalMillis()) {
-                Log.w(TAG, "Specified interval for " + mJobService.getPackageName() + " is "
-                        + formatForLogging(mIntervalMillis) + ". Clamped to " +
-                        formatForLogging(job.getIntervalMillis()));
-            }
-            if (job.flexMillis != job.getFlexMillis()) {
-                Log.w(TAG, "Specified interval for " + mJobService.getPackageName() + " is "
-                        + formatForLogging(mFlexMillis) + ". Clamped to " +
-                        formatForLogging(job.getFlexMillis()));
+            if (job.isPeriodic()) {
+                if (job.intervalMillis != job.getIntervalMillis()) {
+                    StringBuilder builder = new StringBuilder();
+                    builder.append("Specified interval for ")
+                            .append(String.valueOf(mJobId))
+                            .append(" is ");
+                    formatDuration(mIntervalMillis, builder);
+                    builder.append(". Clamped to ");
+                    formatDuration(job.getIntervalMillis(), builder);
+                    Log.w(TAG, builder.toString());
+                }
+                if (job.flexMillis != job.getFlexMillis()) {
+                    StringBuilder builder = new StringBuilder();
+                    builder.append("Specified flex for ")
+                            .append(String.valueOf(mJobId))
+                            .append(" is ");
+                    formatDuration(mFlexMillis, builder);
+                    builder.append(". Clamped to ");
+                    formatDuration(job.getFlexMillis(), builder);
+                    Log.w(TAG, builder.toString());
+                }
             }
             return job;
         }
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 5573896..6736d34 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -628,7 +628,12 @@
      * close the camera further by unconfiguring and then firing {@code onClosed}.</p>
      */
     private void finishPendingSequence(int sequenceId) {
-        mSequenceDrainer.taskFinished(sequenceId);
+        try {
+            mSequenceDrainer.taskFinished(sequenceId);
+        } catch (IllegalStateException e) {
+            // Workaround for b/27870771
+            Log.w(TAG, e.getMessage());
+        }
     }
 
     private class SequenceDrainListener implements TaskDrainer.DrainListener {
diff --git a/core/java/android/net/metrics/IpConnectivityEvent.java b/core/java/android/net/metrics/IpConnectivityEvent.java
index 2eb8edb..d455a0f 100644
--- a/core/java/android/net/metrics/IpConnectivityEvent.java
+++ b/core/java/android/net/metrics/IpConnectivityEvent.java
@@ -39,9 +39,10 @@
     public static final int IPCE_IPMGR_BASE                = 4 * 1024;
     public static final int IPCE_DNS_BASE                  = 5 * 1024;
 
-    public static final int IPCE_IPRM_PROBE_RESULT         = IPCE_IPRM_BASE + 0;
-    public static final int IPCE_IPRM_MESSAGE_RECEIVED     = IPCE_IPRM_BASE + 1;
-    public static final int IPCE_IPRM_REACHABILITY_LOST    = IPCE_IPRM_BASE + 2;
+    public static final int IPCE_IPRM_PROBE_STARTED        = IPCE_IPRM_BASE + 0;
+    public static final int IPCE_IPRM_PROBE_FAILURE        = IPCE_IPRM_BASE + 1;
+    public static final int IPCE_IPRM_NUD_FAILED           = IPCE_IPRM_BASE + 2;
+    public static final int IPCE_IPRM_PROVISIONING_LOST    = IPCE_IPRM_BASE + 3;
 
     public static final int IPCE_DHCP_RECV_ERROR           = IPCE_DHCP_BASE + 0;
     public static final int IPCE_DHCP_PARSE_ERROR          = IPCE_DHCP_BASE + 1;
diff --git a/core/java/android/net/metrics/IpReachabilityEvent.java b/core/java/android/net/metrics/IpReachabilityEvent.java
new file mode 100644
index 0000000..73dcb94
--- /dev/null
+++ b/core/java/android/net/metrics/IpReachabilityEvent.java
@@ -0,0 +1,84 @@
+/*
+ * 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 android.net.metrics;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+@SystemApi
+public final class IpReachabilityEvent extends IpConnectivityEvent implements Parcelable {
+
+    public static final int PROBE             = 1 << 8;
+    public static final int NUD_FAILED        = 2 << 8;
+    public static final int PROVISIONING_LOST = 3 << 8;
+
+    public final String ifName;
+    // eventType byte format (MSB to LSB):
+    // byte 0: unused
+    // byte 1: unused
+    // byte 2: type of event: PROBE, NUD_FAILED, PROVISIONING_LOST
+    // byte 3: kernel errno from RTNetlink or IpReachabilityMonitor
+    public final int eventType;
+
+    private IpReachabilityEvent(String ifName, int eventType) {
+        this.ifName = ifName;
+        this.eventType = eventType;
+    }
+
+    private IpReachabilityEvent(Parcel in) {
+        this.ifName = in.readString();
+        this.eventType = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(ifName);
+        out.writeInt(eventType);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<IpReachabilityEvent> CREATOR
+        = new Parcelable.Creator<IpReachabilityEvent>() {
+        public IpReachabilityEvent createFromParcel(Parcel in) {
+            return new IpReachabilityEvent(in);
+        }
+
+        public IpReachabilityEvent[] newArray(int size) {
+            return new IpReachabilityEvent[size];
+        }
+    };
+
+    public static void logProbeEvent(String ifName, int nlErrorCode) {
+        final int tag = (nlErrorCode == 0) ? IPCE_IPRM_PROBE_STARTED : IPCE_IPRM_PROBE_FAILURE;
+        final int eventType = PROBE | (nlErrorCode & 0xFF);
+        logEvent(tag, new IpReachabilityEvent(ifName, eventType));
+    }
+
+    public static void logNudFailed(String ifName) {
+        logEvent(IPCE_IPRM_NUD_FAILED, new IpReachabilityEvent(ifName, NUD_FAILED));
+    }
+
+    public static void logProvisioningLost(String ifName) {
+        logEvent(IPCE_IPRM_PROVISIONING_LOST, new IpReachabilityEvent(ifName, PROVISIONING_LOST));
+    }
+};
diff --git a/core/java/android/net/metrics/IpReachabilityMonitorLostEvent.java b/core/java/android/net/metrics/IpReachabilityMonitorLostEvent.java
deleted file mode 100644
index 5215995..0000000
--- a/core/java/android/net/metrics/IpReachabilityMonitorLostEvent.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class IpReachabilityMonitorLostEvent extends IpConnectivityEvent
-        implements Parcelable {
-    public final String ifName;
-
-    private IpReachabilityMonitorLostEvent(String ifName) {
-        this.ifName = ifName;
-    }
-
-    private IpReachabilityMonitorLostEvent(Parcel in) {
-        this.ifName = in.readString();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<IpReachabilityMonitorLostEvent> CREATOR
-        = new Parcelable.Creator<IpReachabilityMonitorLostEvent>() {
-        public IpReachabilityMonitorLostEvent createFromParcel(Parcel in) {
-            return new IpReachabilityMonitorLostEvent(in);
-        }
-
-        public IpReachabilityMonitorLostEvent[] newArray(int size) {
-            return new IpReachabilityMonitorLostEvent[size];
-        }
-    };
-
-    public static void logEvent(String ifName) {
-        logEvent(IPCE_IPRM_REACHABILITY_LOST, new IpReachabilityMonitorLostEvent(ifName));
-    }
-};
diff --git a/core/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java b/core/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java
deleted file mode 100644
index 0ed8c1c..0000000
--- a/core/java/android/net/metrics/IpReachabilityMonitorMessageEvent.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class IpReachabilityMonitorMessageEvent extends IpConnectivityEvent
-        implements Parcelable {
-    public final String ifName;
-    public final String destination;
-    public final int msgType;
-    public final int nudState;
-
-    private IpReachabilityMonitorMessageEvent(String ifName, String destination, int msgType,
-            int nudState) {
-        this.ifName = ifName;
-        this.destination = destination;
-        this.msgType = msgType;
-        this.nudState = nudState;
-    }
-
-    private IpReachabilityMonitorMessageEvent(Parcel in) {
-        this.ifName = in.readString();
-        this.destination = in.readString();
-        this.msgType = in.readInt();
-        this.nudState = in.readInt();
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
-        out.writeString(destination);
-        out.writeInt(msgType);
-        out.writeInt(nudState);
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<IpReachabilityMonitorMessageEvent> CREATOR
-        = new Parcelable.Creator<IpReachabilityMonitorMessageEvent>() {
-        public IpReachabilityMonitorMessageEvent createFromParcel(Parcel in) {
-            return new IpReachabilityMonitorMessageEvent(in);
-        }
-
-        public IpReachabilityMonitorMessageEvent[] newArray(int size) {
-            return new IpReachabilityMonitorMessageEvent[size];
-        }
-    };
-
-    public static void logEvent(String ifName, String destination, int msgType, int nudState) {
-        logEvent(IPCE_IPRM_MESSAGE_RECEIVED,
-                new IpReachabilityMonitorMessageEvent(ifName, destination, msgType, nudState));
-    }
-};
diff --git a/core/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java b/core/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java
deleted file mode 100644
index a55c2b4..0000000
--- a/core/java/android/net/metrics/IpReachabilityMonitorProbeEvent.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 android.net.metrics;
-
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * {@hide}
- */
-@SystemApi
-public final class IpReachabilityMonitorProbeEvent extends IpConnectivityEvent
-        implements Parcelable {
-    public final String ifName;
-    public final String destination;
-    public final boolean success;
-
-    private IpReachabilityMonitorProbeEvent(String ifName, String destination, boolean success) {
-        this.ifName = ifName;
-        this.destination = destination;
-        this.success = success;
-    }
-
-    private IpReachabilityMonitorProbeEvent(Parcel in) {
-        this.ifName = in.readString();
-        this.destination = in.readString();
-        this.success = in.readByte() > 0 ? true : false;
-    }
-
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(ifName);
-        out.writeString(destination);
-        out.writeByte((byte)(success ? 1 : 0));
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<IpReachabilityMonitorProbeEvent> CREATOR
-        = new Parcelable.Creator<IpReachabilityMonitorProbeEvent>() {
-        public IpReachabilityMonitorProbeEvent createFromParcel(Parcel in) {
-            return new IpReachabilityMonitorProbeEvent(in);
-        }
-
-        public IpReachabilityMonitorProbeEvent[] newArray(int size) {
-            return new IpReachabilityMonitorProbeEvent[size];
-        }
-    };
-
-    public static void logEvent(String ifName, String destination, boolean success) {
-        logEvent(IPCE_IPRM_PROBE_RESULT,
-                new IpReachabilityMonitorProbeEvent(ifName, destination, success));
-    }
-};
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 16d90de..c285acb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1023,7 +1023,7 @@
     /**
      * Returns True if the device supports Sustained Performance Mode.
      * Applications Should check if the device supports this mode, before
-     * using {@link #SUSTAINED_PERFORMANCE_WAKE_LOCK}.
+     * using {@link android.view.Window#setSustainedPerformanceMode}.
      */
     public boolean isSustainedPerformanceModeSupported() {
         return mContext.getResources().getBoolean(
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index 71f0bd6..5d0ad55 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -778,6 +778,12 @@
 
         public PrintDocumentAdapterDelegate(Activity activity,
                 PrintDocumentAdapter documentAdapter) {
+            if (activity.isFinishing()) {
+                // The activity is already dead hence the onActivityDestroyed callback won't be
+                // triggered. Hence it is not save to print in this situation.
+                throw new IllegalStateException("Cannot start printing for finishing activity");
+            }
+
             mActivity = activity;
             mDocumentAdapter = documentAdapter;
             mHandler = new MyHandler(mActivity.getMainLooper());
diff --git a/core/java/android/printservice/CustomPrinterIconCallback.java b/core/java/android/printservice/CustomPrinterIconCallback.java
index 6b9d0d8..a1fbdab 100644
--- a/core/java/android/printservice/CustomPrinterIconCallback.java
+++ b/core/java/android/printservice/CustomPrinterIconCallback.java
@@ -27,7 +27,7 @@
 /**
  * Callback for {@link PrinterDiscoverySession#onRequestCustomPrinterIcon}.
  */
-public class CustomPrinterIconCallback {
+public final class CustomPrinterIconCallback {
     /** The printer the call back is for */
     private final @NonNull PrinterId mPrinterId;
     private final @NonNull IPrintServiceClient mObserver;
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
index 7a7ca23..3226f34 100644
--- a/core/java/android/printservice/PrintJob.java
+++ b/core/java/android/printservice/PrintJob.java
@@ -347,18 +347,15 @@
      * <p />
      * This overrides any previously set status set via {@link #setStatus(CharSequence)},
      * {@link #setStatus(int)}, {@link #block(String)}, or {@link #fail(String)},
-     * <p />
-     * To clear the status use {@link #setStatus(CharSequence) <code>setStatus(null)</code>}
      *
-     * @param status  The new status as a String resource.
+     * @param statusResId The new status as a String resource. If 0 the status will be empty.
      */
     @MainThread
-    public void setStatus(@StringRes int status) {
+    public void setStatus(@StringRes int statusResId) {
         PrintService.throwIfNotCalledOnMainThread();
-        Preconditions.checkArgument(status != 0, "status has to be != 0");
 
         try {
-            mPrintServiceClient.setStatusRes(mCachedInfo.getId(), status,
+            mPrintServiceClient.setStatusRes(mCachedInfo.getId(), statusResId,
                     mContext.getPackageName());
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error setting status for job: " + mCachedInfo.getId(), re);
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
index 7b9533d..4987e8b 100644
--- a/core/java/android/printservice/PrinterDiscoverySession.java
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -408,15 +408,15 @@
     public abstract void onStartPrinterStateTracking(@NonNull PrinterId printerId);
 
     /**
-     * Request the custom icon for a printer. Once the icon is available use
-     * {@link CustomPrinterIconCallback#onCustomPrinterIconLoaded} to send the data to the print
-     * service.
+     * Called by the system to request the custom icon for a printer. Once the icon is available the
+     * print services uses {@link CustomPrinterIconCallback#onCustomPrinterIconLoaded} to send the
+     * icon to the system.
      *
      * @param printerId The printer to icon belongs to.
-     * @param cancellationSignal Signal used to cancel the request
-     * @param callback Callback for returning the icon to the print spooler.
+     * @param cancellationSignal Signal used to cancel the request.
+     * @param callback Callback for returning the icon to the system.
      *
-     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon()
+     * @see android.print.PrinterInfo.Builder#setHasCustomPrinterIcon(boolean)
      */
     public void onRequestCustomPrinterIcon(@NonNull PrinterId printerId,
             @NonNull CancellationSignal cancellationSignal,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 97af8f4..1781d9d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -20619,6 +20619,12 @@
         }
     }
 
+    /**
+     * Updates the drag shadow for the ongoing drag and drop operation.
+     *
+     * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
+     * new drag shadow.
+     */
     public final void updateDragShadow(DragShadowBuilder shadowBuilder) {
         if (ViewDebug.DEBUG_DRAG) {
             Log.d(VIEW_LOG_TAG, "updateDragShadow");
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index 1b52146..27ffb8b 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -94,14 +94,14 @@
 
     private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
 
-    long mRawRealtime;
-    long mRawUptime;
-    long mBatteryRealtime;
-    long mBatteryUptime;
-    long mTypeBatteryRealtime;
-    long mTypeBatteryUptime;
-    long mBatteryTimeRemaining;
-    long mChargeTimeRemaining;
+    long mRawRealtimeUs;
+    long mRawUptimeUs;
+    long mBatteryRealtimeUs;
+    long mBatteryUptimeUs;
+    long mTypeBatteryRealtimeUs;
+    long mTypeBatteryUptimeUs;
+    long mBatteryTimeRemainingUs;
+    long mChargeTimeRemainingUs;
 
     private long mStatsPeriod = 0;
 
@@ -389,22 +389,22 @@
         mFlashlightPowerCalculator.reset();
 
         mStatsType = statsType;
-        mRawUptime = rawUptimeUs;
-        mRawRealtime = rawRealtimeUs;
-        mBatteryUptime = mStats.getBatteryUptime(rawUptimeUs);
-        mBatteryRealtime = mStats.getBatteryRealtime(rawRealtimeUs);
-        mTypeBatteryUptime = mStats.computeBatteryUptime(rawUptimeUs, mStatsType);
-        mTypeBatteryRealtime = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType);
-        mBatteryTimeRemaining = mStats.computeBatteryTimeRemaining(rawRealtimeUs);
-        mChargeTimeRemaining = mStats.computeChargeTimeRemaining(rawRealtimeUs);
+        mRawUptimeUs = rawUptimeUs;
+        mRawRealtimeUs = rawRealtimeUs;
+        mBatteryUptimeUs = mStats.getBatteryUptime(rawUptimeUs);
+        mBatteryRealtimeUs = mStats.getBatteryRealtime(rawRealtimeUs);
+        mTypeBatteryUptimeUs = mStats.computeBatteryUptime(rawUptimeUs, mStatsType);
+        mTypeBatteryRealtimeUs = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType);
+        mBatteryTimeRemainingUs = mStats.computeBatteryTimeRemaining(rawRealtimeUs);
+        mChargeTimeRemainingUs = mStats.computeChargeTimeRemaining(rawRealtimeUs);
 
         if (DEBUG) {
             Log.d(TAG, "Raw time: realtime=" + (rawRealtimeUs/1000) + " uptime="
                     + (rawUptimeUs/1000));
-            Log.d(TAG, "Battery time: realtime=" + (mBatteryRealtime/1000) + " uptime="
-                    + (mBatteryUptime/1000));
-            Log.d(TAG, "Battery type time: realtime=" + (mTypeBatteryRealtime/1000) + " uptime="
-                    + (mTypeBatteryUptime/1000));
+            Log.d(TAG, "Battery time: realtime=" + (mBatteryRealtimeUs /1000) + " uptime="
+                    + (mBatteryUptimeUs /1000));
+            Log.d(TAG, "Battery type time: realtime=" + (mTypeBatteryRealtimeUs /1000) + " uptime="
+                    + (mTypeBatteryUptimeUs /1000));
         }
         mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
                 * mPowerProfile.getBatteryCapacity()) / 100;
@@ -489,7 +489,7 @@
 
     private void processAppUsage(SparseArray<UserHandle> asUsers) {
         final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null);
-        mStatsPeriod = mTypeBatteryRealtime;
+        mStatsPeriod = mTypeBatteryRealtimeUs;
 
         BatterySipper osSipper = null;
         final SparseArray<? extends Uid> uidStats = mStats.getUidStats();
@@ -498,14 +498,14 @@
             final Uid u = uidStats.valueAt(iu);
             final BatterySipper app = new BatterySipper(BatterySipper.DrainType.APP, u, 0);
 
-            mCpuPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mWakelockPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mMobileRadioPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mWifiPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mBluetoothPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mSensorPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mCameraPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
-            mFlashlightPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
+            mCpuPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mWakelockPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mMobileRadioPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mWifiPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mBluetoothPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mSensorPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mCameraPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
+            mFlashlightPowerCalculator.calculateApp(app, u, mRawRealtimeUs, mRawUptimeUs, mStatsType);
 
             final double totalPower = app.sumPower();
             if (DEBUG && totalPower != 0) {
@@ -547,14 +547,14 @@
             // The device has probably been awake for longer than the screen on
             // time and application wake lock time would account for.  Assign
             // this remainder to the OS, if possible.
-            mWakelockPowerCalculator.calculateRemaining(osSipper, mStats, mRawRealtime,
-                                                        mRawUptime, mStatsType);
+            mWakelockPowerCalculator.calculateRemaining(osSipper, mStats, mRawRealtimeUs,
+                    mRawUptimeUs, mStatsType);
             osSipper.sumPower();
         }
     }
 
     private void addPhoneUsage() {
-        long phoneOnTimeMs = mStats.getPhoneOnTime(mRawRealtime, mStatsType) / 1000;
+        long phoneOnTimeMs = mStats.getPhoneOnTime(mRawRealtimeUs, mStatsType) / 1000;
         double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
                 * phoneOnTimeMs / (60*60*1000);
         if (phoneOnPower != 0) {
@@ -562,16 +562,19 @@
         }
     }
 
+    /**
+     * Screen power is the additional power the screen takes while the device is running.
+     */
     private void addScreenUsage() {
         double power = 0;
-        long screenOnTimeMs = mStats.getScreenOnTime(mRawRealtime, mStatsType) / 1000;
+        long screenOnTimeMs = mStats.getScreenOnTime(mRawRealtimeUs, mStatsType) / 1000;
         power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON);
         final double screenFullPower =
                 mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
         for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) {
             double screenBinPower = screenFullPower * (i + 0.5f)
                     / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
-            long brightnessTime = mStats.getScreenBrightnessTime(i, mRawRealtime, mStatsType)
+            long brightnessTime = mStats.getScreenBrightnessTime(i, mRawRealtimeUs, mStatsType)
                     / 1000;
             double p = screenBinPower*brightnessTime;
             if (DEBUG && p != 0) {
@@ -588,7 +591,7 @@
 
     private void addRadioUsage() {
         BatterySipper radio = new BatterySipper(BatterySipper.DrainType.CELL, null, 0);
-        mMobileRadioPowerCalculator.calculateRemaining(radio, mStats, mRawRealtime, mRawUptime,
+        mMobileRadioPowerCalculator.calculateRemaining(radio, mStats, mRawRealtimeUs, mRawUptimeUs,
                 mStatsType);
         radio.sumPower();
         if (radio.totalPowerMah > 0) {
@@ -606,16 +609,26 @@
         bs.sumPower();
     }
 
+    /**
+     * Calculate the baseline power usage for the device when it is in suspend and idle.
+     * The device is drawing POWER_CPU_IDLE power at its lowest power state.
+     * The device is drawing POWER_CPU_IDLE + POWER_CPU_AWAKE power when a wakelock is held.
+     */
     private void addIdleUsage() {
-        long idleTimeMs = (mTypeBatteryRealtime
-                - mStats.getScreenOnTime(mRawRealtime, mStatsType)) / 1000;
-        double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE))
-                / (60*60*1000);
-        if (DEBUG && idlePower != 0) {
-            Log.d(TAG, "Idle: time=" + idleTimeMs + " power=" + makemAh(idlePower));
+        final double suspendPowerMaMs = (mTypeBatteryRealtimeUs / 1000) *
+                mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE);
+        final double idlePowerMaMs = (mTypeBatteryUptimeUs / 1000) *
+                mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE);
+        final double totalPowerMah = (suspendPowerMaMs + idlePowerMaMs) / (60 * 60 * 1000);
+        if (DEBUG && totalPowerMah != 0) {
+            Log.d(TAG, "Suspend: time=" + (mTypeBatteryRealtimeUs / 1000)
+                    + " power=" + makemAh(suspendPowerMaMs / (60 * 60 * 1000)));
+            Log.d(TAG, "Idle: time=" + (mTypeBatteryUptimeUs / 1000)
+                    + " power=" + makemAh(idlePowerMaMs / (60 * 60 * 1000)));
         }
-        if (idlePower != 0) {
-            addEntry(BatterySipper.DrainType.IDLE, idleTimeMs, idlePower);
+
+        if (totalPowerMah != 0) {
+            addEntry(BatterySipper.DrainType.IDLE, mTypeBatteryRealtimeUs / 1000, totalPowerMah);
         }
     }
 
@@ -628,7 +641,7 @@
      */
     private void addWiFiUsage() {
         BatterySipper bs = new BatterySipper(DrainType.WIFI, null, 0);
-        mWifiPowerCalculator.calculateRemaining(bs, mStats, mRawRealtime, mRawUptime, mStatsType);
+        mWifiPowerCalculator.calculateRemaining(bs, mStats, mRawRealtimeUs, mRawUptimeUs, mStatsType);
         aggregateSippers(bs, mWifiSippers, "WIFI");
         if (bs.totalPowerMah > 0) {
             mUsageList.add(bs);
@@ -641,7 +654,7 @@
      */
     private void addBluetoothUsage() {
         BatterySipper bs = new BatterySipper(BatterySipper.DrainType.BLUETOOTH, null, 0);
-        mBluetoothPowerCalculator.calculateRemaining(bs, mStats, mRawRealtime, mRawUptime,
+        mBluetoothPowerCalculator.calculateRemaining(bs, mStats, mRawRealtimeUs, mRawUptimeUs,
                 mStatsType);
         aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
         if (bs.totalPowerMah > 0) {
@@ -709,10 +722,6 @@
         return mMaxDrainedPower;
     }
 
-    public long getBatteryTimeRemaining() { return mBatteryTimeRemaining; }
-
-    public long getChargeTimeRemaining() { return mChargeTimeRemaining; }
-
     public static byte[] readFully(FileInputStream stream) throws java.io.IOException {
         return readFully(stream, stream.available());
     }
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index d77b998..ea4575a 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -93,6 +93,8 @@
      * @hide
      */
     public static final native void disableBackgroundScheduling(boolean disable);
+
+    public static final native void setMaxThreads(int numThreads);
     
     static native final void handleGc();
     
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 79138b7..d217474 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -51,7 +51,7 @@
      * Power consumption when CPU is awake (when a wake lock is held).  This
      * should be 0 on devices that can go into full CPU power collapse even
      * when a wake lock is held.  Otherwise, this is the power consumption in
-     * addition to POWERR_CPU_IDLE due to a wake lock being held but with no
+     * addition to POWER_CPU_IDLE due to a wake lock being held but with no
      * CPU activity.
      */
     public static final String POWER_CPU_AWAKE = "cpu.awake";
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 3e45309..9d296fa 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -183,6 +183,9 @@
 
     @Override
     public void onRestoreFinished() {
-        mWallpaperHelper.onRestoreFinished();
+        // helper will be null following 'adb restore' or other full-data operation
+        if (mWallpaperHelper != null) {
+            mWallpaperHelper.onRestoreFinished();
+        }
     }
 }
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index abc6c4b..5559d48 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -917,6 +917,12 @@
     IPCThreadState::disableBackgroundScheduling(disable ? true : false);
 }
 
+static void android_os_BinderInternal_setMaxThreads(JNIEnv* env,
+        jobject clazz, jint maxThreads)
+{
+    ProcessState::self()->setThreadPoolMaxThreadCount(maxThreads);
+}
+
 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
 {
     ALOGV("Gc has executed, clearing binder ops");
@@ -930,6 +936,7 @@
     { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
     { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
     { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
+    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
     { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
 };
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6776d3b..2040d7d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -497,14 +497,14 @@
     <string name="bugreport_option_interactive_title">Interactive report</string>
     <!-- Summary in the bugreport dialog for the interactive workflow. [CHAR LIMIT=NONE] -->
     <string name="bugreport_option_interactive_summary">Use this under most circumstances.
-        It allows you to track progress of the report and enter more details about the problem.
+        It allows you to track progress of the report, enter more details about the problem, and take screenshots.
         It might omit some less-used sections that take a long time to report.</string>
     <!-- Title in the bugreport dialog for the full workflow. Should fit in one line. [CHAR LIMIT=30] -->
     <string name="bugreport_option_full_title">Full report</string>
     <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=NONE] -->
     <string name="bugreport_option_full_summary">Use this option for minimal system interference when
         your device is unresponsive or too slow, or when you need all report sections.
-        Does not take a screenshot or allow you to enter more details.</string>
+        Does not allow you to enter more details or take additional screenshots.</string>
     <!--  Toast message informing user in how many seconds a bugreport screenshot will be taken -->
     <plurals name="bugreport_countdown">
         <item quantity="one">Taking screenshot for bug report in <xliff:g id="number">%d</xliff:g> second.</item>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index ecdbe63..32fdb64 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -70,11 +70,7 @@
     }
 
     public boolean isDocumentEnabled(String docMimeType, int docFlags) {
-        if (isDirectory(docMimeType)) {
-            return true;
-        }
-
-        return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+        return true;
     }
 
     abstract void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch);
diff --git a/packages/SystemUI/res/layout/tv_pip_control_button.xml b/packages/SystemUI/res/layout/tv_pip_control_button.xml
index 0beeda1..f18a5da 100644
--- a/packages/SystemUI/res/layout/tv_pip_control_button.xml
+++ b/packages/SystemUI/res/layout/tv_pip_control_button.xml
@@ -38,5 +38,6 @@
         android:alpha="0"
         android:fontFamily="sans-serif"
         android:textSize="12sp"
-        android:textColor="#EEEEEE" />
+        android:textColor="#EEEEEE"
+        android:importantForAccessibility="no" />
 </merge>
diff --git a/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml b/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
index 1e464d8..4a67000 100644
--- a/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
+++ b/packages/SystemUI/res/layout/tv_pip_recents_overlay.xml
@@ -23,7 +23,7 @@
     <com.android.systemui.tv.pip.PipRecentsControlsView
         android:id="@+id/pip_controls"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent" />
+        android:layout_height="wrap_content" />
 
     <View
         android:id="@+id/recents"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ea55ac2..981b2dd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -381,6 +381,9 @@
     <!-- Content description of the battery level icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_battery_level">Battery <xliff:g id="number">%d</xliff:g> percent.</string>
 
+    <!-- Content description of the battery level icon for accessibility while the device is charging (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_battery_level_charging">Battery charging, <xliff:g id="battery_percentage">%d</xliff:g> percent.</string>
+
     <!-- Content description of the button for showing a settings panel in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_settings_button">System settings.</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 0bf81e9..d8b95cc 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -89,7 +89,8 @@
     @Override
     public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
         setContentDescription(
-                getContext().getString(R.string.accessibility_battery_level, level));
+                getContext().getString(charging ? R.string.accessibility_battery_level_charging
+                        : R.string.accessibility_battery_level, level));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
index 5e35d76..851ab77 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
@@ -67,7 +67,7 @@
         // If the phone is rotated to landscape, the calculations would be wrong if xdpi and ydpi
         // were to be used separately. Due negligible differences in xdpi and ydpi we can just
         // take the average.
-        // TODO: make this respect DPI changes.
+        // Note that xdpi and ydpi are the physical pixels per inch and are not affected by scaling.
         mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f;
         mClassifierData = new ClassifierData(mDpi);
         mHistoryEvaluator = new HistoryEvaluator();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index 7378102..4a8abf7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -26,6 +26,7 @@
 import android.view.View;
 import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout.LayoutParams;
 
 import com.android.systemui.R;
@@ -131,6 +132,7 @@
                 @Override
                 public void onRecentsFocused() {
                     mRecentsView.requestFocus();
+                    mRecentsView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
                 }
             };
     private final View.OnFocusChangeListener mPipViewFocusChangeListener =
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 44a167b..9fd4b05 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -32,7 +32,6 @@
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.util.AttributeSet;
-import android.util.MutableInt;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.GestureDetector;
@@ -105,6 +104,8 @@
             new PathInterpolator(0.5f, 1f, 0.5f, 1f);
     private static final PathInterpolator DIM_INTERPOLATOR =
             new PathInterpolator(.23f, .87f, .52f, -0.11f);
+    private static final Interpolator IME_ADJUST_INTERPOLATOR =
+            new PathInterpolator(0.2f, 0f, 0.1f, 1f);
 
     private DividerHandleView mHandle;
     private View mBackground;
@@ -701,7 +702,7 @@
             resetBackground();
         } else if (mDockSide == WindowManager.DOCKED_TOP) {
             mBackground.setPivotY(0);
-            mBackground.setScaleY(MINIMIZE_DOCK_SCALE);
+            mBackground.setScaleY(ADJUSTED_FOR_IME_SCALE);
         }
         mAdjustedForIme = adjustedForIme;
     }
@@ -709,20 +710,20 @@
     public void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
         updateDockSide();
         mHandle.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .setInterpolator(IME_ADJUST_INTERPOLATOR)
                 .setDuration(animDuration)
                 .alpha(adjustedForIme ? 0f : 1f)
                 .start();
         if (mDockSide == WindowManager.DOCKED_TOP) {
             mBackground.setPivotY(0);
             mBackground.animate()
-                    .scaleY(adjustedForIme ? MINIMIZE_DOCK_SCALE : 1f);
+                    .scaleY(adjustedForIme ? ADJUSTED_FOR_IME_SCALE : 1f);
         }
         if (!adjustedForIme) {
             mBackground.animate().withEndAction(mResetBackgroundRunnable);
         }
         mBackground.animate()
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .setInterpolator(IME_ADJUST_INTERPOLATOR)
                 .setDuration(animDuration)
                 .start();
         mAdjustedForIme = adjustedForIme;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 3293964..66152fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -61,6 +61,7 @@
     private Calendar mCalendar;
     private String mClockFormatString;
     private SimpleDateFormat mClockFormat;
+    private SimpleDateFormat mContentDescriptionFormat;
     private Locale mLocale;
 
     private static final int AM_PM_STYLE_NORMAL  = 0;
@@ -158,6 +159,7 @@
         if (mDemoMode) return;
         mCalendar.setTimeInMillis(System.currentTimeMillis());
         setText(getSmallTime());
+        setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime()));
     }
 
     @Override
@@ -207,6 +209,7 @@
                 ? is24 ? d.timeFormat_Hms : d.timeFormat_hms
                 : is24 ? d.timeFormat_Hm : d.timeFormat_hm;
         if (!format.equals(mClockFormatString)) {
+            mContentDescriptionFormat = new SimpleDateFormat(format);
             /*
              * Search for an unquoted "a" in the format string, so we can
              * add dummy characters around it to let us find it again after
@@ -295,6 +298,7 @@
                 mCalendar.set(Calendar.MINUTE, mm);
             }
             setText(getSmallTime());
+            setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime()));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java
index c65415e..bcf2f67 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipControlButtonView.java
@@ -92,8 +92,8 @@
         TypedArray typedArray =
             context.obtainStyledAttributes(attrs, values, defStyleAttr, defStyleRes);
 
-        mButtonImageView.setImageDrawable(typedArray.getDrawable(0));
-        mDescriptionTextView.setText(typedArray.getText(1));
+        setImageResource(typedArray.getResourceId(0, 0));
+        setText(typedArray.getResourceId(1, 0));
 
         typedArray.recycle();
     }
@@ -132,6 +132,7 @@
      * Sets the text for description the with the given resource id.
      */
     public void setText(int resId) {
+        mButtonImageView.setContentDescription(getContext().getString(resId));
         mDescriptionTextView.setText(resId);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 5febb9b..d7efca7 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -276,9 +276,6 @@
     void movePipToFullscreen() {
         mState = STATE_NO_PIP;
         mPipTaskId = TASK_ID_NO_PIP;
-        for (int i = mListeners.size() - 1; i >= 0; --i) {
-            mListeners.get(i).onMoveToFullscreen();
-        }
         resizePinnedStack(mState);
     }
 
@@ -638,6 +635,11 @@
         public void onPinnedStackAnimationEnded() {
             if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
             switch (mState) {
+                case STATE_NO_PIP:
+                    for (int i = mListeners.size() - 1; i >= 0; --i) {
+                        mListeners.get(i).onMoveToFullscreen();
+                    }
+                    break;
                 case STATE_PIP_OVERLAY:
                     if (!mPipRecentsOverlayManager.isRecentsShown()) {
                         showPipOverlay();
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
index d75561b..5ad0bf6 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java
@@ -21,6 +21,7 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManager;
 
@@ -141,6 +142,7 @@
 
         mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
         mPipControlsView.requestFocus();
+        mPipControlsView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
         mPipControlsView.startFocusGainAnimation();
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 4d7f82d..2a7d945 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -20,6 +20,7 @@
 import android.os.PowerManager;
 import android.util.Pools.SimplePool;
 import android.util.Slog;
+import android.util.SparseBooleanArray;
 import android.view.Choreographer;
 import android.view.InputDevice;
 import android.view.InputEvent;
@@ -637,10 +638,10 @@
     }
 
     /**
-     * Keeps state of stream of events from a keyboard device.
+     * Keeps state of streams of events from all keyboard devices.
      */
     private static class KeyboardEventStreamState extends EventStreamState {
-        private boolean mEventSequenceStarted;
+        private SparseBooleanArray mEventSequenceStartedMap = new SparseBooleanArray();
 
         public KeyboardEventStreamState() {
             reset();
@@ -649,17 +650,35 @@
         @Override
         final public void reset() {
             super.reset();
-            mEventSequenceStarted = false;
+            mEventSequenceStartedMap.clear();
         }
 
+        /*
+         * Key events from different devices may be interleaved. For example, the volume up and
+         * down keys can come from different device IDs.
+         */
+        @Override
+        public boolean updateDeviceId(int deviceId) {
+            return false;
+        }
+
+        // We manage all device ids simultaneously; there is no concept of validity.
+        @Override
+        public boolean deviceIdValid() {
+            return true;
+        }
+
+
         @Override
         final public boolean shouldProcessKeyEvent(KeyEvent event) {
-            // Wait for a down key event to start processing.
-            if (mEventSequenceStarted) {
+            // For each keyboard device, wait for a down event from a device to start processing
+            int deviceId = event.getDeviceId();
+            if (mEventSequenceStartedMap.get(deviceId, false)) {
                 return true;
             }
-            mEventSequenceStarted = event.getAction() == KeyEvent.ACTION_DOWN;
-            return mEventSequenceStarted;
+            boolean shouldProcess = event.getAction() == KeyEvent.ACTION_DOWN;
+            mEventSequenceStartedMap.put(deviceId, shouldProcess);
+            return shouldProcess;
         }
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 9c93f2c..3ffdb95 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -582,7 +582,7 @@
                 null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/,
                 0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/,
                 0 /*realCallingPid*/, 0 /*realCallingUid*/, 0 /*startFlags*/, null /*options*/,
-                false /*ignoreTargetSecurity*/, false /*componentSpecified*/,  null /*outActivity*/,
+                false /*ignoreTargetSecurity*/, false /*componentSpecified*/, null /*outActivity*/,
                 null /*container*/, null /*inTask*/);
         if (mSupervisor.inResumeTopActivity) {
             // If we are in resume section already, home activity will be initialized, but not
@@ -1432,7 +1432,7 @@
                             == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
                 if (!willClearTask) {
                     final ActivityStack launchStack = getLaunchStack(
-                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, true);
+                            mStartActivity, mLaunchFlags, mStartActivity.task, mOptions);
                     if (launchStack == null || launchStack == mTargetStack) {
                         // We only want to move to the front, if we aren't going to launch on a
                         // different stack. If we launch on a different stack, we will put the
@@ -1606,8 +1606,11 @@
         // We only want to allow changing stack if the target task is not the top one,
         // otherwise we would move the launching task to the other side, rather than show
         // two side by side.
-        final boolean launchToSideAllowed = sourceTask.stack.topTask() != sourceTask;
-        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task, mOptions, launchToSideAllowed);
+        final boolean moveStackAllowed = sourceTask.stack.topTask() != sourceTask;
+        if (moveStackAllowed) {
+            mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, mStartActivity.task,
+                    mOptions);
+        }
 
         if (mTargetStack == null) {
             mTargetStack = sourceTask.stack;
@@ -1780,7 +1783,7 @@
             return mSupervisor.mHomeStack;
         }
 
-        ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions, true);
+        ActivityStack stack = getLaunchStack(r, launchFlags, task, aOptions);
         if (stack != null) {
             return stack;
         }
@@ -1845,7 +1848,7 @@
     }
 
     private ActivityStack getLaunchStack(ActivityRecord r, int launchFlags, TaskRecord task,
-            ActivityOptions aOptions, boolean launchToSideAllowed) {
+            ActivityOptions aOptions) {
         final int launchStackId =
                 (aOptions != null) ? aOptions.getLaunchStackId() : INVALID_STACK_ID;
 
@@ -1857,7 +1860,7 @@
             return mSupervisor.getStack(FULLSCREEN_WORKSPACE_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
         }
 
-        if (!launchToSideAllowed || (launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
+        if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0) {
             return null;
         }
         // Otherwise handle adjacent launch.
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index a2472ac..48fecd5 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -17,8 +17,6 @@
 package com.android.server.am;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Debug;
@@ -519,7 +517,7 @@
         if (DEBUG) Slog.d(TAG, "removeObsoleteFiles: persistentTaskIds=" + persistentTaskIds +
                 " files=" + files);
         if (files == null) {
-            Slog.e(TAG, "File error accessing recents directory (too many files open?).");
+            Slog.e(TAG, "File error accessing recents directory (directory doesn't exist?).");
             return;
         }
         for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) {
@@ -597,15 +595,12 @@
     }
 
     static File getUserImagesDir(int userId) {
-        File userImagesDir = new File(Environment.getDataSystemCeDirectory(userId), IMAGES_DIRNAME);
+        return new File(Environment.getDataSystemCeDirectory(userId), IMAGES_DIRNAME);
+    }
 
-        if (!userImagesDir.exists()) {
-            if (!userImagesDir.mkdir()) {
-                Slog.e(TAG, "Failure creating images directory for user " + userId + ": "
-                        + userImagesDir);
-            }
-        }
-        return userImagesDir;
+    private static boolean createParentDirectory(String filePath) {
+        File parentDir = new File(filePath).getParentFile();
+        return parentDir.exists() || parentDir.mkdirs();
     }
 
     private class LazyTaskWriterThread extends Thread {
@@ -693,6 +688,10 @@
                 if (item instanceof ImageWriteQueueItem) {
                     ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
                     final String filePath = imageWriteQueueItem.mFilePath;
+                    if (!createParentDirectory(filePath)) {
+                        Slog.e(TAG, "Error while creating images directory for file: " + filePath);
+                        continue;
+                    }
                     final Bitmap bitmap = imageWriteQueueItem.mImage;
                     if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath);
                     FileOutputStream imageFile = null;
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index debb382..1f44b29 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -149,11 +149,15 @@
         public void onAnimationEnd(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
                     + " mMoveToFullScreen=" + mMoveToFullScreen + " mWillReplace=" + mWillReplace);
-
-            finishAnimation();
             if (mMoveToFullScreen && !mWillReplace) {
                 mTarget.moveToFullscreen();
             }
+
+            // If we finish the animation before we move the target to fullscreen,
+            // recents may close itself and we may try and resume the previous
+            // fullscreen app leading to churn and flicker after we then move
+            // our target to fullscreen.
+            finishAnimation();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9994af3..6ff09b1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1805,6 +1805,16 @@
         return true;
     }
 
+    private static boolean excludeWindowTypeFromTapOutTask(int windowType) {
+        switch (windowType) {
+            case TYPE_STATUS_BAR:
+            case TYPE_NAVIGATION_BAR:
+            case TYPE_INPUT_METHOD_DIALOG:
+                return true;
+        }
+        return false;
+    }
+
     public int addWindow(Session session, IWindow client, int seq,
             WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
             Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
@@ -2003,7 +2013,7 @@
 
             res = WindowManagerGlobal.ADD_OKAY;
 
-            if (type == TYPE_STATUS_BAR || type == TYPE_NAVIGATION_BAR) {
+            if (excludeWindowTypeFromTapOutTask(type)) {
                 displayContent.mTapExcludedWindows.add(win);
             }
 
@@ -2395,7 +2405,7 @@
         }
 
         final int type = win.mAttrs.type;
-        if (type == TYPE_STATUS_BAR || type == TYPE_NAVIGATION_BAR) {
+        if (excludeWindowTypeFromTapOutTask(type)) {
             final DisplayContent displaycontent = win.getDisplayContent();
             displaycontent.mTapExcludedWindows.remove(win);
         }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8c2f559..9f2ca59 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -165,6 +165,10 @@
     private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
     private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map";
 
+    // maximum number of binder threads used for system_server
+    // will be higher than the system default
+    private static final int sMaxBinderThreads = 31;
+
     /**
      * Default theme used by the system context. This is used to style
      * system-provided dialogs, such as the Power Off dialog, and other
@@ -285,6 +289,9 @@
             // Ensure binder calls into the system always run at foreground priority.
             BinderInternal.disableBackgroundScheduling(true);
 
+            // Increase the number of binder threads in system_server
+            BinderInternal.setMaxThreads(sMaxBinderThreads);
+
             // Prepare the main looper thread (this thread).
             android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index c8dbe02..27600a7 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -24,9 +24,7 @@
 import android.net.LinkProperties.ProvisioningChange;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
-import android.net.metrics.IpReachabilityMonitorMessageEvent;
-import android.net.metrics.IpReachabilityMonitorProbeEvent;
-import android.net.metrics.IpReachabilityMonitorLostEvent;
+import android.net.metrics.IpReachabilityEvent;
 import android.net.netlink.NetlinkConstants;
 import android.net.netlink.NetlinkErrorMessage;
 import android.net.netlink.NetlinkMessage;
@@ -168,47 +166,54 @@
      * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
      * for the given IP address on the specified interface index.
      *
-     * @return true, if the request was successfully passed to the kernel; false otherwise.
+     * @return 0 if the request was successfully passed to the kernel; otherwise return
+     *         a non-zero error code.
      */
-    public static boolean probeNeighbor(int ifIndex, InetAddress ip) {
-        final long IO_TIMEOUT = 300L;
+    private static int probeNeighbor(int ifIndex, InetAddress ip) {
         final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
         if (DBG) { Log.d(TAG, msgSnippet); }
 
         final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
                 1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
-        boolean returnValue = false;
 
+        int errno = -OsConstants.EPROTO;
         try (NetlinkSocket nlSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE)) {
+            final long IO_TIMEOUT = 300L;
             nlSocket.connectToKernel();
             nlSocket.sendMessage(msg, 0, msg.length, IO_TIMEOUT);
             final ByteBuffer bytes = nlSocket.recvMessage(IO_TIMEOUT);
+            // recvMessage() guaranteed to not return null if it did not throw.
             final NetlinkMessage response = NetlinkMessage.parse(bytes);
             if (response != null && response instanceof NetlinkErrorMessage &&
-                    (((NetlinkErrorMessage) response).getNlMsgError() != null) &&
-                    (((NetlinkErrorMessage) response).getNlMsgError().error == 0)) {
-                returnValue = true;
-            } else {
-                String errmsg;
-                if (bytes == null) {
-                    errmsg = "null recvMessage";
-                } else if (response == null) {
-                    bytes.position(0);
-                    errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
-                } else {
+                    (((NetlinkErrorMessage) response).getNlMsgError() != null)) {
+                errno = ((NetlinkErrorMessage) response).getNlMsgError().error;
+                if (errno != 0) {
                     // TODO: consider ignoring EINVAL (-22), which appears to be
                     // normal when probing a neighbor for which the kernel does
                     // not already have / no longer has a link layer address.
+                    Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + response.toString());
+                }
+            } else {
+                String errmsg;
+                if (response == null) {
+                    bytes.position(0);
+                    errmsg = "raw bytes: " + NetlinkConstants.hexify(bytes);
+                } else {
                     errmsg = response.toString();
                 }
                 Log.e(TAG, "Error " + msgSnippet + ", errmsg=" + errmsg);
             }
-        } catch (ErrnoException | InterruptedIOException | SocketException e) {
-            Log.d(TAG, "Error " + msgSnippet, e);
+        } catch (ErrnoException e) {
+            Log.e(TAG, "Error " + msgSnippet, e);
+            errno = -e.errno;
+        } catch (InterruptedIOException e) {
+            Log.e(TAG, "Error " + msgSnippet, e);
+            errno = -OsConstants.ETIMEDOUT;
+        } catch (SocketException e) {
+            Log.e(TAG, "Error " + msgSnippet, e);
+            errno = -OsConstants.EIO;
         }
-        IpReachabilityMonitorProbeEvent.logEvent("ifindex-" + ifIndex, ip.getHostAddress(),
-                returnValue);
-        return returnValue;
+        return errno;
     }
 
     public IpReachabilityMonitor(Context context, String ifName, Callback callback)
@@ -354,7 +359,7 @@
         }
 
         if (delta == ProvisioningChange.LOST_PROVISIONING) {
-            IpReachabilityMonitorLostEvent.logEvent(mInterfaceName);
+            IpReachabilityEvent.logProvisioningLost(mInterfaceName);
             final String logMsg = "FAILURE: LOST_PROVISIONING, " + msg;
             Log.w(TAG, logMsg);
             if (mCallback != null) {
@@ -362,6 +367,8 @@
                 // an InetAddress argument.
                 mCallback.notifyLost(ip, logMsg);
             }
+        } else {
+            IpReachabilityEvent.logNudFailed(mInterfaceName);
         }
     }
 
@@ -385,7 +392,8 @@
             if (!stillRunning()) {
                 break;
             }
-            probeNeighbor(mInterfaceIndex, target);
+            final int returnValue = probeNeighbor(mInterfaceIndex, target);
+            IpReachabilityEvent.logProbeEvent(mInterfaceName, returnValue);
         }
     }
 
@@ -523,8 +531,6 @@
 
             final short msgType = neighMsg.getHeader().nlmsg_type;
             final short nudState = ndMsg.ndm_state;
-            IpReachabilityMonitorMessageEvent.logEvent(mInterfaceName,
-                    destination.getHostAddress(), msgType, nudState);
             final String eventMsg = "NeighborEvent{"
                     + "elapsedMs=" + whenMs + ", "
                     + destination.getHostAddress() + ", "
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 1e9db18..3f9da4c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -183,11 +183,11 @@
         try {
             if (mActiveSession == null || token != mActiveSession.mToken) {
                 Slog.w(TAG, "startVoiceActivity does not match active session");
-                return ActivityManager.START_CANCELED;
+                return ActivityManager.START_VOICE_NOT_ACTIVE_SESSION;
             }
             if (!mActiveSession.mShown) {
                 Slog.w(TAG, "startVoiceActivity not allowed on hidden session");
-                return ActivityManager.START_CANCELED;
+                return ActivityManager.START_VOICE_HIDDEN_SESSION;
             }
             intent = new Intent(intent);
             intent.addCategory(Intent.CATEGORY_VOICE);
diff --git a/telephony/java/android/telephony/ModemActivityInfo.java b/telephony/java/android/telephony/ModemActivityInfo.java
index 84883d8..03ce2d8 100644
--- a/telephony/java/android/telephony/ModemActivityInfo.java
+++ b/telephony/java/android/telephony/ModemActivityInfo.java
@@ -151,12 +151,24 @@
      * @return if the record is valid
      */
     public boolean isValid() {
-        int totalTxTimeMs = 0;
-        int txTime [] = getTxTimeMillis();
-        for (int i = 0; i < TX_POWER_LEVELS; i++) {
-            totalTxTimeMs += txTime[i];
+        for (int txVal : getTxTimeMillis()) {
+            if(txVal < 0) {
+                return false;
+            }
         }
-        return ((getIdleTimeMillis() >= 0) && (totalTxTimeMs >= 0)
-                && (getSleepTimeMillis() >= 0) && (getIdleTimeMillis() >= 0));
+
+        return ((getIdleTimeMillis() >= 0) && (getSleepTimeMillis() >= 0)
+                && (getRxTimeMillis() >= 0) && (getEnergyUsed() >= 0) && !isEmpty());
+    }
+
+    private boolean isEmpty() {
+        for (int txVal : getTxTimeMillis()) {
+            if(txVal != 0) {
+                return false;
+            }
+        }
+
+        return ((getIdleTimeMillis() == 0) && (getSleepTimeMillis() == 0)
+                && (getRxTimeMillis() == 0) && (getEnergyUsed() == 0));
     }
 }