Merge "Import translations. DO NOT MERGE" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 28b8d97..35514f2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6457,7 +6457,7 @@
   public class NetworkStatsManager {
     method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
-    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
     method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -23727,7 +23727,6 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isMetered();
     method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -28370,7 +28369,7 @@
     field public static final int LOLLIPOP = 21; // 0x15
     field public static final int LOLLIPOP_MR1 = 22; // 0x16
     field public static final int M = 23; // 0x17
-    field public static final int N = 10000; // 0x2710
+    field public static final int N = 24; // 0x18
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -34507,7 +34506,7 @@
     field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
     field public static final int RECEIVE_OPTIONS_DEFAULT = 0; // 0x0
     field public static final int RECEIVE_OPTIONS_DROP = 1; // 0x1
-    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE = 2; // 0x2
+    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 2; // 0x2
     field public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; // 0x1
     field public static final int SEND_STATUS_ERROR = 2; // 0x2
     field public static final int SEND_STATUS_OK = 0; // 0x0
@@ -36752,11 +36751,9 @@
 package android.telephony {
 
   public class CarrierConfigManager {
-    method public android.os.PersistableBundle getConfig(int);
     method public android.os.PersistableBundle getConfig();
-    method public deprecated android.os.PersistableBundle getConfigForSubId(int);
-    method public void notifyConfigChanged(int);
-    method public deprecated void notifyConfigChangedForSubId(int);
+    method public android.os.PersistableBundle getConfigForSubId(int);
+    method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
@@ -37928,7 +37925,7 @@
     ctor public MockApplication();
   }
 
-  public deprecated class MockContentProvider extends android.content.ContentProvider {
+  public class MockContentProvider extends android.content.ContentProvider {
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -37940,13 +37937,13 @@
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
-  public deprecated class MockContentResolver extends android.content.ContentResolver {
+  public class MockContentResolver extends android.content.ContentResolver {
     ctor public MockContentResolver();
     ctor public MockContentResolver(android.content.Context);
     method public void addProvider(java.lang.String, android.content.ContentProvider);
   }
 
-  public deprecated class MockContext extends android.content.Context {
+  public class MockContext extends android.content.Context {
     ctor public MockContext();
     method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
     method public int checkCallingOrSelfPermission(java.lang.String);
@@ -42557,7 +42554,6 @@
     method public boolean hasNestedScrollingParent();
     method public boolean hasOnClickListeners();
     method public boolean hasOverlappingRendering();
-    method public boolean hasPointerCapture();
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
@@ -42670,6 +42666,7 @@
     method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
     method public boolean performAccessibilityAction(int, android.os.Bundle);
     method public boolean performClick();
+    method public boolean performContextClick(float, float);
     method public boolean performContextClick();
     method public boolean performHapticFeedback(int);
     method public boolean performHapticFeedback(int, int);
@@ -42687,7 +42684,6 @@
     method public void postOnAnimation(java.lang.Runnable);
     method public void postOnAnimationDelayed(java.lang.Runnable, long);
     method public void refreshDrawableState();
-    method public void releasePointerCapture();
     method public boolean removeCallbacks(java.lang.Runnable);
     method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
     method public void removeOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
@@ -42698,7 +42694,6 @@
     method public boolean requestFocus(int, android.graphics.Rect);
     method public final boolean requestFocusFromTouch();
     method public void requestLayout();
-    method public void requestPointerCapture();
     method public boolean requestRectangleOnScreen(android.graphics.Rect);
     method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
diff --git a/api/removed.txt b/api/removed.txt
index 42c64ea..0ff2476 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -31,37 +31,6 @@
 
 }
 
-package android.app.usage {
-
-  public class DataUsagePolicy {
-    field public final int networkType;
-    field public final java.lang.String[] subscriberIds;
-    field public final long thresholdInBytes;
-    field public final int[] uids;
-  }
-
-  public static class DataUsagePolicy.Builder {
-    ctor public DataUsagePolicy.Builder();
-    method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
-    method public android.app.usage.DataUsagePolicy.Builder addUid(int);
-    method public android.app.usage.DataUsagePolicy build();
-    method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
-    method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
-  }
-
-  public class NetworkStatsManager {
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
-    method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
-  }
-
-  public static abstract class NetworkStatsManager.DataUsageCallback {
-    ctor public NetworkStatsManager.DataUsageCallback();
-    method public deprecated void onLimitReached();
-  }
-
-}
-
 package android.content {
 
   public abstract class Context {
diff --git a/api/system-current.txt b/api/system-current.txt
index b31ff3f..1e4722d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6738,7 +6738,7 @@
   public class NetworkStatsManager {
     method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
-    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
     method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -25549,7 +25549,6 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isMetered();
     method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -30809,7 +30808,7 @@
     field public static final int LOLLIPOP = 21; // 0x15
     field public static final int LOLLIPOP_MR1 = 22; // 0x16
     field public static final int M = 23; // 0x17
-    field public static final int N = 10000; // 0x2710
+    field public static final int N = 24; // 0x18
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -37213,7 +37212,7 @@
     field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
     field public static final int RECEIVE_OPTIONS_DEFAULT = 0; // 0x0
     field public static final int RECEIVE_OPTIONS_DROP = 1; // 0x1
-    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE = 2; // 0x2
+    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 2; // 0x2
     field public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; // 0x1
     field public static final int SEND_STATUS_ERROR = 2; // 0x2
     field public static final int SEND_STATUS_OK = 0; // 0x0
@@ -39683,12 +39682,10 @@
 package android.telephony {
 
   public class CarrierConfigManager {
-    method public android.os.PersistableBundle getConfig(int);
     method public android.os.PersistableBundle getConfig();
-    method public deprecated android.os.PersistableBundle getConfigForSubId(int);
+    method public android.os.PersistableBundle getConfigForSubId(int);
     method public static android.os.PersistableBundle getDefaultConfig();
-    method public void notifyConfigChanged(int);
-    method public deprecated void notifyConfigChangedForSubId(int);
+    method public void notifyConfigChangedForSubId(int);
     method public void updateConfigForPhoneId(int, java.lang.String);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
@@ -40914,7 +40911,7 @@
     ctor public MockApplication();
   }
 
-  public deprecated class MockContentProvider extends android.content.ContentProvider {
+  public class MockContentProvider extends android.content.ContentProvider {
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -40926,13 +40923,13 @@
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
-  public deprecated class MockContentResolver extends android.content.ContentResolver {
+  public class MockContentResolver extends android.content.ContentResolver {
     ctor public MockContentResolver();
     ctor public MockContentResolver(android.content.Context);
     method public void addProvider(java.lang.String, android.content.ContentProvider);
   }
 
-  public deprecated class MockContext extends android.content.Context {
+  public class MockContext extends android.content.Context {
     ctor public MockContext();
     method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
     method public int checkCallingOrSelfPermission(java.lang.String);
@@ -45555,7 +45552,6 @@
     method public boolean hasNestedScrollingParent();
     method public boolean hasOnClickListeners();
     method public boolean hasOverlappingRendering();
-    method public boolean hasPointerCapture();
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
@@ -45668,6 +45664,7 @@
     method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
     method public boolean performAccessibilityAction(int, android.os.Bundle);
     method public boolean performClick();
+    method public boolean performContextClick(float, float);
     method public boolean performContextClick();
     method public boolean performHapticFeedback(int);
     method public boolean performHapticFeedback(int, int);
@@ -45685,7 +45682,6 @@
     method public void postOnAnimation(java.lang.Runnable);
     method public void postOnAnimationDelayed(java.lang.Runnable, long);
     method public void refreshDrawableState();
-    method public void releasePointerCapture();
     method public boolean removeCallbacks(java.lang.Runnable);
     method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
     method public void removeOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
@@ -45696,7 +45692,6 @@
     method public boolean requestFocus(int, android.graphics.Rect);
     method public final boolean requestFocusFromTouch();
     method public void requestLayout();
-    method public void requestPointerCapture();
     method public boolean requestRectangleOnScreen(android.graphics.Rect);
     method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 4873605..715312f 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -29,37 +29,6 @@
 
 }
 
-package android.app.usage {
-
-  public class DataUsagePolicy {
-    field public final int networkType;
-    field public final java.lang.String[] subscriberIds;
-    field public final long thresholdInBytes;
-    field public final int[] uids;
-  }
-
-  public static class DataUsagePolicy.Builder {
-    ctor public DataUsagePolicy.Builder();
-    method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
-    method public android.app.usage.DataUsagePolicy.Builder addUid(int);
-    method public android.app.usage.DataUsagePolicy build();
-    method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
-    method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
-  }
-
-  public class NetworkStatsManager {
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
-    method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
-  }
-
-  public static abstract class NetworkStatsManager.DataUsageCallback {
-    ctor public NetworkStatsManager.DataUsageCallback();
-    method public deprecated void onLimitReached();
-  }
-
-}
-
 package android.content {
 
   public abstract class Context {
diff --git a/api/test-current.txt b/api/test-current.txt
index 0af02451..6dc2e48 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6463,7 +6463,7 @@
   public class NetworkStatsManager {
     method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
-    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int);
+    method public android.app.usage.NetworkStats queryDetailsForUidTag(int, java.lang.String, long, long, int, int) throws java.lang.SecurityException;
     method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
     method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
@@ -23797,7 +23797,6 @@
     method public boolean isConnected();
     method public boolean isConnectedOrConnecting();
     method public boolean isFailover();
-    method public boolean isMetered();
     method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
@@ -28440,7 +28439,7 @@
     field public static final int LOLLIPOP = 21; // 0x15
     field public static final int LOLLIPOP_MR1 = 22; // 0x16
     field public static final int M = 23; // 0x17
-    field public static final int N = 10000; // 0x2710
+    field public static final int N = 24; // 0x18
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -34585,7 +34584,7 @@
     field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
     field public static final int RECEIVE_OPTIONS_DEFAULT = 0; // 0x0
     field public static final int RECEIVE_OPTIONS_DROP = 1; // 0x1
-    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE = 2; // 0x2
+    field public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 2; // 0x2
     field public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; // 0x1
     field public static final int SEND_STATUS_ERROR = 2; // 0x2
     field public static final int SEND_STATUS_OK = 0; // 0x0
@@ -36830,11 +36829,9 @@
 package android.telephony {
 
   public class CarrierConfigManager {
-    method public android.os.PersistableBundle getConfig(int);
     method public android.os.PersistableBundle getConfig();
-    method public deprecated android.os.PersistableBundle getConfigForSubId(int);
-    method public void notifyConfigChanged(int);
-    method public deprecated void notifyConfigChangedForSubId(int);
+    method public android.os.PersistableBundle getConfigForSubId(int);
+    method public void notifyConfigChangedForSubId(int);
     field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
     field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
@@ -38006,7 +38003,7 @@
     ctor public MockApplication();
   }
 
-  public deprecated class MockContentProvider extends android.content.ContentProvider {
+  public class MockContentProvider extends android.content.ContentProvider {
     ctor protected MockContentProvider();
     ctor public MockContentProvider(android.content.Context);
     ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]);
@@ -38018,13 +38015,13 @@
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
-  public deprecated class MockContentResolver extends android.content.ContentResolver {
+  public class MockContentResolver extends android.content.ContentResolver {
     ctor public MockContentResolver();
     ctor public MockContentResolver(android.content.Context);
     method public void addProvider(java.lang.String, android.content.ContentProvider);
   }
 
-  public deprecated class MockContext extends android.content.Context {
+  public class MockContext extends android.content.Context {
     ctor public MockContext();
     method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
     method public int checkCallingOrSelfPermission(java.lang.String);
@@ -42637,7 +42634,6 @@
     method public boolean hasNestedScrollingParent();
     method public boolean hasOnClickListeners();
     method public boolean hasOverlappingRendering();
-    method public boolean hasPointerCapture();
     method public boolean hasTransientState();
     method public boolean hasWindowFocus();
     method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
@@ -42750,6 +42746,7 @@
     method protected boolean overScrollBy(int, int, int, int, int, int, int, int, boolean);
     method public boolean performAccessibilityAction(int, android.os.Bundle);
     method public boolean performClick();
+    method public boolean performContextClick(float, float);
     method public boolean performContextClick();
     method public boolean performHapticFeedback(int);
     method public boolean performHapticFeedback(int, int);
@@ -42767,7 +42764,6 @@
     method public void postOnAnimation(java.lang.Runnable);
     method public void postOnAnimationDelayed(java.lang.Runnable, long);
     method public void refreshDrawableState();
-    method public void releasePointerCapture();
     method public boolean removeCallbacks(java.lang.Runnable);
     method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
     method public void removeOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
@@ -42778,7 +42774,6 @@
     method public boolean requestFocus(int, android.graphics.Rect);
     method public final boolean requestFocusFromTouch();
     method public void requestLayout();
-    method public void requestPointerCapture();
     method public boolean requestRectangleOnScreen(android.graphics.Rect);
     method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
     method public final void requestUnbufferedDispatch(android.view.MotionEvent);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 42c64ea..0ff2476 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -31,37 +31,6 @@
 
 }
 
-package android.app.usage {
-
-  public class DataUsagePolicy {
-    field public final int networkType;
-    field public final java.lang.String[] subscriberIds;
-    field public final long thresholdInBytes;
-    field public final int[] uids;
-  }
-
-  public static class DataUsagePolicy.Builder {
-    ctor public DataUsagePolicy.Builder();
-    method public android.app.usage.DataUsagePolicy.Builder addSubscriberId(java.lang.String);
-    method public android.app.usage.DataUsagePolicy.Builder addUid(int);
-    method public android.app.usage.DataUsagePolicy build();
-    method public android.app.usage.DataUsagePolicy.Builder setNetworkType(int);
-    method public android.app.usage.DataUsagePolicy.Builder setThreshold(long);
-  }
-
-  public class NetworkStatsManager {
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.DataUsageCallback, android.os.Handler);
-    method public void registerDataUsageCallback(android.app.usage.DataUsagePolicy, android.app.usage.NetworkStatsManager.UsageCallback, android.os.Handler);
-    method public void unregisterDataUsageCallback(android.app.usage.NetworkStatsManager.DataUsageCallback);
-  }
-
-  public static abstract class NetworkStatsManager.DataUsageCallback {
-    ctor public NetworkStatsManager.DataUsageCallback();
-    method public deprecated void onLimitReached();
-  }
-
-}
-
 package android.content {
 
   public abstract class Context {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 30753c1..7198146b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5007,8 +5007,11 @@
                 return;
             }
         }
-        throw new AssertionError("chosen locale " + bestLocale + " must be present in LocaleList: "
-                + newLocaleList.toLanguageTags());
+
+        // The app may have overridden the LocaleList with its own Locale
+        // (not present in the available list). Push the chosen Locale
+        // to the front of the list.
+        LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
     }
 
     private void handleBindApplication(AppBindData data) {
diff --git a/core/java/android/app/usage/DataUsagePolicy.java b/core/java/android/app/usage/DataUsagePolicy.java
deleted file mode 100644
index ee6b60c..0000000
--- a/core/java/android/app/usage/DataUsagePolicy.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy
- * of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package android.app.usage;
-
-import android.net.ConnectivityManager;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.IntArray;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Defines a policy for data usage callbacks, made through {@link DataUsagePolicy.Builder} and used
- * to be notified on data usage via {@link NetworkStatsManager#registerDataUsageCallback}.
- * @removed
- */
-public class DataUsagePolicy {
-
-    /**
-     * Network type to be monitored, as defined in {@link ConnectivityManager}, e.g.
-     * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} etc.
-     */
-    public final int networkType;
-
-    /**
-     * Set of subscriber ids to be monitored for the given network type. May be empty if not
-     * applicable.
-     * <p>Should not be modified once created.
-     */
-    public final String[] subscriberIds;
-
-    /**
-     * Set of UIDs of which to monitor data usage.
-     *
-     * <p>If not {@code null}, the caller will be notified when any of the uids exceed
-     * the given threshold. If empty all uids for which the calling process has access
-     * to stats will be monitored.
-     * <p>Should not be modified once created.
-     */
-    public final int[] uids;
-
-    /**
-     * Threshold in bytes to be notified on.
-     */
-    public final long thresholdInBytes;
-
-    /**
-     * @hide
-     */
-    DataUsagePolicy(int networkType, String[] subscriberIds, int[] uids,
-                long thresholdInBytes) {
-        this.networkType = networkType;
-        this.subscriberIds = subscriberIds;
-        this.uids = uids;
-        this.thresholdInBytes = thresholdInBytes;
-    }
-
-    /**
-     * Builder used to create {@link DataUsagePolicy} objects.
-     */
-    public static class Builder {
-        private static final int INVALID_NETWORK_TYPE = -1;
-        private int mNetworkType = INVALID_NETWORK_TYPE;
-        private List<String> mSubscriberList = new ArrayList<>();
-        private IntArray mUids = new IntArray();
-        private long mThresholdInBytes;
-
-        /**
-         * Default constructor for Builder.
-         */
-        public Builder() {}
-
-        /**
-         * Build {@link DataUsagePolicy} given the current policies.
-         */
-        public DataUsagePolicy build() {
-            if (mNetworkType == INVALID_NETWORK_TYPE) {
-                throw new IllegalArgumentException(
-                        "DataUsagePolicy requires a valid network type to be set");
-            }
-            return new DataUsagePolicy(mNetworkType,
-                    mSubscriberList.toArray(new String[mSubscriberList.size()]),
-                    mUids.toArray(), mThresholdInBytes);
-        }
-
-        /**
-         * Specifies that the given {@code subscriberId} should be monitored.
-         *
-         * @param subscriberId the subscriber id of the network interface.
-         */
-        public Builder addSubscriberId(String subscriberId) {
-            mSubscriberList.add(subscriberId);
-            return this;
-        }
-
-        /**
-         * Specifies that the given {@code uid} should be monitored.
-         */
-        public Builder addUid(int uid) {
-            mUids.add(uid);
-            return this;
-        }
-
-        /**
-         * Specifies that the callback should monitor the given network. It is mandatory
-         * to set one.
-         *
-         * @param networkType As defined in {@link ConnectivityManager}, e.g.
-         *            {@link ConnectivityManager#TYPE_MOBILE},
-         *            {@link ConnectivityManager#TYPE_WIFI}, etc.
-         */
-        public Builder setNetworkType(int networkType) {
-            mNetworkType = networkType;
-            return this;
-        }
-
-        /**
-         * Sets the threshold in bytes on which the listener should be called. The framework may
-         * impose a minimum threshold to avoid too many notifications to be triggered.
-         */
-        public Builder setThreshold(long thresholdInBytes) {
-            mThresholdInBytes = thresholdInBytes;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "DataUsagePolicy [ networkType=" + networkType
-                + ", subscriberIds=" + Arrays.toString(subscriberIds)
-                + ", uids=" + Arrays.toString(uids)
-                + ", thresholdInBytes=" + thresholdInBytes + " ]";
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof DataUsagePolicy == false) return false;
-        DataUsagePolicy that = (DataUsagePolicy) obj;
-        return that.networkType == this.networkType
-                && Arrays.deepEquals(that.subscriberIds, this.subscriberIds)
-                && Arrays.equals(that.uids, this.uids)
-                && that.thresholdInBytes == this.thresholdInBytes;
-    }
-
-    @Override
-    public int hashCode() {
-        // Start with a non-zero constant.
-        int result = 17;
-
-        // Include a hash for each field.
-        result = 31 * result + networkType;
-        result = 31 * result + Arrays.deepHashCode(subscriberIds);
-        result = 31 * result + Arrays.hashCode(uids);
-        result = 31 * result + (int) (thresholdInBytes ^ (thresholdInBytes >>> 32));
-
-        return result;
-   }
-}
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 4a28117..720c84a 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -240,18 +240,13 @@
      *            {@link java.lang.System#currentTimeMillis}.
      * @param uid UID of app
      * @param tag TAG of interest. Use {@link NetworkStats.Bucket#TAG_NONE} for no tags.
-     * @return Statistics object or null if permissions are insufficient or error happened during
-     *         statistics collection.
+     * @return Statistics object or null if an error happened during statistics collection.
+     * @throws SecurityException if permissions are insufficient to read network statistics.
      */
     public NetworkStats queryDetailsForUidTag(int networkType, String subscriberId,
-            long startTime, long endTime, int uid, int tag) {
+            long startTime, long endTime, int uid, int tag) throws SecurityException {
         NetworkTemplate template;
-        try {
-            template = createTemplate(networkType, subscriberId);
-        } catch (IllegalArgumentException e) {
-            if (DBG) Log.e(TAG, "Cannot create template", e);
-            return null;
-        }
+        template = createTemplate(networkType, subscriberId);
 
         NetworkStats result;
         try {
@@ -303,17 +298,6 @@
         return result;
     }
 
-    /** @removed */
-    public void registerDataUsageCallback(DataUsagePolicy policy, DataUsageCallback callback,
-                @Nullable Handler handler) {}
-
-    /** @removed */
-    public void registerDataUsageCallback(DataUsagePolicy policy, UsageCallback callback,
-                @Nullable Handler handler) {}
-
-    /** @removed */
-    public void unregisterDataUsageCallback(DataUsageCallback callback) {}
-
     /**
      * Registers to receive notifications about data usage on specified networks.
      *
@@ -396,13 +380,6 @@
         }
     }
 
-    /** @removed */
-    public static abstract class DataUsageCallback {
-        /** @removed */
-        @Deprecated
-        public void onLimitReached() {}
-    }
-
     /**
      * Base class for usage callbacks. Should be extended by applications wanting notifications.
      */
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 2d9f4a7..cd14469 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -34,7 +34,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.SparseArray;
 import android.util.TypedValue;
@@ -187,19 +186,28 @@
                 idsToUpdate[i] = mViews.keyAt(i);
             }
         }
-        List<RemoteViews> updatedViews;
-        int[] updatedIds = new int[idsToUpdate.length];
+        List<PendingHostUpdate> updates;
         try {
-            updatedViews = sService.startListening(
-                    mCallbacks, mContextOpPackageName, mHostId, idsToUpdate, updatedIds).getList();
+            updates = sService.startListening(
+                    mCallbacks, mContextOpPackageName, mHostId, idsToUpdate).getList();
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
 
-        int N = updatedViews.size();
+        int N = updates.size();
         for (int i = 0; i < N; i++) {
-            updateAppWidgetView(updatedIds[i], updatedViews.get(i));
+            PendingHostUpdate update = updates.get(i);
+            switch (update.type) {
+                case PendingHostUpdate.TYPE_VIEWS_UPDATE:
+                    updateAppWidgetView(update.appWidgetId, update.views);
+                    break;
+                case PendingHostUpdate.TYPE_PROVIDER_CHANGED:
+                    onProviderChanged(update.appWidgetId, update.widgetInfo);
+                    break;
+                case PendingHostUpdate.TYPE_VIEW_DATA_CHANGED:
+                    viewDataChanged(update.appWidgetId, update.viewId);
+            }
         }
     }
 
diff --git a/core/java/android/appwidget/PendingHostUpdate.java b/core/java/android/appwidget/PendingHostUpdate.java
new file mode 100644
index 0000000..5780319
--- /dev/null
+++ b/core/java/android/appwidget/PendingHostUpdate.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.appwidget;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.RemoteViews;
+
+/**
+ * @hide
+ */
+public class PendingHostUpdate implements Parcelable {
+
+    static final int TYPE_VIEWS_UPDATE = 0;
+    static final int TYPE_PROVIDER_CHANGED = 1;
+    static final int TYPE_VIEW_DATA_CHANGED = 2;
+
+    final int appWidgetId;
+    final int type;
+    RemoteViews views;
+    AppWidgetProviderInfo widgetInfo;
+    int viewId;
+
+    public static PendingHostUpdate updateAppWidget(int appWidgetId, RemoteViews views) {
+        PendingHostUpdate update = new PendingHostUpdate(appWidgetId, TYPE_VIEWS_UPDATE);
+        update.views = views;
+        return update;
+    }
+
+    public static PendingHostUpdate providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
+        PendingHostUpdate update = new PendingHostUpdate(appWidgetId, TYPE_PROVIDER_CHANGED);
+        update.widgetInfo = info;
+        return update;
+    }
+
+    public static PendingHostUpdate viewDataChanged(int appWidgetId, int viewId) {
+        PendingHostUpdate update = new PendingHostUpdate(appWidgetId, TYPE_VIEW_DATA_CHANGED);
+        update.viewId = viewId;
+        return update;
+    }
+
+    private PendingHostUpdate(int appWidgetId, int type) {
+        this.appWidgetId = appWidgetId;
+        this.type = type;
+    }
+
+    private PendingHostUpdate(Parcel in) {
+        appWidgetId = in.readInt();
+        type = in.readInt();
+
+        switch (type) {
+            case TYPE_VIEWS_UPDATE:
+                if (0 != in.readInt()) {
+                    views = new RemoteViews(in);
+                }
+                break;
+            case TYPE_PROVIDER_CHANGED:
+                if (0 != in.readInt()) {
+                    widgetInfo = new AppWidgetProviderInfo(in);
+                }
+                break;
+            case TYPE_VIEW_DATA_CHANGED:
+                viewId = in.readInt();
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(appWidgetId);
+        dest.writeInt(type);
+        switch (type) {
+            case TYPE_VIEWS_UPDATE:
+                writeNullParcelable(views, dest, flags);
+                break;
+            case TYPE_PROVIDER_CHANGED:
+                writeNullParcelable(widgetInfo, dest, flags);
+                break;
+            case TYPE_VIEW_DATA_CHANGED:
+                dest.writeInt(viewId);
+                break;
+        }
+    }
+
+    private void writeNullParcelable(Parcelable p, Parcel dest, int flags) {
+        if (p != null) {
+            dest.writeInt(1);
+            p.writeToParcel(dest, flags);
+        } else {
+            dest.writeInt(0);
+        }
+    }
+
+    /**
+     * Parcelable.Creator that instantiates PendingHostUpdate objects
+     */
+    public static final Parcelable.Creator<PendingHostUpdate> CREATOR
+            = new Parcelable.Creator<PendingHostUpdate>() {
+        public PendingHostUpdate createFromParcel(Parcel parcel) {
+            return new PendingHostUpdate(parcel);
+        }
+
+        public PendingHostUpdate[] newArray(int size) {
+            return new PendingHostUpdate[size];
+        }
+    };
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ebd833e..fc579a9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1415,6 +1415,8 @@
      * this context. This is typically used to migrate data between storage
      * locations after an upgrade, such as migrating to device protected
      * storage.
+     * <p>
+     * The database must be closed before being moved.
      *
      * @param sourceContext The source context which contains the existing
      *            database to move.
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 49c106e..a9c09c4 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -81,6 +81,4 @@
 
     void setPointerIconType(int typeId);
     void setCustomPointerIcon(in PointerIcon icon);
-
-    void setPointerIconDetached(boolean detached);
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index a5aeae3..803337b 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -893,24 +893,6 @@
         }
     }
 
-    /**
-     * Update the pointer icon status. When detached, the pointer icon disappears, and further
-     * mouse location will be stuck at the current point. Mouse movement events will still arrive,
-     * and movement should be handled through {@link MotionEvent.AXIS_RELATIVE_X} and
-     * {@link MotionEvent.AXIS_RELATIVE_Y}.
-     *
-     * @param detached true if the icon will be detached from the actual mouse movement.
-     *
-     * @hide
-     */
-    public void setPointerIconDetached(boolean detached) {
-        try {
-            mIm.setPointerIconDetached(detached);
-        } catch (RemoteException ex) {
-            throw ex.rethrowFromSystemServer();
-        }
-    }
-
     private void populateInputDevicesLocked() {
         if (mInputDevicesChangedListener == null) {
             final InputDevicesChangedListener listener = new InputDevicesChangedListener();
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index b6c5c6f..42f5feb 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -334,6 +334,7 @@
      *
      * @return {@code true} if large transfers should be avoided, otherwise
      *         {@code false}.
+     * @hide
      */
     public boolean isMetered() {
         synchronized (this) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7e1fc15..dc7be6b 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -671,7 +671,7 @@
         /**
          * N is for ¯\_(ツ)_/¯.
          */
-        public static final int N = CUR_DEVELOPMENT;
+        public static final int N = 24;
     }
 
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 438bb8c..9e8e5ef 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2230,19 +2230,37 @@
          * @param outConfig Where to place the configuration settings.
          */
         public static void getConfiguration(ContentResolver cr, Configuration outConfig) {
-            getConfigurationForUser(cr, outConfig, UserHandle.myUserId());
+            adjustConfigurationForUser(cr, outConfig, UserHandle.myUserId(),
+                    false /* updateSettingsIfEmpty */);
         }
 
         /** @hide */
-        public static void getConfigurationForUser(ContentResolver cr, Configuration outConfig,
-                int userHandle) {
+        public static void adjustConfigurationForUser(ContentResolver cr, Configuration outConfig,
+                int userHandle, boolean updateSettingsIfEmpty) {
             outConfig.fontScale = Settings.System.getFloatForUser(
                     cr, FONT_SCALE, DEFAULT_FONT_SCALE, userHandle);
             if (outConfig.fontScale < 0) {
                 outConfig.fontScale = DEFAULT_FONT_SCALE;
             }
-            outConfig.setLocales(LocaleList.forLanguageTags(
-                    Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle)));
+
+            final String localeValue =
+                    Settings.System.getStringForUser(cr, SYSTEM_LOCALES, userHandle);
+            if (localeValue != null) {
+                outConfig.setLocales(LocaleList.forLanguageTags(localeValue));
+            } else {
+                // Do not update configuration with emtpy settings since we need to take over the
+                // locale list of previous user if the settings value is empty. This happens when a
+                // new user is created.
+
+                if (updateSettingsIfEmpty) {
+                    // Make current configuration persistent. This is necessary the first time a
+                    // user log in. At the first login, the configuration settings are empty, so we
+                    // need to store the adjusted configuration as the initial settings.
+                    Settings.System.putStringForUser(
+                            cr, SYSTEM_LOCALES, outConfig.getLocales().toLanguageTags(),
+                            userHandle);
+                }
+            }
         }
 
         /**
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index 140341c..88a78c3 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -56,7 +56,7 @@
      * new message notification should be shown.
      *
      * @see #RECEIVE_OPTIONS_DROP
-     * @see #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE
+     * @see #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE
      */
     public static final int RECEIVE_OPTIONS_DEFAULT = 0;
 
@@ -72,7 +72,7 @@
      * credential-encrypted storage of the device is not available before the user unlocks the
      * phone. It is only applicable to devices that support file-based encryption.
      */
-    public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE = 0x2;
+    public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 0x2;
 
     /**
      * Indicates that an SMS or MMS message was successfully sent.
@@ -148,7 +148,7 @@
      * @param subId SMS subscription ID of the SIM
      * @param callback result callback. Call with a bitmask integer to indicate how the incoming
      *        text SMS should be handled by the platform. Use {@link #RECEIVE_OPTIONS_DROP} and
-     *        {@link #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE}
+     *        {@link #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE}
      *        to set the flags in the bitmask.
      */
     public void onReceiveTextSms(@NonNull MessagePdu pdu, @NonNull String format,
@@ -157,7 +157,7 @@
             @Override
             public void onReceiveResult(Boolean result) throws RemoteException {
                 callback.onReceiveResult(result ? RECEIVE_OPTIONS_DEFAULT : RECEIVE_OPTIONS_DROP
-                    | RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_ENCRYPTED_STORAGE_UNAVAILABLE);
+                    | RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE);
             }
         });
     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 7b01267..b4131b4 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -46,7 +46,7 @@
             boolean allLayers, boolean useIdentityTransform);
 
     private static native void nativeOpenTransaction();
-    private static native void nativeCloseTransaction();
+    private static native void nativeCloseTransaction(boolean sync);
     private static native void nativeSetAnimationTransaction();
 
     private static native void nativeSetLayer(long nativeObject, int zorder);
@@ -372,7 +372,11 @@
 
     /** end a transaction */
     public static void closeTransaction() {
-        nativeCloseTransaction();
+        nativeCloseTransaction(false);
+    }
+
+    public static void closeTransactionSync() {
+        nativeCloseTransaction(true);
     }
 
     public void deferTransactionUntil(IBinder handle, long frame) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2269282..414882a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5698,6 +5698,18 @@
     /**
      * Call this view's OnContextClickListener, if it is defined.
      *
+     * @param x the x coordinate of the context click
+     * @param y the y coordinate of the context click
+     * @return True if there was an assigned OnContextClickListener that consumed the event, false
+     *         otherwise.
+     */
+    public boolean performContextClick(float x, float y) {
+        return performContextClick();
+    }
+
+    /**
+     * Call this view's OnContextClickListener, if it is defined.
+     *
      * @return True if there was an assigned OnContextClickListener that consumed the event, false
      *         otherwise.
      */
@@ -10044,7 +10056,7 @@
                 if (isContextClickable() && !mInContextButtonPress && !mHasPerformedLongPress
                         && (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY
                         || actionButton == MotionEvent.BUTTON_SECONDARY)) {
-                    if (performContextClick()) {
+                    if (performContextClick(event.getX(), event.getY())) {
                         mInContextButtonPress = true;
                         setPressed(true, event.getX(), event.getY());
                         removeTapCallback();
@@ -15250,7 +15262,6 @@
         destroyDrawingCache();
 
         cleanupDraw();
-        releasePointerCapture();
         mCurrentAnimation = null;
     }
 
@@ -21824,57 +21835,6 @@
         return mPointerIcon;
     }
 
-
-    /**
-     * Request capturing further mouse events.
-     *
-     * When the view captures, the pointer icon will disappear and will not change its
-     * position. Further pointer events will come to the capturing view, and the pointer movements
-     * will can be detected through {@link MotionEvent#AXIS_RELATIVE_X} and
-     * {@link MotionEvent#AXIS_RELATIVE_Y}. Non-mouse events (touchscreens, or stylus) will not
-     * be affected.
-     *
-     * The capture will be released through {@link #releasePointerCapture()}, or will be lost
-     * automatically when the view or containing window disappear.
-     *
-     * @return true when succeeds.
-     * @see #releasePointerCapture()
-     * @see #hasPointerCapture()
-     */
-    public void requestPointerCapture() {
-        final ViewRootImpl viewRootImpl = getViewRootImpl();
-        if (viewRootImpl != null) {
-            viewRootImpl.requestPointerCapture(this);
-        }
-    }
-
-
-    /**
-     * Release the current capture of mouse events.
-     *
-     * If the view does not have the capture, it will do nothing.
-     * @see #requestPointerCapture()
-     * @see #hasPointerCapture()
-     */
-    public void releasePointerCapture() {
-        final ViewRootImpl viewRootImpl = getViewRootImpl();
-        if (viewRootImpl != null) {
-            viewRootImpl.releasePointerCapture(this);
-        }
-    }
-
-    /**
-     * Checks the capture status of mouse events.
-     *
-     * @return true if the view has the capture.
-     * @see #requestPointerCapture()
-     * @see #hasPointerCapture()
-     */
-    public boolean hasPointerCapture() {
-        final ViewRootImpl viewRootImpl = getViewRootImpl();
-        return (viewRootImpl != null) && viewRootImpl.hasPointerCapture(this);
-    }
-
     //
     // Properties
     //
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1c6600d..d812cb4 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3168,32 +3168,6 @@
         }
     }
 
-    void requestPointerCapture(View view) {
-        if (!mAttachInfo.mHasWindowFocus) {
-            Log.w(mTag, "Can't set capture if it's not focused.");
-            return;
-        }
-        if (mCapturingView == view) {
-            return;
-        }
-        mCapturingView = view;
-        InputManager.getInstance().setPointerIconDetached(true);
-        return;
-    }
-
-    void releasePointerCapture(View view) {
-        if (mCapturingView != view || mCapturingView == null) {
-            return;
-        }
-
-        mCapturingView = null;
-        InputManager.getInstance().setPointerIconDetached(false);
-    }
-
-    boolean hasPointerCapture(View view) {
-        return view != null && mCapturingView == view;
-    }
-
     @Override
     public void requestChildFocus(View child, View focused) {
         if (DEBUG_INPUT_RESIZE) {
@@ -3271,10 +3245,6 @@
         mView = null;
         mAttachInfo.mRootView = null;
 
-        if (mCapturingView != null) {
-            releasePointerCapture(mCapturingView);
-        }
-
         mSurface.release();
 
         if (mInputQueueCallback != null && mInputQueue != null) {
@@ -3615,8 +3585,6 @@
                                 .softInputMode &=
                                     ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
                         mHasHadWindowFocus = true;
-                    } else if (mCapturingView != null) {
-                        releasePointerCapture(mCapturingView);
                     }
                 }
             } break;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index d0d4507..52f35de 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -16,6 +16,7 @@
 
 package android.view.accessibility;
 
+import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -101,8 +102,9 @@
     /**
      * Gets the title of the window.
      *
-     * @return The title.
+     * @return The title of the window, or {@code null} if none is available.
      */
+    @Nullable
     public CharSequence getTitle() {
         return mTitle;
     }
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 2c80f28..2fd52b5 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -432,7 +432,8 @@
     public void setMinDate(long minDate) {
         mTempDate.setTimeInMillis(minDate);
         if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) {
+            // Same day, no-op.
             return;
         }
         if (mCurrentDate.before(mTempDate)) {
@@ -453,7 +454,8 @@
     public void setMaxDate(long maxDate) {
         mTempDate.setTimeInMillis(maxDate);
         if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+            // Same day, no-op.
             return;
         }
         if (mCurrentDate.after(mTempDate)) {
diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java
index 17af014..1a6d351 100644
--- a/core/java/android/widget/DatePickerSpinnerDelegate.java
+++ b/core/java/android/widget/DatePickerSpinnerDelegate.java
@@ -288,7 +288,8 @@
     public void setMinDate(long minDate) {
         mTempDate.setTimeInMillis(minDate);
         if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMinDate.get(Calendar.DAY_OF_YEAR)) {
+            // Same day, no-op.
             return;
         }
         mMinDate.setTimeInMillis(minDate);
@@ -311,7 +312,8 @@
     public void setMaxDate(long maxDate) {
         mTempDate.setTimeInMillis(maxDate);
         if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+                && mTempDate.get(Calendar.DAY_OF_YEAR) == mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+            // Same day, no-op.
             return;
         }
         mMaxDate.setTimeInMillis(maxDate);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fc120eb..3711b94 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6983,14 +6983,19 @@
         return false;
     }
 
-    private static int desired(Layout layout) {
+    private static int desired(Layout layout, int maxLines) {
         int n = layout.getLineCount();
         CharSequence text = layout.getText();
         float max = 0;
 
+        // if maxLines is set, and the text length is greater that the length of the text in the
+        // layout, it means that there is a cut-off and we cannot use it.
+        if (maxLines != -1 && text.length() > layout.getLineEnd(n - 1)) {
+            return -1;
+        }
+
         // if any line was wrapped, we can't use it.
         // but it's ok for the last line not to have a newline
-
         for (int i = 0; i < n - 1; i++) {
             if (text.charAt(layout.getLineEnd(i) - 1) != '\n')
                 return -1;
@@ -7063,7 +7068,7 @@
             width = widthSize;
         } else {
             if (mLayout != null && mEllipsize == null) {
-                des = desired(mLayout);
+                des = desired(mLayout, getMaxLines());
             }
 
             if (des < 0) {
@@ -7095,7 +7100,7 @@
                 int hintWidth;
 
                 if (mHintLayout != null && mEllipsize == null) {
-                    hintDes = desired(mHintLayout);
+                    hintDes = desired(mHintLayout, getMaxLines());
                 }
 
                 if (hintDes < 0) {
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 4260e50..951a45a 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -34,7 +34,7 @@
     // for AppWidgetHost
     //
     ParceledListSlice startListening(IAppWidgetHost host, String callingPackage, int hostId,
-            in int[] appWidgetIds, out int[] updatedIds);
+            in int[] appWidgetIds);
     void stopListening(String callingPackage, int hostId);
     int allocateAppWidgetId(String callingPackage, int hostId);
     void deleteAppWidgetId(String callingPackage, int appWidgetId);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 5bb8969..4f15ece 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -521,16 +521,22 @@
 
     @Override
     public void setTitle(CharSequence title) {
+        setTitle(title, true);
+    }
+
+    public void setTitle(CharSequence title, boolean updateAccessibilityTitle) {
         if (mTitleView != null) {
             mTitleView.setText(title);
         } else if (mDecorContentParent != null) {
             mDecorContentParent.setWindowTitle(title);
         }
         mTitle = title;
-        WindowManager.LayoutParams params = getAttributes();
-        if (!TextUtils.equals(title, params.accessibilityTitle)) {
-            params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
-            dispatchWindowAttributesChanged(getAttributes());
+        if (updateAccessibilityTitle) {
+            WindowManager.LayoutParams params = getAttributes();
+            if (!TextUtils.equals(title, params.accessibilityTitle)) {
+                params.accessibilityTitle = TextUtils.stringOrSpannedString(title);
+                dispatchWindowAttributesChanged(getAttributes());
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 6b93d8336..05b839d 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,6 +28,7 @@
     long getLong(in String key, in long defaultValue, in int userId);
     String getString(in String key, in String defaultValue, in int userId);
     void setLockPattern(in String pattern, in String savedPattern, int userId);
+    void resetKeyStore(int userId);
     VerifyCredentialResponse checkPattern(in String pattern, int userId);
     VerifyCredentialResponse verifyPattern(in String pattern, long challenge, int userId);
     void setLockPassword(in String password, in String savedPassword, int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 70941b6..1beea8c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -535,6 +535,18 @@
     }
 
     /**
+     * Use it to reset keystore without wiping work profile
+     */
+    public void resetKeyStore(int userId) {
+        try {
+            getLockSettings().resetKeyStore(userId);
+        } catch (RemoteException e) {
+            // It should not happen
+            Log.e(TAG, "Couldn't reset keystore " + e);
+        }
+    }
+
+    /**
      * Clear any lock pattern or password.
      */
     public void clearLock(int userHandle) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 864a0bf..a9ed9dc 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -223,8 +223,9 @@
     SurfaceComposerClient::openGlobalTransaction();
 }
 
-static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
-    SurfaceComposerClient::closeGlobalTransaction();
+
+static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
+    SurfaceComposerClient::closeGlobalTransaction(sync);
 }
 
 static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
@@ -649,7 +650,7 @@
             (void*)nativeScreenshot },
     {"nativeOpenTransaction", "()V",
             (void*)nativeOpenTransaction },
-    {"nativeCloseTransaction", "()V",
+    {"nativeCloseTransaction", "(Z)V",
             (void*)nativeCloseTransaction },
     {"nativeSetAnimationTransaction", "()V",
             (void*)nativeSetAnimationTransaction },
diff --git a/core/res/res/values-notround/dimens_micro.xml b/core/res/res/values-notround/dimens_micro.xml
index 326f7e5..51291d9 100644
--- a/core/res/res/values-notround/dimens_micro.xml
+++ b/core/res/res/values-notround/dimens_micro.xml
@@ -15,5 +15,6 @@
 -->
 <resources>
     <dimen name="dialog_padding_micro">8dp</dimen>
-    <dimen name="list_item_padding_horizontal_micro">16dp</dimen>
+    <dimen name="list_item_padding_left_micro">16dp</dimen>
+    <dimen name="list_item_padding_right_micro">16dp</dimen>
 </resources>
diff --git a/core/res/res/values-round/dimens_micro.xml b/core/res/res/values-round/dimens_micro.xml
index 9bf97dd..8dbc905 100644
--- a/core/res/res/values-round/dimens_micro.xml
+++ b/core/res/res/values-round/dimens_micro.xml
@@ -15,5 +15,6 @@
 -->
 <resources>
     <dimen name="dialog_padding_micro">32dp</dimen>
-    <dimen name="list_item_padding_horizontal_micro">22dp</dimen>
+    <dimen name="list_item_padding_left_micro">40dp</dimen>
+    <dimen name="list_item_padding_right_micro">24dp</dimen>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index c0060fd..bb07834 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -303,7 +303,7 @@
     </style>
 
     <style name="TextAppearance.Material.Widget.Button.Borderless.Colored" parent="TextAppearance.Material.Widget.Button">
-        <item name="textColor">@color/btn_colored_text_material</item>
+        <item name="textColor">@color/btn_colored_borderless_text_material</item>
     </style>
 
     <style name="TextAppearance.Material.Widget.EditText">
diff --git a/core/res/res/values/styles_micro.xml b/core/res/res/values/styles_micro.xml
index dba1705..aecf982 100644
--- a/core/res/res/values/styles_micro.xml
+++ b/core/res/res/values/styles_micro.xml
@@ -127,6 +127,10 @@
         <item name="hyphenationFrequency">normal</item>
     </style>
 
+    <style name="Widget.Micro.EditText" parent="Widget.Material.EditText">
+        <item name="android:breakStrategy">simple</item>
+    </style>
+
     <style name="Widget.Micro.NumberPicker">
         <item name="internalLayout">@layout/number_picker_with_selector_wheel_micro</item>
         <item name="solidColor">@color/transparent</item>
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index 92106b2..89c33b2 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -19,6 +19,7 @@
         <item name="alertDialogStyle">@style/AlertDialog.Micro</item>
         <item name="dialogTheme">@style/Theme.Micro.Dialog</item>
         <item name="textViewStyle">@style/Widget.Micro.TextView</item>
+        <item name="editTextStyle">@style/Widget.Micro.EditText</item>
         <item name="numberPickerStyle">@style/Widget.Micro.NumberPicker</item>
         <item name="windowAnimationStyle">@style/Animation.Micro.Activity</item>
         <item name="windowBackground">@color/background_micro_dark</item>
@@ -37,10 +38,10 @@
         <item name="textAppearanceListItem">@style/TextAppearance.Micro.Subtitle</item>
         <item name="textAppearanceListItemSmall">@style/TextAppearance.Micro.Body1</item>
         <item name="textAppearanceListItemSecondary">@style/TextAppearance.Micro.Body2</item>
-        <item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_horizontal_micro</item>
-        <item name="listPreferredItemPaddingRight">@dimen/list_item_padding_horizontal_micro</item>
-        <item name="listPreferredItemPaddingStart">@dimen/list_item_padding_horizontal_micro</item>
-        <item name="listPreferredItemPaddingEnd">@dimen/list_item_padding_horizontal_micro</item>
+        <item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_left_micro</item>
+        <item name="listPreferredItemPaddingRight">@dimen/list_item_padding_right_micro</item>
+        <item name="listPreferredItemPaddingStart">@dimen/list_item_padding_left_micro</item>
+        <item name="listPreferredItemPaddingEnd">@dimen/list_item_padding_right_micro</item>
 
         <!-- Dialog styling -->
         <item name="buttonBarStyle">@style/Widget.Micro.ButtonBar</item>
diff --git a/docs/html-intl/intl/es/preview/setup-sdk.jd b/docs/html-intl/intl/es/preview/setup-sdk.jd
index 769121d..39e84a8 100644
--- a/docs/html-intl/intl/es/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/es/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 y <a href="{@docRoot}preview/api-overview.html">API y funciones de Android N
 </a>.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/in/preview/setup-sdk.jd b/docs/html-intl/intl/in/preview/setup-sdk.jd
index c6e43f1..2502d7d 100644
--- a/docs/html-intl/intl/in/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/in/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 dan <a href="{@docRoot}preview/api-overview.html">Android N API
 dan Fiturnya</a>.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ja/preview/setup-sdk.jd b/docs/html-intl/intl/ja/preview/setup-sdk.jd
index 4331641..36c2144 100644
--- a/docs/html-intl/intl/ja/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ja/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 
 </li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ko/preview/setup-sdk.jd b/docs/html-intl/intl/ko/preview/setup-sdk.jd
index 91f17c1..d04acef 100644
--- a/docs/html-intl/intl/ko/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ko/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 및 기능</a>에서 Android N 플랫폼에
 대해 자세히 알아봅니다.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/pt-br/preview/setup-sdk.jd b/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
index 9035e50..a917da3 100644
--- a/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/pt-br/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 e <a href="{@docRoot}preview/api-overview.html">Recursos de APIs do
 Android N</a>.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/ru/preview/setup-sdk.jd b/docs/html-intl/intl/ru/preview/setup-sdk.jd
index 582fe9f..6ae86e9 100644
--- a/docs/html-intl/intl/ru/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/ru/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 и в описании <a href="{@docRoot}preview/api-overview.html">API-интерфейсов и возможностей Android N</a>.
 </li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/vi/preview/index.jd b/docs/html-intl/intl/vi/preview/index.jd
index 25289e0..bd64b25 100644
--- a/docs/html-intl/intl/vi/preview/index.jd
+++ b/docs/html-intl/intl/vi/preview/index.jd
@@ -31,7 +31,7 @@
           <strong>thông báo trả lời trực tiếp</strong> và nhiều tính năng khác.
         </p>
 
-        <a href="http://factoryberlin.com" target="_new">
+        <a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
           <span class="dac-sprite dac-auto-chevron"></span>
           Bắt đầu
         </a><!--<br>
@@ -61,19 +61,19 @@
     </a>
     <ul class="dac-actions">
       <li class="dac-action">
-        <a href="http://factoryberlin.com" target="_new">
+        <a class="dac-action-link" href="https://developer.android.com/preview/bug">
           <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
           Báo cáo vấn đề
         </a>
       </li>
       <li class="dac-action">
-        <a href="http://factoryberlin.com" target="_new">
+        <a class="dac-action-link" href="{@docRoot}preview/support.html">
           <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
           Xem ghi chú phát hành
         </a>
       </li>
       <li class="dac-action">
-        <a href="http://factoryberlin.com" target="_new">
+        <a class="dac-action-link" href="{@docRoot}preview/dev-community">
           <i class="dac-action-sprite dac-sprite dac-auto-chevron-large"></i>
           Tham gia cộng đồng nhà phát triển
         </a>
@@ -86,15 +86,15 @@
   <div class="wrap dac-offset-parent">
 
     <div class="actions">
-      <div><a href="http://factoryberlin.com" target="_new">
+      <div><a href="https://developer.android.com/preview/bug">
         <span class="dac-sprite dac-auto-chevron-large"></span>
         Báo cáo vấn đề
       </a></div>
-      <div><a href="http://factoryberlin.com" target="_new">
+      <div><a href="{@docRoot}preview/support.html">
         <span class="dac-sprite dac-auto-chevron-large"></span>
         Xem ghi chú phát hành
       </a></div>
-      <div><a href="http://factoryberlin.com" target="_new">
+      <div><a href="{@docRoot}preview/dev-community">
         <span class="dac-sprite dac-auto-chevron-large"></span>
         Tham gia cộng đồng nhà phát triển
       </a></div>
diff --git a/docs/html-intl/intl/vi/preview/setup-sdk.jd b/docs/html-intl/intl/vi/preview/setup-sdk.jd
index 6f6cd20..bdba713 100644
--- a/docs/html-intl/intl/vi/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/vi/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1: 6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 và<a href="{@docRoot}preview/api-overview.html">API Android N
 và Các tính năng</a>.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd b/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
index eaef7a1..69971d8 100644
--- a/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/zh-cn/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1:6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 
 </li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd b/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
index 7a46aca..b486ed4 100644
--- a/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
+++ b/docs/html-intl/intl/zh-tw/preview/setup-sdk.jd
@@ -130,7 +130,7 @@
       SHA-1:6a3880b3ccd19614daae5a4d0698ea6ae11c20a5
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -221,4 +221,3 @@
 
 </li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 4211c6f..42c8889 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -127,6 +127,8 @@
   to: https://developers.google.com/mobile-ads-sdk/
 - from: /google/play-services/wallet.html
   to: https://developers.google.com/wallet/instant-buy/
+- from: /google/play-services/id.html
+  to: https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
 - from: /google/play/safetynet/...
   to: /training/safetynet/index.html
 - from: /google/gcm/...
diff --git a/docs/html/google/_book.yaml b/docs/html/google/_book.yaml
index 92357e9..885ad7a 100644
--- a/docs/html/google/_book.yaml
+++ b/docs/html/google/_book.yaml
@@ -63,9 +63,6 @@
 - title: Google Play Developer API
   path: /google/play/developer-api.html
 
-- title: Advertising ID
-  path: /google/play-services/id.html
-
 - title: Multiple APK Support
   path: /google/play/publishing/multiple-apks.html
 
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
deleted file mode 100644
index 2f0664c..0000000
--- a/docs/html/google/play-services/id.jd
+++ /dev/null
@@ -1,193 +0,0 @@
-page.title=Advertising ID
-page.tags=Ads,Advertising ID,ID
-
-@jd:body
-<div class="landing-banner">
-
-<div class="col-8">
-<p itemprop="description">
-  The advertising ID is a user-specific, unique, resettable ID for advertising,
-  provided by Google Play services. It gives users better controls and provides
-  developers with a simple, standard system to continue to monetize your apps.
-  It is an anonymous identifier for advertising purposes and enables users to
-  reset their identifier or opt out of interest-based ads within Google Play
-  apps.
-</p>
-<p>
-  The advertising ID is accessible through a straightforward API that you can
-  implement in your apps. For details, take a look at the <a href=
-  "#get_started">overview</a> and the <a href=
-  "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/package-summary">
-  advertising ID API reference</a>.
-</p>
-</div>
-</div>
-<div class="landing-docs">
-  <div class="col-6 normal-links">
-    <h3 style="clear:left">Key Developer Features</h3>
-      <h4>Standard, simple ID</h4>
-      <p>The advertising ID is a part of a standard, simple system for serving ads and performing analytics.</p>
-      <h4>Giving users control</h4>
-      <p>Users  can reset their advertising ID or opt out of interest-based ads at any time, right from the Google Settings app.
-      Their preferences apply across all ad companies that use the advertising ID.</p>
-
-  </div>
-  <div class="col-6 normal-links">
-    <h3 style="clear:left">Getting Started</h3>
-    <h4>1. Get the Google Play services SDK</h4>
-    <p>The advertising ID APIs are part of the Google Play services platform.</p>
-    <p>To get started, <a href="https://developers.google.com/android/guides/setup">set up
-      the Google Play services SDK</a>. </p>
-    <h4>2. Read the docs and example code</h4>
-    <p>Once you've installed the Google Play services package, review the <a href="#get_started">overview</a>
-    below, as well as the <a href="#example">example</a>.</p>
-    <p>
-    For detailed documentation, take a look at the <a href=
-  "https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/package-summary">
-    advertising ID API reference documentation</a>.
-    </p>
-  </div>
-</div>
-<p class="caution" style=
-"background-color:#fffdeb;width:100%;margin-bottom:1em;padding:.5em;">
-  As a reminder, please note that starting <strong>1 August 2014</strong>, new
-  apps and app updates distributed through Google Play must use the advertising
-  ID in lieu of any other persistent identifiers for any advertising purposes,
-  on devices that support the advertising ID.<br>
-  <br>
-  To learn how to check your app's compliance through the Developer Console, or
-  for details on the associated developer policy changes, please see the
-  <a href=
-  "https://support.google.com/googleplay/android-developer/answer/6048248">Advertising
-  ID topic</a> in the Google Play developer help center.
-</p>
-<h2 id="get_started">Using the Advertising ID</h2>
-<p>
-  The <strong>advertising ID</strong> is a unique but
-  user-resettable string identifier that lets ad networks and other apps anonymously
-  identify a user. The user's advertising ID is made available to apps through APIs
-  provided in Google Play services.
-</p>
-<p>
-  Users can reset their advertising ID at any time, right from the Ads section of the
-  Google Settings app on their devices. From the same app, users can also
-  opt-out of targeted advertising based on the advertising ID by setting the appropriate
-  <strong style="white-space:nowrap">ad tracking preference</strong>. When the
-  user opts-out of targeted ads, this ad tracking preference is made available
-  to apps through a Google Play services API.
-</p>
-<p>
-  Apps making use of the advertising ID <strong>must check for and respect</strong> the
-  user's ad tracking preference. Also please note that any use of the advertising ID
-  must abide by the terms of the <a class="external-link"
-  href="http://play.google.com/about/developer-content-policy.html#ADID">Google Play
-  Developer Content Policies</a>.
-</p>
-<h3 id="format">Format of the Advertising ID</h3>
-<p>
-  Google Play services APIs expose the user's advertising ID as a string format of UUID,
-  with values similar to this:
-</p>
-<p style="margin-left:1.5em;"><code>"38400000-8cf0-11bd-b23e-10b96e40000d"</code></p>
-<h3 id="requirements">Requirements</h3>
-<ul>
-  <li>The advertising ID APIs are supported in Google Play services 4.0+</li>
-  <li>Support for the advertising ID on specific devices is based on their installed versions
-  of Google Play services</li>
-</ul>
-<h3 id="obtaining">Obtaining the user's advertising ID and ad tracking preference</h3>
-<p>
-  If you want to use the advertising ID in your app, you must first install the Google
-  Play services SDK. As noted in the requirements above, you should install the
-  SDK for Google Play services 4.0 or higher if you will develop using the advertising ID
-  APIs. For information about how to get started, see <a href=
-  "https://developers.google.com/android/guides/setup">Setting Up Google Play services</a>.
-</p>
-<p>
-  The advertising ID APIs are available in the <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
-  <code>com.google.android.gms.ads.identifier</code></a> package in the Google
-  Play Services library. To obtain the user's advertising ID and tracking preference,
-  call the method
-  <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html#getAdvertisingIdInfo(android.content.Context)">
-  <code>getAdvertisingIdInfo()</code></a>, which returns an <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
-  <code>AdvertisingIdClient.Info</code></a> encapsulating the user's current Advertising ID
-  and tracking preference.
-</p>
-<p class="note">
-  <strong>Note:</strong> The
-  <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.html#getAdvertisingIdInfo(android.content.Context)"><code>getAdvertisingIdInfo()</code></a>
-  method is a blocking call, so you must not call it on the main (UI) thread.
-  If called on the main thread, the method throws
-  {@link java.lang.IllegalStateException}.
-</p>
-<p>
-  Once you've retrieved the
-  <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html">
-  <code>AdvertisingIdClient.Info</code></a>
-  object, you can use its <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#getId()">
-  <code>getId()</code></a> and <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">
-  <code>isLimitAdTrackingEnabled()</code></a> methods to access the advertising ID and
-  ad tracking preference.
-</p>
-<table>
-<tr>
-<th>Method</th>
-<th>Description</th>
-</tr>
-<tr>
-<td><code>public String <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#getId()">getId()</a></code></td>
-<td style="white-space:nowrap;">Retrieves the advertising ID.</td>
-</tr>
-<tr>
-<td style="white-space:nowrap;"><code>public boolean <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info.html#isLimitAdTrackingEnabled()">isLimitAdTrackingEnabled()</a></code></td>
-<td>Retrieves whether the user has limit ad tracking enabled or not.</td>
-</tr>
-</table>
-<p>
-  The advertising ID APIs do not include a "reset" method. Only users can initiate a
-  reset of their own advertising IDs, through the Google Settings application.
-</p>
-<p>
-  For more information about the advertising ID APIs, see the <a href=
-  "{@docRoot}reference/com/google/android/gms/ads/identifier/package-summary.html">
-  reference documentation</a>.
-</p>
-<h3 id="example">Example implementation</h3>
-<p>
-  Here's a basic illustration of how you can retrieve the user's advertising ID and ad
-  tracking preference in your app:
-</p>
-<pre>
-import com.google.android.gms.ads.identifier.AdvertisingIdClient;
-import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
-import com.google.android.gms.common.GooglePlayServicesAvailabilityException;
-import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
-import java.io.IOException;
-...
-// Do not call this function from the main thread. Otherwise,
-// an IllegalStateException will be thrown.
-public void getIdThread() {
-  Info adInfo = null;
-  try {
-    adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext.getApplicationContext());
-  } catch (IOException e) {
-    // Unrecoverable error connecting to Google Play services (e.g.,
-    // the old version of the service doesn't support getting AdvertisingId).
-
-  } catch (GooglePlayServicesAvailabilityException e) {
-    // Encountered a recoverable error connecting to Google Play services.
-  } catch (GooglePlayServicesNotAvailableException e) {
-    // Google Play services is not available entirely.
-  }
-  final String id = adInfo.getId();
-  final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
-}</pre>
diff --git a/docs/html/license.jd b/docs/html/license.jd
index 0f671e2..4f4036b 100644
--- a/docs/html/license.jd
+++ b/docs/html/license.jd
@@ -29,7 +29,9 @@
 documentation (code comments) extracted from a source code module that
 is licensed under GPLv2 or other license. In those cases, the license
 covering the source code module will apply to the documentation
-extracted from it. </p>
+extracted from it. Source code modules that are used in the generation
+of documentation and have licenses that require attribution can be
+found in the <a href="#doclicenses">Documentation Licences section</a> below.</p>
 
 <p>Third-party components of this site such as JavaScript libraries are included in the Android
 Open Source Project under the licenses specified by their authors. For information about these
@@ -144,4 +146,102 @@
  written attribution in the spirit of the messages above.
 </p>
 
+<h2 id="doclicenses">Documentation Licenses</h2>
+<h3 id="icu">ICU License</h3>
+<p>The Android public API documentation incorporates text from the following source code libraries under the ICU License:</p>
+<ul>
+<li><a href="{@docRoot}reference/android/icu/lang/package-summary.html">android.icu.lang</a></li>
+<li><a href="{@docRoot}reference/android/icu/math/package-summary.html">android.icu.math</a></li>
+<li><a href="{@docRoot}reference/android/icu/text/package-summary.html">android.icu.text</a></li>
+<li><a href="{@docRoot}reference/android/icu/util/package-summary.html">android.icu.util</a></li>
+</ul>
+
+<div class="aside" style="overflow:scroll; height:250px;">
+<p>COPYRIGHT AND PERMISSION NOTICE</p>
+
+<p>
+Copyright (c) 1995-2015 International Business Machines Corporation and others
+</p>
+<p>
+All rights reserved.
+</p>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies
+of the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+</p>
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL
+THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM,
+OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+USE OR PERFORMANCE OF THIS SOFTWARE.
+</p>
+<p>
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization of the copyright holder.
+</p>
+</div>
+
+<h3 id="w3c_license">W3C Software and Document Notice and License</h3>
+<p>The Android public API documentation incorporates text from the following source code libraries under the W3C Software and Document Notice and License:</p>
+<ul>
+<li><a href="{@docRoot}reference/org/w3c/dom/package-summary.html">org.w3c.dom</a></li>
+<li><a href="{@docRoot}reference/org/w3c/dom/ls/package-summary.html">org.w3c.dom.ls</a></li>
+</ul>
+
+<div class="aside" style="overflow:scroll; height:250px;">
+<p>This work is being provided by the copyright holders under the following license.</p>
+<h5>License</h5>
+<p>
+ By obtaining and/or copying this work, you (the licensee) agree that you have read, understood,
+ and will comply with the following terms and conditions.
+</p>
+<p>
+ Permission to copy, modify, and distribute this work, with or without modification, for any
+ purpose and without fee or royalty is hereby granted, provided that you include the following on
+ ALL copies of the work or portions thereof, including modifications:
+</p>
+<ul>
+<li>
+ The full text of this NOTICE in a location viewable to users of the redistributed or
+ derivative work.
+</li>
+<li>
+ Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none
+ exist, the W3C Software and Document Short Notice should be included.
+</li>
+<li>
+ Notice of any changes or modifications, through a copyright statement on the new code or document
+ such as "This software or document includes material copied from or derived from [title and URI of
+ the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)."
+</li>
+</ul>
+<h5>Disclaimers</h5>
+<p>
+ THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY
+ PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+</p>
+<p>
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES
+ ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT.
+</p>
+<p>
+ The name and trademarks of copyright holders may NOT be used in advertising or publicity
+ pertaining to the work without specific, written prior permission. Title to copyright in this work
+ will at all times remain with copyright holders.
+</p>
+</div>
 </div>
diff --git a/docs/html/preview/features/security-config.jd b/docs/html/preview/features/security-config.jd
index 633c0e5..2706ced 100644
--- a/docs/html/preview/features/security-config.jd
+++ b/docs/html/preview/features/security-config.jd
@@ -18,7 +18,7 @@
       </ol>
   </li>
   <li><a href="#TrustingDebugCa">Debugging-only CAs</a></li>
-  <li><a href="#UsesCleartextTraffic">Opting Out of Cleartext Traffic</a></li>
+  <li><a href="#CleartextTrafficPermitted">Opting Out of Cleartext Traffic</a></li>
   <li><a href="#CertificatePinning">Pinning Certificates</a></li>
   <li><a href="#ConfigInheritance">Configuration Inheritance Behavior</a></li>
   <li><a href="#FileFormat">Configuration File Format</a></li>
@@ -72,9 +72,8 @@
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?&gt;
 &lt;manifest ... &gt;
-  &lt;application ... &gt;
-    &lt;meta-data android:name="android.security.net.config"
-               android:resource="@xml/network_security_config" /&gt;
+  &lt;application android:networkSecurityConfig="@xml/network_security_config"
+               ... &gt;
     ...
   &lt;/application&gt;
 &lt;/manifest&gt;
@@ -240,7 +239,7 @@
 </p>
 
 
-<h2 id="UsesCleartextTraffic">Opting Out of Cleartext Traffic</h2>
+<h2 id="CleartextTrafficPermitted">Opting Out of Cleartext Traffic</h2>
 
 <p>
   Applications intending to connect to destinations using only secure
@@ -263,7 +262,7 @@
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?&gt;
 &lt;network-security-config&gt;
-    &lt;domain-config usesCleartextTraffic="false"&gt;
+    &lt;domain-config cleartextTrafficPermitted="false"&gt;
         &lt;domain includeSubdomains="true"&gt;secure.example.com&lt;/domain&gt;
     &lt;/domain-config&gt;
 &lt;/network-security-config&gt;
@@ -436,7 +435,7 @@
 
 <pre class="stx">
 &lt;base-config <a href=
-"#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]&gt;
+"#CleartextTrafficPermitted">cleartextTrafficPermitted</a>=["true" | "false"]&gt;
     ...
 &lt;/base-config&gt;
 </pre>
@@ -463,7 +462,7 @@
 </p>
 
 <pre>
-&lt;base-config usesCleartextTraffic="true"&gt;
+&lt;base-config cleartextTrafficPermitted="true"&gt;
     &lt;trust-anchors&gt;
         &lt;certificates src="system" /&gt;
     &lt;/trust-anchors&gt;
@@ -471,7 +470,7 @@
 </pre>
 The default configuration for apps targeting API level 23 and below is:
 <pre>
-&lt;base-config usesCleartextTraffic="true"&gt;
+&lt;base-config cleartextTrafficPermitted="true"&gt;
     &lt;trust-anchors&gt;
         &lt;certificates src="system" /&gt;
         &lt;certificates src="user" /&gt;
@@ -486,7 +485,7 @@
 <dl class="xml">
 <dt>syntax:</dt>
 <dd>
-<pre class="stx">&lt;domain-config <a href="#usesCleartextTraffic">usesCleartextTraffic</a>=["true" | "false"]&gt;
+<pre class="stx">&lt;domain-config <a href="#CleartextTrafficPermitted">cleartextTrafficPermitted</a>=["true" | "false"]&gt;
     ...
 &lt;/domain-config&gt;</pre>
 </dd>
diff --git a/docs/html/preview/setup-sdk.jd b/docs/html/preview/setup-sdk.jd
index ebeae74..3b479e2 100644
--- a/docs/html/preview/setup-sdk.jd
+++ b/docs/html/preview/setup-sdk.jd
@@ -98,7 +98,7 @@
       SHA-1: 9224bd4445cd7f653c4c294d362ccb195a2101e7 
     </td>
   </tr>
-<table>
+</table>
 
 
 
@@ -189,4 +189,3 @@
 and <a href="{@docRoot}preview/api-overview.html">Android N APIs
 and Features</a>.</li>
 </ul>
-<div class="end-content-title"></div>
diff --git a/docs/html/topic/instant-apps/faqs.jd b/docs/html/topic/instant-apps/faqs.jd
index 0a1f571..bf37241 100644
--- a/docs/html/topic/instant-apps/faqs.jd
+++ b/docs/html/topic/instant-apps/faqs.jd
@@ -63,7 +63,9 @@
   <strong>How can developers get involved?</strong>
   <br/>
   Developers interested in upgrading their Android apps can visit
-  <a class="external-link" href="g.co/InstantApps">g.co/InstantApps</a> to
+  <a class="external-link"
+  href="http://g.co/InstantApps">
+  g.co/InstantApps</a> to
   sign up. We will be reaching out to interested
   developers in the coming months.
 </p>
\ No newline at end of file
diff --git a/docs/html/topic/instant-apps/index.jd b/docs/html/topic/instant-apps/index.jd
index d8de0b5..e2da9c5 100644
--- a/docs/html/topic/instant-apps/index.jd
+++ b/docs/html/topic/instant-apps/index.jd
@@ -12,17 +12,8 @@
 <!-- Hero section -->
 <section class="dac-expand dac-hero dac-section-light">
 <div class="wrap">
-  <div class="cols dac-hero-content">
-
-    <div class="col-1of2 col-push-1of2 dac-hero-figure">
-      <div class="dev-bytes-video">
-        <iframe width="560" height="350" src=
-        "https://www.youtube.com/embed/cosqlfqrpFA" frameborder="0"
-        allowfullscreen=""></iframe>
-      </div>
-    </div>
-
-    <div class="col-1of2 col-pull-1of2" style="margin-bottom:40px">
+  <div class="dac-hero-content">
+    <div style="margin-bottom:40px">
       <h1>
         Android Instant Apps
       </h1>
@@ -47,6 +38,11 @@
         <a class="landing-button green download-bundle-button" href=
         "https://docs.google.com/a/google.com/forms/d/1S3MzsMVIlchLCqyNLaFbv64llxWaf90QSeYLeswco90/viewform"
         target="_blank">I'M INTERESTED IN ANDROID INSTANT APPS<br></a>
+        <a class="dac-hero-cta dev-bytes"
+          href="https://www.youtube.com/watch?v=cosqlfqrpFA">
+          <span class="dac-sprite dac-auto-chevron"></span>
+          Watch a video about Instant Apps
+        </a>
       </p>
     </div>
 
@@ -56,7 +52,7 @@
 
 <!-- Second section -->
 
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
 <div class="cols dac-hero-content">
   <div class="col-1of2 dac-hero-figure">
     <img src="/images/topic/instant-apps/instant-apps-section-2.png">
@@ -64,7 +60,7 @@
 <div class="col-1of2">
 <div class="dac-hero-tag"></div>
 
-  <h2 id="section-2">Run Android Apps Without Installation</h2>
+  <h2 id="section-2" class="norule">Run Android Apps Without Installation</h2>
   <p class="dac-hero-description">
     Android Instant Apps lets you experience beautiful and immersive
     apps, with material design and smooth animations, without installing them
@@ -77,9 +73,9 @@
 
 <!-- Third section -->
 
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
 
-  <h2 id="section-3">Access Apps From Anywhere</h2>
+  <h2 id="section-3" class="norule">Access Apps From Anywhere</h2>
 
   <p>
     Get people to your flagship Android experience from links that would
@@ -126,7 +122,7 @@
 
 <!-- Fourth section -->
 
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
 <div class="cols dac-hero-content">
   <div class="col-1of2 dac-hero-figure">
     <img src="/images/topic/instant-apps/instant-apps-section-4.png">
@@ -134,9 +130,10 @@
 <div class="col-1of2">
 <div class="dac-hero-tag"></div>
 
-  <h2 id="section-4">Built On Google Play Services</h2>
+  <h2 id="section-4" class="norule">Built On Google Play Services</h2>
   <p class="dac-hero-description">
-    Take advantage of Google Play services features &mdash; like location, identity,
+    Take advantage of Google Play services features &mdash; like location,
+    identity,
     payments, and Firebase &mdash; which are built right in for a seamless user
     experience.
   </p>
@@ -147,17 +144,16 @@
 
 <!-- Fifth section -->
 
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
 <div class="cols dac-hero-content">
   <div class="col-1of2 col-push-1of2 dac-hero-figure">
     <img src="/images/topic/instant-apps/instant-apps-section-5.png">
   </div>
 <div class="col-1of2 col-pull-1of2">
 <div class="dac-hero-tag"></div>
-  <h2 id="section-5">Works On Most Android Devices</h2>
+  <h2 id="section-5" class="norule">Works On Most Android Devices</h2>
 
   <p class="dac-hero-description">
-
     Android Instant Apps can work on Android devices running Android 4.1+
     (API Level 16) or higher with Google Play services.
   </p>
@@ -168,7 +164,7 @@
 
 <!-- Sixth section -->
 
-<div class="wrap" style="margin-top:60px">
+<div class="wrap sub-section">
 <div class="cols dac-hero-content">
   <div class="col-1of2 dac-hero-figure">
     <img src="/images/topic/instant-apps/upgrade-your-app-2x.png">
@@ -176,7 +172,7 @@
 <div class="col-1of2">
 <div class="dac-hero-tag"></div>
 
-  <h2 id="section-6">Upgrade Your Existing App</h2>
+  <h2 id="section-6" class="norule">Upgrade Your Existing App</h2>
   <p class="dac-hero-description">
     Android Instant Apps functionality is an upgrade to your existing Android
     app, not a new, separate app. It's the same Android APIs, the same
@@ -192,18 +188,18 @@
 
 <!-- Seventh section -->
 
-<div class="wrap" style="margin-top:60px" id="section-7">
-  <h2 id="sign-up-docs" style="margin-bottom: 0px;">
+<div class="wrap sub-section" id="section-7">
+  <h2 id="sign-up-docs" class="dac-section-title norule" style="margin-bottom: 0px;">
     Sign up for access to Android Instant Apps documentation
   </h2>
 
-  <p>
+  <p class="dac-section-subtitle" style="margin-top:0px">
     We’ll let you know if you’re selected for early access
     to Android Instant
     Apps.
   </p>
 
-  <p>
+  <p class="dac-section-subtitle">
     <a class="landing-button green download-bundle-button"
       href="https://docs.google.com/forms/d/1S3MzsMVIlchLCqyNLaFbv64llxWaf90QSeYLeswco90/viewform"
       target="_blank">
@@ -211,7 +207,7 @@
     </a>
   </p>
 
-  <p style="margin-top:24px">
+  <p  class="dac-section-subtitle" style="margin-top:24px">
     Check out our <a href="faqs.html">frequently asked questions</a> to find out
     more about Android Instant Apps.
   </p>
@@ -230,28 +226,14 @@
     background: #B0BEC5;
   }
 
-  /* Styling and layout for video. */
-  .dev-bytes-video {
-    margin-top: 30px;
-    position: relative;
-    padding-bottom: 56.25%; /* 16:9 */
-    padding-top: 30px;
-    height: 0;
-  }
-
-  .dev-bytes-video iframe,
-  .dev-bytes-video object,
-  .dev-bytes-video embed {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-  }
-
   /* Increase top margin for sections */
-  .wrap {
-    margin-top: 1.5em;
+  .sub-section {
+    margin-top: 2em;
+  }
+
+  a.dev-bytes {
+   padding-top: 1em;
+   padding-left: 1em;
   }
 
   #section-3, #sign-up-docs {
@@ -259,11 +241,6 @@
     border-top: 0px;
   }
 
-  /* Align the seventh section in the center. */
-  #section-7 {
-    text-align: center;
-  }
-
   /* GIF section styling */
   .figure-caption {
     text-align: center;
diff --git a/docs/html/training/volley/request.jd b/docs/html/training/volley/request.jd
index a2b2ecd..97efc17 100644
--- a/docs/html/training/volley/request.jd
+++ b/docs/html/training/volley/request.jd
@@ -38,7 +38,7 @@
 
 <p>If your expected response is one of these types, you probably won't have to implement a
 custom request. This lesson describes how to use these standard request types. For
-information on how to implement your own custom request, see <a href="requests-custom.html">
+information on how to implement your own custom request, see <a href="request-custom.html">
 Implementing a Custom Request</a>.</p>
 
 
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 61f78cc..27193b7 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -90,7 +90,6 @@
     mLocked.lastFrameUpdatedTime = 0;
 
     mLocked.buttonState = 0;
-    mLocked.iconDetached = false;
 
     mPolicy->loadPointerIcon(&mLocked.pointerIcon);
 
@@ -185,10 +184,6 @@
 }
 
 void PointerController::setPositionLocked(float x, float y) {
-    if (mLocked.iconDetached) {
-        return;
-    }
-
     float minX, minY, maxX, maxY;
     if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
         if (x <= minX) {
@@ -222,10 +217,6 @@
     // Remove the inactivity timeout, since we are fading now.
     removeInactivityTimeoutLocked();
 
-    if (mLocked.iconDetached) {
-        return;
-    }
-
     // Start fading.
     if (transition == TRANSITION_IMMEDIATE) {
         mLocked.pointerFadeDirection = 0;
@@ -243,10 +234,6 @@
     // Always reset the inactivity timer.
     resetInactivityTimeoutLocked();
 
-    if (mLocked.iconDetached) {
-        return;
-    }
-
     // Start unfading.
     if (transition == TRANSITION_IMMEDIATE) {
         mLocked.pointerFadeDirection = 0;
@@ -362,22 +349,6 @@
     updatePointerLocked();
 }
 
-void PointerController::detachPointerIcon(bool detached) {
-    AutoMutex _l(mLock);
-
-    if (mLocked.iconDetached == detached) {
-        return;
-    }
-
-    mLocked.iconDetached = detached;
-    if (detached) {
-        mLocked.pointerFadeDirection = -1;
-    } else {
-        mLocked.pointerFadeDirection = 1;
-    }
-    startAnimationLocked();
-}
-
 void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
     AutoMutex _l(mLock);
 
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index b47139a..99292d7 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -111,10 +111,6 @@
     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
     void reloadPointerResources();
 
-    /* Detach or attach the pointer icon status. When detached, the pointer icon disappears
-     * and the icon location does not change at all. */
-    void detachPointerIcon(bool detached);
-
 private:
     static const size_t MAX_RECYCLED_SPRITES = 12;
     static const size_t MAX_SPOTS = 12;
@@ -184,8 +180,6 @@
 
         int32_t buttonState;
 
-        bool iconDetached;
-
         Vector<Spot*> spots;
         Vector<sp<Sprite> > recycledSprites;
     } mLocked;
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 87c6d88..349d67e 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -567,6 +567,34 @@
                     return false;
                 }
             }
+
+            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
+            Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL);
+
+            if (profile != null) {
+                if (!supportsProfileLevel(profile, level)) {
+                    return false;
+                }
+
+                // If we recognize this profile, check that this format is supported by the
+                // highest level supported by the codec for that profile. (Ignore specified
+                // level beyond the above profile/level check as level is only used as a
+                // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
+                // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
+                // 1080p format is not supported even if codec supports Main Profile Level High,
+                // as Simple Profile does not support 1080p.
+                CodecCapabilities levelCaps = null;
+                int maxLevel = 0;
+                for (CodecProfileLevel pl : profileLevels) {
+                    if (pl.profile == profile && pl.level > maxLevel) {
+                        maxLevel = pl.level;
+                    }
+                }
+                levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
+                if (levelCaps != null && !levelCaps.isFormatSupported(format)) {
+                    return false;
+                }
+            }
             if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
                 return false;
             }
@@ -579,6 +607,57 @@
             return true;
         }
 
+        private static boolean supportsBitrate(
+                Range<Integer> bitrateRange, MediaFormat format) {
+            Map<String, Object> map = format.getMap();
+
+            // consider max bitrate over average bitrate for support
+            Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE);
+            Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE);
+            if (bitrate == null) {
+                bitrate = maxBitrate;
+            } else if (maxBitrate != null) {
+                bitrate = Math.max(bitrate, maxBitrate);
+            }
+
+            if (bitrate != null && bitrate > 0) {
+                return bitrateRange.contains(bitrate);
+            }
+
+            return true;
+        }
+
+        private boolean supportsProfileLevel(int profile, Integer level) {
+            for (CodecProfileLevel pl: profileLevels) {
+                if (pl.profile != profile) {
+                    continue;
+                }
+
+                // AAC does not use levels
+                if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+                    return true;
+                }
+
+                // H.263 levels are not completely ordered:
+                // Level45 support only implies Level10 support
+                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
+                    if (pl.level != level && pl.level == CodecProfileLevel.H263Level45
+                            && level > CodecProfileLevel.H263Level10) {
+                        continue;
+                    }
+                }
+                if (pl.level >= level) {
+                    // if we recognize the listed profile/level, we must also recognize the
+                    // profile/level arguments.
+                    if (createFromProfileLevel(mMime, profile, pl.level) != null) {
+                        return createFromProfileLevel(mMime, profile, level) != null;
+                    }
+                    return true;
+                }
+            }
+            return false;
+        }
+
         // errors while reading profile levels - accessed from sister capabilities
         int mError;
 
@@ -1004,10 +1083,15 @@
             Map<String, Object> map = format.getMap();
             Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
             Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
+
             if (!supports(sampleRate, channels)) {
                 return false;
             }
 
+            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+                return false;
+            }
+
             // nothing to do for:
             // KEY_CHANNEL_MASK: codecs don't get this
             // KEY_IS_ADTS:      required feature for all AAC decoders
@@ -1310,8 +1394,7 @@
             return supports(width, height, null);
         }
 
-        private boolean supports(
-                Integer width, Integer height, Number rate) {
+        private boolean supports(Integer width, Integer height, Number rate) {
             boolean ok = true;
 
             if (ok && width != null) {
@@ -1353,9 +1436,16 @@
             Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
             Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE);
 
-            // we ignore color-format for now as it is not reliably reported by codec
+            if (!supports(width, height, rate)) {
+                return false;
+            }
 
-            return supports(width, height, rate);
+            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+                return false;
+            }
+
+            // we ignore color-format for now as it is not reliably reported by codec
+            return true;
         }
 
         /* no public constructor */
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 93c595f..33e3957 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -185,12 +185,20 @@
     public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
 
     /**
-     * A key describing the bitrate in bits/sec.
+     * A key describing the average bitrate in bits/sec.
      * The associated value is an integer
      */
     public static final String KEY_BIT_RATE = "bitrate";
 
     /**
+     * A key describing the max bitrate in bits/sec.
+     * This is usually over a one-second sliding window (e.g. over any window of one second).
+     * The associated value is an integer
+     * @hide
+     */
+    public static final String KEY_MAX_BIT_RATE = "max-bitrate";
+
+    /**
      * A key describing the color format of the content in a video format.
      * Constants are declared in {@link android.media.MediaCodecInfo.CodecCapabilities}.
      */
diff --git a/packages/PrintRecommendationService/res/values/donottranslate.xml b/packages/PrintRecommendationService/res/values/donottranslate.xml
index 68effbf..86027cd 100644
--- a/packages/PrintRecommendationService/res/values/donottranslate.xml
+++ b/packages/PrintRecommendationService/res/values/donottranslate.xml
@@ -32,8 +32,15 @@
         <item>Hewlett Packard</item>
     </string-array>
 
+    <string-array name="known_print_vendor_info_for_samsung" translatable="false">
+        <item>com.sec.app.samsungprintservice</item>
+        <item>Samsung Electronics</item>
+        <item>Samsung</item>
+    </string-array>
+
     <array name="known_print_plugin_vendors" translatable="false">
         <item>@array/known_print_vendor_info_for_mopria</item>
         <item>@array/known_print_vendor_info_for_hp</item>
+        <item>@array/known_print_vendor_info_for_samsung</item>
     </array>
 </resources>
diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml
index 97281de..348fcac 100644
--- a/packages/PrintRecommendationService/res/values/strings.xml
+++ b/packages/PrintRecommendationService/res/values/strings.xml
@@ -23,7 +23,7 @@
     <string name="plugin_vendor_brother">Brother</string>
     <string name="plugin_vendor_canon">Canon</string>
     <string name="plugin_vendor_xerox">Xerox</string>
-    <string name="plugin_vendor_samsung">Samsung Electronics</string>
+    <string name="plugin_vendor_samsung">Samsung</string>
     <string name="plugin_vendor_epson">Epson</string>
     <string name="plugin_vendor_konica_minolta">Konica Minolta</string>
     <string name="plugin_vendor_fuji">Fuji</string>
diff --git a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
index b7925df..108ea66 100644
--- a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
+++ b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
@@ -51,14 +51,6 @@
     </vendor>
 
     <vendor>
-        <name>@string/plugin_vendor_samsung</name>
-        <package>com.sec.app.samsungprintservice</package>
-        <mdns-names>
-            <mdns-name>Samsung</mdns-name>
-        </mdns-names>
-    </vendor>
-
-    <vendor>
         <name>@string/plugin_vendor_epson</name>
         <package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
         <mdns-names>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
index 4b4b470..d95654f 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
@@ -25,6 +25,7 @@
 import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin;
 import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
 import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
+import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
@@ -74,6 +75,14 @@
                     " plugin", e);
         }
 
+        try {
+            mPlugins.add(new RemotePrintServicePlugin(new SamsungRecommendationPlugin(this), this,
+                    false));
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_samsung) +
+                    " plugin", e);
+        }
+
         final int numPlugins = mPlugins.size();
         for (int i = 0; i < numPlugins; i++) {
             try {
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java
new file mode 100644
index 0000000..963e09b
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/MDnsUtils.java
@@ -0,0 +1,74 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+import java.util.Map;
+
+public class MDnsUtils {
+    public static final String ATTRIBUTE__TY = "ty";
+    public static final String ATTRIBUTE__PRODUCT = "product";
+    public static final String ATTRIBUTE__USB_MFG = "usb_MFG";
+    public static final String ATTRIBUTE__MFG = "mfg";
+
+    public static String getString(byte[] value) {
+        if (value != null) return new String(value,StandardCharsets.UTF_8);
+        return null;
+    }
+
+    public static boolean isVendorPrinter(NsdServiceInfo networkDevice, String[] vendorValues) {
+
+        Map<String,byte[]> attributes = networkDevice.getAttributes();
+        String product = getString(attributes.get(ATTRIBUTE__PRODUCT));
+        String ty = getString(attributes.get(ATTRIBUTE__TY));
+        String usbMfg = getString(attributes.get(ATTRIBUTE__USB_MFG));
+        String mfg = getString(attributes.get(ATTRIBUTE__MFG));
+        return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues);
+
+    }
+
+    public static String getVendor(NsdServiceInfo networkDevice) {
+        String vendor;
+
+        Map<String,byte[]> attributes = networkDevice.getAttributes();
+        vendor = getString(attributes.get(ATTRIBUTE__MFG));
+        if (!TextUtils.isEmpty(vendor)) return vendor;
+        vendor = getString(attributes.get(ATTRIBUTE__USB_MFG));
+        if (!TextUtils.isEmpty(vendor)) return vendor;
+
+        return null;
+    }
+
+    private static boolean containsVendor(String container, String[] vendorValues) {
+        if ((container == null) || (vendorValues == null)) return false;
+        for (String value : vendorValues) {
+            if (containsString(container, value)
+                || containsString(container.toLowerCase(Locale.US), value.toLowerCase(Locale.US))
+                || containsString(container.toUpperCase(Locale.US), value.toUpperCase(Locale.US)))
+                return true;
+        }
+        return false;
+    }
+
+    private static boolean containsString(String container, String contained) {
+        return (container != null) && (contained != null) && (container.equalsIgnoreCase(contained) || container.contains(contained + " "));
+    }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java
new file mode 100644
index 0000000..032fe22
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/PrinterHashMap.java
@@ -0,0 +1,33 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdServiceInfo;
+
+import java.util.HashMap;
+
+final class PrinterHashMap extends HashMap<String, NsdServiceInfo> {
+    public static String getKey(NsdServiceInfo serviceInfo) {
+        return serviceInfo.getServiceName();
+    }
+    public NsdServiceInfo addPrinter(NsdServiceInfo device) {
+        return put(getKey(device), device);
+    }
+    public NsdServiceInfo removePrinter(NsdServiceInfo device) {
+        return remove(getKey(device));
+    }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java
new file mode 100644
index 0000000..e5b8a0f
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/SamsungRecommendationPlugin.java
@@ -0,0 +1,102 @@
+/*

+(c) Copyright 2016 Samsung Electronics..

+

+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.printservice.recommendation.plugin.samsung;

+

+import android.content.Context;

+import android.net.nsd.NsdServiceInfo;

+import android.text.TextUtils;

+

+import java.util.Locale;

+import java.util.Map;

+

+import com.android.printservice.recommendation.R;

+

+public class SamsungRecommendationPlugin extends ServiceRecommendationPlugin {

+

+    private static final String TAG = "SamsungRecommendation";

+

+    private static final String ATTR_USB_MFG = "usb_MFG";

+    private static final String ATTR_MFG = "mfg";

+    private static final String ATTR_USB_MDL = "usb_MDL";

+    private static final String ATTR_MDL = "mdl";

+    private static final String ATTR_PRODUCT = "product";

+    private static final String ATTR_TY = "ty";

+

+    private static String[] mNotSupportedDevices = new String[]{

+            "SCX-5x15",

+            "SF-555P",

+            "CF-555P",

+            "SCX-4x16",

+            "SCX-4214F",

+            "CLP-500",

+            "CJX-",

+            "MJC-"

+    };

+

+    private static boolean isSupportedModel(String model) {

+        if (!TextUtils.isEmpty(model)) {

+            String modelToUpper = model.toUpperCase(Locale.US);

+            for (String unSupportedPrinter : mNotSupportedDevices) {

+                if (modelToUpper.contains(unSupportedPrinter)) {

+                    return  false;

+                }

+            }

+        }

+        return true;

+    }

+

+    public SamsungRecommendationPlugin(Context context) {

+        super(context, R.string.plugin_vendor_samsung, new VendorInfo(context.getResources(), R.array.known_print_vendor_info_for_samsung), new String[]{"_pdl-datastream._tcp"});

+    }

+

+    @Override

+    public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) {

+        if (!TextUtils.equals(vendor, mVendorInfo.mVendorID)) return false;

+

+        String modelName = getModelName(nsdServiceInfo);

+        if (modelName != null) {

+            return (isSupportedModel(modelName));

+        }

+        return false;

+    }

+

+    private String getModelName(NsdServiceInfo resolvedDevice) {

+        Map<String,byte[]> attributes = resolvedDevice.getAttributes();

+        String usb_mfg = MDnsUtils.getString(attributes.get(ATTR_USB_MFG));

+        if (TextUtils.isEmpty(usb_mfg)) {

+            usb_mfg = MDnsUtils.getString(attributes.get(ATTR_MFG));

+        }

+

+        String usb_mdl = MDnsUtils.getString(attributes.get(ATTR_USB_MDL));

+        if (TextUtils.isEmpty(usb_mdl)) {

+            usb_mdl = MDnsUtils.getString(attributes.get(ATTR_MDL));

+        }

+

+        String modelName = null;

+        if (!TextUtils.isEmpty(usb_mfg) && !TextUtils.isEmpty(usb_mdl)) {

+            modelName = usb_mfg.trim() + " " + usb_mdl.trim();

+        } else {

+            modelName = MDnsUtils.getString(attributes.get(ATTR_PRODUCT));

+            if (TextUtils.isEmpty(modelName)) {

+                modelName = MDnsUtils.getString(attributes.get(ATTR_TY));

+            }

+        }

+

+        return modelName;

+    }

+}

diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java
new file mode 100644
index 0000000..7bb83c9
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceListener.java
@@ -0,0 +1,186 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.printservice.recommendation.R;
+import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
+
+public class ServiceListener implements ServiceResolveQueue.ResolveCallback {
+
+    private final NsdManager mNSDManager;
+    private final Map<String, VendorInfo> mVendorInfoHashMap;
+    private final String[] mServiceType;
+    private final Observer mObserver;
+    private final ServiceResolveQueue mResolveQueue;
+    private List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
+    public HashMap<String, PrinterHashMap> mVendorHashMap = new HashMap<>();
+
+    public interface Observer {
+        boolean matchesCriteria(String vendor, NsdServiceInfo serviceInfo);
+        void dataSetChanged();
+    }
+
+    public ServiceListener(Context context, Observer observer, String[] serviceTypes) {
+        mObserver = observer;
+        mServiceType = serviceTypes;
+        mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
+        mResolveQueue = ServiceResolveQueue.getInstance(mNSDManager);
+
+        Map<String, VendorInfo> vendorInfoMap = new HashMap<>();
+        TypedArray testArray = context.getResources().obtainTypedArray(R.array.known_print_plugin_vendors);
+        for(int i = 0; i < testArray.length(); i++) {
+            int arrayID = testArray.getResourceId(i, 0);
+            if (arrayID != 0) {
+                VendorInfo info = new VendorInfo(context.getResources(), arrayID);
+                vendorInfoMap.put(info.mVendorID, info);
+                vendorInfoMap.put(info.mPackageName, info);
+            }
+        }
+        testArray.recycle();
+        mVendorInfoHashMap = vendorInfoMap;
+    }
+
+    @Override
+    public void serviceResolved(NsdServiceInfo nsdServiceInfo) {
+        printerFound(nsdServiceInfo);
+    }
+
+    private synchronized void printerFound(NsdServiceInfo nsdServiceInfo) {
+        if (nsdServiceInfo == null) return;
+        if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
+        String vendor = MDnsUtils.getVendor(nsdServiceInfo);
+        if (vendor == null) vendor = "";
+        for(Map.Entry<String,VendorInfo> entry : mVendorInfoHashMap.entrySet()) {
+            for(String vendorValues : entry.getValue().mDNSValues) {
+                if (vendor.equalsIgnoreCase(vendorValues)) {
+                    vendor = entry.getValue().mVendorID;
+                    break;
+                }
+            }
+            // intentional pointer check
+            //noinspection StringEquality
+            if ((vendor != entry.getValue().mVendorID) &&
+                    MDnsUtils.isVendorPrinter(nsdServiceInfo, entry.getValue().mDNSValues)) {
+                vendor = entry.getValue().mVendorID;
+            }
+            // intentional pointer check
+            //noinspection StringEquality
+            if (vendor == entry.getValue().mVendorID) break;
+        }
+
+        if (TextUtils.isEmpty(vendor)) {
+            return;
+        }
+
+        if (!mObserver.matchesCriteria(vendor, nsdServiceInfo))
+            return;
+        boolean mapsChanged;
+
+        PrinterHashMap vendorHash = mVendorHashMap.get(vendor);
+        if (vendorHash == null) {
+            vendorHash = new PrinterHashMap();
+        }
+        mapsChanged = (vendorHash.addPrinter(nsdServiceInfo) == null);
+        mVendorHashMap.put(vendor, vendorHash);
+
+        if (mapsChanged) {
+            mObserver.dataSetChanged();
+        }
+    }
+
+    private synchronized void printerRemoved(NsdServiceInfo nsdServiceInfo) {
+        boolean wasRemoved = false;
+        Set<String> vendors = mVendorHashMap.keySet();
+        for(String vendor : vendors) {
+            PrinterHashMap map = mVendorHashMap.get(vendor);
+            wasRemoved |= (map.removePrinter(nsdServiceInfo) != null);
+            if (map.isEmpty()) wasRemoved |= (mVendorHashMap.remove(vendor) != null);
+        }
+        if (wasRemoved) {
+            mObserver.dataSetChanged();
+        }
+    }
+
+    public void start() {
+        stop();
+        for(final String service :mServiceType) {
+            NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
+                @Override
+                public void onStartDiscoveryFailed(String s, int i) {
+
+                }
+
+                @Override
+                public void onStopDiscoveryFailed(String s, int i) {
+
+                }
+
+                @Override
+                public void onDiscoveryStarted(String s) {
+
+                }
+
+                @Override
+                public void onDiscoveryStopped(String s) {
+
+                }
+
+                @Override
+                public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
+                    mResolveQueue.queueRequest(nsdServiceInfo, ServiceListener.this);
+                }
+
+                @Override
+                public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
+                    mResolveQueue.removeRequest(nsdServiceInfo, ServiceListener.this);
+                    printerRemoved(nsdServiceInfo);
+                }
+            };
+            DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
+            mListeners.add(listener);
+        }
+    }
+
+    public void stop() {
+        for(NsdManager.DiscoveryListener listener : mListeners) {
+            DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
+        }
+        mVendorHashMap.clear();
+        mListeners.clear();
+    }
+
+    public Pair<Integer, Integer> getCount() {
+        int count = 0;
+        for (PrinterHashMap map : mVendorHashMap.values()) {
+            count += map.size();
+        }
+        return Pair.create(mVendorHashMap.size(), count);
+    }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java
new file mode 100644
index 0000000..9d15f30
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceRecommendationPlugin.java
@@ -0,0 +1,86 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.annotation.NonNull;
+import android.text.TextUtils;
+import com.android.printservice.recommendation.PrintServicePlugin;
+
+public abstract class ServiceRecommendationPlugin implements PrintServicePlugin, ServiceListener.Observer {
+
+    protected static final String PDL_ATTRIBUTE = "pdl";
+
+    protected final Object mLock = new Object();
+    protected PrinterDiscoveryCallback mCallback = null;
+    protected final ServiceListener mListener;
+    protected final NsdManager mNSDManager;
+    protected final VendorInfo mVendorInfo;
+    private final int mVendorStringID;
+
+    protected ServiceRecommendationPlugin(Context context, int vendorStringID, VendorInfo vendorInfo, String[] services) {
+        mNSDManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
+        mVendorStringID = vendorStringID;
+        mVendorInfo = vendorInfo;
+        mListener = new ServiceListener(context, this, services);
+    }
+
+    @Override
+    public int getName() {
+        return mVendorStringID;
+    }
+
+    @NonNull
+    @Override
+    public CharSequence getPackageName() {
+        return mVendorInfo.mPackageName;
+    }
+
+    @Override
+    public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception {
+        synchronized (mLock) {
+            mCallback = callback;
+        }
+        mListener.start();
+    }
+
+    @Override
+    public void stop() throws Exception {
+        synchronized (mLock) {
+            mCallback = null;
+        }
+        mListener.stop();
+    }
+
+    @Override
+    public void dataSetChanged() {
+        synchronized (mLock) {
+            if (mCallback != null) mCallback.onChanged(getCount());
+        }
+    }
+
+    @Override
+    public boolean matchesCriteria(String vendor, NsdServiceInfo nsdServiceInfo) {
+        return TextUtils.equals(vendor, mVendorInfo.mVendorID);
+    }
+
+    public int getCount() {
+        return mListener.getCount().second;
+    }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java
new file mode 100644
index 0000000..e5691b7
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/ServiceResolveQueue.java
@@ -0,0 +1,109 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Pair;
+import com.android.printservice.recommendation.util.NsdResolveQueue;
+
+import java.util.LinkedList;
+
+final class ServiceResolveQueue {
+
+    private final NsdManager mNsdManager;
+    private final LinkedList<Pair<NsdServiceInfo, ResolveCallback>> mQueue = new LinkedList<>();
+    private final Object mLock = new Object();
+
+    private static Object sLock = new Object();
+    private static ServiceResolveQueue sInstance = null;
+    private final NsdResolveQueue mNsdResolveQueue;
+    private Pair<NsdServiceInfo, ResolveCallback> mCurrentRequest = null;
+
+    public static void createInstance(NsdManager nsdManager) {
+        if (sInstance == null) sInstance = new ServiceResolveQueue(nsdManager);
+    }
+
+    public static ServiceResolveQueue getInstance(NsdManager nsdManager) {
+        synchronized (sLock) {
+            createInstance(nsdManager);
+            return sInstance;
+        }
+    }
+
+    public static void destroyInstance() {
+        sInstance = null;
+    }
+
+    public interface ResolveCallback {
+        void serviceResolved(NsdServiceInfo nsdServiceInfo);
+    }
+
+    public ServiceResolveQueue(NsdManager nsdManager) {
+        mNsdManager = nsdManager;
+        mNsdResolveQueue = NsdResolveQueue.getInstance();
+    }
+
+    public void queueRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) {
+        synchronized (mLock) {
+            Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback);
+            if (mQueue.contains(newRequest)) return;
+            mQueue.add(newRequest);
+            makeNextRequest();
+        }
+    }
+
+    public void removeRequest(NsdServiceInfo serviceInfo, ResolveCallback callback) {
+        synchronized (mLock) {
+            Pair<NsdServiceInfo, ResolveCallback> newRequest = Pair.create(serviceInfo, callback);
+            mQueue.remove(newRequest);
+            if ((mCurrentRequest != null) && newRequest.equals(mCurrentRequest)) mCurrentRequest = null;
+        }
+    }
+
+    private void makeNextRequest() {
+        synchronized (mLock) {
+            if (mCurrentRequest != null) return;
+            if (mQueue.isEmpty()) return;
+            mCurrentRequest = mQueue.removeFirst();
+            mNsdResolveQueue.resolve(mNsdManager, mCurrentRequest.first,
+                    new NsdManager.ResolveListener() {
+                        @Override
+                        public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
+                            synchronized (mLock) {
+                                if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
+                                makeNextRequest();
+                            }
+                        }
+
+                        @Override
+                        public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
+                            synchronized (mLock) {
+                                if (mCurrentRequest != null) {
+                                    mCurrentRequest.second.serviceResolved(nsdServiceInfo);
+                                    mCurrentRequest = null;
+                                }
+                                makeNextRequest();
+                            }
+                        }
+                    });
+
+        }
+    }
+
+
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java
new file mode 100644
index 0000000..0ebb4e4
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/samsung/VendorInfo.java
@@ -0,0 +1,40 @@
+/*
+ * 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.printservice.recommendation.plugin.samsung;
+
+import android.content.res.Resources;
+
+import java.util.Arrays;
+
+public final class VendorInfo {
+
+    public final String mPackageName;
+    public final String mVendorID;
+    public final String[] mDNSValues;
+    public final int mID;
+
+    public VendorInfo(Resources resources, int vendor_info_id) {
+        mID = vendor_info_id;
+        String[] data = resources.getStringArray(vendor_info_id);
+        if ((data == null) || (data.length < 2)) {
+            data = new String[] { null, null };
+        }
+        mPackageName = data[0];
+        mVendorID = data[1];
+        mDNSValues = (data.length > 2) ? Arrays.copyOfRange(data, 2, data.length) : new String[]{};
+    }
+}
diff --git a/packages/PrintSpooler/res/layout/add_printer_list_header.xml b/packages/PrintSpooler/res/layout/add_printer_list_header.xml
index 9eee0c4..488b3ab 100644
--- a/packages/PrintSpooler/res/layout/add_printer_list_header.xml
+++ b/packages/PrintSpooler/res/layout/add_printer_list_header.xml
@@ -24,6 +24,7 @@
         android:gravity="start|center_vertical">
 
     <TextView android:id="@+id/text"
-            style="?android:attr/listSeparatorTextViewStyle" />
+            style="?android:attr/listSeparatorTextViewStyle"
+            android:textAlignment="viewStart" />
 
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout-television/recents_on_tv.xml b/packages/SystemUI/res/layout-television/recents_on_tv.xml
index 1dbd1b3..82b9f8c 100644
--- a/packages/SystemUI/res/layout-television/recents_on_tv.xml
+++ b/packages/SystemUI/res/layout-television/recents_on_tv.xml
@@ -40,4 +40,16 @@
         android:focusable="true"
         android:visibility="visible" />
 
+    <!-- Placeholder to dismiss during talkback. -->
+    <ImageView
+            android:id="@+id/dismiss_placeholder"
+            android:layout_width="@dimen/recents_tv_dismiss_icon_size"
+            android:layout_height="@dimen/recents_tv_dismiss_icon_size"
+            android:layout_gravity="bottom|center_horizontal"
+            android:layout_marginBottom="50dp"
+            android:src="@drawable/ic_cancel_white_24dp"
+            android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
+            android:focusable="true"
+            android:visibility="gone" />
+
 </com.android.systemui.recents.tv.views.RecentsTvView>
diff --git a/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml b/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
index 36df924..201f47d 100644
--- a/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
+++ b/packages/SystemUI/res/layout-television/recents_tv_task_card_view.xml
@@ -19,7 +19,6 @@
         android:layout_height="wrap_content"
         android:focusable="true"
         android:focusableInTouchMode="true"
-        android:contentDescription="@string/status_bar_recent_inspect_item_title"
         android:layout_gravity="center"
         android:layout_centerInParent="true"
         android:clipToPadding="false"
@@ -50,7 +49,6 @@
             android:layout_gravity="center_horizontal"
             android:layout_marginTop="@dimen/recents_tv_dismiss_icon_top_margin"
             android:layout_marginBottom="@dimen/recents_tv_dismiss_icon_bottom_margin"
-            android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
             android:alpha="@integer/dismiss_unselected_alpha"
             android:src="@drawable/recents_tv_dismiss_icon" />
     <TextView
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index ecb64f6..1a55958 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -388,6 +388,26 @@
             mTaskStackHorizontalGridView.setSelectedPosition(0);
         }
 
+        View dismissPlaceholder = findViewById(R.id.dismiss_placeholder);
+        if (ssp.isTouchExplorationEnabled()) {
+            dismissPlaceholder.setAccessibilityTraversalBefore(R.id.task_list);
+            dismissPlaceholder.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
+            mTaskStackHorizontalGridView.setAccessibilityTraversalAfter(R.id.dismiss_placeholder);
+            mTaskStackHorizontalGridView.setAccessibilityTraversalBefore(R.id.pip);
+            dismissPlaceholder.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mTaskStackHorizontalGridView.requestFocus();
+                    mTaskStackHorizontalGridView.
+                            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+                    Task focusedTask = mTaskStackHorizontalGridView.getFocusedTask();
+                    if (focusedTask != null) {
+                        mTaskStackViewAdapter.removeTask(focusedTask);
+                        EventBus.getDefault().send(new DeleteTaskDataEvent(focusedTask));
+                    }
+                }
+            });
+        }
         updatePipUI();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index b082658..06b2441 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -54,6 +54,7 @@
     private TaskStack mStack;
     private TaskStackHorizontalGridView mTaskStackHorizontalView;
     private View mEmptyView;
+    private View mDismissPlaceholder;
     private RecentsRowFocusAnimationHolder mEmptyViewFocusAnimationHolder;
     private boolean mAwaitingFirstLayout = true;
     private Rect mSystemInsets = new Rect();
@@ -86,6 +87,12 @@
         mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler);
     }
 
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mDismissPlaceholder = findViewById(R.id.dismiss_placeholder);
+    }
+
     public void setTaskStack(TaskStack stack) {
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
@@ -198,6 +205,9 @@
     public void showEmptyView() {
         mEmptyView.setVisibility(View.VISIBLE);
         mTaskStackHorizontalView.setVisibility(View.GONE);
+        if (Recents.getSystemServices().isTouchExplorationEnabled()) {
+            mDismissPlaceholder.setVisibility(View.GONE);
+        }
     }
 
     /**
@@ -206,6 +216,9 @@
     public void hideEmptyView() {
         mEmptyView.setVisibility(View.GONE);
         mTaskStackHorizontalView.setVisibility(View.VISIBLE);
+        if (Recents.getSystemServices().isTouchExplorationEnabled()) {
+            mDismissPlaceholder.setVisibility(View.VISIBLE);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index bd85748..758f93a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -88,22 +88,10 @@
                 R.dimen.recents_task_view_rounded_corners_radius);
         mRecentsRowFocusAnimationHolder = new RecentsRowFocusAnimationHolder(this, title);
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.isTouchExplorationEnabled()) {
-            mDismissIconView.setFocusable(true);
-            mDismissIconView.setFocusableInTouchMode(true);
-            mDismissIconView.setOnFocusChangeListener(new OnFocusChangeListener() {
-                @Override
-                public void onFocusChange(View v, boolean hasFocus) {
-                    if (hasFocus) {
-                        setDismissState(true);
-                    } else {
-                        setDismissState(false);
-                    }
-                }
-            });
+        if (!ssp.isTouchExplorationEnabled()) {
+            mDismissIconView.setVisibility(VISIBLE);
         } else {
-            mDismissIconView.setFocusable(false);
-            mDismissIconView.setFocusableInTouchMode(false);
+            mDismissIconView.setVisibility(GONE);
         }
         mViewFocusAnimator = new ViewFocusAnimator(this);
     }
@@ -113,6 +101,7 @@
         mTitleTextView.setText(task.title);
         mBadgeView.setImageDrawable(task.icon);
         setThumbnailView();
+        setContentDescription(task.titleDescription);
     }
 
     public Task getTask() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 32b61cd..f3c666f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -263,6 +263,7 @@
         invalidateOutline();
         selectLayout(false /* animate */, mForceSelectNextLayout /* force */);
         mForceSelectNextLayout = false;
+        updateExpandButtons(mExpandable);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 4e643f0..7d3da1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -463,9 +463,7 @@
         mTransformedView.animate().cancel();
         mTransformedView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
         mTransformedView.setAlpha(visible ? 1.0f : 0.0f);
-        if (visible) {
-            resetTransformedView();
-        }
+        resetTransformedView();
     }
 
     public void prepareFadeIn() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index d9dd9e2..81c0d81 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -217,6 +217,8 @@
             mSimState = IccCardConstants.State.ABSENT;
         } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
             mSimState = IccCardConstants.State.CARD_IO_ERROR;
+        } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.CARD_RESTRICTED;
         } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
             mSimState = IccCardConstants.State.READY;
         } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 3cc991c..ecba245 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -648,7 +648,16 @@
      * @param policyFlags The policy flags associated with the event.
      */
     private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) {
-        final int pointerIdBits = (1 << mDraggingPointerId);
+        int pointerIdBits = 0;
+        // Clear the dragging pointer id if it's no longer valid.
+        if (event.findPointerIndex(mDraggingPointerId) == -1) {
+            Slog.e(LOG_TAG, "mDraggingPointerId doesn't match any pointers on current event. " +
+                    "mDraggingPointerId: " + Integer.toString(mDraggingPointerId) +
+                    ", Event: " + event);
+            mDraggingPointerId = INVALID_POINTER_ID;
+        } else {
+            pointerIdBits = (1 << mDraggingPointerId);
+        }
         switch (event.getActionMasked()) {
             case MotionEvent.ACTION_DOWN: {
                 throw new IllegalStateException("Dragging state can be reached only if two "
@@ -664,6 +673,9 @@
                 sendDownForAllNotInjectedPointers(event, policyFlags);
             } break;
             case MotionEvent.ACTION_MOVE: {
+                if (mDraggingPointerId == INVALID_POINTER_ID) {
+                    break;
+                }
                 switch (event.getPointerCount()) {
                     case 1: {
                         // do nothing
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 4e0ddd6..04a0990 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -29,6 +29,7 @@
 import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
+import android.appwidget.PendingHostUpdate;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -70,10 +71,12 @@
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.AttributeSet;
+import android.util.LongSparseArray;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
+import android.util.SparseLongArray;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
@@ -732,8 +735,8 @@
     }
 
     @Override
-    public ParceledListSlice<RemoteViews> startListening(IAppWidgetHost callbacks,
-            String callingPackage, int hostId, int[] appWidgetIds, int[] updatedIds) {
+    public ParceledListSlice<PendingHostUpdate> startListening(IAppWidgetHost callbacks,
+            String callingPackage, int hostId, int[] appWidgetIds) {
         final int userId = UserHandle.getCallingUserId();
 
         if (DEBUG) {
@@ -753,18 +756,19 @@
             host.callbacks = callbacks;
 
             int N = appWidgetIds.length;
-            ArrayList<RemoteViews> outViews = new ArrayList<>(N);
-            RemoteViews rv;
-            int added = 0;
+            ArrayList<PendingHostUpdate> outUpdates = new ArrayList<>(N);
+
+            LongSparseArray<PendingHostUpdate> updatesMap = new LongSparseArray<>();
             for (int i = 0; i < N; i++) {
-                rv = host.getPendingViewsForId(appWidgetIds[i]);
-                if (rv != null) {
-                    updatedIds[added] = appWidgetIds[i];
-                    outViews.add(rv);
-                    added++;
+                if (host.getPendingUpdatesForId(appWidgetIds[i], updatesMap)) {
+                    // We key the updates based on time, so that the values are sorted by time.
+                    int M = updatesMap.size();
+                    for (int j = 0; j < M; j++) {
+                        outUpdates.add(updatesMap.valueAt(j));
+                    }
                 }
             }
-            return new ParceledListSlice<>(outViews);
+            return new ParceledListSlice<>(outUpdates);
         }
     }
 
@@ -1804,6 +1808,15 @@
     }
 
     private void scheduleNotifyAppWidgetViewDataChanged(Widget widget, int viewId) {
+        if (viewId == ID_VIEWS_UPDATE || viewId == ID_PROVIDER_CHANGED) {
+            // A view id should never collide with these constants but a developer can call this
+            // method with a wrong id. In that case, ignore the call.
+            return;
+        }
+        long requestTime = SystemClock.uptimeMillis();
+        if (widget != null) {
+            widget.updateTimes.put(viewId, requestTime);
+        }
         if (widget == null || widget.host == null || widget.host.zombie
                 || widget.host.callbacks == null || widget.provider == null
                 || widget.provider.zombie) {
@@ -1813,6 +1826,7 @@
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = widget.host;
         args.arg2 = widget.host.callbacks;
+        args.arg3 = requestTime;
         args.argi1 = widget.appWidgetId;
         args.argi2 = viewId;
 
@@ -1823,9 +1837,10 @@
 
 
     private void handleNotifyAppWidgetViewDataChanged(Host host, IAppWidgetHost callbacks,
-            int appWidgetId, int viewId) {
+            int appWidgetId, int viewId, long requestTime) {
         try {
             callbacks.viewDataChanged(appWidgetId, viewId);
+            host.lastWidgetUpdateTime = requestTime;
         } catch (RemoteException re) {
             // It failed; remove the callback. No need to prune because
             // we know that this host is still referenced by this instance.
@@ -1874,7 +1889,7 @@
     private void scheduleNotifyUpdateAppWidgetLocked(Widget widget, RemoteViews updateViews) {
         long requestTime = SystemClock.uptimeMillis();
         if (widget != null) {
-            widget.lastUpdateTime = requestTime;
+            widget.updateTimes.put(ID_VIEWS_UPDATE, requestTime);
         }
         if (widget == null || widget.provider == null || widget.provider.zombie
                 || widget.host.callbacks == null || widget.host.zombie) {
@@ -1907,6 +1922,12 @@
     }
 
     private void scheduleNotifyProviderChangedLocked(Widget widget) {
+        long requestTime = SystemClock.uptimeMillis();
+        if (widget != null) {
+            // When the provider changes, reset everything else.
+            widget.updateTimes.clear();
+            widget.updateTimes.append(ID_PROVIDER_CHANGED, requestTime);
+        }
         if (widget == null || widget.provider == null || widget.provider.zombie
                 || widget.host.callbacks == null || widget.host.zombie) {
             return;
@@ -1916,6 +1937,7 @@
         args.arg1 = widget.host;
         args.arg2 = widget.host.callbacks;
         args.arg3 = widget.provider.info;
+        args.arg4 = requestTime;
         args.argi1 = widget.appWidgetId;
 
         mCallbackHandler.obtainMessage(
@@ -1924,9 +1946,10 @@
     }
 
     private void handleNotifyProviderChanged(Host host, IAppWidgetHost callbacks,
-            int appWidgetId, AppWidgetProviderInfo info) {
+            int appWidgetId, AppWidgetProviderInfo info, long requestTime) {
         try {
             callbacks.providerChanged(appWidgetId, info);
+            host.lastWidgetUpdateTime = requestTime;
         } catch (RemoteException re) {
             synchronized (mLock){
                 Slog.e(TAG, "Widget host dead: " + host.id, re);
@@ -3410,10 +3433,11 @@
                     Host host = (Host) args.arg1;
                     IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
                     AppWidgetProviderInfo info = (AppWidgetProviderInfo)args.arg3;
+                    long requestTime = (Long) args.arg4;
                     final int appWidgetId = args.argi1;
                     args.recycle();
 
-                    handleNotifyProviderChanged(host, callbacks, appWidgetId, info);
+                    handleNotifyProviderChanged(host, callbacks, appWidgetId, info, requestTime);
                 } break;
 
                 case MSG_NOTIFY_PROVIDERS_CHANGED: {
@@ -3429,11 +3453,13 @@
                     SomeArgs args = (SomeArgs) message.obj;
                     Host host = (Host) args.arg1;
                     IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2;
+                    long requestTime = (Long) args.arg3;
                     final int appWidgetId = args.argi1;
                     final int viewId = args.argi2;
                     args.recycle();
 
-                    handleNotifyAppWidgetViewDataChanged(host, callbacks, appWidgetId, viewId);
+                    handleNotifyAppWidgetViewDataChanged(host, callbacks, appWidgetId, viewId,
+                            requestTime);
                 } break;
             }
         }
@@ -3772,20 +3798,41 @@
         }
 
         /**
-         * Returns the RemoveViews for the provided widget id if an update is pending
-         * for that widget.
+         * Adds all pending updates in {@param outUpdates} keys by the update time.
          */
-        public RemoteViews getPendingViewsForId(int appWidgetId) {
+        public boolean getPendingUpdatesForId(int appWidgetId,
+                LongSparseArray<PendingHostUpdate> outUpdates) {
             long updateTime = lastWidgetUpdateTime;
             int N = widgets.size();
             for (int i = 0; i < N; i++) {
                 Widget widget = widgets.get(i);
-                if (widget.appWidgetId == appWidgetId
-                        && widget.lastUpdateTime > updateTime) {
-                    return cloneIfLocalBinder(widget.getEffectiveViewsLocked());
+                if (widget.appWidgetId == appWidgetId) {
+                    outUpdates.clear();
+                    for (int j = widget.updateTimes.size() - 1; j >= 0; j--) {
+                        long time = widget.updateTimes.valueAt(j);
+                        if (time <= updateTime) {
+                            continue;
+                        }
+                        int id = widget.updateTimes.keyAt(j);
+                        final PendingHostUpdate update;
+                        switch (id) {
+                            case ID_PROVIDER_CHANGED:
+                                update = PendingHostUpdate.providerChanged(
+                                        appWidgetId, widget.provider.info);
+                                break;
+                            case ID_VIEWS_UPDATE:
+                                update = PendingHostUpdate.updateAppWidget(appWidgetId,
+                                        cloneIfLocalBinder(widget.getEffectiveViewsLocked()));
+                                break;
+                            default:
+                                update = PendingHostUpdate.viewDataChanged(appWidgetId, id);
+                        }
+                        outUpdates.put(time, update);
+                    }
+                    return true;
                 }
             }
-            return null;
+            return false;
         }
 
         @Override
@@ -3850,6 +3897,10 @@
         }
     }
 
+    // These can be any constants that would not collide with a resource id.
+    private static final int ID_VIEWS_UPDATE = 0;
+    private static final int ID_PROVIDER_CHANGED = 1;
+
     private static final class Widget {
         int appWidgetId;
         int restoredId;  // tracking & remapping any restored state
@@ -3858,7 +3909,8 @@
         RemoteViews maskedViews;
         Bundle options;
         Host host;
-        long lastUpdateTime;
+        // timestamps for various operations
+        SparseLongArray updateTimes = new SparseLongArray(2);
 
         @Override
         public String toString() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2f2d8a4..5118b3f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3228,9 +3228,6 @@
     @Override
     public LegacyVpnInfo getLegacyVpnInfo(int userId) {
         enforceCrossUserPermission(userId);
-        if (mLockdownEnabled) {
-            return null;
-        }
 
         synchronized(mVpns) {
             return mVpns.get(userId).getLegacyVpnInfo();
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 1d8bb6b..fbbdccc 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -47,6 +47,7 @@
 import android.os.IBinder;
 import android.os.IProgressListener;
 import android.os.Parcel;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.storage.IMountService;
 import android.os.ServiceManager;
@@ -128,6 +129,14 @@
     private NotificationManager mNotificationManager;
     private UserManager mUserManager;
 
+    private final KeyStore mKeyStore = KeyStore.getInstance();
+
+    /**
+     * The UIDs that are used for system credential storage in keystore.
+     */
+    private static final int[] SYSTEM_CREDENTIAL_UIDS = {Process.WIFI_UID, Process.VPN_UID,
+        Process.ROOT_UID, Process.SYSTEM_UID};
+
     static {
         // Just launch the home screen, which happens anyway
         ACTION_NULL = new Intent(Intent.ACTION_MAIN);
@@ -235,6 +244,11 @@
             randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40);
             String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed));
             setLockPasswordInternal(newPassword, managedUserPassword, managedUserId);
+            // We store a private credential for the managed user that's unlocked by the primary
+            // account holder's credential. As such, the user will never be prompted to enter this
+            // password directly, so we always store a password.
+            setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                    DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId);
             tieProfileLockToParent(managedUserId, newPassword);
         } catch (NoSuchAlgorithmException | RemoteException e) {
             Slog.e(TAG, "Fail to tie managed profile", e);
@@ -535,6 +549,30 @@
                 setString("migrated_lockscreen_disabled", "true", 0);
                 Slog.i(TAG, "Migrated lockscreen disabled flag");
             }
+
+            final List<UserInfo> users = mUserManager.getUsers();
+            for (int i = 0; i < users.size(); i++) {
+                final UserInfo userInfo = users.get(i);
+                if (userInfo.isManagedProfile() && mStorage.hasChildProfileLock(userInfo.id)) {
+                    // When managed profile has a unified lock, the password quality stored has 2
+                    // possibilities only.
+                    // 1). PASSWORD_QUALITY_UNSPECIFIED, which is upgraded from dp2, and we are
+                    // going to set it back to PASSWORD_QUALITY_ALPHANUMERIC.
+                    // 2). PASSWORD_QUALITY_ALPHANUMERIC, which is the actual password quality for
+                    // unified lock.
+                    final long quality = getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                            DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userInfo.id);
+                    if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                        // Only possible when it's upgraded from nyc dp3
+                        Slog.i(TAG, "Migrated tied profile lock type");
+                        setLong(LockPatternUtils.PASSWORD_TYPE_KEY,
+                                DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, userInfo.id);
+                    } else if (quality != DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) {
+                        // It should not happen
+                        Slog.e(TAG, "Invalid tied profile lock type: " + quality);
+                    }
+                }
+            }
         } catch (RemoteException re) {
             Slog.e(TAG, "Unable to migrate old data", re);
         }
@@ -686,7 +724,7 @@
             NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
             InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
             CertificateException, IOException {
-        if (DEBUG) Slog.v(TAG, "Unlock keystore for child profile");
+        if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
         byte[] storedData = mStorage.readChildProfileLock(userId);
         if (storedData == null) {
             throw new FileNotFoundException("Child profile lock file not found");
@@ -1106,6 +1144,49 @@
     }
 
     @Override
+    public void resetKeyStore(int userId) throws RemoteException {
+        if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+        int managedUserId = -1;
+        String managedUserDecryptedPassword = null;
+        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        for (UserInfo pi : profiles) {
+            // Unlock managed profile with unified lock
+            if (pi.isManagedProfile()
+                    && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+                    && mStorage.hasChildProfileLock(pi.id)) {
+                try {
+                    if (managedUserId == -1) {
+                        managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
+                        managedUserId = pi.id;
+                    } else {
+                        // Should not happen
+                        Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
+                                + ", uid2:" + pi.id);
+                    }
+                } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+                        | NoSuchAlgorithmException | NoSuchPaddingException
+                        | InvalidAlgorithmParameterException | IllegalBlockSizeException
+                        | BadPaddingException | CertificateException | IOException e) {
+                    Slog.e(TAG, "Failed to decrypt child profile key", e);
+                }
+            }
+        }
+        try {
+            // Clear all the users credentials could have been installed in for this user.
+            for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
+                for (int uid : SYSTEM_CREDENTIAL_UIDS) {
+                    mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+                }
+            }
+        } finally {
+            if (managedUserId != -1 && managedUserDecryptedPassword != null) {
+                if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
+                tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+            }
+        }
+    }
+
+    @Override
     public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException {
         return doVerifyPattern(pattern, false, 0, userId);
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6c302ed..ed55263 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17520,13 +17520,13 @@
                                 final boolean killProcess =
                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
                                 final boolean fullUninstall = removed && !replacing;
-                                if (killProcess) {
-                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
-                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
-                                            false, true, true, false, fullUninstall, userId,
-                                            removed ? "pkg removed" : "pkg changed");
-                                }
                                 if (removed) {
+                                    if (killProcess) {
+                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
+                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
+                                                false, true, true, false, fullUninstall, userId,
+                                                removed ? "pkg removed" : "pkg changed");
+                                    }
                                     final int cmd = killProcess
                                             ? IApplicationThread.PACKAGE_REMOVED
                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
@@ -17543,6 +17543,12 @@
                                         mBatteryStatsService.notePackageUninstalled(ssp);
                                     }
                                 } else {
+                                    if (killProcess) {
+                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
+                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
+                                                userId, ProcessList.INVALID_ADJ,
+                                                false, true, true, false, "change " + ssp);
+                                    }
                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
                                             intent.getStringArrayExtra(
                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
@@ -18300,8 +18306,8 @@
 
     void updateUserConfigurationLocked() {
         Configuration configuration = new Configuration(mConfiguration);
-        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
-                mUserController.getCurrentUserIdLocked());
+        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
+                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
         updateConfigurationLocked(configuration, null, false);
     }
 
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index b4df10f..def6828 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -88,6 +88,9 @@
      */
     private static final long EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS = 2000;
 
+    // There is some accuracy error in wifi reports so allow some slop in the results.
+    private static final long MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS = 750;
+
     private static IBatteryStats sService;
 
     final BatteryStatsImpl mStats;
@@ -1338,32 +1341,33 @@
         } else {
             final long totalActiveTimeMs = txTimeMs + rxTimeMs;
             long maxExpectedIdleTimeMs;
-            // Active time can never be greater than the total time, the stats received seem
-            // to be corrupt.
             if (totalActiveTimeMs > timePeriodMs) {
-                maxExpectedIdleTimeMs = timePeriodMs;
-                StringBuilder sb = new StringBuilder();
-                sb.append("Total Active time ");
-                TimeUtils.formatDuration(totalActiveTimeMs, sb);
-                sb.append(" is longer than sample period ");
-                TimeUtils.formatDuration(timePeriodMs, sb);
-                sb.append(".\n");
-                sb.append("Previous WiFi snapshot: ").append("idle=");
-                TimeUtils.formatDuration(lastIdleMs, sb);
-                sb.append(" rx=");
-                TimeUtils.formatDuration(lastRxMs, sb);
-                sb.append(" tx=");
-                TimeUtils.formatDuration(lastTxMs, sb);
-                sb.append(" e=").append(lastEnergy);
-                sb.append("\n");
-                sb.append("Current WiFi snapshot: ").append("idle=");
-                TimeUtils.formatDuration(latest.mControllerIdleTimeMs, sb);
-                sb.append(" rx=");
-                TimeUtils.formatDuration(latest.mControllerRxTimeMs, sb);
-                sb.append(" tx=");
-                TimeUtils.formatDuration(latest.mControllerTxTimeMs, sb);
-                sb.append(" e=").append(latest.mControllerEnergyUsed);
-                Slog.wtf(TAG, sb.toString());
+                // Cap the max idle time at zero since the active time consumed the whole time
+                maxExpectedIdleTimeMs = 0;
+                if (totalActiveTimeMs > timePeriodMs + MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS) {
+                    StringBuilder sb = new StringBuilder();
+                    sb.append("Total Active time ");
+                    TimeUtils.formatDuration(totalActiveTimeMs, sb);
+                    sb.append(" is longer than sample period ");
+                    TimeUtils.formatDuration(timePeriodMs, sb);
+                    sb.append(".\n");
+                    sb.append("Previous WiFi snapshot: ").append("idle=");
+                    TimeUtils.formatDuration(lastIdleMs, sb);
+                    sb.append(" rx=");
+                    TimeUtils.formatDuration(lastRxMs, sb);
+                    sb.append(" tx=");
+                    TimeUtils.formatDuration(lastTxMs, sb);
+                    sb.append(" e=").append(lastEnergy);
+                    sb.append("\n");
+                    sb.append("Current WiFi snapshot: ").append("idle=");
+                    TimeUtils.formatDuration(latest.mControllerIdleTimeMs, sb);
+                    sb.append(" rx=");
+                    TimeUtils.formatDuration(latest.mControllerRxTimeMs, sb);
+                    sb.append(" tx=");
+                    TimeUtils.formatDuration(latest.mControllerTxTimeMs, sb);
+                    sb.append(" e=").append(latest.mControllerEnergyUsed);
+                    Slog.wtf(TAG, sb.toString());
+                }
             } else {
                 maxExpectedIdleTimeMs = timePeriodMs - totalActiveTimeMs;
             }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 2103cce..1b2ccd7 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,9 +20,11 @@
 import android.accounts.Account;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
@@ -296,11 +298,12 @@
         final int callingUserHandle = UserHandle.getCallingUserId();
         // Registering an observer for any user other than the calling user requires uri grant or
         // cross user permission
-        if (callingUserHandle != userHandle &&
-                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                        != PackageManager.PERMISSION_GRANTED) {
-            enforceCrossUserPermission(userHandle,
-                    "no permission to observe other users' provider view");
+        if (callingUserHandle != userHandle) {
+            if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle)
+                    != PackageManager.PERMISSION_GRANTED) {
+                enforceCrossUserPermission(userHandle,
+                        "no permission to observe other users' provider view");
+            }
         }
 
         if (userHandle < 0) {
@@ -360,10 +363,11 @@
         final int pid = Binder.getCallingPid();
         final int callingUserHandle = UserHandle.getCallingUserId();
         // Notify for any user other than the caller requires uri grant or cross user permission
-        if (callingUserHandle != userHandle &&
-                mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
-                        != PackageManager.PERMISSION_GRANTED) {
-            enforceCrossUserPermission(userHandle, "no permission to notify other users");
+        if (callingUserHandle != userHandle) {
+            if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+                    userHandle) != PackageManager.PERMISSION_GRANTED) {
+                enforceCrossUserPermission(userHandle, "no permission to notify other users");
+            }
         }
 
         // We passed the permission check; resolve pseudouser targets as appropriate
@@ -389,9 +393,18 @@
             for (int i=0; i<numCalls; i++) {
                 ObserverCall oc = calls.get(i);
                 try {
-                    oc.mObserver.onChange(oc.mSelfChange, uri, userHandle);
+                    // If the uri does not belong to the same user as the observer: we must add
+                    // the userId to the uri. Otherewise the observer would think the uri belongs
+                    // to his user.
+                    final Uri tempUri;
+                    if (oc.mObserverUserId != userHandle) {
+                        tempUri = ContentProvider.maybeAddUserId(uri, userHandle);
+                    } else {
+                        tempUri = uri;
+                    }
+                    oc.mObserver.onChange(oc.mSelfChange, tempUri, userHandle);
                     if (DEBUG) Slog.d(TAG, "Notified " + oc.mObserver + " of " + "update at "
-                            + uri);
+                            + tempUri);
                 } catch (RemoteException ex) {
                     synchronized (mRootNode) {
                         Log.w(TAG, "Found dead observer, removing");
@@ -427,6 +440,15 @@
         }
     }
 
+    private int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, int userHandle) {
+        try {
+            return ActivityManagerNative.getDefault().checkUriPermission(
+                    uri, pid, uid, modeFlags, userHandle, null);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+    }
+
     public void notifyChange(Uri uri, IContentObserver observer,
                              boolean observerWantsSelfNotifications, boolean syncToNetwork) {
         notifyChange(uri, observer, observerWantsSelfNotifications,
@@ -444,11 +466,13 @@
         final ObserverNode mNode;
         final IContentObserver mObserver;
         final boolean mSelfChange;
+        final int mObserverUserId;
 
-        ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange) {
+        ObserverCall(ObserverNode node, IContentObserver observer, boolean selfChange, int observerUserId) {
             mNode = node;
             mObserver = observer;
             mSelfChange = selfChange;
+            mObserverUserId = observerUserId;
         }
     }
 
@@ -1361,7 +1385,8 @@
                     if (DEBUG) Slog.d(TAG, "Reporting to " + entry.observer + ": leaf=" + leaf
                             + " flags=" + Integer.toHexString(flags)
                             + " desc=" + entry.notifyForDescendants);
-                    calls.add(new ObserverCall(this, entry.observer, selfChange));
+                    calls.add(new ObserverCall(this, entry.observer, selfChange,
+                            UserHandle.getUserId(entry.uid)));
                 }
             }
         }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0daa8ba..aa1d73f 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -222,7 +222,6 @@
     private static native void nativeSetPointerIconType(long ptr, int iconId);
     private static native void nativeReloadPointerIcons(long ptr);
     private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon);
-    private static native void nativeSetPointerIconDetached(long ptr, boolean detached);
 
     // Input event injection constants defined in InputDispatcher.h.
     private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
@@ -1503,11 +1502,6 @@
         nativeSetFocusedApplication(mPtr, application);
     }
 
-    @Override
-    public void setPointerIconDetached(boolean detached) {
-        nativeSetPointerIconDetached(mPtr, detached);
-    }
-
     public void setInputDispatchMode(boolean enabled, boolean frozen) {
         nativeSetInputDispatchMode(mPtr, enabled, frozen);
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsObservers.java b/services/core/java/com/android/server/net/NetworkStatsObservers.java
index 230c2e9..ea36170 100644
--- a/services/core/java/com/android/server/net/NetworkStatsObservers.java
+++ b/services/core/java/com/android/server/net/NetworkStatsObservers.java
@@ -190,11 +190,9 @@
 
     private void handleUpdateStats(StatsContext statsContext) {
         if (mDataUsageRequests.size() == 0) {
-            if (LOGV) Slog.v(TAG, "No registered listeners of data usage");
             return;
         }
 
-        if (LOGV) Slog.v(TAG, "Checking if any registered observer needs to be notified");
         for (int i = 0; i < mDataUsageRequests.size(); i++) {
             RequestInfo requestInfo = mDataUsageRequests.valueAt(i);
             requestInfo.updateStats(statsContext);
@@ -371,9 +369,6 @@
             NetworkStats stats = mCollection.getSummary(template,
                     Long.MIN_VALUE /* start */, Long.MAX_VALUE /* end */,
                     mAccessLevel, mCallingUid);
-            if (LOGV) {
-                Slog.v(TAG, "Netstats for " + template + ": " + stats);
-            }
             return stats.getTotalBytes();
         }
     }
@@ -391,11 +386,6 @@
 
             for (int i = 0; i < uidsToMonitor.length; i++) {
                 long bytesSoFar = getTotalBytesForNetworkUid(mRequest.template, uidsToMonitor[i]);
-
-                if (LOGV) {
-                    Slog.v(TAG, bytesSoFar + " bytes so far since notification for "
-                            + mRequest.template + " for uid=" + uidsToMonitor[i]);
-                }
                 if (bytesSoFar > mRequest.thresholdInBytes) {
                     return true;
                 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ed061a5..f0e35e0 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2589,8 +2589,15 @@
             final PhoneWindow win = new PhoneWindow(context);
             win.setIsStartingWindow(true);
 
+            final WindowManager.LayoutParams params = win.getAttributes();
             final Resources r = context.getResources();
-            win.setTitle(r.getText(labelRes, nonLocalizedLabel));
+            CharSequence label = r.getText(labelRes);
+            // Only change the accessibility title if the label is localized
+            if (label != null) {
+                win.setTitle(label, true);
+            } else {
+                win.setTitle(nonLocalizedLabel, false);
+            }
 
             win.setType(
                 WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
@@ -2624,7 +2631,6 @@
             win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.MATCH_PARENT);
 
-            final WindowManager.LayoutParams params = win.getAttributes();
             params.token = appToken;
             params.packageName = packageName;
             params.windowAnimations = win.getWindowStyle().getResourceId(
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 101f56f..8be5dfb 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1203,9 +1203,6 @@
             window.layer = windowState.mLayer;
             window.token = windowState.mClient.asBinder();
             window.title = windowState.mAttrs.accessibilityTitle;
-            if (window.title == null) {
-                window.title = windowState.mAttrs.getTitle();
-            }
             window.accessibilityIdOfAnchor = windowState.mAttrs.accessibilityIdOfAnchor;
 
             WindowState attachedWindow = windowState.mAttachedWindow;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index f51fd8a..114d9be 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
@@ -380,6 +381,11 @@
     }
 
     private boolean updateBoundsAfterConfigChange() {
+        if (mDisplayContent == null) {
+            // If the stack is already detached we're not updating anything,
+            // as it's going away soon anyway.
+            return false;
+        }
         final int newRotation = getDisplayInfo().rotation;
         final int newDensity = getDisplayInfo().logicalDensityDpi;
 
@@ -403,6 +409,13 @@
             snapDockedStackAfterRotation(mTmpRect2);
             final int newDockSide = getDockSide(mTmpRect2);
             if (oldDockSide != newDockSide) {
+                // Update the dock create mode and clear the dock create bounds, these
+                // might change after a rotation and the original values will be invalid.
+                mService.setDockedStackCreateStateLocked(
+                        (newDockSide == DOCKED_LEFT || newDockSide == DOCKED_TOP)
+                        ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
+                        : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT,
+                        null);
                 mDisplayContent.getDockedDividerController().notifyDockSideChanged(newDockSide);
             }
         }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d363712..c7148c1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4959,11 +4959,15 @@
 
     public void setDockedStackCreateState(int mode, Rect bounds) {
         synchronized (mWindowMap) {
-            mDockedStackCreateMode = mode;
-            mDockedStackCreateBounds = bounds;
+            setDockedStackCreateStateLocked(mode, bounds);
         }
     }
 
+    void setDockedStackCreateStateLocked(int mode, Rect bounds) {
+        mDockedStackCreateMode = mode;
+        mDockedStackCreateBounds = bounds;
+    }
+
     /**
      * Create a new TaskStack and place it on a DisplayContent.
      * @param stackId The unique identifier of the new stack.
@@ -6386,6 +6390,11 @@
             if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
                     "Taking screenshot while rotating");
 
+            // We force pending transactions to flush before taking
+            // the screenshot by pushing an empty synchronous transaction.
+            SurfaceControl.openTransaction();
+            SurfaceControl.closeTransactionSync();
+
             bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
                     inRotation, rot);
             if (bm == null) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 2e82cec..2f72a5c 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -207,7 +207,6 @@
     void setPointerIconType(int32_t iconId);
     void reloadPointerIcons();
     void setCustomPointerIcon(const SpriteIcon& icon);
-    void setPointerIconDetached(bool detached);
 
     /* --- InputReaderPolicyInterface implementation --- */
 
@@ -712,14 +711,6 @@
     mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
 }
 
-void NativeInputManager::setPointerIconDetached(bool detached) {
-    AutoMutex _l(mLock);
-    sp<PointerController> controller = mLocked.pointerController.promote();
-    if (controller != NULL) {
-        controller->detachPointerIcon(detached);
-    }
-}
-
 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
     mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
 }
@@ -1332,12 +1323,6 @@
     im->setFocusedApplication(env, applicationHandleObj);
 }
 
-static void nativeSetPointerIconDetached(JNIEnv* env, jclass /* clazz */, jlong ptr,
-        jboolean detached) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-    im->setPointerIconDetached(detached);
-}
-
 static void nativeSetInputDispatchMode(JNIEnv* /* env */,
         jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1520,8 +1505,6 @@
             (void*) nativeSetInputWindows },
     { "nativeSetFocusedApplication", "(JLcom/android/server/input/InputApplicationHandle;)V",
             (void*) nativeSetFocusedApplication },
-    { "nativeSetPointerIconDetached", "(JZ)V",
-            (void*) nativeSetPointerIconDetached },
     { "nativeSetInputDispatchMode", "(JZZ)V",
             (void*) nativeSetInputDispatchMode },
     { "nativeSetSystemUiVisibility", "(JI)V",
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index b7701c6..22e2882 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -865,28 +865,9 @@
      * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
      * @return A {@link PersistableBundle} containing the config for the given subId, or default
      *         values for an invalid subId.
-     *
-     * @deprecated use getConfig.
      */
     @Nullable
     public PersistableBundle getConfigForSubId(int subId) {
-        return getConfig(subId);
-    }
-
-    /**
-     * Gets the configuration values for a particular subscription, which is associated with a
-     * specific SIM card. If an invalid subId is used, the returned config will contain default
-     * values.
-     *
-     * <p>Requires Permission:
-     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     *
-     * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
-     * @return A {@link PersistableBundle} containing the config for the given subId, or default
-     *         values for an invalid subId.
-     */
-    @Nullable
-    public PersistableBundle getConfig(int subId) {
         try {
             ICarrierConfigLoader loader = getICarrierConfigLoader();
             if (loader == null) {
@@ -908,11 +889,11 @@
      * <p>Requires Permission:
      * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      *
-     * @return A {@link PersistableBundle} containing the config for the default subscription.
+     * @see #getConfigForSubId
      */
     @Nullable
     public PersistableBundle getConfig() {
-        return getConfig(SubscriptionManager.getDefaultSubscriptionId());
+        return getConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
     }
 
     /**
@@ -929,29 +910,8 @@
      * {@link android.service.carrier.CarrierService#onLoadConfig} will be called from an
      * arbitrary thread.
      * </p>
-     *
-     * @deprecated use notifyConfigChanged.
      */
     public void notifyConfigChangedForSubId(int subId) {
-        notifyConfigChanged(subId);
-    }
-
-    /**
-     * Calling this method triggers telephony services to fetch the current carrier configuration.
-     * <p>
-     * Normally this does not need to be called because the platform reloads config on its own.
-     * This should be called by a carrier service app if it wants to update config at an arbitrary
-     * moment.
-     * </p>
-     * <p>Requires that the calling app has carrier privileges.
-     * @see #hasCarrierPrivileges
-     * <p>
-     * This method returns before the reload has completed, and
-     * {@link android.service.carrier.CarrierService#onLoadConfig} will be called from an
-     * arbitrary thread.
-     * </p>
-     */
-    public void notifyConfigChanged(int subId) {
         try {
             ICarrierConfigLoader loader = getICarrierConfigLoader();
             if (loader == null) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ddf5f2b..fe1027a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1730,6 +1730,11 @@
      *@hide
      */
     public static final int SIM_STATE_CARD_IO_ERROR = 8;
+    /** SIM card state: SIM Card restricted, present but not usable due to
+     * carrier restrictions.
+     *@hide
+     */
+    public static final int SIM_STATE_CARD_RESTRICTED = 9;
 
     /**
      * @return true if a ICC card is present
diff --git a/telephony/java/com/android/internal/telephony/IccCardConstants.java b/telephony/java/com/android/internal/telephony/IccCardConstants.java
index c1e2518..f3d9335 100644
--- a/telephony/java/com/android/internal/telephony/IccCardConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccCardConstants.java
@@ -32,6 +32,8 @@
     public static final String INTENT_VALUE_ICC_ABSENT = "ABSENT";
     /* CARD_IO_ERROR means for three consecutive times there was SIM IO error */
     static public final String INTENT_VALUE_ICC_CARD_IO_ERROR = "CARD_IO_ERROR";
+    /* CARD_RESTRICTED means card is present but not usable due to carrier restrictions */
+    static public final String INTENT_VALUE_ICC_CARD_RESTRICTED = "CARD_RESTRICTED";
     /* LOCKED means ICC is locked by pin or by network */
     public static final String INTENT_VALUE_ICC_LOCKED = "LOCKED";
     //TODO: we can remove this state in the future if Bug 18489776 analysis
@@ -74,7 +76,8 @@
         READY,          /** ordinal(5) == {@See TelephonyManager#SIM_STATE_READY} */
         NOT_READY,      /** ordinal(6) == {@See TelephonyManager#SIM_STATE_NOT_READY} */
         PERM_DISABLED,  /** ordinal(7) == {@See TelephonyManager#SIM_STATE_PERM_DISABLED} */
-        CARD_IO_ERROR;  /** ordinal(8) == {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR} */
+        CARD_IO_ERROR,  /** ordinal(8) == {@See TelephonyManager#SIM_STATE_CARD_IO_ERROR} */
+        CARD_RESTRICTED;/** ordinal(9) == {@See TelephonyManager#SIM_STATE_CARD_RESTRICTED} */
 
         public boolean isPinLocked() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
@@ -83,7 +86,8 @@
         public boolean iccCardExist() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
                     || (this == NETWORK_LOCKED) || (this == READY)
-                    || (this == PERM_DISABLED) || (this == CARD_IO_ERROR));
+                    || (this == PERM_DISABLED) || (this == CARD_IO_ERROR)
+                    || (this == CARD_RESTRICTED));
         }
 
         public static State intToState(int state) throws IllegalArgumentException {
@@ -97,6 +101,7 @@
                 case 6: return NOT_READY;
                 case 7: return PERM_DISABLED;
                 case 8: return CARD_IO_ERROR;
+                case 9: return CARD_RESTRICTED;
                 default:
                     throw new IllegalArgumentException();
             }
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index 3743fb0..5ef71df 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -41,12 +41,7 @@
  * Mock implementation of ContentProvider.  All methods are non-functional and throw
  * {@link java.lang.UnsupportedOperationException}.  Tests can extend this class to
  * implement behavior needed for tests.
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
  */
-@Deprecated
 public class MockContentProvider extends ContentProvider {
     /*
      * Note: if you add methods to ContentProvider, you must add similar methods to
diff --git a/test-runner/src/android/test/mock/MockContentResolver.java b/test-runner/src/android/test/mock/MockContentResolver.java
index 75c8335..d8e0977 100644
--- a/test-runner/src/android/test/mock/MockContentResolver.java
+++ b/test-runner/src/android/test/mock/MockContentResolver.java
@@ -49,12 +49,7 @@
  * <p>For more information about application testing, read the
  * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
  * </div>
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
  */
-@Deprecated
 public class MockContentResolver extends ContentResolver {
     Map<String, ContentProvider> mProviders;
 
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index c7cbf97..b14fc41 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -55,12 +55,7 @@
  * A mock {@link android.content.Context} class.  All methods are non-functional and throw
  * {@link java.lang.UnsupportedOperationException}.  You can use this to inject other dependencies,
  * mocks, or monitors into the classes you are testing.
- *
- * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
- * New tests should be written using the
- * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
  */
-@Deprecated
 public class MockContext extends Context {
 
     @Override