Merge "Clear active requests on switching voice interactor" into nyc-dev
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index bb2cc95..e60712a 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -465,20 +465,18 @@
         final String zip = mIncludeCode ? TextUtils.join(File.pathSeparator, zipPaths) : "";
         final boolean isBundledApp = mApplicationInfo.isSystemApp()
                 && !mApplicationInfo.isUpdatedSystemApp();
-        String libraryPermittedPath = mDataDir;
+
+        // Apps are allowed to open any native library under /data
+        // TODO (dimitry):This is something which could be limited to apps own directory
+        // later on but currently there are number of apps relying on this.
+        // (see http://b/27588281 and http://b/26954419 for examples)
+        String libraryPermittedPath = "/data";
         if (isBundledApp) {
             // This is necessary to grant bundled apps access to
             // libraries located in subdirectories of /system/lib
             libraryPermittedPath += File.pathSeparator +
                                     System.getProperty("java.library.path");
         }
-        // DO NOT SHIP: this is a workaround for apps loading native libraries
-        // provided by 3rd party apps using absolute path instead of corresponding
-        // classloader; see http://b/26954419 for example.
-        if (mApplicationInfo.targetSdkVersion <= 23) {
-            libraryPermittedPath += File.pathSeparator + "/data/app";
-        }
-        // -----------------------------------------------------------------------------
 
         final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
 
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 58630b0..f71cfe9 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -44,9 +44,9 @@
 /**
  * Representation of a clipped data on the clipboard.
  *
- * <p>ClippedData is a complex type containing one or Item instances,
+ * <p>ClipData is a complex type containing one or more Item instances,
  * each of which can hold one or more representations of an item of data.
- * For display to the user, it also has a label and iconic representation.</p>
+ * For display to the user, it also has a label.</p>
  *
  * <p>A ClipData contains a {@link ClipDescription}, which describes
  * important meta-data about the clip.  In particular, its
@@ -71,7 +71,7 @@
  * <a name="ImplementingPaste"></a>
  * <h3>Implementing Paste or Drop</h3>
  *
- * <p>To implement a paste or drop of a ClippedData object into an application,
+ * <p>To implement a paste or drop of a ClipData object into an application,
  * the application must correctly interpret the data for its use.  If the {@link Item}
  * it contains is simple text or an Intent, there is little to be done: text
  * can only be interpreted as text, and an Intent will typically be used for
@@ -85,7 +85,7 @@
  * since any clip item can always be converted to a string.
  *
  * <p>More complicated exchanges will be done through URIs, in particular
- * "content:" URIs.  A content URI allows the recipient of a ClippedData item
+ * "content:" URIs.  A content URI allows the recipient of a ClipData item
  * to interact closely with the ContentProvider holding the data in order to
  * negotiate the transfer of that data.  The clip must also be filled in with
  * the available MIME types; {@link #newUri(ContentResolver, CharSequence, Uri)}
@@ -116,7 +116,7 @@
  * <a name="ImplementingCopy"></a>
  * <h3>Implementing Copy or Drag</h3>
  *
- * <p>To be the source of a clip, the application must construct a ClippedData
+ * <p>To be the source of a clip, the application must construct a ClipData
  * object that any recipient can interpret best for their context.  If the clip
  * is to contain a simple text, Intent, or URI, this is easy: an {@link Item}
  * containing the appropriate data type can be constructed and used.
@@ -163,13 +163,13 @@
         ClipDescription.MIMETYPE_TEXT_INTENT };
 
     final ClipDescription mClipDescription;
-    
+
     final Bitmap mIcon;
 
     final ArrayList<Item> mItems;
 
     /**
-     * Description of a single item in a ClippedData.
+     * Description of a single item in a ClipData.
      *
      * <p>The types than an individual item can currently contain are:</p>
      *
@@ -351,7 +351,7 @@
 
                 } catch (IOException e) {
                     // Something bad has happened.
-                    Log.w("ClippedData", "Failure loading text", e);
+                    Log.w("ClipData", "Failure loading text", e);
                     return e.toString();
 
                 } finally {
@@ -534,7 +534,7 @@
 
                     } catch (IOException e) {
                         // Something bad has happened.
-                        Log.w("ClippedData", "Failure loading text", e);
+                        Log.w("ClipData", "Failure loading text", e);
                         return Html.escapeHtml(e.toString());
 
                     } finally {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 959b309..a4bd8eb 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1158,7 +1158,8 @@
         public short batteryTemperature;
         public char batteryVoltage;
 
-        public int batteryChargeCoulombs;
+        // The charge of the battery in micro-Ampere-hours.
+        public int batteryChargeUAh;
         
         // Constants from SCREEN_BRIGHTNESS_*
         public static final int STATE_BRIGHTNESS_SHIFT = 0;
@@ -1356,7 +1357,7 @@
             bat = (((int)batteryTemperature)&0xffff)
                     | ((((int)batteryVoltage)<<16)&0xffff0000);
             dest.writeInt(bat);
-            dest.writeInt(batteryChargeCoulombs);
+            dest.writeInt(batteryChargeUAh);
             dest.writeInt(states);
             dest.writeInt(states2);
             if (wakelockTag != null) {
@@ -1385,7 +1386,7 @@
             int bat2 = src.readInt();
             batteryTemperature = (short)(bat2&0xffff);
             batteryVoltage = (char)((bat2>>16)&0xffff);
-            batteryChargeCoulombs = src.readInt();
+            batteryChargeUAh = src.readInt();
             states = src.readInt();
             states2 = src.readInt();
             if ((bat&0x10000000) != 0) {
@@ -1425,7 +1426,7 @@
             batteryPlugType = 0;
             batteryTemperature = 0;
             batteryVoltage = 0;
-            batteryChargeCoulombs = 0;
+            batteryChargeUAh = 0;
             states = 0;
             states2 = 0;
             wakelockTag = null;
@@ -1453,7 +1454,7 @@
             batteryPlugType = o.batteryPlugType;
             batteryTemperature = o.batteryTemperature;
             batteryVoltage = o.batteryVoltage;
-            batteryChargeCoulombs = o.batteryChargeCoulombs;
+            batteryChargeUAh = o.batteryChargeUAh;
             states = o.states;
             states2 = o.states2;
             if (o.wakelockTag != null) {
@@ -1485,7 +1486,7 @@
                     && batteryPlugType == o.batteryPlugType
                     && batteryTemperature == o.batteryTemperature
                     && batteryVoltage == o.batteryVoltage
-                    && batteryChargeCoulombs == o.batteryChargeCoulombs
+                    && batteryChargeUAh == o.batteryChargeUAh
                     && states == o.states
                     && states2 == o.states2
                     && currentTime == o.currentTime;
@@ -4536,7 +4537,7 @@
         int oldPlug = -1;
         int oldTemp = -1;
         int oldVolt = -1;
-        int oldCharge = -1;
+        int oldChargeMAh = -1;
         long lastTime = -1;
 
         void reset() {
@@ -4547,7 +4548,7 @@
             oldPlug = -1;
             oldTemp = -1;
             oldVolt = -1;
-            oldCharge = -1;
+            oldChargeMAh = -1;
         }
 
         public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
@@ -4709,10 +4710,11 @@
                     pw.print(checkin ? ",Bv=" : " volt=");
                     pw.print(oldVolt);
                 }
-                if (oldCharge != rec.batteryChargeCoulombs) {
-                    oldCharge = rec.batteryChargeCoulombs;
+                final int chargeMAh = rec.batteryChargeUAh / 1000;
+                if (oldChargeMAh != chargeMAh) {
+                    oldChargeMAh = chargeMAh;
                     pw.print(checkin ? ",Bcc=" : " charge=");
-                    pw.print(oldCharge);
+                    pw.print(oldChargeMAh);
                 }
                 printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
                         HISTORY_STATE_DESCRIPTIONS, !checkin);
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 0221b66..2913128 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -143,8 +143,18 @@
      * Returns true if this notification is part of a group.
      */
     public boolean isGroup() {
-        if (overrideGroupKey != null || getNotification().getGroup() != null
-                || getNotification().getSortKey() != null) {
+        if (overrideGroupKey != null || isAppGroup()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if application asked that this notification be part of a group.
+     * @hide
+     */
+    public boolean isAppGroup() {
+        if (getNotification().getGroup() != null || getNotification().getSortKey() != null) {
             return true;
         }
         return false;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 3f7bbdf..6cf8cd1 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5473,6 +5473,14 @@
 
     @Override
     public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
+        return getChildVisibleRect(child, r, offset, false);
+    }
+
+    /**
+     * @hide
+     */
+    public boolean getChildVisibleRect(
+            View child, Rect r, android.graphics.Point offset, boolean forceParentCheck) {
         // It doesn't make a whole lot of sense to call this on a view that isn't attached,
         // but for some simple tests it can be useful. If we don't have attach info this
         // will allocate memory.
@@ -5512,20 +5520,22 @@
             rectIsVisible = rect.intersect(0, 0, width, height);
         }
 
-        if (rectIsVisible && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
+        if ((forceParentCheck || rectIsVisible)
+                && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
             // Clip to padding.
             rectIsVisible = rect.intersect(mPaddingLeft, mPaddingTop,
                     width - mPaddingRight, height - mPaddingBottom);
         }
 
-        if (rectIsVisible && mClipBounds != null) {
+        if ((forceParentCheck || rectIsVisible) && mClipBounds != null) {
             // Clip to clipBounds.
             rectIsVisible = rect.intersect(mClipBounds.left, mClipBounds.top, mClipBounds.right,
                     mClipBounds.bottom);
         }
         r.set((int) Math.floor(rect.left), (int) Math.floor(rect.top),
                 (int) Math.ceil(rect.right), (int) Math.ceil(rect.bottom));
-        if (rectIsVisible && mParent != null) {
+
+        if ((forceParentCheck || rectIsVisible) && mParent != null) {
             rectIsVisible = mParent.getChildVisibleRect(this, r, offset);
         }
         return rectIsVisible;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 26697f9..a0843c7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7311,7 +7311,7 @@
         // If we have a fixed width, we can just swap in a new text layout
         // if the text height stays the same or if the view height is fixed.
 
-        if (((mLayoutParams.width != LayoutParams.WRAP_CONTENT && mLayoutParams.width != 0) ||
+        if ((mLayoutParams.width != LayoutParams.WRAP_CONTENT ||
                 (mMaxWidthMode == mMinWidthMode && mMaxWidth == mMinWidth)) &&
                 (mHint == null || mHintLayout != null) &&
                 (mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight() > 0)) {
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 42b89d5..44e072d 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -123,7 +123,7 @@
     void noteNetworkStatsEnabled();
     void noteDeviceIdleMode(int mode, String activeReason, int activeUid);
     void setBatteryState(int status, int health, int plugType, int level, int temp, int volt,
-            int chargeCount);
+            int chargeUAh);
     long getAwakeTimeBattery();
     long getAwakeTimePlugged();
 
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 654a4f1..9fdc9c4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2185,8 +2185,8 @@
     static final int DELTA_WAKELOCK_FLAG                    = 0x00400000;
     // Flag in delta int: contains an event description.
     static final int DELTA_EVENT_FLAG                       = 0x00800000;
-    // Flag in delta int: contains a coulomb charge count.
-    static final int DELTA_BATTERY_CHARGE_COULOMBS_FLAG     = 0x01000000;
+    // Flag in delta int: contains the battery charge count in uAh.
+    static final int DELTA_BATTERY_CHARGE_FLAG              = 0x01000000;
     // These upper bits are the frequently changing state bits.
     static final int DELTA_STATE_MASK                       = 0xfe000000;
 
@@ -2250,10 +2250,9 @@
             firstToken |= DELTA_EVENT_FLAG;
         }
 
-        final boolean batteryChargeCoulombsChanged = cur.batteryChargeCoulombs
-                != last.batteryChargeCoulombs;
-        if (batteryChargeCoulombsChanged) {
-            firstToken |= DELTA_BATTERY_CHARGE_COULOMBS_FLAG;
+        final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh;
+        if (batteryChargeChanged) {
+            firstToken |= DELTA_BATTERY_CHARGE_FLAG;
         }
         dest.writeInt(firstToken);
         if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
@@ -2338,10 +2337,9 @@
         }
         mLastHistoryStepLevel = cur.batteryLevel;
 
-        if (batteryChargeCoulombsChanged) {
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeCoulombs="
-                    + cur.batteryChargeCoulombs);
-            dest.writeInt(cur.batteryChargeCoulombs);
+        if (batteryChargeChanged) {
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh);
+            dest.writeInt(cur.batteryChargeUAh);
         }
     }
 
@@ -2590,8 +2588,8 @@
             cur.stepDetails = null;
         }
 
-        if ((firstToken&DELTA_BATTERY_CHARGE_COULOMBS_FLAG) != 0) {
-            cur.batteryChargeCoulombs = src.readInt();
+        if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) {
+            cur.batteryChargeUAh = src.readInt();
         }
     }
 
@@ -9310,7 +9308,7 @@
     public static final int BATTERY_PLUGGED_NONE = 0;
 
     public void setBatteryStateLocked(int status, int health, int plugType, int level,
-            int temp, int volt, int chargeCount) {
+            int temp, int volt, int chargeUAh) {
         final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
         final long uptime = mClocks.uptimeMillis();
         final long elapsedRealtime = mClocks.elapsedRealtime();
@@ -9362,7 +9360,7 @@
             mHistoryCur.batteryPlugType = (byte)plugType;
             mHistoryCur.batteryTemperature = (short)temp;
             mHistoryCur.batteryVoltage = (char)volt;
-            mHistoryCur.batteryChargeCoulombs = chargeCount;
+            mHistoryCur.batteryChargeUAh = chargeUAh;
             setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
         } else {
             boolean changed = false;
@@ -9396,9 +9394,9 @@
                 mHistoryCur.batteryVoltage = (char)volt;
                 changed = true;
             }
-            if (chargeCount >= (mHistoryCur.batteryChargeCoulombs+10)
-                    || chargeCount <= (mHistoryCur.batteryChargeCoulombs-10)) {
-                mHistoryCur.batteryChargeCoulombs = chargeCount;
+            if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10)
+                    || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) {
+                mHistoryCur.batteryChargeUAh = chargeUAh;
                 changed = true;
             }
             long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index b8bc161..d6172db 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -86,7 +86,7 @@
         return new DividerSnapAlgorithm(ctx.getResources(),
                 displayInfo.logicalWidth, displayInfo.logicalHeight,
                 dividerWindowWidth - 2 * dividerInsets,
-                ctx.getResources().getConfiguration().orientation
+                ctx.getApplicationContext().getResources().getConfiguration().orientation
                         == Configuration.ORIENTATION_PORTRAIT,
                 insets);
     }
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index ccdb024..31ab26f 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -173,7 +173,8 @@
         final ViewParent parent = mOriginatingView.getParent();
         if (parent instanceof ViewGroup) {
             ((ViewGroup) parent).getChildVisibleRect(
-                    mOriginatingView, mContentRectOnScreen, null /* offset */);
+                    mOriginatingView, mContentRectOnScreen,
+                    null /* offset */, true /* forceParentCheck */);
             mContentRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]);
         } else {
             mContentRectOnScreen.offset(mViewPositionOnScreen[0], mViewPositionOnScreen[1]);
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index bc12391..8cc8509 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -909,8 +909,8 @@
                     mOverflowPanel.setX(0);  // align left
                 } else {
                     mContentContainer.setX(  // align right
-                            mMarginHorizontal +
-                                    mMainPanelSize.getWidth() - containerSize.getWidth());
+                            mPopupWindow.getWidth() -
+                                    containerSize.getWidth() - mMarginHorizontal);
                     mMainPanel.setX(-mContentContainer.getX());  // align right
                     mOverflowButton.setX(0);  // align left
                     mOverflowPanel.setX(0);  // align left
@@ -949,7 +949,9 @@
                         mOverflowButton.setX(0);  // align left
                         mOverflowPanel.setX(0);  // align left
                     } else {
-                        mContentContainer.setX(mMarginHorizontal);  // align left
+                        mContentContainer.setX(  // align right
+                                mPopupWindow.getWidth() -
+                                        containerSize.getWidth() - mMarginHorizontal);
                         mMainPanel.setX(0);  // align left
                         mOverflowButton.setX(  // align right
                                 containerSize.getWidth() - mOverflowButtonSize.getWidth());
diff --git a/core/jni/android/graphics/pdf/PdfDocument.cpp b/core/jni/android/graphics/pdf/PdfDocument.cpp
index 88e37e5..d535193 100644
--- a/core/jni/android/graphics/pdf/PdfDocument.cpp
+++ b/core/jni/android/graphics/pdf/PdfDocument.cpp
@@ -88,7 +88,7 @@
     }
 
     void write(SkWStream* stream) {
-        SkDocument* document = SkDocument::CreatePDF(stream);
+        SkAutoTUnref<SkDocument> document(SkDocument::CreatePDF(stream));
         for (unsigned i = 0; i < mPages.size(); i++) {
             PageRecord* page =  mPages[i];
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a93677e..d7bc54d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -178,6 +178,8 @@
     <protected-broadcast
         android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
     <protected-broadcast
+        android:name="android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast
         android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
     <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index b7b4ec6..30f8ce4 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -4,23 +4,23 @@
 - from: /about/versions/api-levels.html
   to: /guide/topics/manifest/uses-sdk-element.html#ApiLevels
 - from: /sdk/oem-usb.html
-  to: /tools/extras/oem-usb.html
+  to: /studio/tools/extras/oem-usb.html
 - from: /sdk/installing.html
-  to: /sdk/installing/index.html
+  to: /studio/index.html
 - from: /sdk/exploring.html
-  to: /tools/help/sdk-manager.html
+  to: /studio/guide/index.html
 - from: /sdk/installing/adding-packages.html
-  to: /tools/help/sdk-manager.html
+  to: /studio/tools/help/sdk-manager.html
 - from: /sdk/installing/bundle.html
-  to: /sdk/index.html
+  to: /studio/index.html
 - from: /sdk/installing/studio.html
-  to: /sdk/index.html
+  to: /studio/index.html
 - from: /sdk/installing/studio-debug.html
-  to: /tools/debugging/debugging-studio.html
+  to: /studio/tools/debugging/debugging-studio.html
 - from: /tools/debugging/debugging-devtools.html
-  to: /tools/debugging/index.html
+  to: /studio/tools/debugging/index.html
 - from: /tools/debugging/debugging-projects-cmdline.html
-  to: /tools/debugging/index.html
+  to: /studio/tools/debugging/index.html
 - from: /sdk/compatibility-library.html
   to: /go/libraries/support-library/index.html
 - from: /tools/extras/support-library.html
@@ -28,47 +28,47 @@
 - from: /training/basics/fragments/support-lib.html
   to: /go/libraries/support-library/setup.html
 - from: /sdk/eclipse-adt.html
-  to: /tools/sdk/eclipse-adt.html
+  to: /studio/tools/sdk/eclipse-adt.html
 - from: /sdk/RELEASENOTES.html
-  to: /tools/sdk/tools-notes.html
+  to: /studio/tools/sdk/tools-notes.html
 - from: /sdk/tools-notes.html
-  to: /tools/sdk/tools-notes.html
+  to: /studio/tools/sdk/tools-notes.html
 - from: /sdk/adding-components.html
-  to: /sdk/exploring.html
+  to: /studio/tools/help/sdk-manager.html
 - from: /sdk/ndk/overview.html
-  to: /tools/sdk/ndk/index.html
+  to: /ndk/index.html
 - from: /sdk/ndk/
-  to: /tools/sdk/ndk/
+  to: /ndk/
 - from: /go/vulkan
   to: /ndk/guides/graphics/index.html
 - from: /tools/sdk/win-usb.html
-  to: /sdk/win-usb.html
+  to: /studio/guide/run/win-usb.html
 - from: /tools/sdk/index.html
-  to: /sdk/index.html
+  to: /studio/index.html
 - from: /tools/index.html
-  to: /sdk/index.html
+  to: /tools-moved.html
 - from: /tools/sdk/installing.html
-  to: /sdk/index.html
+  to: /studio/sdk/index.html
 - from: /tools/eclipse/installing-adt.html
-  to: /sdk/installing/index.html?pkg=adt
+  to: /studio/index.html
 - from: /sdk/requirements.html
-  to: /sdk/index.html
+  to: /studio/index.html
 - from: /sdk/installing/next.html
   to: /training/basics/firstapp/index.html
 - from: /sdk/installing/installing-adt.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/projects/projects-eclipse.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/building/building-eclipse.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/building/building-cmdline-ant.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/testing/testing_eclipse.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/debugging/debugging-projects.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/publishing/app-signing-eclipse.html
-  to: /tools/help/adt.html
+  to: /studio/tools/help/adt.html
 - from: /tools/help/uiautomator/...
   to: /go/libraries/testing-support-library/
 - from: /tools/testing/testing_ui.html
@@ -154,9 +154,9 @@
 - from: /google/play/billing/billing_about.html
   to: /google/play/billing/index.html
 - from: /guide/developing/tools/
-  to: /tools/help/
+  to: /studio/tools/help/
 - from: /guide/developing/
-  to: /tools/
+  to: /studio/
 - from: /tools/aidl.html
   to: /guide/components/aidl.html
 - from: /guide/market/publishing/multiple-apks.html
@@ -164,7 +164,7 @@
 - from: /guide/publishing/publishing.html
   to: /distribute/tools/launch-checklist.html
 - from: /guide/publishing/
-  to: /tools/publishing/
+  to: /studio/tools/publishing/publishing_overview.html
 - from: /guide/topics/fundamentals.html
   to: /guide/components/fundamentals.html
 - from: /guide/topics/intents/intents-filters.html
@@ -180,25 +180,23 @@
 - from: /guide/topics/drawing/...
   to: /guide/topics/graphics/opengl.html
 - from: /guide/topics/connectivity/usb/adk.html
-  to: /tools/adk/index.html
+  to: /adk/index.html
 - from: /tools/workflow/publishing/versioning.html
-  to: /tools/publishing/versioning.html
+  to: /studio/tools/publishing/versioning.html
 - from: /tools/workflow/publishing/publishing.html
-  to: /tools/publishing/publishing_overview.html
+  to: /studio/tools/publishing/publishing_overview.html
 - from: /tools/workflow/publishing_overview.html
-  to: /tools/publishing/publishing_overview.html
+  to: /studio/tools/publishing/publishing_overview.html
 - from: /tools/workflow/publishing/publishing_overview.html
-  to: /tools/publishing/publishing_overview.html
+  to: /studio/tools/publishing/publishing_overview.html
 - from: /tools/workflow/app-signing.html
-  to: /tools/publishing/app-signing.html
+  to: /studio/tools/publishing/app-signing.html
 - from: /tools/adk/aoa.html
   to: https://source.android.com/tech/accessories/aoap/aoa.html
 - from: /tools/adk/aoa2.html
   to: https://source.android.com/tech/accessories/aoap/aoa2.html
-- from: /sdk/exploring.html
-  to: /sdk/index.html
 - from: /tools/eclipse/migrate-adt.html
-  to: /sdk/installing/migrate.html
+  to: /studio/installing/migrate.html
 - from: /guide/topics/usb
   to: /guide/topics/connectivity/usb
 - from: /guide/appendix/api-levels.html
@@ -216,7 +214,7 @@
 - from: /guide/appendix/market-filters.html
   to: /google/play/filters.html
 - from: /guide/topics/testing/
-  to: /tools/testing/
+  to: /studio/tools/testing/
 - from: /guide/topics/graphics/animation.html
   to: /guide/topics/graphics/overview.html
 - from: /guide/topics/graphics/renderscript/compute.html
@@ -800,47 +798,47 @@
 - from: /2016/03/first-preview-of-android-n-developer.html
   to: http://android-developers.blogspot.com/2016/03/first-preview-of-android-n-developer.html
 - from: /r/studio-ui/vector-asset-studio.html
-  to: /tools/help/vector-asset-studio.html
+  to: /studio/tools/help/vector-asset-studio.html
 - from: /r/studio-ui/image-asset-studio.html
-  to: /tools/help/image-asset-studio.html
+  to: /studio/tools/help/image-asset-studio.html
 - from: /r/studio-ui/project-structure.html
-  to: /tools/help/project-mgmt.html
+  to: /studio/tools/help/project-mgmt.html
 - from: /r/studio-ui/android-monitor.html
-  to: /tools/help/android-monitor.html
+  to: /studio/tools/help/android-monitor.html
 - from: /r/studio-ui/am-logcat.html
-  to: /tools/help/am-logcat.html
+  to: /studio/tools/help/am-logcat.html
 - from: /r/studio-ui/am-memory.html
-  to: /tools/help/am-memory.html
+  to: /studio/tools/help/am-memory.html
 - from: /r/studio-ui/am-cpu.html
-  to: /tools/help/am-cpu.html
+  to: /studio/tools/help/am-cpu.html
 - from: /r/studio-ui/am-gpu.html
-  to: /tools/help/am-gpu.html
+  to: /studio/tools/help/am-gpu.html
 - from: /r/studio-ui/am-network.html
-  to: /tools/help/am-network.html
+  to: /studio/tools/help/am-network.html
 - from: /r/studio-ui/am-hprof.html
-  to: /tools/help/am-memory.html
+  to: /studio/tools/help/am-memory.html
 - from: /r/studio-ui/am-allocation.html
-  to: /tools/help/am-memory.html
+  to: /studio/tools/help/am-memory.html
 - from: /r/studio-ui/am-methodtrace.html
-  to: /tools/help/am-cpu.html
+  to: /studio/tools/help/am-cpu.html
 - from: /r/studio-ui/am-sysinfo.html
-  to: /tools/help/android-monitor.html
+  to: /studio/tools/help/android-monitor.html
 - from: /r/studio-ui/am-screenshot.html
-  to: /tools/help/android-monitor.html
+  to: /studio/tools/help/android-monitor.html
 - from: /r/studio-ui/am-video.html
-  to: /tools/help/android-monitor.html
+  to: /studio/tools/help/android-monitor.html
 - from: /r/studio-ui/avd-manager.html
-  to: /tools/help/avd-manager.html
+  to: /studio/tools/help/avd-manager.html
 - from: /r/studio-ui/rundebugconfig.html
-  to: /tools/devices/emulator.html
+  to: /studio/tools/devices/emulator.html
 - from: /r/studio-ui/devicechooser.html
-  to: /tools/devices/emulator.html
+  to: /studio/tools/devices/emulator.html
 - from: /r/studio-ui/virtualdeviceconfig.html
-  to: /tools/devices/emulator.html
+  to: /studio/tools/devices/emulator.html
 - from: /r/studio-ui/emulator.html
-  to: /tools/devices/emulator.html
+  to: /studio/tools/devices/emulator.html
 - from: /r/studio-ui/instant-run.html
-  to: /tools/building/building-studio.html#instant-run
+  to: /studio/tools/building/building-studio.html#instant-run
 - from: /reference/org/apache/http/...
   to: /about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
 - from: /shareables/
@@ -862,3 +860,45 @@
 # GCM redirects
 - from: /reference/com/google/...
   to: https://developers.google.com/android/reference/com/google/...
+
+# Files moved during the /studio restructure
+- from: /sdk/index.html
+  to: /studio/index.html
+- from: /sdk/win-usb.html
+  to: /studio/guide/run/win-usb.html
+- from: /sdk/terms.html
+  to: /studio/terms.html
+- from: /sdk/installing/...
+  to: /studio/installing/...
+- from: /tools/studio/index.html
+  to: /studio/guide/index.html
+- from: /tools/sdk/ndk/...
+  to: /ndk/index.html
+- from: /tools/adk/...
+  to: /adk/...
+
+# Removed files
+- from: /tools/help/android.html
+  to: /studio/tools/projects/index.html
+- from: /tools/help/hprof-conv.html
+  to: /studio/tools/debugging/debugging-memory.html
+- from: /tools/studio/code-tools.html
+  to: /studio/guide/write/index.html
+- from: /tools/studio/ui-tools.html
+  to: /studio/guide/write/index.html
+- from: /tools/help/avd-manager.html
+  to: /studio/tools/devices/managing-avds.html
+- from: /tools/devices/managing-avds-cmdline.html
+  to: /studio/tools/devices/managing-avds.html
+- from: /tools/projects/projects-cmdline.html
+  to: /studio/tools/revisions/studio.html
+- from: /tools/help/dmtracedump.html
+  to: /studio/tools/debugging/debugging-tracing.html
+- from: /tools/help/lint.html
+  to: /studio/tools/debugging/improving-w-lint.html
+- from: /tools/debugging/index.html
+  to: /studio/tools/debugging/debugging-studio.html
+
+# Handle the rest of the tool pages that moved into /studio
+- from: /tools/...
+  to: /studio/tools/...
\ No newline at end of file
diff --git a/docs/html/training/index.jd b/docs/html/training/index.jd
index 18971ab..ea8b4bb 100644
--- a/docs/html/training/index.jd
+++ b/docs/html/training/index.jd
@@ -43,7 +43,4 @@
        data-items-per-page="24"
        data-initial-results="6"></div>
   </div>
-</section>
-
-<h2 class="norule" id="class-list"
-  style="margin:0 0 -40px">Training guides</h2>
\ No newline at end of file
+</section>
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index 875e260..e7e8af1 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -18,6 +18,7 @@
 
 #include <gtest/gtest.h>
 #include <SkShader.h>
+#include <SkColorMatrixFilter.h>
 
 using namespace android;
 using namespace android::uirenderer;
@@ -28,7 +29,7 @@
  */
 TEST(SkiaBehavior, CreateBitmapShader1x1) {
     SkBitmap origBitmap = TestUtils::createSkBitmap(1, 1);
-    std::unique_ptr<SkShader> s(SkShader::CreateBitmapShader(
+    SkAutoTUnref<SkShader> s(SkShader::CreateBitmapShader(
             origBitmap,
             SkShader::kClamp_TileMode,
             SkShader::kRepeat_TileMode));
@@ -48,3 +49,17 @@
     bitmap.notifyPixelsChanged();
     EXPECT_NE(genId, bitmap.getGenerationID());
 }
+
+TEST(SkiaBehavior, lightingColorFilter_simplify) {
+    SkAutoTUnref<SkColorFilter> filter(SkColorMatrixFilter::CreateLightingFilter(0x11223344, 0));
+
+    SkColor observedColor;
+    SkXfermode::Mode observedMode;
+    ASSERT_TRUE(filter->asColorMode(&observedColor, &observedMode));
+    EXPECT_EQ(0xFF223344, observedColor);
+    EXPECT_EQ(SkXfermode::Mode::kModulate_Mode, observedMode);
+
+    SkAutoTUnref<SkColorFilter> failFilter(
+            SkColorMatrixFilter::CreateLightingFilter(0x11223344, 0x1));
+    EXPECT_FALSE(filter->asColorMode(nullptr, nullptr));
+}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 60444e0..73485af 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -206,13 +206,34 @@
         /** Microphone audio source */
         public static final int MIC = 1;
 
-        /** Voice call uplink (Tx) audio source */
+        /** Voice call uplink (Tx) audio source.
+         * <p>
+         * Capturing from <code>VOICE_UPLINK</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
         public static final int VOICE_UPLINK = 2;
 
-        /** Voice call downlink (Rx) audio source */
+        /** Voice call downlink (Rx) audio source.
+         * <p>
+         * Capturing from <code>VOICE_DOWNLINK</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
         public static final int VOICE_DOWNLINK = 3;
 
-        /** Voice call uplink + downlink audio source */
+        /** Voice call uplink + downlink audio source
+         * <p>
+         * Capturing from <code>VOICE_CALL</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
         public static final int VOICE_CALL = 4;
 
         /** Microphone audio source with same orientation as camera if available, the main
diff --git a/packages/CtsShim/Android.mk b/packages/CtsShim/Android.mk
index b827bdf..cd5b288 100644
--- a/packages/CtsShim/Android.mk
+++ b/packages/CtsShim/Android.mk
@@ -29,6 +29,7 @@
 LOCAL_BUILT_MODULE_STEM := package.apk
 # Make sure the build system doesn't try to resign the APK
 LOCAL_CERTIFICATE := PRESIGNED
+LOCAL_DEX_PREOPT := false
 
 LOCAL_SRC_FILES := CtsShimPriv.apk
 
@@ -46,6 +47,7 @@
 LOCAL_BUILT_MODULE_STEM := package.apk
 # Make sure the build system doesn't try to resign the APK
 LOCAL_CERTIFICATE := PRESIGNED
+LOCAL_DEX_PREOPT := false
 
 LOCAL_SRC_FILES := CtsShim.apk
 
diff --git a/packages/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
index fefedf8..f3ce355 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Ranker.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
@@ -59,7 +59,7 @@
         if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
         try {
             List<String> notificationsToBundle = new ArrayList<>();
-            if (!sbn.isGroup()) {
+            if (!sbn.isAppGroup()) {
                 // Not grouped by the app, add to the list of notifications for the app;
                 // send bundling update if app exceeds the autobundling limit.
                 synchronized (mUnbundledNotifications) {
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index 60eebeb..9d2a14a 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -60,25 +60,25 @@
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"إيقاف"</item>
-    <item msgid="1593289376502312923">"64 كيلوبايت"</item>
-    <item msgid="487545340236145324">"256 كيلوبايت"</item>
+    <item msgid="1593289376502312923">"٦٤ كيلوبايت"</item>
+    <item msgid="487545340236145324">"٢٥٦ كيلوبايت"</item>
     <item msgid="2423528675294333831">"1 ميغابايت"</item>
-    <item msgid="180883774509476541">"4 ميغابايت"</item>
-    <item msgid="2803199102589126938">"16 ميغابايت"</item>
+    <item msgid="180883774509476541">"٤ ميغابايت"</item>
+    <item msgid="2803199102589126938">"١٦ ميغابايت"</item>
   </string-array>
   <string-array name="select_logd_size_lowram_titles">
     <item msgid="6089470720451068364">"إيقاف"</item>
-    <item msgid="4622460333038586791">"64 كيلوبايت"</item>
-    <item msgid="2212125625169582330">"256 كيلوبايت"</item>
+    <item msgid="4622460333038586791">"٦٤ كيلوبايت"</item>
+    <item msgid="2212125625169582330">"٢٥٦ كيلوبايت"</item>
     <item msgid="1704946766699242653">"1 ميغابايت"</item>
   </string-array>
   <string-array name="select_logd_size_summaries">
     <item msgid="6921048829791179331">"إيقاف"</item>
-    <item msgid="2969458029344750262">"64 كيلوبايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
-    <item msgid="1342285115665698168">"256 كيلوبايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
+    <item msgid="2969458029344750262">"٦٤ كيلوبايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
+    <item msgid="1342285115665698168">"٢٥٦ كيلوبايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
     <item msgid="1314234299552254621">"1 ميغابايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
-    <item msgid="3606047780792894151">"4 ميغابايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
-    <item msgid="5431354956856655120">"16 ميغابايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
+    <item msgid="3606047780792894151">"٤ ميغابايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
+    <item msgid="5431354956856655120">"١٦ ميغابايت لكل ذاكرة تخزين مؤقت للتسجيل"</item>
   </string-array>
   <string-array name="window_animation_scale_entries">
     <item msgid="8134156599370824081">"إيقاف الرسوم المتحركة"</item>
@@ -148,7 +148,7 @@
     <item msgid="4810006996171705398">"عملية واحدة بحد أقصى"</item>
     <item msgid="8586370216857360863">"عمليتان بحد أقصى"</item>
     <item msgid="836593137872605381">"3 عمليات بحد أقصى"</item>
-    <item msgid="7899496259191969307">"4 عمليات بحد أقصى"</item>
+    <item msgid="7899496259191969307">"٤ عمليات بحد أقصى"</item>
   </string-array>
   <string-array name="usb_configuration_titles">
     <item msgid="488237561639712799">"الشحن"</item>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index e4b661e..a64e873 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -29,7 +29,7 @@
     <item msgid="4221763391123233270">"Conexión establecida"</item>
     <item msgid="624838831631122137">"Suspendida"</item>
     <item msgid="7979680559596111948">"Desconectando..."</item>
-    <item msgid="1634960474403853625">"Desconectada"</item>
+    <item msgid="1634960474403853625">"Desconectado"</item>
     <item msgid="746097431216080650">"Con error"</item>
     <item msgid="6367044185730295334">"Bloqueada"</item>
     <item msgid="503942654197908005">"Inhabilitando conexión inestable temporalmente..."</item>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 1cfd3d4..dd828c1 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -50,12 +50,12 @@
   </string-array>
   <string-array name="hdcp_checking_titles">
     <item msgid="441827799230089869">"Ne jamais vérifier"</item>
-    <item msgid="6042769699089883931">"Vérifier le contenu GDN uniquement"</item>
+    <item msgid="6042769699089883931">"Vérifier le contenu DRM uniquement"</item>
     <item msgid="9174900380056846820">"Toujours vérifier"</item>
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="505558545611516707">"Ne jamais utiliser la vérification HDCP"</item>
-    <item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu GDN"</item>
+    <item msgid="3878793616631049349">"Utiliser la vérification HDCP uniquement pour le contenu DRM"</item>
     <item msgid="45075631231212732">"Toujours utiliser la vérification HDCP"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
diff --git a/packages/SettingsLib/res/values-hy-rAM/arrays.xml b/packages/SettingsLib/res/values-hy-rAM/arrays.xml
index 0755a8a..3e477cd 100644
--- a/packages/SettingsLib/res/values-hy-rAM/arrays.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/arrays.xml
@@ -125,7 +125,7 @@
     <item msgid="3191973083884253830">"Ոչ մեկը"</item>
     <item msgid="9089630089455370183">"Logcat"</item>
     <item msgid="5397807424362304288">"Համակարգային հետագիծ (գծապատկերներ)"</item>
-    <item msgid="1340692776955662664">"Կանչել glGetError-ի կույտը"</item>
+    <item msgid="1340692776955662664">"glGetError կանչերի ցուցակ"</item>
   </string-array>
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"Անջատված"</item>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 284827b..e071f6a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -28,10 +28,13 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.SparseArray;
+import android.view.View;
 import android.widget.TextView;
 
 import com.android.settingslib.R;
 
+import java.util.Objects;
+
 public class AccessPointPreference extends Preference {
 
     private static final int[] STATE_SECURED = {
@@ -108,6 +111,7 @@
             mTitleView.setCompoundDrawablePadding(mBadgePadding);
         }
         view.itemView.setContentDescription(mContentDescription);
+        view.itemView.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
     }
 
     protected void updateIcon(int level, Context context) {
@@ -148,6 +152,7 @@
      * Updates the title and summary; may indirectly call notifyChanged().
      */
     public void refresh() {
+        boolean updated = false;
         if (mForSavedNetworks) {
             setTitle(mAccessPoint.getConfigName());
         } else {
@@ -159,21 +164,28 @@
         if (level != mLevel) {
             mLevel = level;
             updateIcon(mLevel, context);
-            notifyChanged();
+            updated = true;
         }
         updateBadge(context);
 
         setSummary(mForSavedNetworks ? mAccessPoint.getSavedNetworkSummary()
                 : mAccessPoint.getSettingsSummary());
 
-        mContentDescription = getTitle();
+        CharSequence contentDescription = getTitle();
         if (getSummary() != null) {
-            mContentDescription = TextUtils.concat(mContentDescription, ",", getSummary());
+            contentDescription = TextUtils.concat(contentDescription, ",", getSummary());
         }
         if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
-            mContentDescription = TextUtils.concat(mContentDescription, ",",
+            contentDescription = TextUtils.concat(contentDescription, ",",
                     getContext().getString(WIFI_CONNECTION_STRENGTH[level]));
         }
+        if (!Objects.equals(contentDescription, mContentDescription)) {
+            mContentDescription = contentDescription;
+            updated = true;
+        }
+        if (updated) {
+            notifyChanged();
+        }
     }
 
     @Override
diff --git a/packages/SettingsProvider/res/values-ky-rKG/strings.xml b/packages/SettingsProvider/res/values-ky-rKG/strings.xml
new file mode 100644
index 0000000..2b3cf61
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ky-rKG/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, 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.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Жөндөөлөрдү сактоо"</string>
+</resources>
diff --git a/packages/StatementService/src/com/android/statementservice/IntentFilterVerificationReceiver.java b/packages/StatementService/src/com/android/statementservice/IntentFilterVerificationReceiver.java
index 57809ac..ba8e7a1 100644
--- a/packages/StatementService/src/com/android/statementservice/IntentFilterVerificationReceiver.java
+++ b/packages/StatementService/src/com/android/statementservice/IntentFilterVerificationReceiver.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.ResultReceiver;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Patterns;
 
@@ -90,8 +91,6 @@
                 String packageName = inputExtras.getString(
                         PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME);
 
-                Log.i(TAG, "Verify IntentFilter for " + hosts);
-
                 Bundle extras = new Bundle();
                 extras.putString(DirectStatementService.EXTRA_RELATION, HANDLE_ALL_URLS_RELATION);
 
@@ -103,6 +102,7 @@
                     return;
                 }
 
+                ArrayList<String> finalHosts = new ArrayList<String>(hostList.length);
                 try {
                     ArrayList<String> sourceAssets = new ArrayList<String>();
                     for (String host : hostList) {
@@ -111,6 +111,7 @@
                             host = host.substring(2);
                         }
                         sourceAssets.add(createWebAssetString(scheme, host));
+                        finalHosts.add(host);
                     }
                     extras.putStringArrayList(DirectStatementService.EXTRA_SOURCE_ASSET_DESCRIPTORS,
                             sourceAssets);
@@ -131,6 +132,9 @@
                         new IsAssociatedResultReceiver(
                                 new Handler(), context.getPackageManager(), verificationId));
 
+                // Required for CTS: log a few details of the validcation operation to be performed
+                logValidationParametersForCTS(verificationId, scheme, finalHosts, packageName);
+
                 serviceIntent.putExtras(extras);
                 context.startService(serviceIntent);
             }
@@ -139,6 +143,15 @@
         }
     }
 
+    // CTS requirement: logging of the validation parameters in a specific format
+    private static final String CTS_LOG_FORMAT =
+            "Verifying IntentFilter. verificationId:%d scheme:\"%s\" hosts:\"%s\" package:\"%s\".";
+    private void logValidationParametersForCTS(int verificationId, String scheme,
+            ArrayList<String> finalHosts, String packageName) {
+        String hostString = TextUtils.join(" ", finalHosts.toArray());
+        Log.i(TAG, String.format(CTS_LOG_FORMAT, verificationId, scheme, hostString, packageName));
+    }
+
     private String createAndroidAssetString(Context context, String packageName)
             throws NameNotFoundException {
         if (!ANDROID_PACKAGE_NAME_PATTERN.matcher(packageName).matches()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f41355c..24260d5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -451,11 +451,13 @@
 
         TaskStack stack = loadPlan.getTaskStack();
         int numStackTasks = stack.getStackTaskCount();
+        boolean showDeferredAnimation = numStackTasks > 0;
 
         EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
                 false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
                 numStackTasks > 0));
-        EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode, stack));
+        EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
+                showDeferredAnimation, stack));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
index 11649fb..64eeafa 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
@@ -25,10 +25,14 @@
 public class MultiWindowStateChangedEvent extends EventBus.AnimatedEvent {
 
     public final boolean inMultiWindow;
+    // This flag is only used when undocking a task
+    public final boolean showDeferredAnimation;
     public final TaskStack stack;
 
-    public MultiWindowStateChangedEvent(boolean inMultiWindow, TaskStack stack) {
+    public MultiWindowStateChangedEvent(boolean inMultiWindow, boolean showDeferredAnimation,
+            TaskStack stack) {
         this.inMultiWindow = inMultiWindow;
+        this.showDeferredAnimation = showDeferredAnimation;
         this.stack = stack;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
index 7bd0958..0628c50 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
@@ -18,6 +18,7 @@
 
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.views.AnimationProps;
 import com.android.systemui.recents.views.TaskView;
 
 /**
@@ -27,9 +28,11 @@
 
     public final Task task;
     public final TaskView taskView;
+    public final AnimationProps animation;
 
-    public TaskViewDismissedEvent(Task task, TaskView taskView) {
+    public TaskViewDismissedEvent(Task task, TaskView taskView, AnimationProps animation) {
         this.task = task;
         this.taskView = taskView;
+        this.animation = animation;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 0e5ebc9..c692a16 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -193,7 +193,7 @@
     }
 
     public final void onBusEvent(ConfigurationChangedEvent event) {
-        if (event.fromDisplayDensityChange) {
+        if (event.fromDisplayDensityChange || event.fromDeviceOrientationChange) {
             updateSnapAlgorithm();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index b422cca..cc8e832 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -309,6 +310,11 @@
         for (int i = 0; i < taskViewCount; i++) {
             int taskIndexFromFront = taskViewCount - i - 1;
             TaskView tv = taskViews.get(i);
+            Task task = tv.getTask();
+
+            if (mStackView.isIgnoredTask(task)) {
+                continue;
+            }
 
             // Animate the tasks down
             AnimationProps taskAnimation;
@@ -384,29 +390,29 @@
      */
     public void startDeleteTaskAnimation(final TaskView deleteTaskView,
             final ReferenceCountedTrigger postAnimationTrigger) {
-        Resources res = mStackView.getResources();
-        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
+        TaskStackViewTouchHandler touchHandler = mStackView.getTouchHandler();
+        touchHandler.onBeginManualDrag(deleteTaskView);
 
-        int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
+        postAnimationTrigger.increment();
+        postAnimationTrigger.addLastDecrementRunnable(() -> {
+            touchHandler.onChildDismissed(deleteTaskView);
+        });
 
-        // Disabling clipping with the stack while the view is animating away, this will get
-        // restored when the task is next picked up from the view pool
-        deleteTaskView.setClipViewInStack(false);
-
-        // Compose the new animation and transform and star the animation
-        AnimationProps taskAnimation = new AnimationProps(DISMISS_TASK_DURATION,
-                Interpolators.ALPHA_OUT, new AnimatorListenerAdapter() {
+        final float dismissSize = touchHandler.getScaledDismissSize();
+        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+        animator.setDuration(400);
+        animator.addUpdateListener((animation) -> {
+            float progress = (Float) animation.getAnimatedValue();
+            deleteTaskView.setTranslationX(progress * dismissSize);
+            touchHandler.updateSwipeProgress(deleteTaskView, true, progress);
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 postAnimationTrigger.decrement();
             }
         });
-        postAnimationTrigger.increment();
-
-        mTmpTransform.fillIn(deleteTaskView);
-        mTmpTransform.alpha = 0f;
-        mTmpTransform.rect.offset(offscreenXOffset, 0);
-        mStackView.updateTaskViewToTransform(deleteTaskView, mTmpTransform, taskAnimation);
+        animator.start();
     }
 
     /**
@@ -419,7 +425,6 @@
         int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
 
         int taskViewCount = taskViews.size();
-
         for (int i = taskViewCount - 1; i >= 0; i--) {
             TaskView tv = taskViews.get(i);
             int taskIndexFromFront = taskViewCount - i - 1;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 270d981..77b7338 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -623,6 +623,24 @@
         }
     }
 
+    /**
+     * Adds and override task progress for the given task when transitioning from focused to
+     * unfocused state.
+     */
+    public void addUnfocusedTaskOverride(TaskView taskView, float stackScroll) {
+        mFocusedRange.offset(stackScroll);
+        mUnfocusedRange.offset(stackScroll);
+
+        Task task = taskView.getTask();
+        int top = taskView.getTop() - mTaskRect.top;
+        float focusedRangeX = getNormalizedXFromFocusedY(top, FROM_TOP);
+        float unfocusedRangeX = getNormalizedXFromUnfocusedY(top, FROM_TOP);
+        float unfocusedTaskProgress = stackScroll + mUnfocusedRange.getAbsoluteX(unfocusedRangeX);
+        if (Float.compare(focusedRangeX, unfocusedRangeX) != 0) {
+            mTaskIndexOverrideMap.put(task.key.id, unfocusedTaskProgress);
+        }
+    }
+
     public void clearUnfocusedTaskOverrides() {
         mTaskIndexOverrideMap.clear();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index a158482..773e587 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -420,6 +420,13 @@
     }
 
     /**
+     * Returns the touch handler for this task stack.
+     */
+    public TaskStackViewTouchHandler getTouchHandler() {
+        return mTouchHandler;
+    }
+
+    /**
      * Adds a task to the ignored set.
      */
     void addIgnoreTask(Task task) {
@@ -1664,7 +1671,7 @@
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
         // Stop any scrolling
-        mTouchHandler.finishAnimations();
+        mTouchHandler.cancelNonDismissTaskAnimations();
         mStackScroller.stopScroller();
         mStackScroller.stopBoundScrollAnimation();
         cancelDeferredTaskViewLayoutAnimation();
@@ -1722,8 +1729,7 @@
                 R.string.accessibility_recents_item_dismissed, event.task.title));
 
         // Remove the task from the stack
-        mStack.removeTask(event.task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
-                Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
+        mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
         EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
 
         MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
@@ -1938,7 +1944,7 @@
     }
 
     public final void onBusEvent(final MultiWindowStateChangedEvent event) {
-        if (event.inMultiWindow) {
+        if (event.inMultiWindow || !event.showDeferredAnimation) {
             setTasks(event.stack, true /* allowNotifyStackChanges */);
         } else {
             // Reset the launch state before handling the multiwindow change
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 81242fd..b554a46 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -32,7 +32,6 @@
 import android.view.ViewDebug;
 import android.view.ViewParent;
 import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -189,15 +188,30 @@
     }
 
     /**
-     * Finishes all scroll-fling and swipe animations currently running.
+     * Finishes all scroll-fling and non-dismissing animations currently running.
      */
-    public void finishAnimations() {
+    public void cancelNonDismissTaskAnimations() {
         Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator);
-        ArrayMap<View, Animator> existingAnimators = new ArrayMap<>(mSwipeHelperAnimations);
-        for (int i = 0; i < existingAnimators.size(); i++) {
-            existingAnimators.get(existingAnimators.keyAt(i)).end();
+        if (!mSwipeHelperAnimations.isEmpty()) {
+            // For the non-dismissing tasks, freeze the position into the task overrides
+            List<TaskView> taskViews = mSv.getTaskViews();
+            for (int i = taskViews.size() - 1; i >= 0; i--) {
+                TaskView tv = taskViews.get(i);
+
+                if (mSv.isIgnoredTask(tv.getTask())) {
+                    continue;
+                }
+
+                tv.cancelTransformAnimation();
+                mSv.getStackAlgorithm().addUnfocusedTaskOverride(tv, mTargetStackScroll);
+            }
+            mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
+            // Update the scroll to the final scroll position from onBeginDrag()
+            mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+
+            mSwipeHelperAnimations.clear();
         }
-        mSwipeHelperAnimations.clear();
+        mActiveTaskView = null;
     }
 
     private boolean handleTouchEvent(MotionEvent ev) {
@@ -210,6 +224,13 @@
         int action = ev.getAction();
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
+                // Stop the current scroll if it is still flinging
+                mScroller.stopScroller();
+                mScroller.stopBoundScrollAnimation();
+                mScroller.resetDeltaScroll();
+                cancelNonDismissTaskAnimations();
+                mSv.cancelDeferredTaskViewLayoutAnimation();
+
                 // Save the touch down info
                 mDownX = (int) ev.getX();
                 mDownY = (int) ev.getY();
@@ -218,13 +239,6 @@
                 mActivePointerId = ev.getPointerId(0);
                 mActiveTaskView = findViewAtPoint(mDownX, mDownY);
 
-                // Stop the current scroll if it is still flinging
-                mSv.cancelDeferredTaskViewLayoutAnimation();
-                mScroller.stopScroller();
-                mScroller.stopBoundScrollAnimation();
-                mScroller.resetDeltaScroll();
-                finishAnimations();
-
                 // Initialize the velocity tracker
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
@@ -431,8 +445,18 @@
     public boolean canChildBeDismissed(View v) {
         // Disallow dismissing an already dismissed task
         TaskView tv = (TaskView) v;
+        Task task = tv.getTask();
         return !mSwipeHelperAnimations.containsKey(v) &&
-                (mSv.getStack().indexOfStackTask(tv.getTask()) != -1);
+                (mSv.getStack().indexOfStackTask(task) != -1);
+    }
+
+    /**
+     * Starts a manual drag that goes through the same swipe helper path.
+     */
+    public void onBeginManualDrag(TaskView v) {
+        mActiveTaskView = v;
+        mSwipeHelperAnimations.put(v, null);
+        onBeginDrag(v);
     }
 
     @Override
@@ -453,7 +477,7 @@
         mSv.addIgnoreTask(tv.getTask());
 
         // Determine if we are animating the other tasks while dismissing this task
-        mCurrentTasks = mSv.getStack().getStackTasks();
+        mCurrentTasks = new ArrayList<Task>(mSv.getStack().getStackTasks());
         MutableBoolean isFrontMostTask = new MutableBoolean(false);
         Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
         TaskStackLayoutAlgorithm layoutAlgorithm = mSv.getStackAlgorithm();
@@ -513,7 +537,12 @@
 
     @Override
     public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
-        updateTaskViewTransforms(Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
+        // Only update the swipe progress for the surrounding tasks if the dismiss animation was not
+        // preempted from a call to cancelNonDismissTaskAnimations
+        if (mActiveTaskView == v || mSwipeHelperAnimations.containsKey(v)) {
+            updateTaskViewTransforms(
+                    Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
+        }
         return true;
     }
 
@@ -528,15 +557,24 @@
         tv.setClipViewInStack(true);
         // Re-enable touch events from this task view
         tv.setTouchEnabled(true);
-        // Remove the task view from the stack
-        EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
-        // Update the scroll to the final scroll position from onBeginDrag()
-        mSv.getScroller().setStackScroll(mTargetStackScroll, null);
-        // Update the focus state to the final focus state
-        mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
-        mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
-        // Stop tracking this deletion animation
-        mSwipeHelperAnimations.remove(v);
+        // Remove the task view from the stack, ignoring the animation if we've started dragging
+        // again
+        EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv,
+                mSwipeHelperAnimations.containsKey(v)
+                    ? new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
+                        Interpolators.FAST_OUT_SLOW_IN)
+                    : null));
+        // Only update the final scroll and layout state (set in onBeginDrag()) if the dismiss
+        // animation was not preempted from a call to cancelNonDismissTaskAnimations
+        if (mSwipeHelperAnimations.containsKey(v)) {
+            // Update the scroll to the final scroll position
+            mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+            // Update the focus state to the final focus state
+            mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
+            mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
+            // Stop tracking this deletion animation
+            mSwipeHelperAnimations.remove(v);
+        }
         // Keep track of deletions by keyboard
         MetricsLogger.histogram(tv.getContext(), "overview_task_dismissed_source",
                 Constants.Metrics.DismissSourceSwipeGesture);
@@ -631,7 +669,7 @@
     /**
      * Returns the scaled size used to calculate the dismiss fraction.
      */
-    private float getScaledDismissSize() {
+    public float getScaledDismissSize() {
         return 1.5f * Math.max(mSv.getWidth(), mSv.getHeight());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 1d476c6..c1e7e04 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -388,7 +388,9 @@
         dismissEvent.addPostAnimationCallback(new Runnable() {
             @Override
             public void run() {
-                EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv));
+                EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv,
+                        new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
+                                Interpolators.FAST_OUT_SLOW_IN)));
             }
         });
         EventBus.getDefault().send(dismissEvent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6fc32de..57c012b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2948,7 +2948,7 @@
     }
 
     public void topAppWindowChanged(boolean showMenu) {
-        if (DEBUG) {
+        if (SPEW) {
             Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
         }
         if (mNavigationBarView != null) {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 6a08191..6b0ead4 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -309,8 +309,8 @@
     private static final int EVENT_DEEP_IDLE = 4;
     private static final int EVENT_DEEP_MAINTENANCE = 5;
 
-    private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
-    private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
+    private final int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
+    private final long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
 
     private void addEvent(int cmd) {
         if (mEventCmds[0] != cmd) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 842a0e3..2c46fbf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6599,7 +6599,8 @@
                 try {
                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
                 } catch (InstallerException e) {
-                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
+                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
+                            e.getMessage() +")");
                 }
                 completedIsas.add(instructionSet);
             }
@@ -10319,9 +10320,9 @@
     }
 
     private void checkTime(long startTime, String where) {
-        long now = SystemClock.elapsedRealtime();
-        if ((now-startTime) > 1000) {
-            // If we are taking more than a second, log about it.
+        long now = SystemClock.uptimeMillis();
+        if ((now-startTime) > 50) {
+            // If we are taking more than 50ms, log about it.
             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
         }
     }
@@ -10333,7 +10334,7 @@
         ProviderInfo cpi = null;
 
         synchronized(this) {
-            long startTime = SystemClock.elapsedRealtime();
+            long startTime = SystemClock.uptimeMillis();
 
             ProcessRecord r = null;
             if (caller != null) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d34ec86..79b1413 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -974,7 +974,7 @@
 
     @Override
     public void setBatteryState(final int status, final int health, final int plugType,
-            final int level, final int temp, final int volt, final int chargeCount) {
+            final int level, final int temp, final int volt, final int chargeUAh) {
         enforceCallingPermission();
 
         // BatteryService calls us here and we may update external state. It would be wrong
@@ -988,7 +988,7 @@
                         // The battery state has not changed, so we don't need to sync external
                         // stats immediately.
                         mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
-                                chargeCount);
+                                chargeUAh);
                         return;
                     }
                 }
@@ -998,7 +998,7 @@
                 updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
                 synchronized (mStats) {
                     mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
-                            chargeCount);
+                            chargeUAh);
                 }
             }
         });
diff --git a/services/core/java/com/android/server/job/JobCompletedListener.java b/services/core/java/com/android/server/job/JobCompletedListener.java
index a7af9cd..655abd7 100644
--- a/services/core/java/com/android/server/job/JobCompletedListener.java
+++ b/services/core/java/com/android/server/job/JobCompletedListener.java
@@ -23,10 +23,9 @@
  * {@link com.android.server.job.JobSchedulerService}.
  */
 public interface JobCompletedListener {
-
     /**
      * Callback for when a job is completed.
      * @param needsReschedule Whether the implementing class should reschedule this job.
      */
-    public void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
+    void onJobCompleted(JobStatus jobStatus, boolean needsReschedule);
 }
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index e5a2095..4ba9dae 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -33,6 +33,28 @@
     // Number of historical data sets we keep.
     static final int NUM_HISTORY = 5;
 
+    private static final int EVENT_BUFFER_SIZE = 50;
+
+    public static final int EVENT_NULL = 0;
+    public static final int EVENT_START_JOB = 1;
+    public static final int EVENT_STOP_JOB = 2;
+
+    private int[] mEventCmds = new int[EVENT_BUFFER_SIZE];
+    private long[] mEventTimes = new long[EVENT_BUFFER_SIZE];
+    private int[] mEventUids = new int[EVENT_BUFFER_SIZE];
+    private String[] mEventTags = new String[EVENT_BUFFER_SIZE];
+
+    public void addEvent(int cmd, int uid, String tag) {
+        System.arraycopy(mEventCmds, 0, mEventCmds, 1, EVENT_BUFFER_SIZE - 1);
+        System.arraycopy(mEventTimes, 0, mEventTimes, 1, EVENT_BUFFER_SIZE - 1);
+        System.arraycopy(mEventUids, 0, mEventUids, 1, EVENT_BUFFER_SIZE - 1);
+        System.arraycopy(mEventTags, 0, mEventTags, 1, EVENT_BUFFER_SIZE - 1);
+        mEventCmds[0] = cmd;
+        mEventTimes[0] = SystemClock.elapsedRealtime();
+        mEventUids[0] = uid;
+        mEventTags[0] = tag;
+    }
+
     DataSet mCurDataSet = new DataSet();
     DataSet[] mLastDataSets = new DataSet[NUM_HISTORY];
 
@@ -240,7 +262,8 @@
             }
         }
 
-        void dump(PrintWriter pw, String header, String prefix, long now, long nowEllapsed) {
+        void dump(PrintWriter pw, String header, String prefix, long now, long nowEllapsed,
+                int filterUid) {
             final long period = getTotalTime(now);
             pw.print(prefix); pw.print(header); pw.print(" at ");
             pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", mStartClockTime).toString());
@@ -251,12 +274,16 @@
             pw.println(":");
             final int NE = mEntries.size();
             for (int i = 0; i < NE; i++) {
+                int uid = mEntries.keyAt(i);
+                if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
+                    continue;
+                }
                 ArrayMap<String, PackageEntry> uidMap = mEntries.valueAt(i);
                 final int NP = uidMap.size();
                 for (int j = 0; j < NP; j++) {
                     PackageEntry pe = uidMap.valueAt(j);
                     pw.print(prefix); pw.print("  ");
-                    UserHandle.formatUid(pw, mEntries.keyAt(i));
+                    UserHandle.formatUid(pw, uid);
                     pw.print(" / "); pw.print(uidMap.keyAt(j));
                     pw.print(":");
                     printDuration(pw, period, pe.getPendingTime(now), "pending");
@@ -309,6 +336,7 @@
         } else {
             mCurDataSet.incActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
+        addEvent(EVENT_START_JOB, job.getSourceUid(), job.getBatteryName());
     }
 
     public void noteInactive(JobStatus job) {
@@ -319,6 +347,7 @@
             mCurDataSet.decActive(job.getSourceUid(), job.getSourcePackageName(), now);
         }
         rebatchIfNeeded(now);
+        addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName());
     }
 
     public float getLoadFactor(JobStatus job) {
@@ -339,7 +368,7 @@
         return time / (float)period;
     }
 
-    public void dump(PrintWriter pw, String prefix) {
+    public void dump(PrintWriter pw, String prefix, int filterUid) {
         final long now = SystemClock.uptimeMillis();
         final long nowEllapsed = SystemClock.elapsedRealtime();
         final DataSet total;
@@ -352,10 +381,43 @@
         mCurDataSet.addTo(total, now);
         for (int i = 1; i < mLastDataSets.length; i++) {
             if (mLastDataSets[i] != null) {
-                mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowEllapsed);
+                mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowEllapsed, filterUid);
                 pw.println();
             }
         }
-        total.dump(pw, "Current stats", prefix, now, nowEllapsed);
+        total.dump(pw, "Current stats", prefix, now, nowEllapsed, filterUid);
+    }
+
+    public boolean dumpHistory(PrintWriter pw, String prefix, int filterUid) {
+        if (mEventCmds[0] == EVENT_NULL) {
+            return false;
+        }
+        pw.println("  Job history:");
+        long now = SystemClock.elapsedRealtime();
+        for (int i=EVENT_BUFFER_SIZE-1; i>=0; i--) {
+            int uid = mEventUids[i];
+            if (filterUid != -1 && filterUid != UserHandle.getAppId(filterUid)) {
+                continue;
+            }
+            int cmd = mEventCmds[i];
+            if (cmd == EVENT_NULL) {
+                continue;
+            }
+            String label;
+            switch (mEventCmds[i]) {
+                case EVENT_START_JOB:           label = "START"; break;
+                case EVENT_STOP_JOB:            label = " STOP"; break;
+                default:                        label = "   ??"; break;
+            }
+            pw.print(prefix);
+            TimeUtils.formatDuration(mEventTimes[i]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
+            pw.print(" ");
+            pw.print(label);
+            pw.print(": ");
+            UserHandle.formatUid(pw, uid);
+            pw.print(" ");
+            pw.println(mEventTags[i]);
+        }
+        return true;
     }
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 075a88f..7e26d4b 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -1477,17 +1477,45 @@
         return s.toString();
     }
 
+    static void dumpHelp(PrintWriter pw) {
+        pw.println("Job Scheduler (jobscheduler) dump options:");
+        pw.println("  [-h] [package] ...");
+        pw.println("    -h: print this help");
+        pw.println("  [package] is an optional package name to limit the output to.");
+    }
+
     void dumpInternal(final PrintWriter pw, String[] args) {
         int filterUid = -1;
         if (!ArrayUtils.isEmpty(args)) {
-            try {
-                filterUid = getContext().getPackageManager().getPackageUid(args[0],
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES);
-            } catch (NameNotFoundException ignored) {
+            int opti = 0;
+            while (opti < args.length) {
+                String arg = args[opti];
+                if ("-h".equals(arg)) {
+                    dumpHelp(pw);
+                    return;
+                } else if ("-a".equals(arg)) {
+                    // Ignore, we always dump all.
+                } else if (arg.length() > 0 && arg.charAt(0) == '-') {
+                    pw.println("Unknown option: " + arg);
+                    return;
+                } else {
+                    break;
+                }
+                opti++;
+            }
+            if (opti < args.length) {
+                String pkg = args[opti];
+                try {
+                    filterUid = getContext().getPackageManager().getPackageUid(pkg,
+                            PackageManager.MATCH_UNINSTALLED_PACKAGES);
+                } catch (NameNotFoundException ignored) {
+                    pw.println("Invalid package: " + pkg);
+                    return;
+                }
             }
         }
 
-        final int filterUidFinal = filterUid;
+        final int filterUidFinal = UserHandle.getAppId(filterUid);
         final long now = SystemClock.elapsedRealtime();
         synchronized (mLock) {
             pw.println("Started users: " + Arrays.toString(mStartedUsers));
@@ -1502,8 +1530,7 @@
                         pw.println(job.toShortString());
 
                         // Skip printing details if the caller requested a filter
-                        if (filterUidFinal != -1 && job.getUid() != filterUidFinal
-                                && job.getSourceUid() != filterUidFinal) {
+                        if (!job.shouldDump(filterUidFinal)) {
                             return;
                         }
 
@@ -1526,17 +1553,23 @@
             }
             for (int i=0; i<mControllers.size(); i++) {
                 pw.println();
-                mControllers.get(i).dumpControllerStateLocked(pw);
+                mControllers.get(i).dumpControllerStateLocked(pw, filterUidFinal);
             }
             pw.println();
             pw.println("Uid priority overrides:");
             for (int i=0; i< mUidPriorityOverride.size(); i++) {
-                pw.print("  "); pw.print(UserHandle.formatUid(mUidPriorityOverride.keyAt(i)));
-                pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i));
+                int uid = mUidPriorityOverride.keyAt(i);
+                if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+                    pw.print("  "); pw.print(UserHandle.formatUid(uid));
+                    pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i));
+                }
             }
             pw.println();
-            mJobPackageTracker.dump(pw, "");
+            mJobPackageTracker.dump(pw, "", filterUidFinal);
             pw.println();
+            if (mJobPackageTracker.dumpHistory(pw, "", filterUidFinal)) {
+                pw.println();
+            }
             pw.println("Pending queue:");
             for (int i=0; i<mPendingJobs.size(); i++) {
                 JobStatus job = mPendingJobs.get(i);
@@ -1571,10 +1604,12 @@
                     }
                 }
             }
-            pw.println();
-            pw.print("mReadyToRock="); pw.println(mReadyToRock);
-            pw.print("mReportedActive="); pw.println(mReportedActive);
-            pw.print("mMaxActiveJobs="); pw.println(mMaxActiveJobs);
+            if (filterUid == -1) {
+                pw.println();
+                pw.print("mReadyToRock="); pw.println(mReadyToRock);
+                pw.print("mReportedActive="); pw.println(mReportedActive);
+                pw.print("mMaxActiveJobs="); pw.println(mMaxActiveJobs);
+            }
         }
         pw.println();
     }
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 02bc36ca..7593035 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -23,10 +23,8 @@
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.JobStore;
-import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Controls when apps are considered idle and if jobs pertaining to those apps should
@@ -123,11 +121,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw) {
+    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
         pw.println("AppIdle");
         pw.println("Parole On: " + mAppIdleParoleOn);
         mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
             @Override public void process(JobStatus jobStatus) {
+                // Skip printing details if the caller requested a filter
+                if (!jobStatus.shouldDump(filterUid)) {
+                    return;
+                }
                 pw.print("  ");
                 pw.print(jobStatus.getSourcePackageName());
                 pw.print(": runnable=");
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index 0772364..a0cb25f 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -194,15 +194,21 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.println("Batt.");
         pw.println("Stable power: " + mChargeTracker.isOnStablePower());
         Iterator<JobStatus> it = mTrackedTasks.iterator();
         if (it.hasNext()) {
-            pw.print(String.valueOf(it.next().hashCode()));
+            JobStatus jobStatus = it.next();
+            if (jobStatus.shouldDump(filterUid)) {
+                pw.print(String.valueOf(jobStatus.hashCode()));
+            }
         }
         while (it.hasNext()) {
-            pw.print("," + String.valueOf(it.next().hashCode()));
+            JobStatus jobStatus = it.next();
+            if (jobStatus.shouldDump(filterUid)) {
+                pw.print("," + String.valueOf(jobStatus.hashCode()));
+            }
         }
         pw.println();
     }
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index f5aac08..9fd22686 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -181,14 +181,16 @@
     };
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.println("Conn.");
         for (int i = 0; i < mTrackedJobs.size(); i++) {
             final JobStatus js = mTrackedJobs.get(i);
-            pw.println(String.valueOf(js.getJobId() + "," + js.getUid())
-                    + ": C=" + js.hasConnectivityConstraint()
-                    + ", UM=" + js.hasUnmeteredConstraint()
-                    + ", NR=" + js.hasNotRoamingConstraint());
+            if (js.shouldDump(filterUid)) {
+                pw.println(String.valueOf(js.getJobId() + "," + js.getUid())
+                        + ": C=" + js.hasConnectivityConstraint()
+                        + ", UM=" + js.hasUnmeteredConstraint()
+                        + ", NR=" + js.hasNotRoamingConstraint());
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index c5b1a3d..6722bfb 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -322,11 +322,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.println("Content.");
         boolean printed = false;
         Iterator<JobStatus> it = mTrackedTasks.iterator();
         while (it.hasNext()) {
+            JobStatus js = it.next();
+            if (!js.shouldDump(filterUid)) {
+                continue;
+            }
             if (!printed) {
                 pw.print("  ");
                 printed = true;
@@ -343,13 +347,24 @@
             pw.println("  Observers:");
             for (int i = 0; i < N; i++) {
                 ObserverInstance obs = mObservers.valueAt(i);
+                int M = obs.mJobs.size();
+                boolean shouldDump = false;
+                for (int j=0; j<M; j++) {
+                    JobInstance inst = obs.mJobs.valueAt(j);
+                    if (inst.mJobStatus.shouldDump(filterUid)) {
+                        shouldDump = true;
+                        break;
+                    }
+                }
+                if (!shouldDump) {
+                    continue;
+                }
                 pw.print("    ");
                 pw.print(mObservers.keyAt(i));
                 pw.print(" (");
                 pw.print(System.identityHashCode(obs));
                 pw.println("):");
                 pw.println("      Jobs:");
-                int M = obs.mJobs.size();
                 for (int j=0; j<M; j++) {
                     JobInstance inst = obs.mJobs.valueAt(j);
                     pw.print("        ");
diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index fe563d2..345a032 100644
--- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -29,10 +29,8 @@
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.JobStore;
-import com.android.server.job.StateChangedListener;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.Arrays;
 
 /**
@@ -175,10 +173,13 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(final PrintWriter pw) {
+    public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
         pw.println("DeviceIdleJobsController");
         mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
             @Override public void process(JobStatus jobStatus) {
+                if (!jobStatus.shouldDump(filterUid)) {
+                    return;
+                }
                 pw.print("  ");
                 pw.print(jobStatus.getSourcePackageName());
                 pw.print(": runnable=");
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 50aa882..c7a679c 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -190,12 +190,15 @@
     }
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.print("Idle: ");
         pw.println(mIdleTracker.isIdle() ? "true" : "false");
         pw.println(mTrackedTasks.size());
         for (int i = 0; i < mTrackedTasks.size(); i++) {
             final JobStatus js = mTrackedTasks.get(i);
+            if (!js.shouldDump(filterUid)) {
+                continue;
+            }
             pw.print("  ");
             pw.print(String.valueOf(js.getJobId() + "," + js.getUid()));
             pw.println("..");
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 19bede9..072787b 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -410,6 +410,11 @@
         return true;
     }
 
+    public boolean shouldDump(int filterUid) {
+        return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
+                || UserHandle.getAppId(getSourceUid()) == filterUid;
+    }
+
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java
index 0139039..1721fb9 100644
--- a/services/core/java/com/android/server/job/controllers/StateController.java
+++ b/services/core/java/com/android/server/job/controllers/StateController.java
@@ -64,5 +64,5 @@
     public void rescheduleForFailure(JobStatus newJob, JobStatus failureToReschedule) {
     }
 
-    public abstract void dumpControllerStateLocked(PrintWriter pw);
+    public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
 }
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index ab6768e..2f8ca7e 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -275,7 +275,7 @@
     };
 
     @Override
-    public void dumpControllerStateLocked(PrintWriter pw) {
+    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         final long nowElapsed = SystemClock.elapsedRealtime();
         pw.println("Alarms (" + SystemClock.elapsedRealtime() + ")");
         pw.println(
@@ -284,6 +284,9 @@
                 + "s");
         pw.println("Tracking:");
         for (JobStatus ts : mTrackedJobs) {
+            if (!ts.shouldDump(filterUid)) {
+                continue;
+            }
             pw.println(String.valueOf(ts.getJobId() + "," + ts.getUid())
                     + ": (" + (ts.hasTimingDelayConstraint() ? ts.getEarliestRunTime() : "N/A")
                     + ", " + (ts.hasDeadlineConstraint() ?ts.getLatestRunTimeElapsed() : "N/A")
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
new file mode 100644
index 0000000..9e4432d
--- /dev/null
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -0,0 +1,30 @@
+/*
+ * 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.server.net;
+
+/**
+ * Network Policy Manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class NetworkPolicyManagerInternal {
+
+    /**
+     * Resets all policies associated with a given user.
+     */
+    public abstract void resetUserState(int userId);
+}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 7ed75ca..a6055c1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -406,6 +406,10 @@
         mAppOps = context.getSystemService(AppOpsManager.class);
 
         mPackageMonitor = new MyPackageMonitor();
+
+        // Expose private service for system components to use.
+        LocalServices.addService(NetworkPolicyManagerInternal.class,
+                new NetworkPolicyManagerInternalImpl());
     }
 
     public void bindConnectivityManager(IConnectivityManager connManager) {
@@ -742,7 +746,7 @@
                     synchronized (mRulesLock) {
                         // Remove any persistable state for the given user; both cleaning up after a
                         // USER_REMOVED, and one last sanity check during USER_ADDED
-                        removeUserStateLocked(userId);
+                        removeUserStateLocked(userId, true);
                         if (action == ACTION_USER_ADDED) {
                             // Add apps that are whitelisted by default.
                             addDefaultRestrictBackgroundWhitelistUidsLocked(userId);
@@ -1742,12 +1746,13 @@
     }
 
     /**
-     * Remove any persistable state associated with given {@link UserHandle}, persisting
-     * if any changes are made.
+     * Removes any persistable state associated with given {@link UserHandle}, persisting
+     * if any changes that are made.
      */
-    void removeUserStateLocked(int userId) {
+    boolean removeUserStateLocked(int userId, boolean writePolicy) {
+
         if (LOGV) Slog.v(TAG, "removeUserStateLocked()");
-        boolean writePolicy = false;
+        boolean changed = false;
 
         // Remove entries from restricted background UID whitelist
         int[] wlUids = new int[0];
@@ -1762,7 +1767,7 @@
             for (int uid : wlUids) {
                 removeRestrictBackgroundWhitelistedUidLocked(uid, false, false);
             }
-            writePolicy = true;
+            changed = true;
         }
 
         // Remove entries from revoked default restricted background UID whitelist
@@ -1770,7 +1775,7 @@
             final int uid = mRestrictBackgroundWhitelistRevokedUids.keyAt(i);
             if (UserHandle.getUserId(uid) == userId) {
                 mRestrictBackgroundWhitelistRevokedUids.removeAt(i);
-                writePolicy = true;
+                changed = true;
             }
         }
 
@@ -1787,14 +1792,15 @@
             for (int uid : uids) {
                 mUidPolicy.delete(uid);
             }
-            writePolicy = true;
+            changed = true;
         }
 
         updateRulesForGlobalChangeLocked(true);
 
-        if (writePolicy) {
+        if (writePolicy && changed) {
             writePolicyLocked();
         }
+        return changed;
     }
 
     @Override
@@ -3295,4 +3301,18 @@
             }
         }
     }
+
+    private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
+
+        @Override
+        public void resetUserState(int userId) {
+            synchronized (mRulesLock) {
+                boolean changed = removeUserStateLocked(userId, false);
+                changed = addDefaultRestrictBackgroundWhitelistUidsLocked(userId) || changed;
+                if (changed) {
+                    writePolicyLocked();
+                }
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index f29970c..1315bcb 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -176,6 +176,9 @@
         mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
         mCreationTimeMs = previous.mCreationTimeMs;
         mVisibleSinceMs = previous.mVisibleSinceMs;
+        if(previous.sbn.getOverrideGroupKey() != null) {
+            sbn.setOverrideGroupKey(previous.sbn.getOverrideGroupKey());
+        }
         // Don't copy importance information or mGlobalSortKey, recompute them.
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 24a6171..c9ba003 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -164,6 +164,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.hardware.display.DisplayManager;
+import android.net.INetworkPolicyManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -243,6 +244,7 @@
 import com.android.server.ServiceThread;
 import com.android.server.SystemConfig;
 import com.android.server.Watchdog;
+import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.pm.PermissionsState.PermissionState;
 import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.pm.Settings.VersionInfo;
@@ -16159,6 +16161,10 @@
         }
     }
 
+    private void resetNetworkPolicies(int userId) {
+        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
+    }
+
     /**
      * Reverts user permission state changes (permissions and flags).
      *
@@ -16649,10 +16655,10 @@
     public void resetApplicationPreferences(int userId) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+        final long identity = Binder.clearCallingIdentity();
         // writer
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
+        try {
+            synchronized (mPackages) {
                 clearPackagePreferredActivitiesLPw(null, userId);
                 mSettings.applyDefaultPreferredAppsLPw(this, userId);
                 // TODO: We have to reset the default SMS and Phone. This requires
@@ -16664,9 +16670,10 @@
                 primeDomainVerificationsLPw(userId);
                 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
                 scheduleWritePackageRestrictionsLocked(userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
             }
+            resetNetworkPolicies(userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
     }
 
diff --git a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
index 249a076..77e8b1f 100644
--- a/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
+++ b/services/core/java/com/android/server/vr/EnabledComponentsObserver.java
@@ -207,6 +207,30 @@
         }
     }
 
+    /**
+     * Return all VrListenerService components installed for this user.
+     *
+     * @param userId ID of the user to check.
+     * @return a set of {@link ComponentName}s.
+     */
+    public ArraySet<ComponentName> getInstalled(int userId) {
+        synchronized (mLock) {
+            return mInstalledSet.get(userId);
+        }
+    }
+
+    /**
+     * Return all VrListenerService components enabled for this user.
+     *
+     * @param userId ID of the user to check.
+     * @return a set of {@link ComponentName}s.
+     */
+    public ArraySet<ComponentName> getEnabled(int userId) {
+        synchronized (mLock) {
+            return mEnabledSet.get(userId);
+        }
+    }
+
     private int[] getCurrentProfileIds() {
         UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         if (userManager == null) {
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index a9553a5..844b5e6 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -59,12 +59,13 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.StringBuilder;
-import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
 /**
  * Service tracking whether VR mode is active, and notifying listening services of state changes.
@@ -93,6 +94,7 @@
     public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager";
 
     private static final int PENDING_STATE_DELAY_MS = 300;
+    private static final int EVENT_LOG_SIZE = 32;
 
     private static native void initializeNative();
     private static native void setVrModeNative(boolean enabled);
@@ -117,6 +119,7 @@
     private String mPreviousCoarseLocationPackage;
     private String mPreviousManageOverlayPackage;
     private VrState mPendingState;
+    private final ArrayDeque<VrState> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
 
     private static final int MSG_VR_STATE_CHANGE = 0;
     private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -154,6 +157,8 @@
         final int userId;
         final ComponentName targetPackageName;
         final ComponentName callingPackage;
+        final long timestamp;
+        final boolean defaultPermissionsGranted;
 
         VrState(boolean enabled, ComponentName targetPackageName, int userId,
                 ComponentName callingPackage) {
@@ -161,8 +166,20 @@
             this.userId = userId;
             this.targetPackageName = targetPackageName;
             this.callingPackage = callingPackage;
+            this.defaultPermissionsGranted = false;
+            this.timestamp = System.currentTimeMillis();
         }
-    };
+
+        VrState(boolean enabled, ComponentName targetPackageName, int userId,
+            ComponentName callingPackage, boolean defaultPermissionsGranted) {
+            this.enabled = enabled;
+            this.userId = userId;
+            this.targetPackageName = targetPackageName;
+            this.callingPackage = callingPackage;
+            this.defaultPermissionsGranted = defaultPermissionsGranted;
+            this.timestamp = System.currentTimeMillis();
+        }
+    }
 
     private static final BinderChecker sBinderChecker = new BinderChecker() {
         @Override
@@ -235,22 +252,42 @@
                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
                 return;
             }
-            pw.print("mVrModeEnabled=");
-            pw.println(mVrModeEnabled);
-            pw.print("mCurrentVrModeUser=");
-            pw.println(mCurrentVrModeUser);
-            pw.print("mRemoteCallbacks=");
+            pw.println("********* Dump of VrManagerService *********");
+            pw.println("Previous state transitions:\n");
+            String tab = "  ";
+            dumpStateTransitions(pw);
+            pw.println("\n\nRemote Callbacks:");
             int i=mRemoteCallbacks.beginBroadcast(); // create the broadcast item array
             while(i-->0) {
+                pw.print(tab);
                 pw.print(mRemoteCallbacks.getBroadcastItem(i));
-                if (i>0) pw.print(", ");
+                if (i>0) pw.println(",");
             }
             mRemoteCallbacks.finishBroadcast();
-            pw.println();
-            pw.print("mCurrentVrService=");
-            pw.println(mCurrentVrService != null ? mCurrentVrService.getComponent() : "(none)");
-            pw.print("mCurrentVrModeComponent=");
-            pw.println(mCurrentVrModeComponent);
+            pw.println("\n");
+            pw.println("Installed VrListenerService components:");
+            int userId = mCurrentVrModeUser;
+            ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
+            if (installed == null || installed.size() == 0) {
+                pw.println("None");
+            } else {
+                for (ComponentName n : installed) {
+                    pw.print(tab);
+                    pw.println(n.flattenToString());
+                }
+            }
+            pw.println("Enabled VrListenerService components:");
+            ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
+            if (enabled == null || enabled.size() == 0) {
+                pw.println("None");
+            } else {
+                for (ComponentName n : enabled) {
+                    pw.print(tab);
+                    pw.println(n.flattenToString());
+                }
+            }
+            pw.println("\n");
+            pw.println("********* End of VrManagerService Dump *********");
         }
 
     };
@@ -486,6 +523,9 @@
 
             boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
                     EnabledComponentsObserver.NO_ERROR);
+            if (!mVrModeEnabled && !enabled) {
+                return validUserComponent; // Disabled -> Disabled transition does nothing.
+            }
 
             // Always send mode change events.
             changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null);
@@ -539,6 +579,7 @@
                     }
                 });
             }
+            logStateLocked();
 
             return validUserComponent;
         } finally {
@@ -827,6 +868,50 @@
         }
     }
 
+    private void logStateLocked() {
+        ComponentName currentBoundService = (mCurrentVrService == null) ? null :
+            mCurrentVrService.getComponent();
+        VrState current = new VrState(mVrModeEnabled, currentBoundService, mCurrentVrModeUser,
+            mCurrentVrModeComponent, mWasDefaultGranted);
+        if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
+            mLoggingDeque.removeFirst();
+        }
+        mLoggingDeque.add(current);
+    }
+
+    private void dumpStateTransitions(PrintWriter pw) {
+        SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+        String tab = "  ";
+        if (mLoggingDeque.size() == 0) {
+            pw.print(tab);
+            pw.println("None");
+        }
+        for (VrState state : mLoggingDeque) {
+            pw.print(d.format(new Date(state.timestamp)));
+            pw.print(tab);
+            pw.print("State changed to:");
+            pw.print(tab);
+            pw.println((state.enabled) ? "ENABLED" : "DISABLED");
+            if (state.enabled) {
+                pw.print(tab);
+                pw.print("User=");
+                pw.println(state.userId);
+                pw.print(tab);
+                pw.print("Current VR Activity=");
+                pw.println((state.callingPackage == null) ?
+                    "None" : state.callingPackage.flattenToString());
+                pw.print(tab);
+                pw.print("Bound VrListenerService=");
+                pw.println((state.targetPackageName == null) ?
+                    "None" : state.targetPackageName.flattenToString());
+                if (state.defaultPermissionsGranted) {
+                    pw.print(tab);
+                    pw.println("Default permissions granted to the bound VrListenerService.");
+                }
+            }
+        }
+    }
+
     /*
      * Implementation of VrManagerInternal calls.  These are callable from system services.
      */
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index abb1bb1..49dab0a 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -224,6 +224,12 @@
         if (transferWinAnimator != null) {
             mAllAppWinAnimators.remove(transferWinAnimator);
             toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
+            toAppAnimator.hasTransformation = transferWinAnimator.mAppAnimator.hasTransformation;
+            if (toAppAnimator.hasTransformation) {
+                toAppAnimator.transformation.set(transferWinAnimator.mAppAnimator.transformation);
+            } else {
+                toAppAnimator.transformation.clear();
+            }
             transferWinAnimator.mAppAnimator = toAppAnimator;
         }
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7ee26a0..efabe31 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -322,6 +322,32 @@
         mPreparedFrozenBounds.set(mBounds);
     }
 
+    /**
+     * Align the task to the adjusted bounds.
+     *
+     * @param adjustedBounds Adjusted bounds to which the task should be aligned.
+     * @param tempInsetBounds Insets bounds for the task.
+     * @param alignBottom True if the task's bottom should be aligned to the adjusted
+     *                    bounds's bottom; false if the task's top should be aligned
+     *                    the adjusted bounds's top.
+     */
+    void alignToAdjustedBounds(
+            Rect adjustedBounds, Rect tempInsetBounds, boolean alignBottom) {
+        if (!isResizeable() || mOverrideConfig == Configuration.EMPTY) {
+            return;
+        }
+
+        getBounds(mTmpRect2);
+        if (alignBottom) {
+            int offsetY = adjustedBounds.bottom - mTmpRect2.bottom;
+            mTmpRect2.offset(0, offsetY);
+        } else {
+            mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
+        }
+        setTempInsetBounds(tempInsetBounds);
+        resizeLocked(mTmpRect2, mOverrideConfig, false /* forced */);
+    }
+
     void resetScrollLocked() {
         if (mScrollValid) {
             mScrollValid = false;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 6c80d1a..b2f3df7 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -240,7 +240,7 @@
         Rect insetBounds = null;
         if (adjusted && isAdjustedForMinimizedDock()) {
             insetBounds = mBounds;
-        } else if (adjusted && isAdjustedForIme()) {
+        } else if (adjusted && mAdjustedForIme) {
             if (mImeGoingAway) {
                 insetBounds = mBounds;
             } else {
@@ -264,16 +264,9 @@
                 task.resizeLocked(null, null, false /* forced */);
                 task.getBounds(mTmpRect2);
                 task.scrollLocked(mTmpRect2);
-            } else if (task.isResizeable() && task.mOverrideConfig != Configuration.EMPTY) {
-                task.getBounds(mTmpRect2);
-                if (mAdjustedForIme && getDockSide() == DOCKED_TOP) {
-                    int offsetY = adjustedBounds.bottom - mTmpRect2.bottom;
-                    mTmpRect2.offset(0, offsetY);
-                } else {
-                    mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
-                }
-                task.setTempInsetBounds(tempInsetBounds);
-                task.resizeLocked(mTmpRect2, task.mOverrideConfig, false /* forced */);
+            } else {
+                final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
+                task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
             }
         }
     }
@@ -868,7 +861,7 @@
     }
 
     boolean isAdjustedForIme() {
-        return mAdjustedForIme || mImeGoingAway;
+        return mAdjustedForIme;
     }
 
     boolean isAnimatingForIme() {
@@ -1083,7 +1076,7 @@
     /**
      * Updates the adjustment depending on it's current state.
      */
-    void updateAdjustedBounds() {
+    private void updateAdjustedBounds() {
         boolean adjust = false;
         if (mMinimizeAmount != 0f) {
             adjust = adjustForMinimizedDockedStack(mMinimizeAmount);
@@ -1103,6 +1096,16 @@
         }
     }
 
+    void applyAdjustForImeIfNeeded(Task task) {
+        if (mMinimizeAmount != 0f || !mAdjustedForIme || mAdjustedBounds.isEmpty()) {
+            return;
+        }
+
+        final Rect insetBounds = mImeGoingAway ? mBounds : mFullyAdjustedImeBounds;
+        task.alignToAdjustedBounds(mAdjustedBounds, insetBounds, getDockSide() == DOCKED_TOP);
+        mDisplayContent.layoutNeeded = true;
+    }
+
     boolean isAdjustedForMinimizedDockedStack() {
         return mMinimizeAmount != 0f;
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index dfe4421..cf5cdc3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2077,6 +2077,10 @@
             // we need to update this new window's scroll position when it's added.
             win.applyScrollIfNeeded();
 
+            // If the window is being added to a stack that's currently adjusted for IME,
+            // make sure to apply the same adjust to this new window.
+            win.applyAdjustForImeIfNeeded();
+
             if (type == TYPE_DOCK_DIVIDER) {
                 getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6a2a91d..304b2a7 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1620,6 +1620,13 @@
         }
     }
 
+    void applyAdjustForImeIfNeeded() {
+        final Task task = getTask();
+        if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) {
+            task.mStack.applyAdjustForImeIfNeeded(task);
+        }
+    }
+
     int getTouchableRegion(Region region, int flags) {
         final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
         if (modal && mAppToken != null) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index a45ae60..240323d 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -19,7 +19,6 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
@@ -71,6 +70,8 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.animation.Animation;
 
+import com.android.server.wm.WindowManagerService.H;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -1052,7 +1053,7 @@
         mService.mSkipAppTransitionAnimation = false;
         mService.mNoAnimationNotifyOnTransitionFinished.clear();
 
-        mService.mH.removeMessages(APP_TRANSITION_TIMEOUT);
+        mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
 
         mService.rebuildAppWindowListLocked();
 
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 183a370..ecdc71e 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -234,8 +234,9 @@
         for (int i = 0; i < num_modes; i++) {
             int added;
 
-            added = snprintf(offset, remaining, "%s_time=%" PRIu64 " %s_count=%" PRIu64 " ",
-                    list[i].name, list[i].residency_in_msec_since_boot, list[i].name,
+            added = snprintf(offset, remaining,
+                    "state_%d name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                    i + 1, list[i].name, list[i].residency_in_msec_since_boot,
                     list[i].total_transitions);
             if (added < 0) {
                 break;
@@ -248,10 +249,10 @@
             total_added += added;
 
             for (unsigned int j = 0; j < list[i].number_of_voters; j++) {
-                added = snprintf(offset, remaining, "%s_time=%" PRIu64 " %s_count=%" PRIu64 " ",
-                        list[i].voters[j].name,
+                added = snprintf(offset, remaining,
+                        "voter_%d name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                        j + 1, list[i].voters[j].name,
                         list[i].voters[j].total_time_in_msec_voted_for_since_boot,
-                        list[i].voters[j].name,
                         list[i].voters[j].total_number_of_times_voted_since_boot);
                 if (added < 0) {
                     break;