Merge "Fix issue with force resizing activity when app level doesn't want to" into oc-dev
diff --git a/Android.mk b/Android.mk
index 8daab8f..eb649c9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1460,7 +1460,8 @@
 LOCAL_SRC_FILES := \
     $(call all-proto-files-under, core/proto) \
     $(call all-proto-files-under, libs/incident/proto)
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_SHARED_LIBRARIES := libprotobuf-cpp-full
+include $(BUILD_SHARED_LIBRARY)
 
 # ====  c++ proto host library  ==============================
 include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index 5287984..00202b6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5586,7 +5586,7 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5641,6 +5641,7 @@
     method public java.lang.String getCreatorPackage();
     method public int getCreatorUid();
     method public android.os.UserHandle getCreatorUserHandle();
+    method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
     method public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
     method public deprecated java.lang.String getTargetPackage();
@@ -8858,6 +8859,7 @@
     method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
     method public abstract void startActivity(android.content.Intent);
     method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+    method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
     method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9049,6 +9051,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -24504,26 +24507,26 @@
   }
 
   public final class TvContract {
-    method public static final android.net.Uri buildChannelLogoUri(long);
-    method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
-    method public static final android.net.Uri buildChannelUri(long);
-    method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
-    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
-    method public static final java.lang.String buildInputId(android.content.ComponentName);
-    method public static final android.net.Uri buildPreviewProgramUri(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramUri(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
-    method public static final android.net.Uri buildRecordedProgramUri(long);
-    method public static final android.net.Uri buildWatchNextProgramUri(long);
-    method public static final boolean isChannelUri(android.net.Uri);
-    method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
-    method public static final boolean isChannelUriForTunerInput(android.net.Uri);
-    method public static final boolean isProgramUri(android.net.Uri);
+    method public static android.net.Uri buildChannelLogoUri(long);
+    method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+    method public static android.net.Uri buildChannelUri(long);
+    method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+    method public static java.lang.String buildInputId(android.content.ComponentName);
+    method public static android.net.Uri buildPreviewProgramUri(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramUri(long);
+    method public static android.net.Uri buildProgramsUriForChannel(long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static android.net.Uri buildRecordedProgramUri(long);
+    method public static android.net.Uri buildWatchNextProgramUri(long);
+    method public static boolean isChannelUri(android.net.Uri);
+    method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+    method public static boolean isChannelUriForTunerInput(android.net.Uri);
+    method public static boolean isProgramUri(android.net.Uri);
     field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -40679,6 +40682,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -45161,8 +45165,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public boolean autofill(android.view.autofill.AutofillValue);
-    method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -47670,6 +47674,7 @@
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+    field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
@@ -48110,7 +48115,8 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public android.view.textclassifier.TextClassifier getTextClassifier();
+    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
 
   public final class TextClassificationResult {
@@ -48147,9 +48153,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
-  }
-
   public final class TextLanguage {
     method public float getConfidenceScore(java.util.Locale);
     method public int getEndIndex();
diff --git a/api/removed.txt b/api/removed.txt
index 75da976..af429b8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -380,6 +380,14 @@
 
 }
 
+package android.view.textclassifier {
+
+  public final class TextClassificationManager {
+    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+  }
+
+}
+
 package android.webkit {
 
   public class WebViewClient {
diff --git a/api/system-current.txt b/api/system-current.txt
index bec8d25..f9e4545 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5312,6 +5312,7 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
     field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
     field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
     field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
@@ -5779,7 +5780,7 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5834,6 +5835,7 @@
     method public java.lang.String getCreatorPackage();
     method public int getCreatorUid();
     method public android.os.UserHandle getCreatorUserHandle();
+    method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
     method public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
     method public deprecated java.lang.String getTargetPackage();
@@ -9352,6 +9354,7 @@
     method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
     method public abstract void startActivity(android.content.Intent);
     method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+    method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
     method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9557,6 +9560,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -26433,28 +26437,28 @@
   }
 
   public final class TvContract {
-    method public static final android.net.Uri buildChannelLogoUri(long);
-    method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
-    method public static final android.net.Uri buildChannelUri(long);
-    method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
-    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
-    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String, boolean);
-    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String, java.lang.String, boolean);
-    method public static final java.lang.String buildInputId(android.content.ComponentName);
-    method public static final android.net.Uri buildPreviewProgramUri(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramUri(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
-    method public static final android.net.Uri buildRecordedProgramUri(long);
-    method public static final android.net.Uri buildWatchNextProgramUri(long);
-    method public static final boolean isChannelUri(android.net.Uri);
-    method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
-    method public static final boolean isChannelUriForTunerInput(android.net.Uri);
-    method public static final boolean isProgramUri(android.net.Uri);
+    method public static android.net.Uri buildChannelLogoUri(long);
+    method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+    method public static android.net.Uri buildChannelUri(long);
+    method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String, boolean);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String, java.lang.String, boolean);
+    method public static java.lang.String buildInputId(android.content.ComponentName);
+    method public static android.net.Uri buildPreviewProgramUri(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramUri(long);
+    method public static android.net.Uri buildProgramsUriForChannel(long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static android.net.Uri buildRecordedProgramUri(long);
+    method public static android.net.Uri buildWatchNextProgramUri(long);
+    method public static boolean isChannelUri(android.net.Uri);
+    method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+    method public static boolean isChannelUriForTunerInput(android.net.Uri);
+    method public static boolean isProgramUri(android.net.Uri);
     field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -44116,6 +44120,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -48616,8 +48621,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public boolean autofill(android.view.autofill.AutofillValue);
-    method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -51128,6 +51133,7 @@
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+    field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
@@ -51568,7 +51574,8 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public android.view.textclassifier.TextClassifier getTextClassifier();
+    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
 
   public final class TextClassificationResult {
@@ -51605,9 +51612,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
-  }
-
   public final class TextLanguage {
     method public float getConfidenceScore(java.util.Locale);
     method public int getEndIndex();
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 3aa9398..272ae77 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -374,6 +374,14 @@
 
 }
 
+package android.view.textclassifier {
+
+  public final class TextClassificationManager {
+    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+  }
+
+}
+
 package android.webkit {
 
   public class WebViewClient {
diff --git a/api/test-current.txt b/api/test-current.txt
index e9f94d9..f800461 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5599,7 +5599,7 @@
     method public boolean removeAutomaticZenRule(java.lang.String);
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
-    method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+    method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5654,6 +5654,7 @@
     method public java.lang.String getCreatorPackage();
     method public int getCreatorUid();
     method public android.os.UserHandle getCreatorUserHandle();
+    method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
     method public android.content.IntentSender getIntentSender();
     method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
     method public deprecated java.lang.String getTargetPackage();
@@ -8890,6 +8891,7 @@
     method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
     method public abstract void startActivity(android.content.Intent);
     method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+    method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
     method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9082,6 +9084,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -24617,26 +24620,26 @@
   }
 
   public final class TvContract {
-    method public static final android.net.Uri buildChannelLogoUri(long);
-    method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
-    method public static final android.net.Uri buildChannelUri(long);
-    method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
-    method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
-    method public static final java.lang.String buildInputId(android.content.ComponentName);
-    method public static final android.net.Uri buildPreviewProgramUri(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
-    method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramUri(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
-    method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
-    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
-    method public static final android.net.Uri buildRecordedProgramUri(long);
-    method public static final android.net.Uri buildWatchNextProgramUri(long);
-    method public static final boolean isChannelUri(android.net.Uri);
-    method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
-    method public static final boolean isChannelUriForTunerInput(android.net.Uri);
-    method public static final boolean isProgramUri(android.net.Uri);
+    method public static android.net.Uri buildChannelLogoUri(long);
+    method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+    method public static android.net.Uri buildChannelUri(long);
+    method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+    method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+    method public static java.lang.String buildInputId(android.content.ComponentName);
+    method public static android.net.Uri buildPreviewProgramUri(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+    method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramUri(long);
+    method public static android.net.Uri buildProgramsUriForChannel(long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+    method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+    method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+    method public static android.net.Uri buildRecordedProgramUri(long);
+    method public static android.net.Uri buildWatchNextProgramUri(long);
+    method public static boolean isChannelUri(android.net.Uri);
+    method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+    method public static boolean isChannelUriForTunerInput(android.net.Uri);
+    method public static boolean isProgramUri(android.net.Uri);
     field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
     field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -40883,6 +40886,7 @@
     method public void startActivities(android.content.Intent[], android.os.Bundle);
     method public void startActivity(android.content.Intent);
     method public void startActivity(android.content.Intent, android.os.Bundle);
+    method public android.content.ComponentName startForegroundService(android.content.Intent);
     method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
     method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -45535,8 +45539,8 @@
     method public void addTouchables(java.util.ArrayList<android.view.View>);
     method public android.view.ViewPropertyAnimator animate();
     method public void announceForAccessibility(java.lang.CharSequence);
-    method public boolean autofill(android.view.autofill.AutofillValue);
-    method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+    method public void autofill(android.view.autofill.AutofillValue);
+    method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
     method protected boolean awakenScrollBars();
     method protected boolean awakenScrollBars(int);
     method protected boolean awakenScrollBars(int, boolean);
@@ -48053,6 +48057,7 @@
     method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
     field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
     field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+    field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
     field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
   }
 
@@ -48493,7 +48498,8 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public android.view.textclassifier.TextClassifier getTextClassifier();
+    method public void setTextClassifier(android.view.textclassifier.TextClassifier);
   }
 
   public final class TextClassificationResult {
@@ -48530,9 +48536,6 @@
     field public static final java.lang.String TYPE_URL = "url";
   }
 
-  public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
-  }
-
   public final class TextLanguage {
     method public float getConfidenceScore(java.util.Locale);
     method public int getEndIndex();
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 75da976..af429b8 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -380,6 +380,14 @@
 
 }
 
+package android.view.textclassifier {
+
+  public final class TextClassificationManager {
+    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+  }
+
+}
+
 package android.webkit {
 
   public class WebViewClient {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bace226..147b5d0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2740,6 +2740,10 @@
                 return true;
             }
             return false;
+        } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+            // Don't consume TAB here since it's used for navigation. Arrow keys
+            // aren't considered "typing keys" so they already won't get consumed.
+            return false;
         } else {
             // Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_*
             boolean clearSpannable = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9f2f669..4004bd6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -405,6 +405,13 @@
      */
     public static final int INTENT_SENDER_SERVICE = 4;
 
+    /**
+     * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+     * for a startForegroundService operation.
+     * @hide
+     */
+    public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5;
+
     /** @hide User operation call: success! */
     public static final int USER_OP_SUCCESS = 0;
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4c080c9..467ba99 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1447,14 +1447,21 @@
     @Override
     public ComponentName startService(Intent service) {
         warnIfCallingFromSystemProcess();
-        return startServiceCommon(service, -1, null, mUser);
+        return startServiceCommon(service, -1, null, false, mUser);
     }
 
     @Override
+    public ComponentName startForegroundService(Intent service) {
+        warnIfCallingFromSystemProcess();
+        return startServiceCommon(service, -1, null, true, mUser);
+    }
+
+    // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+    @Override
     public ComponentName startServiceInForeground(Intent service,
             int id, Notification notification) {
         warnIfCallingFromSystemProcess();
-        return startServiceCommon(service, id, notification, mUser);
+        return startServiceCommon(service, id, notification, false, mUser);
     }
 
     @Override
@@ -1465,24 +1472,30 @@
 
     @Override
     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
-        return startServiceCommon(service, -1, null, user);
+        return startServiceCommon(service, -1, null, false, user);
     }
 
     @Override
+    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+        return startServiceCommon(service, -1, null, true, user);
+    }
+
+    // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+    @Override
     public ComponentName startServiceInForegroundAsUser(Intent service,
             int id, Notification notification, UserHandle user) {
-        return startServiceCommon(service, id, notification, user);
+        return startServiceCommon(service, id, notification, false, user);
     }
 
     private ComponentName startServiceCommon(Intent service, int id, Notification notification,
-            UserHandle user) {
+            boolean requireForeground, UserHandle user) {
         try {
             validateServiceIntent(service);
             service.prepareToLeaveProcess(this);
             ComponentName cn = ActivityManager.getService().startService(
                 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
-                            getContentResolver()), id, notification, getOpPackageName(),
-                            user.getIdentifier());
+                            getContentResolver()), id, notification, requireForeground,
+                            getOpPackageName(), user.getIdentifier());
             if (cn != null) {
                 if (cn.getPackageName().equals("!")) {
                     throw new SecurityException(
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 5d025d9..0c1be07 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2725,7 +2725,15 @@
             for (int i = 0; i < count; i++) {
                 Fragment f = nonConfigFragments.get(i);
                 if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
-                FragmentState fs = fms.mActive[f.mIndex];
+                int index = 0; // index of f in fms.mActive
+                while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) {
+                    index++;
+                }
+                if (index == fms.mActive.length) {
+                    throwException(new IllegalStateException("Could not find active fragment "
+                            + "with index " + f.mIndex));
+                }
+                FragmentState fs = fms.mActive[index];
                 fs.mInstance = f;
                 f.mSavedViewState = null;
                 f.mBackStackNesting = 0;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index b9d1d91..0a5e4be 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -130,7 +130,7 @@
     PendingIntent getRunningServiceControlPanel(in ComponentName service);
     ComponentName startService(in IApplicationThread caller, in Intent service,
             in String resolvedType, int id, in Notification notification,
-            in String callingPackage, int userId);
+            boolean requireForeground, in String callingPackage, int userId);
     int stopService(in IApplicationThread caller, in Intent service,
             in String resolvedType, int userId);
     int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c78b3cd..4bbc003 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -971,6 +971,7 @@
      * Only available to notifications coming from the android package.
      * @hide
      */
+    @SystemApi
     public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
 
     /**
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 75998f2..72c5978 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1171,8 +1171,11 @@
      * @return If the service is being started or is already running, the
      *      {@link ComponentName} of the actual service that was started is
      *      returned; else if the service does not exist null is returned.
+     *
+     * @deprecated STOPSHIP transition away from this for O
      */
     @Nullable
+    @Deprecated
     public ComponentName startServiceInForeground(Intent service,
             int id, Notification notification) {
         return mContext.startServiceInForeground(service, id, notification);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 7d1a16a..dc432af 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -596,6 +596,42 @@
      */
     public static PendingIntent getService(Context context, int requestCode,
             @NonNull Intent intent, @Flags int flags) {
+        return buildServicePendingIntent(context, requestCode, intent, flags,
+                ActivityManager.INTENT_SENDER_SERVICE);
+    }
+
+    /**
+     * Retrieve a PendingIntent that will start a foreground service, like calling
+     * {@link Context#startService Context.startForegroundService()}.  The start
+     * arguments given to the service will come from the extras of the Intent.
+     *
+     * <p class="note">For security reasons, the {@link android.content.Intent}
+     * you supply here should almost always be an <em>explicit intent</em>,
+     * that is specify an explicit component to be delivered to through
+     * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
+     *
+     * @param context The Context in which this PendingIntent should start
+     * the service.
+     * @param requestCode Private request code for the sender
+     * @param intent An Intent describing the service to be started.
+     * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
+     * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
+     * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
+     * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
+     * of the intent that can be supplied when the actual send happens.
+     *
+     * @return Returns an existing or new PendingIntent matching the given
+     * parameters.  May return null only if {@link #FLAG_NO_CREATE} has been
+     * supplied.
+     */
+    public static PendingIntent getForegroundService(Context context, int requestCode,
+            @NonNull Intent intent, @Flags int flags) {
+        return buildServicePendingIntent(context, requestCode, intent, flags,
+                ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE);
+    }
+
+    private static PendingIntent buildServicePendingIntent(Context context, int requestCode,
+            Intent intent, int flags, int serviceKind) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -603,7 +639,7 @@
             intent.prepareToLeaveProcess(context);
             IIntentSender target =
                 ActivityManager.getService().getIntentSender(
-                    ActivityManager.INTENT_SENDER_SERVICE, packageName,
+                    serviceKind, packageName,
                     null, null, requestCode, new Intent[] { intent },
                     resolvedType != null ? new String[] { resolvedType } : null,
                     flags, null, UserHandle.myUserId());
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 78e4c0d..f9094c0 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -83,6 +83,9 @@
     /* Minimum flex for a periodic job, in milliseconds. */
     private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes
 
+    /* Minimum backoff interval for a job, in milliseconds */
+    private static final long MIN_BACKOFF_MILLIS = 10 * 1000L;      // 10 seconds
+
     /**
      * Query the minimum interval allowed for periodic scheduled jobs.  Attempting
      * to declare a smaller period that this when scheduling a job will result in a
@@ -106,6 +109,14 @@
     }
 
     /**
+     * Query the minimum automatic-reschedule backoff interval permitted for jobs.
+     * @hide
+     */
+    public static final long getMinBackoffMillis() {
+        return MIN_BACKOFF_MILLIS;
+    }
+
+    /**
      * Default type of backoff.
      * @hide
      */
@@ -361,7 +372,8 @@
      * job does not recur periodically.
      */
     public long getIntervalMillis() {
-        return intervalMillis >= getMinPeriodMillis() ? intervalMillis : getMinPeriodMillis();
+        final long minInterval = getMinPeriodMillis();
+        return intervalMillis >= minInterval ? intervalMillis : minInterval;
     }
 
     /**
@@ -381,7 +393,8 @@
      * to 5 seconds.
      */
     public long getInitialBackoffMillis() {
-        return initialBackoffMillis;
+        final long minBackoff = getMinBackoffMillis();
+        return initialBackoffMillis >= minBackoff ? initialBackoffMillis : minBackoff;
     }
 
     /**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3a8a420..1803bbe 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2576,7 +2576,7 @@
      * {@link ComponentName} of the actual service that was started is
      * returned; else if the service does not exist null is returned.
      *
-     * @throws SecurityException If the caller does not permission to access the service
+     * @throws SecurityException If the caller does not have permission to access the service
      * or the service can not be found.
      * @throws IllegalStateException If the application is in a state where the service
      * can not be started (such as not in the foreground in a state when services are allowed).
@@ -2588,11 +2588,47 @@
     public abstract ComponentName startService(Intent service);
 
     /**
+     * Similar to {@link #startService(Intent)}, but with an implicit promise that the
+     * Service will call {@link android.app.Service#startForeground(int, Notification)
+     * startForeground(int, Notification)} once it begins running.  The service is given
+     * an amount of time comparable to the ANR interval to do this, otherwise the system
+     * will automatically stop the service and declare the app ANR.
+     *
+     * <p>Unlike the ordinary {@link #startService(Intent)}, this method can be used
+     * at any time, regardless of whether the app hosting the service is in a foreground
+     * state.
+     *
+     * @param service Identifies the service to be started.  The Intent must be
+     *      fully explicit (supplying a component name).  Additional values
+     *      may be included in the Intent extras to supply arguments along with
+     *      this specific start call.
+     *
+     * @return If the service is being started or is already running, the
+     * {@link ComponentName} of the actual service that was started is
+     * returned; else if the service does not exist null is returned.
+     *
+     * @throws SecurityException If the caller does not have permission to access the service
+     * or the service can not be found.
+     *
+     * @see #stopService
+     * @see android.app.Service#startForeground(int, Notification)
+     */
+    @Nullable
+    public abstract ComponentName startForegroundService(Intent service);
+
+    /**
+     * @hide like {@link #startForegroundService(Intent)} but for a specific user.
+     */
+    @Nullable
+    public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user);
+
+    /**
      * Start a service directly into the "foreground service" state.  Unlike {@link #startService},
      * this method can be used from within background operations like broadcast receivers
      * or scheduled jobs.  The API entry point for this is in NotificationManager in order to
      * preserve appropriate public package layering.
      * @hide
+     * @deprecated STOPSHIP remove in favor of two-step startForegroundService() + startForeground()
      */
     @Nullable
     public abstract ComponentName startServiceInForeground(Intent service,
@@ -2620,7 +2656,7 @@
      * @return If there is a service matching the given Intent that is already
      * running, then it is stopped and {@code true} is returned; else {@code false} is returned.
      *
-     * @throws SecurityException If the caller does not permission to access the service
+     * @throws SecurityException If the caller does not have permission to access the service
      * or the service can not be found.
      * @throws IllegalStateException If the application is in a state where the service
      * can not be started (such as not in the foreground in a state when services are allowed).
@@ -2638,7 +2674,9 @@
     /**
      * @hide like {@link #startServiceInForeground(Intent, int, Notification)}
      * but for a specific user.
+     * @deprecated STOPSHIP remove when trial API is turned off
      */
+    @Deprecated
     @Nullable
     public abstract ComponentName startServiceInForegroundAsUser(Intent service,
             int id, Notification notification, UserHandle user);
@@ -2685,7 +2723,7 @@
      *         {@code false} is returned if the connection is not made so you will not
      *         receive the service object.
      *
-     * @throws SecurityException If the caller does not permission to access the service
+     * @throws SecurityException If the caller does not have permission to access the service
      * or the service can not be found.
      *
      * @see #unbindService
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6b0bbfa..75784a6 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -644,7 +644,12 @@
         return mBase.startService(service);
     }
 
-    /** @hide */
+    @Override
+    public ComponentName startForegroundService(Intent service) {
+        return mBase.startForegroundService(service);
+    }
+
+    /** @hide STOPSHIP remove when trial API is turned down */
     @Override
     public ComponentName startServiceInForeground(Intent service,
             int id, Notification notification) {
@@ -664,6 +669,12 @@
 
     /** @hide */
     @Override
+    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+        return mBase.startForegroundServiceAsUser(service, user);
+    }
+
+    /** @hide STOPSHIP removed when trial API is turned down */
+    @Override
     public ComponentName startServiceInForegroundAsUser(Intent service,
             int id, Notification notification, UserHandle user) {
         return mBase.startServiceInForegroundAsUser(service, id, notification, user);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 370af17..16d582ef 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -314,4 +314,17 @@
      */
     public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
             int flags, int userId);
+
+    /**
+     * Track the creator of a new isolated uid.
+     * @param isolatedUid The newly created isolated uid.
+     * @param ownerUid The uid of the app that created the isolated process.
+     */
+    public abstract void addIsolatedUid(int isolatedUid, int ownerUid);
+
+    /**
+     * Track removal of an isolated uid.
+     * @param isolatedUid isolated uid that is no longer being used.
+     */
+    public abstract void removeIsolatedUid(int isolatedUid);
 }
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 5fa2461..5f66abd 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -741,6 +741,10 @@
             int timeTotal = -1;
             int uncryptTime = -1;
             int sourceVersion = -1;
+            int temperature_start = -1;
+            int temperature_end = -1;
+            int temperature_max = -1;
+
             while ((line = in.readLine()) != null) {
                 // Here is an example of lines in last_install:
                 // ...
@@ -785,6 +789,12 @@
                 } else if (line.startsWith("bytes_stashed")) {
                     bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled :
                             bytesStashedInMiB + scaled;
+                } else if (line.startsWith("temperature_start")) {
+                    temperature_start = scaled;
+                } else if (line.startsWith("temperature_end")) {
+                    temperature_end = scaled;
+                } else if (line.startsWith("temperature_max")) {
+                    temperature_max = scaled;
                 }
             }
 
@@ -804,6 +814,15 @@
             if (bytesStashedInMiB != -1) {
                 MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB);
             }
+            if (temperature_start != -1) {
+                MetricsLogger.histogram(context, "ota_temperature_start", temperature_start);
+            }
+            if (temperature_end != -1) {
+                MetricsLogger.histogram(context, "ota_temperature_end", temperature_end);
+            }
+            if (temperature_max != -1) {
+                MetricsLogger.histogram(context, "ota_temperature_max", temperature_max);
+            }
 
         } catch (IOException e) {
             Log.e(TAG, "Failed to read lines in last_install", e);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 42575b6..a6bf2d2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -369,8 +369,10 @@
     public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
 
     /**
-     * Specifies if a user is disallowed from disabling application
-     * verification. The default value is <code>false</code>.
+     * Specifies if a user is disallowed from disabling application verification.
+     * Starting from {@link android.os.Build.VERSION_CODES#O}, application verification
+     * is enforced across all users on the device if a profile owner or device owner sets
+     * this restriction to <code>true</code>. The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 86318e9..d3cc175 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -36,8 +36,8 @@
 
     /**
      * Creates a new context wrapper with no theme and no base context.
-     * <p>
-     * <stong>Note:</strong> A base context <strong>must</strong> be attached
+     * <p class="note">
+     * <strong>Note:</strong> A base context <strong>must</strong> be attached
      * using {@link #attachBaseContext(Context)} before calling any other
      * method on the newly constructed context wrapper.
      */
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 519c1e2..1cb563f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -451,10 +451,6 @@
         return nativeGetHandle(mNativeObject);
     }
 
-    public boolean getTransformToDisplayInverse() {
-        return nativeGetTransformToDisplayInverse(mNativeObject);
-    }
-
     /** flag the transaction as an animation */
     public static void setAnimationTransaction() {
         nativeSetAnimationTransaction();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e924f77..23fcb55 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7447,11 +7447,8 @@
      * </pre>
      *
      * @param value value to be autofilled.
-     *
-     * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
      */
-    public boolean autofill(@SuppressWarnings("unused") AutofillValue value) {
-        return false;
+    public void autofill(@SuppressWarnings("unused") AutofillValue value) {
     }
 
     /**
@@ -7461,12 +7458,8 @@
      * {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
      *
      * @param values map of values to be autofilled, keyed by virtual child id.
-     *
-     * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
      */
-    public boolean autofill(
-            @NonNull @SuppressWarnings("unused") SparseArray<AutofillValue>values) {
-        return false;
+    public void autofill(@NonNull @SuppressWarnings("unused") SparseArray<AutofillValue> values) {
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a43b13e..2e201bf 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6386,7 +6386,7 @@
         args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets;
         args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets;
         args.arg4 = sameProcessCall && mergedConfiguration != null
-                ? new MergedConfiguration(mergedConfiguration) : null;
+                ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration;
         args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
         args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
         args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b4d2c6b..19980fb 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -56,9 +56,9 @@
 
     /**
      * Intent extra: The assist structure which captures the filled screen.
+     *
      * <p>
      * Type: {@link android.app.assist.AssistStructure}
-     * </p>
      */
     public static final String EXTRA_ASSIST_STRUCTURE =
             "android.view.autofill.extra.ASSIST_STRUCTURE";
@@ -72,11 +72,25 @@
      * <p>
      * Type: {@link android.service.autofill.FillResponse} or a
      * {@link android.service.autofill.Dataset}
-     * </p>
      */
     public static final String EXTRA_AUTHENTICATION_RESULT =
             "android.view.autofill.extra.AUTHENTICATION_RESULT";
 
+    /**
+     * Intent extra: The optional extras provided by the
+     * {@link android.service.autofill.AutofillService}.
+     *
+     * <p>For example, when the service responds to a {@link
+     * android.service.autofill.FillCallback#onSuccess(android.service.autofill.FillResponse)} with
+     * a {@code FillResponse} that requires authentication, the Intent that launches the
+     * service authentication will contain the Bundle set by
+     * {@link android.service.autofill.FillResponse.Builder#setExtras(Bundle)} on this extra.
+     *
+     * <p>
+     * Type: {@link android.os.Bundle}
+     */
+    public static final String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
+
     // Public flags start from the lowest bit
     /**
      * Indicates autofill was explicitly requested by the user.
@@ -554,9 +568,8 @@
                 }
                 valuesByParent.put(id.getVirtualChildId(), value);
             } else {
-                if (view.autofill(value)) {
-                    numApplied++;
-                }
+                view.autofill(value);
+                numApplied++;
             }
         }
 
@@ -564,9 +577,8 @@
             for (int i = 0; i < virtualValues.size(); i++) {
                 final View parent = virtualValues.keyAt(i);
                 final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
-                if (parent.autofill(childrenValues)) {
-                    numApplied += childrenValues.size();
-                }
+                parent.autofill(childrenValues);
+                numApplied += childrenValues.size();
             }
         }
 
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 5487965..0b6021a 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -17,6 +17,7 @@
 package android.view.textclassifier;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
@@ -45,7 +46,7 @@
 
     private final Context mContext;
     private ParcelFileDescriptor mLangIdFd;
-    private TextClassifier mDefault;
+    private TextClassifier mTextClassifier;
     private LangId mLangId;
 
     /** @hide */
@@ -53,15 +54,32 @@
         mContext = Preconditions.checkNotNull(context);
     }
 
-    /**
-     * Returns the default text classifier.
-     */
+    // TODO: Remove.
+    /** @removed */
     public TextClassifier getDefaultTextClassifier() {
+        return getTextClassifier();
+    }
+
+    /**
+     * Returns the text classifier.
+     */
+    public TextClassifier getTextClassifier() {
         synchronized (mTextClassifierLock) {
-            if (mDefault == null) {
-                mDefault = new TextClassifierImpl(mContext);
+            if (mTextClassifier == null) {
+                mTextClassifier = new TextClassifierImpl(mContext);
             }
-            return mDefault;
+            return mTextClassifier;
+        }
+    }
+
+    /**
+     * Sets the text classifier.
+     * Set to null to use the system default text classifier.
+     * Set to {@link TextClassifier#NO_OP} to disable text classifier features.
+     */
+    public void setTextClassifier(@Nullable TextClassifier textClassifier) {
+        synchronized (mTextClassifierLock) {
+            mTextClassifier = textClassifier;
         }
     }
 
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index dabbf31..0831e20 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -39,9 +39,10 @@
     String TYPE_ADDRESS = "address";
     String TYPE_URL = "url";
 
+    /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @StringDef({
-            TYPE_OTHER, TYPE_EMAIL, TYPE_PHONE, TYPE_ADDRESS
+            TYPE_OTHER, TYPE_EMAIL, TYPE_PHONE, TYPE_ADDRESS, TYPE_URL
     })
     @interface EntityType {}
 
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index 8f662ba..352e7de 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -526,15 +526,15 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (!isEnabled()) return false;
+    public void autofill(AutofillValue value) {
+        if (!isEnabled()) return;
 
-        if (value.isList()) {
-            setSelection(value.getListValue());
-        } else {
+        if (!value.isList()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+            return;
         }
-        return true;
+
+        setSelection(value.getListValue());
     }
 
     @Override
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 9dc61ab..c7ba7b5 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -584,16 +584,15 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (!isEnabled()) return false;
+    public void autofill(AutofillValue value) {
+        if (!isEnabled()) return;
 
-        if (value.isToggle()) {
-            setChecked(value.getToggleValue());
-        } else {
+        if (!value.isToggle()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+            return;
         }
 
-        return true;
+        setChecked(value.getToggleValue());
     }
 
     @Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 7d04f35..463ff58 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -775,16 +775,15 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (!isEnabled()) return false;
+    public void autofill(AutofillValue value) {
+        if (!isEnabled()) return;
 
-        if (value.isDate()) {
-            mDelegate.updateDate(value.getDateValue());
-        } else {
+        if (!value.isDate()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+            return;
         }
 
-        return true;
+        mDelegate.updateDate(value.getDateValue());
     }
 
     @Override
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index a7574c7..08e6575 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -426,24 +426,22 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (!isEnabled()) return false;
+    public void autofill(AutofillValue value) {
+        if (!isEnabled()) return;
 
-        int index;
-        if (value.isList()) {
-            index = value.getListValue();
-        } else {
+        if (!value.isList()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
-            return false;
+            return;
         }
 
+        final int index = value.getListValue();
         final View child = getChildAt(index);
         if (child == null) {
             Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
-            return false;
+            return;
         }
+
         check(child.getId());
-        return true;
     }
 
     @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bc7c79d..3d5e81b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10050,17 +10050,13 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (value.isText()) {
-            if (isTextEditable()) {
-                setText(value.getTextValue(), mBufferType, true, 0);
-                return true;
-            }
-        } else {
+    public void autofill(AutofillValue value) {
+        if (!value.isText() || !isTextEditable()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+            return;
         }
 
-        return false;
+        setText(value.getTextValue(), mBufferType, true, 0);
     }
 
     @Override
@@ -10769,7 +10765,7 @@
             TextClassificationManager tcm =
                     mContext.getSystemService(TextClassificationManager.class);
             if (tcm != null) {
-                mTextClassifier = tcm.getDefaultTextClassifier();
+                mTextClassifier = tcm.getTextClassifier();
             } else {
                 mTextClassifier = TextClassifier.NO_OP;
             }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 1e97e3b..0289dad 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -530,16 +530,14 @@
     }
 
     @Override
-    public boolean autofill(AutofillValue value) {
-        if (!isEnabled()) return false;
+    public void autofill(AutofillValue value) {
+        if (!isEnabled()) return;
 
-        if (value.isDate()) {
-            mDelegate.setDate(value.getDateValue());
-        } else {
+        if (!value.isDate()) {
             Log.w(LOG_TAG, value + " could not be autofilled into " + this);
         }
 
-        return true;
+        mDelegate.setDate(value.getDateValue());
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 7ce5fc3..b3904f4 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -477,12 +477,9 @@
             final KeyCharacterMap kmap = KeyCharacterMap.load(
                     event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
             menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
-            menu.performShortcut(keyCode, event, 0);
+            return menu.performShortcut(keyCode, event, 0);
         }
-        // This action bar always returns true for handling keyboard shortcuts.
-        // This will block the window from preparing a temporary panel to handle
-        // keyboard shortcuts.
-        return true;
+        return false;
     }
 
     @Override
@@ -525,6 +522,17 @@
             }
             return result;
         }
+
+        @Override
+        public View onCreatePanelView(int featureId) {
+            if (featureId == Window.FEATURE_OPTIONS_PANEL) {
+                // This gets called by PhoneWindow.preparePanel. Since this already manages
+                // its own panel, we return a dummy view here to prevent PhoneWindow from
+                // preparing a default one.
+                return new View(mDecorToolbar.getContext());
+            }
+            return super.onCreatePanelView(featureId);
+        }
     }
 
     private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3d0d6bf..b263657 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -114,7 +114,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 151 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 152 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -10057,6 +10057,9 @@
 
     public void setBatteryStateLocked(int status, int health, int plugType, int level,
             int temp, int volt, int chargeUAh, int chargeFullUAh) {
+        // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
+        temp = Math.max(0, temp);
+
         final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
         final long uptime = mClocks.uptimeMillis();
         final long elapsedRealtime = mClocks.elapsedRealtime();
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 6fbf49b..e2443bb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -735,16 +735,6 @@
     return javaObjectForIBinder(env, ctrl->getHandle());
 }
 
-static jboolean nativeGetTransformToDisplayInverse(JNIEnv* env, jclass clazz, jlong nativeObject) {
-    bool out = false;
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    status_t status = ctrl->getTransformToDisplayInverse(&out);
-    if (status != NO_ERROR) {
-        return false;
-    }
-    return out;
-}
-
 static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
     if (token == NULL) return NULL;
@@ -854,8 +844,6 @@
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
-    {"nativeGetTransformToDisplayInverse", "(J)Z",
-     (void*)nativeGetTransformToDisplayInverse },
     {"nativeScreenshotToBuffer",
      "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
      (void*)nativeScreenshotToBuffer },
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index db234e7..cda2369 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -784,9 +784,14 @@
     -->
     <integer name="config_defaultNightMode">1</integer>
 
+    <!-- Boolean indicating whether the HWC setColorTransform function can be performed efficiently
+         in hardware. -->
+    <bool name="config_setColorTransformAccelerated">false</bool>
+
     <!-- Control whether Night display is available. This should only be enabled on devices
-         with HWC 2.0 or higher. -->
-    <bool name="config_nightDisplayAvailable">false</bool>
+         that have a HWC implementation that can apply the matrix passed to setColorTransform
+         without impacting power, performance, and app compatibility (e.g. protected content). -->
+    <bool name="config_nightDisplayAvailable">@bool/config_setColorTransformAccelerated</bool>
 
     <!-- Default mode to control how Night display is automatically activated.
          One of the following values (see NightDisplayController.java):
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92436f4..db5fade 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2774,6 +2774,7 @@
   <java-symbol type="drawable" name="ic_doc_video" />
   <java-symbol type="drawable" name="ic_doc_generic" />
 
+  <java-symbol type="bool" name="config_setColorTransformAccelerated" />
   <java-symbol type="bool" name="config_nightDisplayAvailable" />
   <java-symbol type="bool" name="config_allowDisablingAssistDisclosure" />
   <java-symbol type="integer" name="config_defaultNightDisplayAutoMode" />
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 8826cfc..7f06421 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -27,7 +27,5 @@
     libft2 \
     libminikin \
     libandroidfw \
-    libRScpp
-
-LOCAL_STATIC_LIBRARIES += \
+    libRScpp \
     libplatformprotos
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 7bf69c0..9739319 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -283,7 +283,7 @@
      * @param name The {@link ComponentName} of the TV input service to build ID for.
      * @return the ID for the given TV input service.
      */
-    public static final String buildInputId(ComponentName name) {
+    public static String buildInputId(ComponentName name) {
         return name.flattenToShortString();
     }
 
@@ -292,7 +292,7 @@
      *
      * @param channelId The ID of the channel to point to.
      */
-    public static final Uri buildChannelUri(long channelId) {
+    public static Uri buildChannelUri(long channelId) {
         return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId);
     }
 
@@ -302,7 +302,7 @@
      * @param inputId The ID of the pass-through input to build a channels URI for.
      * @see TvInputInfo#isPassthroughInput()
      */
-    public static final Uri buildChannelUriForPassthroughInput(String inputId) {
+    public static Uri buildChannelUriForPassthroughInput(String inputId) {
         return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
                 .appendPath(PATH_PASSTHROUGH).appendPath(inputId).build();
     }
@@ -312,7 +312,7 @@
      *
      * @param channelId The ID of the channel whose logo is pointed to.
      */
-    public static final Uri buildChannelLogoUri(long channelId) {
+    public static Uri buildChannelLogoUri(long channelId) {
         return buildChannelLogoUri(buildChannelUri(channelId));
     }
 
@@ -321,7 +321,7 @@
      *
      * @param channelUri The URI of the channel whose logo is pointed to.
      */
-    public static final Uri buildChannelLogoUri(Uri channelUri) {
+    public static Uri buildChannelLogoUri(Uri channelUri) {
         if (!isChannelUriForTunerInput(channelUri)) {
             throw new IllegalArgumentException("Not a channel: " + channelUri);
         }
@@ -334,7 +334,7 @@
      * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
      *            URI for all the TV inputs.
      */
-    public static final Uri buildChannelsUriForInput(@Nullable String inputId) {
+    public static Uri buildChannelsUriForInput(@Nullable String inputId) {
         return buildChannelsUriForInput(inputId, false);
     }
 
@@ -349,7 +349,7 @@
      * @hide
      */
     @SystemApi
-    public static final Uri buildChannelsUriForInput(@Nullable String inputId,
+    public static Uri buildChannelsUriForInput(@Nullable String inputId,
             boolean browsableOnly) {
         Uri.Builder builder = Channels.CONTENT_URI.buildUpon();
         if (inputId != null) {
@@ -372,7 +372,7 @@
      * @hide
      */
     @SystemApi
-    public static final Uri buildChannelsUriForInput(@Nullable String inputId,
+    public static Uri buildChannelsUriForInput(@Nullable String inputId,
             @Nullable String genre, boolean browsableOnly) {
         if (genre == null) {
             return buildChannelsUriForInput(inputId, browsableOnly);
@@ -389,7 +389,7 @@
      *
      * @param programId The ID of the program to point to.
      */
-    public static final Uri buildProgramUri(long programId) {
+    public static Uri buildProgramUri(long programId) {
         return ContentUris.withAppendedId(Programs.CONTENT_URI, programId);
     }
 
@@ -398,7 +398,7 @@
      *
      * @param channelId The ID of the channel to return programs for.
      */
-    public static final Uri buildProgramsUriForChannel(long channelId) {
+    public static Uri buildProgramsUriForChannel(long channelId) {
         return Programs.CONTENT_URI.buildUpon()
                 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
     }
@@ -408,7 +408,7 @@
      *
      * @param channelUri The URI of the channel to return programs for.
      */
-    public static final Uri buildProgramsUriForChannel(Uri channelUri) {
+    public static Uri buildProgramsUriForChannel(Uri channelUri) {
         if (!isChannelUriForTunerInput(channelUri)) {
             throw new IllegalArgumentException("Not a channel: " + channelUri);
         }
@@ -425,7 +425,7 @@
      * @param endTime The end time used to filter programs. The returned programs should have
      *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
      */
-    public static final Uri buildProgramsUriForChannel(long channelId, long startTime,
+    public static Uri buildProgramsUriForChannel(long channelId, long startTime,
             long endTime) {
         Uri uri = buildProgramsUriForChannel(channelId);
         return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime))
@@ -442,7 +442,7 @@
      * @param endTime The end time used to filter programs. The returned programs should have
      *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
      */
-    public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
+    public static Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
             long endTime) {
         if (!isChannelUriForTunerInput(channelUri)) {
             throw new IllegalArgumentException("Not a channel: " + channelUri);
@@ -455,7 +455,7 @@
      *
      * @param recordedProgramId The ID of the recorded program to point to.
      */
-    public static final Uri buildRecordedProgramUri(long recordedProgramId) {
+    public static Uri buildRecordedProgramUri(long recordedProgramId) {
         return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId);
     }
 
@@ -464,7 +464,7 @@
      *
      * @param previewProgramId The ID of the preview program to point to.
      */
-    public static final Uri buildPreviewProgramUri(long previewProgramId) {
+    public static Uri buildPreviewProgramUri(long previewProgramId) {
         return ContentUris.withAppendedId(PreviewPrograms.CONTENT_URI, previewProgramId);
     }
 
@@ -473,7 +473,7 @@
      *
      * @param channelId The ID of the channel to return preview programs for.
      */
-    public static final Uri buildPreviewProgramsUriForChannel(long channelId) {
+    public static Uri buildPreviewProgramsUriForChannel(long channelId) {
         return PreviewPrograms.CONTENT_URI.buildUpon()
                 .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
     }
@@ -483,7 +483,7 @@
      *
      * @param channelUri The URI of the channel to return preview programs for.
      */
-    public static final Uri buildPreviewProgramsUriForChannel(Uri channelUri) {
+    public static Uri buildPreviewProgramsUriForChannel(Uri channelUri) {
         if (!isChannelUriForTunerInput(channelUri)) {
             throw new IllegalArgumentException("Not a channel: " + channelUri);
         }
@@ -495,7 +495,7 @@
      *
      * @param watchNextProgramId The ID of the watch next program to point to.
      */
-    public static final Uri buildWatchNextProgramUri(long watchNextProgramId) {
+    public static Uri buildWatchNextProgramUri(long watchNextProgramId) {
         return ContentUris.withAppendedId(WatchNextPrograms.CONTENT_URI, watchNextProgramId);
     }
 
@@ -505,7 +505,7 @@
      * @param watchedProgramId The ID of the watched program to point to.
      * @hide
      */
-    public static final Uri buildWatchedProgramUri(long watchedProgramId) {
+    public static Uri buildWatchedProgramUri(long watchedProgramId) {
         return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
     }
 
@@ -522,28 +522,28 @@
     /**
      * Returns {@code true}, if {@code uri} is a channel URI.
      */
-    public static final boolean isChannelUri(Uri uri) {
+    public static boolean isChannelUri(Uri uri) {
         return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri);
     }
 
     /**
      * Returns {@code true}, if {@code uri} is a channel URI for a tuner input.
      */
-    public static final boolean isChannelUriForTunerInput(Uri uri) {
+    public static boolean isChannelUriForTunerInput(Uri uri) {
         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL);
     }
 
     /**
      * Returns {@code true}, if {@code uri} is a channel URI for a pass-through input.
      */
-    public static final boolean isChannelUriForPassthroughInput(Uri uri) {
+    public static boolean isChannelUriForPassthroughInput(Uri uri) {
         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH);
     }
 
     /**
      * Returns {@code true}, if {@code uri} is a program URI.
      */
-    public static final boolean isProgramUri(Uri uri) {
+    public static boolean isProgramUri(Uri uri) {
         return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM);
     }
 
@@ -580,7 +580,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_TITLE = "title";
+        String COLUMN_TITLE = "title";
 
         /**
          * The season display number of this TV program for episodic TV shows.
@@ -592,7 +592,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+        String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
 
         /**
          * The title of the season for this TV program for episodic TV shows.
@@ -608,7 +608,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_SEASON_TITLE = "season_title";
+        String COLUMN_SEASON_TITLE = "season_title";
 
         /**
          * The episode display number of this TV program for episodic TV shows.
@@ -620,7 +620,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+        String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
 
         /**
          * The episode title of this TV program for episodic TV shows.
@@ -629,7 +629,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_EPISODE_TITLE = "episode_title";
+        String COLUMN_EPISODE_TITLE = "episode_title";
 
         /**
          * The comma-separated canonical genre string of this TV program.
@@ -643,7 +643,7 @@
          * @see Genres#encode
          * @see Genres#decode
          */
-        public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";
+        String COLUMN_CANONICAL_GENRE = "canonical_genre";
 
         /**
          * The short description of this TV program that is displayed to the user by default.
@@ -652,7 +652,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_SHORT_DESCRIPTION = "short_description";
+        String COLUMN_SHORT_DESCRIPTION = "short_description";
 
         /**
          * The detailed, lengthy description of this TV program that is displayed only when the user
@@ -663,7 +663,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_LONG_DESCRIPTION = "long_description";
+        String COLUMN_LONG_DESCRIPTION = "long_description";
 
         /**
          * The width of the video for this TV program, in the unit of pixels.
@@ -675,7 +675,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_VIDEO_WIDTH = "video_width";
+        String COLUMN_VIDEO_WIDTH = "video_width";
 
         /**
          * The height of the video for this TV program, in the unit of pixels.
@@ -687,7 +687,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_VIDEO_HEIGHT = "video_height";
+        String COLUMN_VIDEO_HEIGHT = "video_height";
 
         /**
          * The comma-separated audio languages of this TV program.
@@ -697,7 +697,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
+        String COLUMN_AUDIO_LANGUAGE = "audio_language";
 
         /**
          * The comma-separated content ratings of this TV program.
@@ -714,7 +714,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_CONTENT_RATING = "content_rating";
+        String COLUMN_CONTENT_RATING = "content_rating";
 
         /**
          * The URI for the poster art of this TV program.
@@ -732,7 +732,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
+        String COLUMN_POSTER_ART_URI = "poster_art_uri";
 
         /**
          * The URI for the thumbnail of this TV program.
@@ -754,7 +754,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+        String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
 
         /**
          * The flag indicating whether this TV program is searchable or not.
@@ -769,7 +769,7 @@
          *
          * <p>Type: INTEGER (boolean)
          */
-        public static final String COLUMN_SEARCHABLE = "searchable";
+        String COLUMN_SEARCHABLE = "searchable";
 
         /**
          * Internal data used by individual TV input services.
@@ -779,7 +779,7 @@
          *
          * <p>Type: BLOB
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+        String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
 
         /**
          * Internal integer flag used by individual TV input services.
@@ -789,7 +789,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+        String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
 
         /**
          * Internal integer flag used by individual TV input services.
@@ -799,7 +799,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+        String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
 
         /**
          * Internal integer flag used by individual TV input services.
@@ -809,7 +809,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+        String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
 
         /**
          * Internal integer flag used by individual TV input services.
@@ -819,7 +819,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+        String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
 
         /**
          * The version number of this row entry used by TV input services.
@@ -831,7 +831,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_VERSION_NUMBER = "version_number";
+        String COLUMN_VERSION_NUMBER = "version_number";
     }
 
     /**
@@ -862,84 +862,84 @@
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_MOVIE = "TYPE_MOVIE";
+        String TYPE_MOVIE = "TYPE_MOVIE";
 
         /**
          * The program type for TV series.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+        String TYPE_TV_SERIES = "TYPE_TV_SERIES";
 
         /**
          * The program type for TV season.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+        String TYPE_TV_SEASON = "TYPE_TV_SEASON";
 
         /**
          * The program type for TV episode.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+        String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
 
         /**
          * The program type for clip.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_CLIP = "TYPE_CLIP";
+        String TYPE_CLIP = "TYPE_CLIP";
 
         /**
          * The program type for event.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_EVENT = "TYPE_EVENT";
+        String TYPE_EVENT = "TYPE_EVENT";
 
         /**
          * The program type for channel.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
+        String TYPE_CHANNEL = "TYPE_CHANNEL";
 
         /**
          * The program type for track.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_TRACK = "TYPE_TRACK";
+        String TYPE_TRACK = "TYPE_TRACK";
 
         /**
          * The program type for album.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_ALBUM = "TYPE_ALBUM";
+        String TYPE_ALBUM = "TYPE_ALBUM";
 
         /**
          * The program type for artist.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_ARTIST = "TYPE_ARTIST";
+        String TYPE_ARTIST = "TYPE_ARTIST";
 
         /**
          * The program type for playlist.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+        String TYPE_PLAYLIST = "TYPE_PLAYLIST";
 
         /**
          * The program type for station.
          *
          * @see #COLUMN_TYPE
          */
-        public static final String TYPE_STATION = "TYPE_STATION";
+        String TYPE_STATION = "TYPE_STATION";
 
         /** @hide */
         @StringDef({
@@ -957,7 +957,7 @@
          * @see #COLUMN_POSTER_ART_ASPECT_RATIO
          * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
          */
-        public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+        String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
 
         /**
          * The aspect ratio for 3:2.
@@ -965,7 +965,7 @@
          * @see #COLUMN_POSTER_ART_ASPECT_RATIO
          * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
          */
-        public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+        String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
 
         /**
          * The aspect ratio for 1:1.
@@ -973,7 +973,7 @@
          * @see #COLUMN_POSTER_ART_ASPECT_RATIO
          * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
          */
-        public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+        String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
 
         /**
          * The aspect ratio for 2:3.
@@ -981,7 +981,7 @@
          * @see #COLUMN_POSTER_ART_ASPECT_RATIO
          * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
          */
-        public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+        String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
 
         /** @hide */
         @StringDef({
@@ -997,14 +997,14 @@
          *
          * @see #COLUMN_AVAILABILITY
          */
-        public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+        String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
 
         /**
          * The availability for "free with subscription".
          *
          * @see #COLUMN_AVAILABILITY
          */
-        public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
+        String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
                 "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
 
         /**
@@ -1013,7 +1013,7 @@
          *
          * @see #COLUMN_AVAILABILITY
          */
-        public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+        String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
 
         /** @hide */
         @StringDef({
@@ -1033,49 +1033,49 @@
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+        String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
 
         /**
          * The interaction type for "followers".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+        String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
 
         /**
          * The interaction type for "fans".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+        String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
 
         /**
          * The interaction type for "likes".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+        String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
 
         /**
          * The interaction type for "thumbs".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+        String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
 
         /**
          * The interaction type for "views".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+        String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
 
         /**
          * The interaction type for "viewers".
          *
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+        String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
 
         /** @hide */
         @StringDef({
@@ -1091,14 +1091,14 @@
          *
          * @see #COLUMN_REVIEW_RATING_STYLE
          */
-        public static final String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+        String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
 
         /**
          * The review rating style for thumbs-up and thumbs-down rating.
          *
          * @see #COLUMN_REVIEW_RATING_STYLE
          */
-        public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
+        String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
                 "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
 
         /**
@@ -1106,7 +1106,7 @@
          *
          * @see #COLUMN_REVIEW_RATING_STYLE
          */
-        public static final String REVIEW_RATING_STYLE_PERCENTAGE =
+        String REVIEW_RATING_STYLE_PERCENTAGE =
                 "REVIEW_RATING_STYLE_PERCENTAGE";
 
         /**
@@ -1131,7 +1131,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_TYPE = "type";
+        String COLUMN_TYPE = "type";
 
         /**
          * The aspect ratio of the poster art for this TV program.
@@ -1144,7 +1144,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+        String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
 
         /**
          * The aspect ratio of the thumbnail for this TV program.
@@ -1157,7 +1157,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+        String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
 
         /**
          * The URI for the logo of this TV program.
@@ -1178,7 +1178,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_LOGO_URI = "logo_uri";
+        String COLUMN_LOGO_URI = "logo_uri";
 
         /**
          * The availability of this TV program.
@@ -1190,7 +1190,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_AVAILABILITY = "availability";
+        String COLUMN_AVAILABILITY = "availability";
 
         /**
          * The starting price of this TV program.
@@ -1201,7 +1201,7 @@
          * <p>Type: TEXT
          * @see #COLUMN_OFFER_PRICE
          */
-        public static final String COLUMN_STARTING_PRICE = "starting_price";
+        String COLUMN_STARTING_PRICE = "starting_price";
 
         /**
          * The offer price of this TV program.
@@ -1212,7 +1212,7 @@
          * <p>Type: TEXT
          * @see #COLUMN_STARTING_PRICE
          */
-        public static final String COLUMN_OFFER_PRICE = "offer_price";
+        String COLUMN_OFFER_PRICE = "offer_price";
 
         /**
          * The release date of this TV program.
@@ -1221,7 +1221,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_RELEASE_DATE = "release_date";
+        String COLUMN_RELEASE_DATE = "release_date";
 
         /**
          * The count of the items included in this TV program.
@@ -1231,7 +1231,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_ITEM_COUNT = "item_count";
+        String COLUMN_ITEM_COUNT = "item_count";
 
         /**
          * The flag indicating whether this TV program is live or not.
@@ -1242,7 +1242,7 @@
          *
          * <p>Type: INTEGER (boolean)
          */
-        public static final String COLUMN_LIVE = "live";
+        String COLUMN_LIVE = "live";
 
         /**
          * The internal ID used by individual TV input services.
@@ -1254,7 +1254,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+        String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
 
         /**
          * The URI for the preview video.
@@ -1273,7 +1273,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+        String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
 
         /**
          * The last playback position (in milliseconds) of the preview video.
@@ -1284,7 +1284,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+        String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
                 "last_playback_position_millis";
 
         /**
@@ -1296,7 +1296,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_DURATION_MILLIS = "duration_millis";
+        String COLUMN_DURATION_MILLIS = "duration_millis";
 
         /**
          * The intent URI which is launched when the preview video is selected.
@@ -1309,7 +1309,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_APP_LINK_INTENT_URI =
+        String COLUMN_APP_LINK_INTENT_URI =
                 "app_link_intent_uri";
 
         /**
@@ -1322,7 +1322,7 @@
          * <p>Type: INTEGER (boolean)
          * @see Channels#COLUMN_TRANSIENT
          */
-        public static final String COLUMN_TRANSIENT = "transient";
+        String COLUMN_TRANSIENT = "transient";
 
         /**
          * The type of interaction for this TV program.
@@ -1339,7 +1339,7 @@
          * <p>Type: TEXT
          * @see #COLUMN_INTERACTION_COUNT
          */
-        public static final String COLUMN_INTERACTION_TYPE = "interaction_type";
+        String COLUMN_INTERACTION_TYPE = "interaction_type";
 
         /**
          * The interaction count for this program.
@@ -1349,14 +1349,14 @@
          * <p>Type: INTEGER (long)
          * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String COLUMN_INTERACTION_COUNT = "interaction_count";
+        String COLUMN_INTERACTION_COUNT = "interaction_count";
 
         /**
          * The author or artist of this content.
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_AUTHOR = "author";
+        String COLUMN_AUTHOR = "author";
 
         /**
          * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
@@ -1367,7 +1367,7 @@
          * <p>Type: TEXT
          * @see #COLUMN_REVIEW_RATING
          */
-        public static final String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+        String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
 
         /**
          * The review rating score for this program.
@@ -1383,7 +1383,7 @@
          * <p>Type: TEXT
          * @see #COLUMN_REVIEW_RATING_STYLE
          */
-        public static final String COLUMN_REVIEW_RATING = "review_rating";
+        String COLUMN_REVIEW_RATING = "review_rating";
 
         /**
          * The flag indicating whether this TV program is browsable or not.
@@ -1401,7 +1401,7 @@
          *
          * <p>Type: INTEGER (boolean)
          */
-        public static final String COLUMN_BROWSABLE = "browsable";
+        String COLUMN_BROWSABLE = "browsable";
 
         /**
          * The content ID of this TV program.
@@ -1413,7 +1413,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_CONTENT_ID = "content_id";
+        String COLUMN_CONTENT_ID = "content_id";
 
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index ec80745..297fe67 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -17,6 +17,7 @@
 package com.android.systemui.pip.phone;
 
 import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACTIONS;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ALLOW_TIMEOUT;
 import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER;
 import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION;
 import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS;
@@ -75,8 +76,8 @@
     public static final int MESSAGE_UPDATE_ACTIONS = 4;
     public static final int MESSAGE_UPDATE_DISMISS_FRACTION = 5;
 
-    private static final long INITIAL_DISMISS_DELAY = 2000;
-    private static final long POST_INTERACTION_DISMISS_DELAY = 1500;
+    private static final long INITIAL_DISMISS_DELAY = 3500;
+    private static final long POST_INTERACTION_DISMISS_DELAY = 2000;
     private static final long MENU_FADE_DURATION = 125;
 
     private static final float MENU_BACKGROUND_ALPHA = 0.3f;
@@ -116,7 +117,8 @@
                 case MESSAGE_SHOW_MENU: {
                     final Bundle data = (Bundle) msg.obj;
                     showMenu(data.getParcelable(EXTRA_STACK_BOUNDS),
-                            data.getParcelable(EXTRA_MOVEMENT_BOUNDS));
+                            data.getParcelable(EXTRA_MOVEMENT_BOUNDS),
+                            data.getBoolean(EXTRA_ALLOW_TIMEOUT));
                     break;
                 }
                 case MESSAGE_POKE_MENU:
@@ -252,7 +254,7 @@
         // Do nothing
     }
 
-    private void showMenu(Rect stackBounds, Rect movementBounds) {
+    private void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
         if (!mMenuVisible) {
             updateActionViews(stackBounds);
             if (mMenuContainerAnimator != null) {
@@ -265,18 +267,22 @@
                     mMenuContainer.getAlpha(), 1f);
             mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
             mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
-            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    repostDelayedFinish(INITIAL_DISMISS_DELAY);
-                }
-            });
+            if (allowMenuTimeout) {
+                mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        repostDelayedFinish(INITIAL_DISMISS_DELAY);
+                    }
+                });
+            }
             mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
             mMenuContainerAnimator.start();
         } else {
             // If we are already visible, then just start the delayed dismiss and unregister any
             // existing input consumers from the previous drag
-            repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+            if (allowMenuTimeout) {
+                repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+            }
             notifyUnregisterInputConsumer();
         }
     }
@@ -320,7 +326,8 @@
         if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) {
             Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
             Rect movementBounds = intent.getParcelableExtra(EXTRA_MOVEMENT_BOUNDS);
-            showMenu(stackBounds, movementBounds);
+            boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true);
+            showMenu(stackBounds, movementBounds, allowMenuTimeout);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index e2069e2..bcaa395 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -33,7 +33,6 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
-import android.util.Pair;
 import android.view.IWindowManager;
 
 import com.android.systemui.pip.phone.PipMediaController.ActionListener;
@@ -56,6 +55,7 @@
     public static final String EXTRA_ACTIONS = "actions";
     public static final String EXTRA_STACK_BOUNDS = "stack_bounds";
     public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds";
+    public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout";
     public static final String EXTRA_SHOW_MENU = "show_menu";
     public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction";
 
@@ -105,7 +105,8 @@
     private ParceledListSlice mMediaActions;
     private boolean mMenuVisible;
 
-    private Bundle mTmpData = new Bundle();
+    // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
+    private Bundle mTmpDismissFractionData = new Bundle();
 
     private boolean mStartActivityRequested;
     private Messenger mToActivityMessenger;
@@ -195,11 +196,11 @@
      */
     public void setDismissFraction(float fraction) {
         if (mToActivityMessenger != null) {
-            mTmpData.clear();
-            mTmpData.putFloat(EXTRA_DISMISS_FRACTION, fraction);
+            mTmpDismissFractionData.clear();
+            mTmpDismissFractionData.putFloat(EXTRA_DISMISS_FRACTION, fraction);
             Message m = Message.obtain();
             m.what = PipMenuActivity.MESSAGE_UPDATE_DISMISS_FRACTION;
-            m.obj = mTmpData;
+            m.obj = mTmpDismissFractionData;
             try {
                 mToActivityMessenger.send(m);
             } catch (RemoteException e) {
@@ -207,28 +208,29 @@
             }
         } else if (!mStartActivityRequested) {
             startMenuActivity(null /* stackBounds */, null /* movementBounds */,
-                    false /* showMenu */);
+                    false /* showMenu */, false /* allowMenuTimeout */);
         }
     }
 
     /**
      * Shows the menu activity.
      */
-    public void showMenu(Rect stackBounds, Rect movementBounds) {
+    public void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
         if (mToActivityMessenger != null) {
-            mTmpData.clear();
-            mTmpData.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
-            mTmpData.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
+            Bundle data = new Bundle();
+            data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
+            data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
+            data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
             Message m = Message.obtain();
             m.what = PipMenuActivity.MESSAGE_SHOW_MENU;
-            m.obj = mTmpData;
+            m.obj = data;
             try {
                 mToActivityMessenger.send(m);
             } catch (RemoteException e) {
                 Log.e(TAG, "Could not notify menu to show", e);
             }
         } else if (!mStartActivityRequested) {
-            startMenuActivity(stackBounds, movementBounds, true /* showMenu */);
+            startMenuActivity(stackBounds, movementBounds, true /* showMenu */, allowMenuTimeout);
         }
     }
 
@@ -290,7 +292,8 @@
     /**
      * Starts the menu activity on the top task of the pinned stack.
      */
-    private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu) {
+    private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu,
+            boolean allowMenuTimeout) {
         try {
             StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
             if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
@@ -305,6 +308,7 @@
                     intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds);
                 }
                 intent.putExtra(EXTRA_SHOW_MENU, showMenu);
+                intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
                 ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
                 options.setLaunchTaskId(
                         pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
@@ -336,12 +340,12 @@
                 Log.e(TAG, "Error showing PIP menu activity", e);
             }
 
-            mTmpData.clear();
-            mTmpData.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
-            mTmpData.putParcelable(EXTRA_ACTIONS, resolveMenuActions());
+            Bundle data = new Bundle();
+            data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
+            data.putParcelable(EXTRA_ACTIONS, resolveMenuActions());
             Message m = Message.obtain();
             m.what = PipMenuActivity.MESSAGE_UPDATE_ACTIONS;
-            m.obj = mTmpData;
+            m.obj = data;
             try {
                 mToActivityMessenger.send(m);
             } catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index a0f491f..0ce3210 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -288,7 +288,8 @@
     }
 
     private void onAccessibilityShowMenu() {
-        mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+        mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+                false /* allowMenuTimeout */);
     }
 
     private boolean handleTouchEvent(MotionEvent ev) {
@@ -617,7 +618,8 @@
                 // If the menu is still visible, and we aren't minimized, then just poke the menu
                 // so that it will timeout after the user stops touching it
                 if (mMenuController.isMenuVisible()) {
-                    mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+                    mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+                            true /* allowMenuTimeout */);
                 }
 
                 if (isFling) {
@@ -631,7 +633,8 @@
                 mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* listener */);
                 setMinimizedStateInternal(false);
             } else if (!mIsMenuVisible) {
-                mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+                mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+                        true /* allowMenuTimeout */);
             } else {
                 mMotionHelper.expandPip();
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 0398f7b..21a0dc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -76,6 +76,7 @@
     private TextView mNumChannelsView;
     private View mChannelDisabledView;
     private Switch mChannelEnabledSwitch;
+    private CheckSaveListener mCheckSaveListener;
 
     private NotificationGuts mGutsContainer;
 
@@ -83,6 +84,13 @@
         super(context, attrs);
     }
 
+    // Specify a CheckSaveListener to override when/if the user's changes are committed.
+    public interface CheckSaveListener {
+        // Invoked when importance has changed and the NotificationInfo wants to try to save it.
+        // Listener should run saveImportance unless the change should be canceled.
+        void checkSave(Runnable saveImportance);
+    }
+
     public interface OnSettingsClickListener {
         void onClick(View v, NotificationChannel channel, int appUid);
     }
@@ -92,11 +100,14 @@
             final String pkg,
             final List<NotificationChannel> notificationChannels,
             OnSettingsClickListener onSettingsClick,
-            OnClickListener onDoneClick, final Set<String> nonBlockablePkgs)
+            OnClickListener onDoneClick,
+            CheckSaveListener checkSaveListener,
+            final Set<String> nonBlockablePkgs)
             throws RemoteException {
         mINotificationManager = iNotificationManager;
         mPkg = pkg;
         mNotificationChannels = notificationChannels;
+        mCheckSaveListener = checkSaveListener;
         boolean isSingleDefaultChannel = false;
         if (mNotificationChannels.isEmpty()) {
             throw new IllegalArgumentException("bindNotification requires at least one channel");
@@ -238,7 +249,7 @@
         doneButton.setOnClickListener(onDoneClick);
     }
 
-    public boolean hasImportanceChanged() {
+    private boolean hasImportanceChanged() {
         return mSingleNotificationChannel != null &&
                 mStartingUserImportance != getSelectedImportance();
     }
@@ -316,8 +327,12 @@
 
     @Override
     public boolean handleCloseControls(boolean save) {
-        if (save) {
-            saveImportance();
+        if (save && hasImportanceChanged()) {
+            if (mCheckSaveListener != null) {
+                mCheckSaveListener.checkSave(() -> { saveImportance(); });
+            } else {
+                saveImportance();
+            }
         }
         return false;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5370ceb..e1fceb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -5778,21 +5778,19 @@
                 startAppNotificationSettingsActivity(pkg, appUid, channel);
             };
             final View.OnClickListener onDoneClick = (View v) -> {
+                saveAndCloseNotificationMenu(info, row, guts, v);
+            };
+            final NotificationInfo.CheckSaveListener checkSaveListener = (Runnable saveImportance) -> {
                 // If the user has security enabled, show challenge if the setting is changed.
-                if (info.hasImportanceChanged()
-                        && isLockscreenPublicMode(userHandle.getIdentifier())
+                if (isLockscreenPublicMode(userHandle.getIdentifier())
                         && (mState == StatusBarState.KEYGUARD
                                 || mState == StatusBarState.SHADE_LOCKED)) {
-                    OnDismissAction dismissAction = new OnDismissAction() {
-                        @Override
-                        public boolean onDismiss() {
-                            saveAndCloseNotificationMenu(info, row, guts, v);
-                            return true;
-                        }
-                    };
-                    onLockedNotificationImportanceChange(dismissAction);
+                    onLockedNotificationImportanceChange(() -> {
+                        saveImportance.run();
+                        return true;
+                    });
                 } else {
-                    saveAndCloseNotificationMenu(info, row, guts, v);
+                    saveImportance.run();
                 }
             };
 
@@ -5815,7 +5813,7 @@
             }
             try {
                 info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels),
-                        onSettingsClick, onDoneClick, mNonBlockablePkgs);
+                        onSettingsClick, onDoneClick, checkSaveListener, mNonBlockablePkgs);
             } catch (RemoteException e) {
                 Log.e(TAG, e.toString());
             }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 5632b71..21930a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -135,7 +135,7 @@
     public void testBindNotification_SetsTextApplicationName() throws Exception {
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
         assertTrue(textView.getText().toString().contains("App Name"));
     }
@@ -146,7 +146,7 @@
         when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
                 .thenReturn(iconDrawable);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
         assertEquals(iconDrawable, iconView.getDrawable());
     }
@@ -154,7 +154,7 @@
     @Test
     public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(View.GONE, groupNameView.getVisibility());
         final TextView groupDividerView =
@@ -171,7 +171,7 @@
                 eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt()))
                 .thenReturn(notificationChannelGroup);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(View.VISIBLE, groupNameView.getVisibility());
         assertEquals("Test Group Name", groupNameView.getText());
@@ -183,7 +183,7 @@
     @Test
     public void testBindNotification_SetsTextChannelName() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(TEST_CHANNEL_NAME, textView.getText());
     }
@@ -196,7 +196,7 @@
                 (View v, NotificationChannel c, int appUid) -> {
                   assertEquals(mNotificationChannel, c);
                   latch.countDown();
-                }, null, null);
+                }, null, null, null);
 
         final TextView settingsButton =
                 (TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -214,7 +214,7 @@
                 (View v, NotificationChannel c, int appUid) -> {
                   assertEquals(null, c);
                   latch.countDown();
-                }, null, null);
+                }, null, null, null);
 
         final TextView settingsButton =
                 (TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -227,7 +227,7 @@
     public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
-                (View v, NotificationChannel c, int appUid) -> {}, null, null);
+                (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
         final TextView settingsButton =
                 (TextView) mNotificationInfo.findViewById(R.id.more_settings);
         assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
@@ -239,7 +239,7 @@
                 eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
-                (View v, NotificationChannel c, int appUid) -> {}, null, null);
+                (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
         final TextView settingsButton =
                 (TextView) mNotificationInfo.findViewById(R.id.more_settings);
         assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText());
@@ -251,7 +251,7 @@
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null,
                 (View v) -> { latch.countDown(); },
-                null);
+                null, null);
 
         final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
         doneButton.performClick();
@@ -262,7 +262,8 @@
     @Test
     public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(View.VISIBLE, numChannelsView.getVisibility());
@@ -274,7 +275,7 @@
     public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
@@ -287,7 +288,7 @@
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
@@ -299,7 +300,7 @@
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
-                null, null, null);
+                null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel),
@@ -315,7 +316,7 @@
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME,
                 Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel),
-                null, null, null);
+                null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(
@@ -336,7 +337,7 @@
                 TEST_PACKAGE_NAME,
                 Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel,
                         fourthChannel),
-                null, null, null);
+                null, null, null, null);
         final TextView numChannelsView =
                 (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
         assertEquals(
@@ -351,7 +352,7 @@
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
-                null, null, null);
+                null, null, null, null);
         final TextView channelNameView =
                 (TextView) mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(getNumChannelsString(2), channelNameView.getText());
@@ -362,7 +363,7 @@
     public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
-                null, null, null);
+                null, null, null, null);
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
     }
@@ -370,7 +371,7 @@
     @Test
     public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView channelDisabledView =
                 (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
         assertEquals(channelDisabledView.getVisibility(), View.GONE);
@@ -380,7 +381,7 @@
     public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         final TextView channelDisabledView =
                 (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
         assertEquals(channelDisabledView.getVisibility(), View.VISIBLE);
@@ -396,35 +397,17 @@
             throws Exception {
         mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+                null, null, null, null);
         final TextView channelDisabledView =
                 (TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
         assertEquals(View.VISIBLE, channelDisabledView.getVisibility());
     }
 
     @Test
-    @UiThreadTest
-    public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
-        assertFalse(mNotificationInfo.hasImportanceChanged());
-    }
-
-    @Test
-    public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception {
-        mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
-        // Find the high button and check it.
-        Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
-        enabledSwitch.setChecked(false);
-        assertTrue(mNotificationInfo.hasImportanceChanged());
-    }
-
-    @Test
     public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), anyInt(), any());
     }
@@ -433,7 +416,7 @@
     public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         enabledSwitch.setChecked(false);
@@ -445,7 +428,7 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
             throws Exception {
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         mNotificationInfo.handleCloseControls(true);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -457,7 +440,7 @@
             throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         mNotificationInfo.handleCloseControls(true);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -468,7 +451,7 @@
     public void testEnabledSwitchOnByDefault() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         assertTrue(enabledSwitch.isChecked());
@@ -478,7 +461,7 @@
     public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         assertFalse(enabledSwitch.isChecked());
@@ -488,7 +471,7 @@
     public void testEnabledSwitchVisibleByDefault() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
         assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
@@ -498,7 +481,7 @@
     public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
                 Collections.singleton(TEST_PACKAGE_NAME));
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -509,7 +492,7 @@
     public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
                 Collections.singleton(TEST_PACKAGE_NAME));
         mNotificationInfo.handleCloseControls(true);
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -520,7 +503,7 @@
     public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
                 Collections.singleton(TEST_PACKAGE_NAME));
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -534,7 +517,7 @@
     public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
         mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
                 Collections.singleton(TEST_PACKAGE_NAME));
 
         Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -543,4 +526,34 @@
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
     }
+
+    @Test
+    public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
+        mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                (Runnable saveImportance) -> {},
+                Collections.singleton(TEST_PACKAGE_NAME));
+
+        Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+        enabledSwitch.setChecked(false);
+        mNotificationInfo.handleCloseControls(true);
+        verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+    }
+
+    @Test
+    public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
+        mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+                (Runnable saveImportance) -> { saveImportance.run(); },
+                Collections.singleton(TEST_PACKAGE_NAME));
+
+        Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+        enabledSwitch.setChecked(false);
+        mNotificationInfo.handleCloseControls(true);
+        verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+                eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 1093e9e..9285027 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -244,10 +244,10 @@
 
     // FillServiceCallbacks
     @Override
-    public void authenticate(IntentSender intent) {
+    public void authenticate(IntentSender intent, Bundle extras) {
         final Intent fillInIntent;
         synchronized (mLock) {
-            fillInIntent = createAuthFillInIntent(mStructure);
+            fillInIntent = createAuthFillInIntent(mStructure, extras);
         }
         mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
     }
@@ -313,7 +313,7 @@
         if (mCurrentResponse == null || data == null) {
             removeSelf();
         } else {
-            Parcelable result = data.getParcelable(
+            final Parcelable result = data.getParcelable(
                     AutofillManager.EXTRA_AUTHENTICATION_RESULT);
             if (result instanceof FillResponse) {
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
@@ -321,7 +321,7 @@
                 mCurrentResponse = (FillResponse) result;
                 processResponseLocked(mCurrentResponse);
             } else if (result instanceof Dataset) {
-                Dataset dataset = (Dataset) result;
+                final Dataset dataset = (Dataset) result;
                 final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset);
                 if (index >= 0) {
                     mCurrentResponse.getDatasets().set(index, dataset);
@@ -614,7 +614,8 @@
 
         if (mCurrentResponse.getAuthentication() != null) {
             // Handle authentication.
-            final Intent fillInIntent = createAuthFillInIntent(mStructure);
+            final Intent fillInIntent = createAuthFillInIntent(mStructure,
+                    mCurrentResponse.getExtras());
             mCurrentViewState.setResponse(mCurrentResponse, fillInIntent);
             return;
         }
@@ -640,7 +641,7 @@
             }
 
             // ...or handle authentication.
-            Intent fillInIntent = createAuthFillInIntent(mStructure);
+            final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
             startAuthentication(dataset.getAuthentication(), fillInIntent);
         }
     }
@@ -649,9 +650,12 @@
         return mService.getServiceName();
     }
 
-    private Intent createAuthFillInIntent(AssistStructure structure) {
-        Intent fillInIntent = new Intent();
+    private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
+        final Intent fillInIntent = new Intent();
         fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
+        if (extras != null) {
+            fillInIntent.putExtra(AutofillManager.EXTRA_DATA_EXTRAS, extras);
+        }
         return fillInIntent;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 2555cee..832ff9a 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.IntentSender;
 import android.metrics.LogMaker;
+import android.os.Bundle;
 import android.os.Handler;
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
@@ -63,7 +64,7 @@
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
-        void authenticate(@NonNull IntentSender intent);
+        void authenticate(@NonNull IntentSender intent, @Nullable Bundle extras);
         void fill(@NonNull Dataset dataset);
         void save();
         void cancelSave();
@@ -156,7 +157,7 @@
                     log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
                     hideFillUiUiThread();
                     if (mCallback != null) {
-                        mCallback.authenticate(response.getAuthentication());
+                        mCallback.authenticate(response.getAuthentication(), response.getExtras());
                     }
                 }
 
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 98242f9..fd44794 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -679,7 +679,7 @@
         pw.println("Battery service (battery) commands:");
         pw.println("  help");
         pw.println("    Print this help text.");
-        pw.println("  set [-f] [ac|usb|wireless|status|level|present|invalid] <value>");
+        pw.println("  set [-f] [ac|usb|wireless|status|level|temp|present|invalid] <value>");
         pw.println("    Force a battery property value, freezing battery state.");
         pw.println("    -f: force a battery change broadcast be sent, prints new sequence.");
         pw.println("  unplug [-f]");
@@ -767,6 +767,9 @@
                         case "level":
                             mBatteryProps.batteryLevel = Integer.parseInt(value);
                             break;
+                        case "temp":
+                            mBatteryProps.batteryTemperature = Integer.parseInt(value);
+                            break;
                         case "invalid":
                             mInvalidCharger = Integer.parseInt(value);
                             break;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 0ccaf8e..015603b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1407,14 +1407,10 @@
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
-            synchronized (accounts.dbLock) {
-                synchronized (accounts.cacheLock) {
-                    if (!accountExistsCacheLocked(accounts, account)) {
-                        return null;
-                    }
-                    return readUserDataInternalLocked(accounts, account, key);
-                }
+            if (!accountExistsCache(accounts, account)) {
+                return null;
             }
+            return readUserDataInternal(accounts, account, key);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -1597,17 +1593,11 @@
                 @Override
                 public void run() throws RemoteException {
                     // Confirm that the owner's account still exists before this step.
-                    UserAccounts owner = getUserAccounts(parentUserId);
-                    synchronized (owner.dbLock) {
-                        synchronized (owner.cacheLock) {
-                            for (Account acc : getAccounts(parentUserId,
-                                    mContext.getOpPackageName())) {
-                                if (acc.equals(account)) {
-                                    mAuthenticator.addAccountFromCredentials(
-                                            this, account, accountCredentials);
-                                    break;
-                                }
-                            }
+                    for (Account acc : getAccounts(parentUserId, mContext.getOpPackageName())) {
+                        if (acc.equals(account)) {
+                            mAuthenticator.addAccountFromCredentials(
+                                    this, account, accountCredentials);
+                            break;
                         }
                     }
                 }
@@ -2509,54 +2499,53 @@
         long identityToken = clearCallingIdentity();
         try {
             UserAccounts accounts = getUserAccounts(userId);
-            synchronized (accounts.dbLock) {
-                synchronized (accounts.cacheLock) {
-                    if (!accountExistsCacheLocked(accounts, account)) {
-                        return;
-                    }
-                    setUserdataInternalLocked(accounts, account, key, value);
-                }
+            if (!accountExistsCache(accounts, account)) {
+                return;
             }
+            setUserdataInternal(accounts, account, key, value);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    private boolean accountExistsCacheLocked(UserAccounts accounts, Account account) {
-        if (accounts.accountCache.containsKey(account.type)) {
-            for (Account acc : accounts.accountCache.get(account.type)) {
-                if (acc.name.equals(account.name)) {
-                    return true;
+    private boolean accountExistsCache(UserAccounts accounts, Account account) {
+        synchronized (accounts.cacheLock) {
+            if (accounts.accountCache.containsKey(account.type)) {
+                for (Account acc : accounts.accountCache.get(account.type)) {
+                    if (acc.name.equals(account.name)) {
+                        return true;
+                    }
                 }
             }
         }
         return false;
     }
 
-    private void setUserdataInternalLocked(UserAccounts accounts, Account account, String key,
+    private void setUserdataInternal(UserAccounts accounts, Account account, String key,
             String value) {
-        if (account == null || key == null) {
-            return;
-        }
-        accounts.accountsDb.beginTransaction();
-        try {
-            long accountId = accounts.accountsDb.findDeAccountId(account);
-            if (accountId < 0) {
-                return;
-            }
-            long extrasId = accounts.accountsDb.findExtrasIdByAccountId(accountId, key);
-            if (extrasId < 0) {
-                extrasId = accounts.accountsDb.insertExtra(accountId, key, value);
-                if (extrasId < 0) {
+        synchronized (accounts.dbLock) {
+            accounts.accountsDb.beginTransaction();
+            try {
+                long accountId = accounts.accountsDb.findDeAccountId(account);
+                if (accountId < 0) {
                     return;
                 }
-            } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
-                return;
+                long extrasId = accounts.accountsDb.findExtrasIdByAccountId(accountId, key);
+                if (extrasId < 0) {
+                    extrasId = accounts.accountsDb.insertExtra(accountId, key, value);
+                    if (extrasId < 0) {
+                        return;
+                    }
+                } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
+                    return;
+                }
+                accounts.accountsDb.setTransactionSuccessful();
+            } finally {
+                accounts.accountsDb.endTransaction();
             }
-            writeUserDataIntoCacheLocked(accounts, account, key, value);
-            accounts.accountsDb.setTransactionSuccessful();
-        } finally {
-            accounts.accountsDb.endTransaction();
+            synchronized (accounts.cacheLock) {
+                writeUserDataIntoCacheLocked(accounts, account, key, value);
+            }
         }
     }
 
@@ -5628,6 +5617,7 @@
         }
     }
 
+    /** protected by the {@code dbLock}, {@code cacheLock} */
     protected void writeUserDataIntoCacheLocked(UserAccounts accounts,
             Account account, String key, String value) {
         Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
@@ -5694,13 +5684,24 @@
         }
     }
 
-    protected String readUserDataInternalLocked(
-            UserAccounts accounts, Account account, String key) {
-        Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
+    private String readUserDataInternal(UserAccounts accounts, Account account, String key) {
+        Map<String, String> userDataForAccount;
+        // Fast path - check if data is already cached
+        synchronized (accounts.cacheLock) {
+            userDataForAccount = accounts.userDataCache.get(account);
+        }
+        // If not cached yet - do slow path and sync with db if necessary
         if (userDataForAccount == null) {
-            // need to populate the cache for this account
-            userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
-            accounts.userDataCache.put(account, userDataForAccount);
+            synchronized (accounts.dbLock) {
+                synchronized (accounts.cacheLock) {
+                    userDataForAccount = accounts.userDataCache.get(account);
+                    if (userDataForAccount == null) {
+                        // need to populate the cache for this account
+                        userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
+                        accounts.userDataCache.put(account, userDataForAccount);
+                    }
+                }
+            }
         }
         return userDataForAccount.get(key);
     }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b4f8f61..8b0665c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static com.android.server.am.ActivityManagerDebugConfig.*;
 
 import java.io.FileDescriptor;
@@ -96,6 +95,10 @@
     // How long we wait for a service to finish executing.
     static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
 
+    // How long the startForegroundService() grace period is to get around to
+    // calling startForeground() before we ANR + stop it.
+    static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
+
     // How long a service needs to be running until restarting its process
     // is no longer considered to be a relaunch of the service.
     static final int SERVICE_RESTART_DURATION = 1*1000;
@@ -307,8 +310,8 @@
     }
 
     ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
-            int id, Notification notification,
-            int callingPid, int callingUid, String callingPackage, final int userId)
+            int id, Notification notification, int callingPid, int callingUid,
+            boolean fgRequired, String callingPackage, final int userId)
             throws TransactionTooLargeException {
         if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
                 + " type=" + resolvedType + " args=" + service.getExtras());
@@ -345,8 +348,9 @@
             return null;
         }
 
-        // Non-null notification means this is a start directly into the foreground
-        if (!r.startRequested && notification == null) {
+        // If this isn't a direct-to-foreground start, check our ability to kick off an
+        // arbitrary service
+        if (!r.startRequested && !fgRequired) {
             final long token = Binder.clearCallingIdentity();
             try {
                 // Before going further -- if this app is not allowed to start services in the
@@ -392,12 +396,13 @@
         r.lastActivity = SystemClock.uptimeMillis();
         r.startRequested = true;
         r.delayedStop = false;
+        r.fgRequired = fgRequired;
         r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                 service, neededGrants));
 
         final ServiceMap smap = getServiceMapLocked(r.userId);
         boolean addToStarting = false;
-        if (!callerFg && r.app == null
+        if (!callerFg && !fgRequired && r.app == null
                 && mAm.mUserController.hasStartedUserState(r.userId)) {
             ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
             if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
@@ -449,9 +454,9 @@
                 Slog.v(TAG_SERVICE, sb.toString());
             }
         } else if (DEBUG_DELAYED_STARTS) {
-            if (callerFg) {
+            if (callerFg || fgRequired) {
                 Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
-                        + callingUid + " pid=" + callingPid + "): " + r);
+                        + callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r);
             } else if (r.app != null) {
                 Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
             } else {
@@ -461,6 +466,7 @@
         }
 
         ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+        // STOPSHIP deprecated; remove when NotificationManager.startServiceInForeground is retired
         if (notification != null) {
             setServiceForegroundInnerLocked(r, id, notification, 0);
         }
@@ -540,7 +546,7 @@
             if (first) {
                 smap.rescheduleDelayedStartsLocked();
             }
-        } else if (callerFg) {
+        } else if (callerFg || r.fgRequired) {
             smap.ensureNotStartingBackgroundLocked(r);
         }
 
@@ -756,8 +762,17 @@
                         }
                 }
             }
+            if (r.fgRequired) {
+                if (DEBUG_BACKGROUND_CHECK) {
+                    Slog.i(TAG, "Service called startForeground() as required: " + r);
+                }
+                r.fgRequired = false;
+                r.fgWaiting = false;
+                mAm.mHandler.removeMessages(
+                        ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
+            }
             if (r.foregroundId != id) {
-                cancelForegroudNotificationLocked(r);
+                cancelForegroundNotificationLocked(r);
                 r.foregroundId = id;
             }
             notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -779,7 +794,7 @@
                 }
             }
             if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
-                cancelForegroudNotificationLocked(r);
+                cancelForegroundNotificationLocked(r);
                 r.foregroundId = 0;
                 r.foregroundNoti = null;
             } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
@@ -792,7 +807,7 @@
         }
     }
 
-    private void cancelForegroudNotificationLocked(ServiceRecord r) {
+    private void cancelForegroundNotificationLocked(ServiceRecord r) {
         if (r.foregroundId != 0) {
             // First check to see if this app has any other active foreground services
             // with the same notification ID.  If so, we shouldn't actually cancel it,
@@ -1631,7 +1646,7 @@
             r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
         }
 
-        cancelForegroudNotificationLocked(r);
+        cancelForegroundNotificationLocked(r);
 
         mAm.mHandler.removeCallbacks(r.restarter);
         mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -1718,7 +1733,9 @@
             return null;
         }
 
-        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
+        if (DEBUG_SERVICE) {
+            Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired);
+        }
 
         // We are now bringing the service up, so no longer in the
         // restarting state.
@@ -1944,8 +1961,10 @@
             ServiceRecord.StartItem si = null;
             try {
                 si = r.pendingStarts.remove(0);
-                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
-                        + r + " " + r.intent + " args=" + si.intent);
+                if (DEBUG_SERVICE) {
+                    Slog.v(TAG_SERVICE, "Sending arguments to: "
+                            + r + " " + r.intent + " args=" + si.intent);
+                }
                 if (si.intent == null && N > 1) {
                     // If somehow we got a dummy null intent in the middle,
                     // then skip it.  DO NOT skip a null intent when it is
@@ -1966,6 +1985,19 @@
                     oomAdjusted = true;
                     mAm.updateOomAdjLocked(r.app);
                 }
+                if (r.fgRequired && !r.fgWaiting) {
+                    if (!r.isForeground) {
+                        if (DEBUG_BACKGROUND_CHECK) {
+                            Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
+                        }
+                        scheduleServiceForegroundTransitionTimeoutLocked(r);
+                    } else {
+                        if (DEBUG_BACKGROUND_CHECK) {
+                            Slog.i(TAG, "Service already foreground; no new timeout: " + r);
+                        }
+                        r.fgRequired = false;
+                    }
+                }
                 int flags = 0;
                 if (si.deliveryCount > 1) {
                     flags |= Service.START_FLAG_RETRY;
@@ -2101,7 +2133,7 @@
             }
         }
 
-        cancelForegroudNotificationLocked(r);
+        cancelForegroundNotificationLocked(r);
         r.isForeground = false;
         r.foregroundId = 0;
         r.foregroundNoti = null;
@@ -2925,23 +2957,53 @@
         }
     }
 
+    void serviceForegroundTimeout(ServiceRecord r) {
+        ProcessRecord app;
+        synchronized (mAm) {
+            if (!r.fgRequired) {
+                return;
+            }
+
+            if (DEBUG_BACKGROUND_CHECK) {
+                Slog.i(TAG, "Service foreground-required timeout for " + r);
+            }
+            app = r.app;
+            r.fgWaiting = false;
+            stopServiceLocked(r);
+        }
+
+        if (app != null) {
+            mAm.mAppErrors.appNotResponding(app, null, null, false,
+                    "Context.startForegroundService() did not then call Service.startForeground()");
+        }
+    }
+
     void scheduleServiceTimeoutLocked(ProcessRecord proc) {
         if (proc.executingServices.size() == 0 || proc.thread == null) {
             return;
         }
-        long now = SystemClock.uptimeMillis();
         Message msg = mAm.mHandler.obtainMessage(
                 ActivityManagerService.SERVICE_TIMEOUT_MSG);
         msg.obj = proc;
-        mAm.mHandler.sendMessageAtTime(msg,
-                proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
+        mAm.mHandler.sendMessageDelayed(msg,
+                proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
+    }
+
+    void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
+        if (r.app.executingServices.size() == 0 || r.app.thread == null) {
+            return;
+        }
+        Message msg = mAm.mHandler.obtainMessage(
+                ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
+        msg.obj = r;
+        r.fgWaiting = true;
+        mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
     }
 
     final class ServiceDumper {
         private final FileDescriptor fd;
         private final PrintWriter pw;
         private final String[] args;
-        private final int opti;
         private final boolean dumpAll;
         private final String dumpPackage;
         private final ItemMatcher matcher;
@@ -2962,7 +3024,6 @@
             this.fd = fd;
             this.pw = pw;
             this.args = args;
-            this.opti = opti;
             this.dumpAll = dumpAll;
             this.dumpPackage = dumpPackage;
             matcher = new ItemMatcher();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8cb0eee..487f383 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1726,6 +1726,7 @@
     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
     static final int NOTIFY_VR_SLEEPING_MSG = 65;
+    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
     static final int START_USER_SWITCH_FG_MSG = 712;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1991,6 +1992,9 @@
                 }
                 mServices.serviceTimeout((ProcessRecord)msg.obj);
             } break;
+            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
+                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
+            } break;
             case UPDATE_TIME_ZONE: {
                 synchronized (ActivityManagerService.this) {
                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -6552,6 +6556,7 @@
             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
                 uidRec.setWhitelist = uidRec.curWhitelist = true;
             }
+            uidRec.updateHasInternetPermission();
             mActiveUids.put(proc.uid, uidRec);
             noteUidProcessState(uidRec.uid, uidRec.curProcState);
             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
@@ -6596,6 +6601,7 @@
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
             if (app.isolated) {
                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
             }
             boolean willRestart = false;
             if (app.persistent && !app.isolated) {
@@ -12089,6 +12095,7 @@
                 // the uid of the isolated process is specified by the caller.
                 uid = isolatedUid;
             }
+            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
 
             // Register the isolated UID with this application so BatteryStats knows to
             // attribute resource usage to the application.
@@ -17896,7 +17903,7 @@
 
     @Override
     public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, int id, Notification notification,
+            String resolvedType, int id, Notification notification, boolean requireForeground,
             String callingPackage, int userId)
             throws TransactionTooLargeException {
         enforceNotIsolatedCaller("startService");
@@ -17910,28 +17917,28 @@
         }
 
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
-                "startService: " + service + " type=" + resolvedType);
+                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
         synchronized(this) {
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
             final long origId = Binder.clearCallingIdentity();
             ComponentName res = mServices.startServiceLocked(caller, service,
-                    resolvedType, id, notification,
-                    callingPid, callingUid, callingPackage, userId);
+                    resolvedType, id, notification, callingPid, callingUid,
+                    requireForeground, callingPackage, userId);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
     }
 
     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
-            String callingPackage, int userId)
+            boolean fgRequired, String callingPackage, int userId)
             throws TransactionTooLargeException {
         synchronized(this) {
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
                     "startServiceInPackage: " + service + " type=" + resolvedType);
             final long origId = Binder.clearCallingIdentity();
             ComponentName res = mServices.startServiceLocked(null, service,
-                    resolvedType, 0, null, -1, uid, callingPackage, userId);
+                    resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
@@ -18865,9 +18872,7 @@
                     }
                     switch (action) {
                         case Intent.ACTION_UID_REMOVED:
-                            final Bundle intentExtras = intent.getExtras();
-                            final int uid = intentExtras != null
-                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
+                            final int uid = getUidFromIntent(intent);
                             if (uid >= 0) {
                                 mBatteryStatsService.removeUid(uid);
                                 mAppOpsService.uidRemoved(uid);
@@ -19063,6 +19068,18 @@
                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
                     break;
             }
+
+            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
+                final int uid = getUidFromIntent(intent);
+                if (uid != -1) {
+                    final UidRecord uidRec = mActiveUids.get(uid);
+                    if (uidRec != null) {
+                        uidRec.updateHasInternetPermission();
+                    }
+                }
+            }
         }
 
         // Add to the sticky list if requested.
@@ -19329,6 +19346,18 @@
         return ActivityManager.BROADCAST_SUCCESS;
     }
 
+    /**
+     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
+     */
+    private int getUidFromIntent(Intent intent) {
+        if (intent == null) {
+            return -1;
+        }
+        final Bundle intentExtras = intent.getExtras();
+        return intent.hasExtra(Intent.EXTRA_UID)
+                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
+    }
+
     final void rotateBroadcastStatsIfNeededLocked() {
         final long now = SystemClock.elapsedRealtime();
         if (mCurBroadcastStats == null ||
@@ -22547,6 +22576,9 @@
             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
                 continue;
             }
+            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
+                continue;
+            }
             // If process state is not changed, then there's nothing to do.
             if (uidRec.setProcState == uidRec.curProcState) {
                 continue;
@@ -22557,7 +22589,7 @@
             if (blockState == NETWORK_STATE_NO_CHANGE) {
                 continue;
             }
-            synchronized (uidRec.lock) {
+            synchronized (uidRec.networkStateLock) {
                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
                 if (blockState == NETWORK_STATE_BLOCK) {
                     if (blockingUids == null) {
@@ -22570,7 +22602,7 @@
                                 + " threads for uid: " + uidRec);
                     }
                     if (uidRec.waitingForNetwork) {
-                        uidRec.lock.notifyAll();
+                        uidRec.networkStateLock.notifyAll();
                     }
                 }
             }
@@ -23500,7 +23532,7 @@
                     return;
                 }
             }
-            synchronized (record.lock) {
+            synchronized (record.networkStateLock) {
                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
                     if (DEBUG_NETWORK) {
                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
@@ -23522,7 +23554,7 @@
                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
                                 + ", procStateSeq: " + procStateSeq);
                     }
-                    record.lock.notifyAll();
+                    record.networkStateLock.notifyAll();
                 }
             }
         }
@@ -23547,7 +23579,7 @@
                 return;
             }
         }
-        synchronized (record.lock) {
+        synchronized (record.networkStateLock) {
             if (record.lastDispatchedProcStateSeq < procStateSeq) {
                 if (DEBUG_NETWORK) {
                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
@@ -23581,7 +23613,7 @@
                 }
                 final long startTime = SystemClock.uptimeMillis();
                 record.waitingForNetwork = true;
-                record.lock.wait(mWaitForNetworkTimeoutMs);
+                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
                 record.waitingForNetwork = false;
                 final long totalTime = SystemClock.uptimeMillis() - startTime;
                 if (totalTime >= mWaitForNetworkTimeoutMs) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 9b6d13a..a9bd872 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -519,7 +519,7 @@
         pw.println("Starting service: " + intent);
         pw.flush();
         ComponentName cn = mInterface.startService(null, intent, intent.getType(),
-                -1, null, SHELL_PACKAGE_NAME, mUserId);
+                -1, null, false, SHELL_PACKAGE_NAME, mUserId);
         if (cn == null) {
             err.println("Error: Not found; no service started.");
             return -1;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 1712d48..d3935d1 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -149,9 +149,11 @@
 
                 case MSG_WRITE_TO_DISK:
                     updateExternalStatsSync("write", UPDATE_ALL);
+                    Slog.d(TAG, "begin writeAsyncLocked");
                     synchronized (mStats) {
                         mStats.writeAsyncLocked();
                     }
+                    Slog.d(TAG, "end writeAsyncLocked");
                     break;
             }
         }
@@ -191,19 +193,24 @@
 
     @Override
     public String getPlatformLowPowerStats() {
-        mUtf8BufferStat.clear();
-        mUtf16BufferStat.clear();
-        mDecoderStat.reset();
-        int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
-        if (bytesWritten < 0) {
-            return null;
-        } else if (bytesWritten == 0) {
-            return "Empty";
+        Slog.d(TAG, "begin getPlatformLowPowerStats");
+        try {
+            mUtf8BufferStat.clear();
+            mUtf16BufferStat.clear();
+            mDecoderStat.reset();
+            int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
+            if (bytesWritten < 0) {
+                return null;
+            } else if (bytesWritten == 0) {
+                return "Empty";
+            }
+            mUtf8BufferStat.limit(bytesWritten);
+            mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
+            mUtf16BufferStat.flip();
+            return mUtf16BufferStat.toString();
+        } finally {
+            Slog.d(TAG, "end getPlatformLowPowerStats");
         }
-        mUtf8BufferStat.limit(bytesWritten);
-        mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
-        mUtf16BufferStat.flip();
-        return mUtf16BufferStat.toString();
     }
 
     BatteryStatsService(File systemDir, Handler handler) {
@@ -551,9 +558,11 @@
         
     public void noteScreenState(int state) {
         enforceCallingPermission();
+        Slog.d(TAG, "begin noteScreenState");
         synchronized (mStats) {
             mStats.noteScreenStateLocked(state);
         }
+        Slog.d(TAG, "end noteScreenState");
     }
     
     public void noteScreenBrightness(int brightness) {
@@ -706,9 +715,11 @@
 
     public void noteStartCamera(int uid) {
         enforceCallingPermission();
+        Slog.d(TAG, "begin noteStartCamera");
         synchronized (mStats) {
             mStats.noteCameraOnLocked(uid);
         }
+        Slog.d(TAG, "end noteStartCamera");
     }
 
     public void noteStopCamera(int uid) {
@@ -1009,24 +1020,32 @@
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                synchronized (mStats) {
-                    final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
-                    if (mStats.isOnBattery() == onBattery) {
-                        // The battery state has not changed, so we don't need to sync external
-                        // stats immediately.
-                        mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
-                                chargeUAh, chargeFullUAh);
-                        return;
+                Slog.d(TAG, "begin setBatteryStateLocked");
+                try {
+                    synchronized (mStats) {
+                        final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
+                        if (mStats.isOnBattery() == onBattery) {
+                            // The battery state has not changed, so we don't need to sync external
+                            // stats immediately.
+                            mStats.setBatteryStateLocked(status, health, plugType, level, temp,
+                                    volt,
+                                    chargeUAh, chargeFullUAh);
+                            return;
+                        }
                     }
+                } finally {
+                    Slog.d(TAG, "end setBatteryStateLocked");
                 }
 
                 // Sync external stats first as the battery has changed states. If we don't sync
                 // immediately here, we may not collect the relevant data later.
                 updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
+                Slog.d(TAG, "begin setBatteryStateLocked");
                 synchronized (mStats) {
                     mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
                             chargeUAh, chargeFullUAh);
                 }
+                Slog.d(TAG, "end setBatteryStateLocked");
             }
         });
     }
@@ -1326,19 +1345,23 @@
                     }
                 }
             }
+            Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
             synchronized (mStats) {
                 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
                 if (writeData) {
                     mStats.writeAsyncLocked();
                 }
             }
+            Slog.d(TAG, "end dumpCheckinLocked");
         } else {
+            Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
             synchronized (mStats) {
                 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
                 if (writeData) {
                     mStats.writeAsyncLocked();
                 }
             }
+            Slog.d(TAG, "end dumpLocked");
         }
     }
 
@@ -1460,9 +1483,11 @@
         SynchronousResultReceiver bluetoothReceiver = null;
         SynchronousResultReceiver modemReceiver = null;
 
+        Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
         synchronized (mExternalStatsLock) {
             if (mContext == null) {
                 // Don't do any work yet.
+                Slog.d(TAG, "end updateExternalStatsSync");
                 return;
             }
 
@@ -1559,6 +1584,7 @@
                 }
             }
         }
+        Slog.d(TAG, "end updateExternalStatsSync");
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index c494171..f05bfb6 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -175,6 +175,8 @@
                     return "broadcastIntent";
                 case ActivityManager.INTENT_SENDER_SERVICE:
                     return "startService";
+                case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
+                    return "startForegroundService";
                 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
                     return "activityResult";
             }
@@ -318,9 +320,11 @@
                         }
                         break;
                     case ActivityManager.INTENT_SENDER_SERVICE:
+                    case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
                         try {
-                            owner.startServiceInPackage(uid, finalIntent,
-                                    resolvedType, key.packageName, userId);
+                            owner.startServiceInPackage(uid, finalIntent, resolvedType,
+                                    key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
+                                    key.packageName, userId);
                         } catch (RuntimeException e) {
                             Slog.w(TAG, "Unable to send startService intent", e);
                         } catch (TransactionTooLargeException e) {
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dfbe59f..44ebf50 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -92,6 +92,8 @@
     ServiceState restartTracker; // tracking service restart
     boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
     boolean delayed;        // are we waiting to start this service in the background?
+    boolean fgRequired;     // is the service required to go foreground after starting?
+    boolean fgWaiting;      // is a timeout for going foreground already scheduled?
     boolean isForeground;   // is service currently in foreground mode?
     int foregroundId;       // Notification ID of last foreground req.
     Notification foregroundNoti; // Notification record of foreground state.
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 67b80f6..c0fb77f 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -16,7 +16,9 @@
 
 package com.android.server.am;
 
+import android.Manifest;
 import android.app.ActivityManager;
+import android.content.pm.PackageManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.TimeUtils;
@@ -43,30 +45,37 @@
      * {@link ActivityManagerService#mProcStateSeqCounter}
      * when {@link #curProcState} changes from background to foreground or vice versa.
      */
-    @GuardedBy("lock")
+    @GuardedBy("networkStateUpdate")
     long curProcStateSeq;
 
     /**
      * Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that
      * network policies rules were updated.
      */
-    @GuardedBy("lock")
+    @GuardedBy("networkStateUpdate")
     long lastNetworkUpdatedProcStateSeq;
 
     /**
      * Last seq number for which AcitivityManagerService dispatched uid state change to
      * NetworkPolicyManagerService.
      */
-    @GuardedBy("lock")
+    @GuardedBy("networkStateUpdate")
     long lastDispatchedProcStateSeq;
 
     /**
      * Indicates if any thread is waiting for network rules to get updated for {@link #uid}.
      */
-    @GuardedBy("lock")
-    boolean waitingForNetwork;
+    volatile boolean waitingForNetwork;
 
-    final Object lock = new Object();
+    /**
+     * Indicates whether this uid has internet permission or not.
+     */
+    volatile boolean hasInternetPermission;
+
+    /**
+     * This object is used for waiting for the network state to get updated.
+     */
+    final Object networkStateLock = new Object();
 
     static final int CHANGE_PROCSTATE = 0;
     static final int CHANGE_GONE = 1;
@@ -95,6 +104,11 @@
         curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
     }
 
+    public void updateHasInternetPermission() {
+        hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET,
+                uid) == PackageManager.PERMISSION_GRANTED;
+    }
+
     /**
      * If the change being dispatched is neither CHANGE_GONE nor CHANGE_GONE_IDLE (not interested in
      * these changes), then update the {@link #lastDispatchedProcStateSeq} with
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 6710bdc..9970c82 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -88,7 +88,7 @@
         state = newState;
     }
 
-    static String stateToString(int state) {
+    public static String stateToString(int state) {
         switch (state) {
             case STATE_BOOTING: return "BOOTING";
             case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 1337046..618feb1 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -597,7 +597,8 @@
                 service.stopJob(mParams);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Error sending onStopJob to client.", e);
-                closeAndCleanupJobH(false /* reschedule */);
+                // The job's host app apparently crashed during the job, so we should reschedule.
+                closeAndCleanupJobH(true /* reschedule */);
             }
         }
 
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 94ca24c..b458d8b 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -17,18 +17,18 @@
 package com.android.server.job.controllers;
 
 import android.app.job.JobInfo;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.net.INetworkPolicyListener;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkPolicyManager;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.Slog;
 
-import com.android.internal.os.BackgroundThread;
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateChangedListener;
@@ -46,9 +46,12 @@
 public class ConnectivityController extends StateController implements
         ConnectivityManager.OnNetworkActiveListener {
     private static final String TAG = "JobScheduler.Conn";
+    private static final boolean DEBUG = false;
 
     private final ConnectivityManager mConnManager;
     private final NetworkPolicyManager mNetPolicyManager;
+    private boolean mConnected;
+    private boolean mValidated;
 
     @GuardedBy("mLock")
     private final ArrayList<JobStatus> mTrackedJobs = new ArrayList<JobStatus>();
@@ -73,10 +76,9 @@
         mConnManager = mContext.getSystemService(ConnectivityManager.class);
         mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
 
-        final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
-        mContext.registerReceiverAsUser(
-                mConnectivityReceiver, UserHandle.SYSTEM, intentFilter, null, null);
+        mConnected = mValidated = false;
 
+        mConnManager.registerDefaultNetworkCallback(mNetworkCallback);
         mNetPolicyManager.registerListener(mNetPolicyListener);
     }
 
@@ -84,7 +86,7 @@
     public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
         if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()
                 || jobStatus.hasNotRoamingConstraint()) {
-            updateConstraintsSatisfied(jobStatus);
+            updateConstraintsSatisfied(jobStatus, null);
             mTrackedJobs.add(jobStatus);
         }
     }
@@ -98,18 +100,43 @@
         }
     }
 
-    private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
+    private boolean updateConstraintsSatisfied(JobStatus jobStatus,
+            NetworkCapabilities capabilities) {
+        final int jobUid = jobStatus.getSourceUid();
         final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
-        final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid(),
-                ignoreBlocked);
-        final boolean connected = (info != null) && info.isConnected();
+        final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobUid, ignoreBlocked);
+        if (capabilities == null) {
+            final Network network = mConnManager.getActiveNetworkForUid(jobUid, ignoreBlocked);
+            capabilities = mConnManager.getNetworkCapabilities(network);
+        }
+
+        final boolean validated = capabilities != null
+                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+        final boolean connected = info != null && info.isConnected();
+        final boolean connectionUsable = connected && validated;
         final boolean unmetered = connected && !info.isMetered();
         final boolean notRoaming = connected && !info.isRoaming();
 
         boolean changed = false;
-        changed |= jobStatus.setConnectivityConstraintSatisfied(connected);
+        changed |= jobStatus.setConnectivityConstraintSatisfied(connectionUsable);
         changed |= jobStatus.setUnmeteredConstraintSatisfied(unmetered);
         changed |= jobStatus.setNotRoamingConstraintSatisfied(notRoaming);
+
+        // Track system-uid connected/validated as a general reportable proxy for the
+        // overall state of connectivity constraint satisfiability.
+        if (jobUid == Process.SYSTEM_UID) {
+            mConnected = connected;
+            mValidated = validated;
+        }
+
+        if (DEBUG) {
+            Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged")
+                    + " for " + jobStatus + ": usable=" + connectionUsable
+                    + " connected=" + connected
+                    + " validated=" + validated
+                    + " unmetered=" + unmetered
+                    + " notRoaming=" + notRoaming);
+        }
         return changed;
     }
 
@@ -119,13 +146,13 @@
      * @param uid only update jobs belonging to this UID, or {@code -1} to
      *            update all tracked jobs.
      */
-    private void updateTrackedJobs(int uid) {
+    private void updateTrackedJobs(int uid, NetworkCapabilities capabilities) {
         synchronized (mLock) {
             boolean changed = false;
             for (int i = 0; i < mTrackedJobs.size(); i++) {
                 final JobStatus js = mTrackedJobs.get(i);
                 if (uid == -1 || uid == js.getSourceUid()) {
-                    changed |= updateConstraintsSatisfied(js);
+                    changed |= updateConstraintsSatisfied(js, capabilities);
                 }
             }
             if (changed) {
@@ -152,38 +179,61 @@
         }
     }
 
-    private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
+    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
         @Override
-        public void onReceive(Context context, Intent intent) {
-            updateTrackedJobs(-1);
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+            if (DEBUG) {
+                Slog.v(TAG, "onCapabilitiesChanged() : " + networkCapabilities);
+            }
+            updateTrackedJobs(-1, networkCapabilities);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (DEBUG) {
+                Slog.v(TAG, "Network lost");
+            }
+            updateTrackedJobs(-1, null);
         }
     };
 
-    private INetworkPolicyListener mNetPolicyListener = new INetworkPolicyListener.Stub() {
+    private final INetworkPolicyListener mNetPolicyListener = new INetworkPolicyListener.Stub() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
-            updateTrackedJobs(uid);
+            if (DEBUG) {
+                Slog.v(TAG, "Uid rules changed for " + uid);
+            }
+            updateTrackedJobs(uid, null);
         }
 
         @Override
         public void onMeteredIfacesChanged(String[] meteredIfaces) {
-            updateTrackedJobs(-1);
+            // We track this via our NetworkCallback
         }
 
         @Override
         public void onRestrictBackgroundChanged(boolean restrictBackground) {
-            updateTrackedJobs(-1);
+            if (DEBUG) {
+                Slog.v(TAG, "Background restriction change to " + restrictBackground);
+            }
+            updateTrackedJobs(-1, null);
         }
 
         @Override
         public void onUidPoliciesChanged(int uid, int uidPolicies) {
-            updateTrackedJobs(uid);
+            if (DEBUG) {
+                Slog.v(TAG, "Uid policy changed for " + uid);
+            }
+            updateTrackedJobs(uid, null);
         }
     };
 
     @Override
     public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
-        pw.println("Connectivity.");
+        pw.print("Connectivity: connected=");
+        pw.print(mConnected);
+        pw.print(" validated=");
+        pw.println(mValidated);
         pw.print("Tracking ");
         pw.print(mTrackedJobs.size());
         pw.println(":");
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7468b95..ede5a5e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -90,7 +90,6 @@
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -3127,9 +3126,8 @@
                     + ", incomingUserId=" + incomingUserId
                     + ", notificationUid=" + notificationUid
                     + ", notification=" + notification;
-            if (Build.IS_DEBUGGABLE) {
-                throw new IllegalArgumentException(noChannelStr);
-            }
+            // STOPSHIP TODO: should throw instead of logging.
+            // throw new IllegalArgumentException(noChannelStr);
             Log.e(TAG, noChannelStr);
             return;
         }
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 126f8c4..6245ffc 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -135,16 +135,7 @@
         }
 
         for (PackageParser.Package p : important) {
-            // Make sure that core apps are optimized according to their own "reason".
-            // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed
-            // (by default is speed-profile) they will be interepreted/JITed. This in itself is
-            // not a problem as we will end up doing profile guided compilation. However, some
-            // core apps may be loaded by system server which doesn't JIT and we need to make
-            // sure we don't interpret-only
-            int compilationReason = p.coreApp
-                    ? PackageManagerService.REASON_CORE_APP
-                    : PackageManagerService.REASON_AB_OTA;
-            mDexoptCommands.addAll(generatePackageDexopts(p, compilationReason));
+            mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA));
         }
         for (PackageParser.Package p : others) {
             // We assume here that there are no core apps left.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 621e37b..2115f31 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -537,12 +537,9 @@
     public static final int REASON_INSTALL = 2;
     public static final int REASON_BACKGROUND_DEXOPT = 3;
     public static final int REASON_AB_OTA = 4;
-    public static final int REASON_NON_SYSTEM_LIBRARY = 5;
-    public static final int REASON_SHARED_APK = 6;
-    public static final int REASON_FORCED_DEXOPT = 7;
-    public static final int REASON_CORE_APP = 8;
+    public static final int REASON_FORCED_DEXOPT = 5;
 
-    public static final int REASON_LAST = REASON_CORE_APP;
+    public static final int REASON_LAST = REASON_FORCED_DEXOPT;
 
     /** All dangerous permission names in the same order as the events in MetricsEvent */
     private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
@@ -653,6 +650,11 @@
     final ArrayMap<String, Set<String>> mKnownCodebase =
             new ArrayMap<String, Set<String>>();
 
+    // Keys are isolated uids and values are the uid of the application
+    // that created the isolated proccess.
+    @GuardedBy("mPackages")
+    final SparseIntArray mIsolatedOwners = new SparseIntArray();
+
     // List of APK paths to load for each user and package. This data is never
     // persisted by the package manager. Instead, the overlay manager will
     // ensure the data is up-to-date in runtime.
@@ -1179,6 +1181,7 @@
     // Stores a list of users whose package restrictions file needs to be updated
     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
 
+    static final long DEFAULT_CONTAINER_WHITELIST_DURATION = 10 * 60 * 1000;
     final private DefaultContainerConnection mDefContainerConn =
             new DefaultContainerConnection();
     class DefaultContainerConnection implements ServiceConnection {
@@ -2378,59 +2381,6 @@
                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
             }
 
-            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
-            final String[] dexCodeInstructionSets =
-                    getDexCodeInstructionSets(
-                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
-
-            /**
-             * Ensure all external libraries have had dexopt run on them.
-             */
-            if (mSharedLibraries.size() > 0) {
-                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-                // NOTE: For now, we're compiling these system "shared libraries"
-                // (and framework jars) into all available architectures. It's possible
-                // to compile them only when we come across an app that uses them (there's
-                // already logic for that in scanPackageLI) but that adds some complexity.
-                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
-                    final int libCount = mSharedLibraries.size();
-                    for (int i = 0; i < libCount; i++) {
-                        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
-                        final int versionCount = versionedLib.size();
-                        for (int j = 0; j < versionCount; j++) {
-                            SharedLibraryEntry libEntry = versionedLib.valueAt(j);
-                            final String libPath = libEntry.path != null
-                                    ? libEntry.path : libEntry.apk;
-                            if (libPath == null) {
-                                continue;
-                            }
-                            try {
-                                // Shared libraries do not have profiles so we perform a full
-                                // AOT compilation (if needed).
-                                int dexoptNeeded = DexFile.getDexOptNeeded(
-                                        libPath, dexCodeInstructionSet,
-                                        getCompilerFilterForReason(REASON_SHARED_APK),
-                                        false /* newProfile */);
-                                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
-                                    mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*",
-                                            dexCodeInstructionSet, dexoptNeeded, null,
-                                            DEXOPT_PUBLIC,
-                                            getCompilerFilterForReason(REASON_SHARED_APK),
-                                            StorageManager.UUID_PRIVATE_INTERNAL,
-                                            PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK);
-                                }
-                            } catch (FileNotFoundException e) {
-                                Slog.w(TAG, "Library not found: " + libPath);
-                            } catch (IOException | InstallerException e) {
-                                Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? "
-                                        + e.getMessage());
-                            }
-                        }
-                    }
-                }
-                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-            }
-
             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
 
             final VersionInfo ver = mSettings.getInternalVersion();
@@ -2819,41 +2769,6 @@
             mSettings.writeLPr();
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
-            // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
-            // early on (before the package manager declares itself as early) because other
-            // components in the system server might ask for package contexts for these apps.
-            //
-            // Note that "onlyCore" in this context means the system is encrypted or encrypting
-            // (i.e, that the data partition is unavailable).
-            if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
-                long start = System.nanoTime();
-                List<PackageParser.Package> coreApps = new ArrayList<>();
-                for (PackageParser.Package pkg : mPackages.values()) {
-                    if (pkg.coreApp) {
-                        coreApps.add(pkg);
-                    }
-                }
-
-                int[] stats = performDexOptUpgrade(coreApps, false,
-                        getCompilerFilterForReason(REASON_CORE_APP));
-
-                final int elapsedTimeSeconds =
-                        (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
-                MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
-
-                if (DEBUG_DEXOPT) {
-                    Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
-                            stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
-                }
-
-
-                // TODO: Should we log these stats to tron too ?
-                // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
-                // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
-                // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
-                // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
-            }
-
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                     SystemClock.uptimeMillis());
 
@@ -6212,6 +6127,10 @@
      * instant, returns {@code null}.
      */
     private String getInstantAppPackageName(int callingUid) {
+        // If the caller is an isolated app use the owner's uid for the lookup.
+        if (Process.isIsolated(callingUid)) {
+            callingUid = mIsolatedOwners.get(callingUid);
+        }
         final int appId = UserHandle.getAppId(callingUid);
         synchronized (mPackages) {
             final Object obj = mSettings.getUserIdLPr(appId);
@@ -7384,17 +7303,22 @@
         if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
             return false;
         }
+        int uid = Binder.getCallingUid();
+        if (Process.isIsolated(uid)) {
+            uid = mIsolatedOwners.get(uid);
+        }
 
         synchronized (mPackages) {
             final PackageSetting ps = mSettings.mPackages.get(packageName);
+            PackageParser.Package pkg = mPackages.get(packageName);
             final boolean returnAllowed =
                     ps != null
-                    && (isCallerSameApp(packageName)
+                    && (isCallerSameApp(packageName, uid)
                             || mContext.checkCallingOrSelfPermission(
                                     android.Manifest.permission.ACCESS_INSTANT_APPS)
                                             == PERMISSION_GRANTED
                             || mInstantAppRegistry.isInstantAccessGranted(
-                                    userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId));
+                                    userId, UserHandle.getAppId(uid), ps.appId));
             if (returnAllowed) {
                 return ps.getInstantApp(userId);
             }
@@ -7411,7 +7335,7 @@
         enforceCrossUserPermission(Binder.getCallingUid(), userId,
                 true /* requireFullPermission */, false /* checkShell */,
                 "getInstantAppCookie");
-        if (!isCallerSameApp(packageName)) {
+        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
             return null;
         }
         synchronized (mPackages) {
@@ -7429,7 +7353,7 @@
         enforceCrossUserPermission(Binder.getCallingUid(), userId,
                 true /* requireFullPermission */, true /* checkShell */,
                 "setInstantAppCookie");
-        if (!isCallerSameApp(packageName)) {
+        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
             return false;
         }
         synchronized (mPackages) {
@@ -7457,10 +7381,10 @@
         }
     }
 
-    private boolean isCallerSameApp(String packageName) {
+    private boolean isCallerSameApp(String packageName, int uid) {
         PackageParser.Package pkg = mPackages.get(packageName);
         return pkg != null
-                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
+                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
     }
 
     @Override
@@ -8497,19 +8421,23 @@
                 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
                 : mPackageDexOptimizer;
 
-        // Optimize all dependencies first. Note: we ignore the return value and march on
+        // Dexopt all dependencies first. Note: we ignore the return value and march on
         // on errors.
+        // Note that we are going to call performDexOpt on those libraries as many times as
+        // they are referenced in packages. When we do a batch of performDexOpt (for example
+        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
+        // and the first package that uses the library will dexopt it. The
+        // others will see that the compiled code for the library is up to date.
         Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
         final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
         if (!deps.isEmpty()) {
             for (PackageParser.Package depPackage : deps) {
                 // TODO: Analyze and investigate if we (should) profile libraries.
-                // Currently this will do a full compilation of the library by default.
                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
                         false /* checkProfiles */,
-                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
+                        targetCompilerFilter,
                         getOrCreateCompilerPackageStats(depPackage),
-                        mDexManager.isUsedByOtherApps(p.packageName));
+                        true /* isUsedByOtherApps */);
             }
         }
         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
@@ -12987,7 +12915,10 @@
         IActivityManager am = ActivityManager.getService();
         if (am != null) {
             try {
-                am.startService(null, intent, null, -1, null, mContext.getOpPackageName(),
+                getDeviceIdleController().addPowerSaveTempWhitelistApp(Process.SYSTEM_UID,
+                        DEFAULT_CONTAINER_PACKAGE, DEFAULT_CONTAINER_WHITELIST_DURATION,
+                        UserHandle.USER_SYSTEM, false, "cleaning packages");
+                am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
                         UserHandle.USER_SYSTEM);
             } catch (RemoteException e) {
             }
@@ -23220,6 +23151,21 @@
             return resolveIntentInternal(
                     intent, resolvedType, flags, userId, true /*includeInstantApp*/);
         }
+
+
+        @Override
+        public void addIsolatedUid(int isolatedUid, int ownerUid) {
+            synchronized (mPackages) {
+                mIsolatedOwners.put(isolatedUid, ownerUid);
+            }
+        }
+
+        @Override
+        public void removeIsolatedUid(int isolatedUid) {
+            synchronized (mPackages) {
+                mIsolatedOwners.delete(isolatedUid);
+            }
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 0634dac..f6872e4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,8 +26,7 @@
 public class PackageManagerServiceCompilerMapping {
     // Names for compilation reasons.
     static final String REASON_STRINGS[] = {
-            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
-            "forced-dexopt", "core-app"
+            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "forced-dexopt"
     };
 
     // Static block to ensure the strings array is of the right length.
@@ -57,7 +56,6 @@
 
         // Ensure that some reasons are not mapped to profile-guided filters.
         switch (reason) {
-            case PackageManagerService.REASON_SHARED_APK:
             case PackageManagerService.REASON_FORCED_DEXOPT:
                 if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
                     throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a31258c3..8ecf6f7 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3389,6 +3389,12 @@
                         pw.print(" <partial>");
                     }
                     pw.println();
+                    pw.print("    State: ");
+                    final int state;
+                    synchronized (mUserStates) {
+                        state = mUserStates.get(userId, -1);
+                    }
+                    pw.println(UserState.stateToString(state));
                     pw.print("    Created: ");
                     if (userInfo.creationTime == 0) {
                         pw.println("<unknown>");
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index aa85574..ae413e5 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -894,9 +894,10 @@
         final int lastOrientation = mLastOrientation;
         final boolean oldAltOrientation = mAltOrientation;
         int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation);
-        final boolean rotateSeamlessly;
+        final boolean rotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,
+                rotation);
 
-        if (mService.mPolicy.shouldRotateSeamlessly(oldRotation, rotation)) {
+        if (rotateSeamlessly) {
             final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
             if (seamlessRotated != null) {
                 // We can't rotate (seamlessly or not) while waiting for the last seamless rotation
@@ -905,27 +906,6 @@
                 // window-removal.
                 return false;
             }
-
-            final WindowState cantSeamlesslyRotate = getWindow((w) ->
-                    w.isChildWindow() && w.isVisibleNow()
-                            && !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse());
-            if (cantSeamlesslyRotate != null) {
-                // In what can only be called an unfortunate workaround we require seamlessly
-                // rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE flag. Due to
-                // limitations in the client API, there is no way for the client to set this flag in
-                // a race free fashion. If we seamlessly rotate a window which does not have this
-                // flag, but then gains it, we will get an incorrect visual result
-                // (rotated viewfinder). This means if we want to support seamlessly rotating
-                // windows which could gain this flag, we can't rotate windows without it. This
-                // limits seamless rotation in N to camera framework users, windows without
-                // children, and native code. This is unfortunate but having the camera work is our
-                // primary goal.
-                rotateSeamlessly = false;
-            } else {
-                rotateSeamlessly = true;
-            }
-        } else {
-            rotateSeamlessly = false;
         }
 
         // TODO: Implement forced rotation changes.
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 826fb45..a7f6db1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -591,6 +591,17 @@
         }
     }
 
+    private int getLayerStack() {
+        return mWin.getDisplayContent().getDisplay().getLayerStack();
+    }
+
+    void updateLayerStackInTransaction() {
+        if (mSurfaceController != null) {
+            mSurfaceController.setLayerStackInTransaction(
+                    getLayerStack());
+        }
+    }
+
     WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
         final WindowState w = mWin;
         if (w.restoreSavedSurface()) {
@@ -703,8 +714,7 @@
         }
 
         // Start a new transaction and apply position & offset.
-        final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
-        mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack, mAnimLayer);
+        mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, getLayerStack(), mAnimLayer);
         mLastHidden = true;
 
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
@@ -1435,7 +1445,6 @@
                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
             w.applyDimLayerIfNeeded();
         }
-
     }
 
     void prepareSurfaceLocked(final boolean recoveringMemory) {
@@ -1926,57 +1935,26 @@
         DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
                 transform);
 
-        // We have two cases:
-        //  1. Windows with NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY:
-        //     These windows never change buffer size when rotating. Rather the window manager
-        //     just updates the scaling factors to fit in the new coordinate system,
-        //     and SurfaceFlinger takes care of updating the buffer contents. So in this case
-        //     we just need we just need to update the scaling factors and things are seamless
-        //     already.
-        //  2. Other windows:
-        //     In this case, we need to apply a rotation matrix to the window. For example
-        //     if we have a portrait window and rotate to landscape, the window is still portrait
-        //     and now extends off the bottom of the screen (and only halfway across). Essentially we
-        //     apply a transform to display the current buffer at it's old position
-        //     (in the new coordinate space). We then freeze layer updates until the resize
-        //     occurs, at which point we undo, them.
-        if (w.isChildWindow() && mSurfaceController.getTransformToDisplayInverse()) {
-            frameRect.set(x, y, x + width, y + height);
-            transform.mapRect(frameRect);
+        // We just need to apply a rotation matrix to the window. For example
+        // if we have a portrait window and rotate to landscape, the window is still portrait
+        // and now extends off the bottom of the screen (and only halfway across). Essentially we
+        // apply a transform to display the current buffer at it's old position
+        // (in the new coordinate space). We then freeze layer updates until the resize
+        // occurs, at which point we undo, them.
+        mService.markForSeamlessRotation(w, true);
+        transform.getValues(mService.mTmpFloats);
 
-            final Rect parentWindowFrame = w.getParentWindow().mFrame;
-            w.mAttrs.x = (int) frameRect.left - parentWindowFrame.left;
-            w.mAttrs.y = (int) frameRect.top - parentWindowFrame.top;
-            w.mAttrs.width = (int) Math.ceil(frameRect.width());
-            w.mAttrs.height = (int) Math.ceil(frameRect.height());
-
-            w.setWindowScale(w.mRequestedWidth, w.mRequestedHeight);
-
-            w.applyGravityAndUpdateFrame(w.mContainingFrame, w.mDisplayFrame);
-            computeShownFrameLocked();
-            setSurfaceBoundariesLocked(false);
-
-            // The stack bounds will not yet be rotated at this point so setSurfaceBoundaries locked
-            // will crop us incorrectly. Overwrite the crop, exposing the full surface. By the next
-            // transaction this will be corrected.
-            cropRect.set(0, 0, w.mRequestedWidth, w.mRequestedWidth + w.mRequestedHeight);
-            mSurfaceController.setCropInTransaction(cropRect, false);
-        } else {
-            mService.markForSeamlessRotation(w, true);
-            transform.getValues(mService.mTmpFloats);
-
-            float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
-            float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
-            float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
-            float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
-            float nx = mService.mTmpFloats[Matrix.MTRANS_X];
-            float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
-            mSurfaceController.setPositionInTransaction(nx, ny, false);
-            mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
-                    DtDx * w.mVScale,
-                    DtDy * w.mHScale,
-                    DsDy * w.mVScale, false);
-        }
+        float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
+        float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
+        float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
+        float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
+        float nx = mService.mTmpFloats[Matrix.MTRANS_X];
+        float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
+        mSurfaceController.setPositionInTransaction(nx, ny, false);
+        mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
+                DtDx * w.mVScale,
+                DtDy * w.mHScale,
+                DsDy * w.mVScale, false);
     }
 
     void enableSurfaceTrace(FileDescriptor fd) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index b08bb70..adf4501 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -276,6 +276,12 @@
         }
     }
 
+    void setLayerStackInTransaction(int layerStack) {
+        if (mSurfaceControl != null) {
+            mSurfaceControl.setLayerStack(layerStack);
+        }
+    }
+
     void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
         final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
         if (surfaceMoved) {
@@ -357,7 +363,8 @@
         return false;
     }
 
-    boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
+    boolean prepareToShowInTransaction(float alpha, int layer,
+            float dsdx, float dtdx, float dsdy,
             float dtdy, boolean recoveringMemory) {
         if (mSurfaceControl != null) {
             try {
@@ -371,7 +378,6 @@
                 mLastDtdy = dtdy;
                 mSurfaceControl.setMatrix(
                         dsdx, dtdx, dsdy, dtdy);
-
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Error updating surface in " + title, e);
                 if (!recoveringMemory) {
@@ -509,10 +515,6 @@
         return mSurfaceControl.getHandle();
     }
 
-    boolean getTransformToDisplayInverse() {
-        return mSurfaceControl.getTransformToDisplayInverse();
-    }
-
     void getSurface(Surface outSurface) {
         outSurface.copyFrom(mSurfaceControl);
     }
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index fab59d6..e3033c9 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -30,6 +30,7 @@
 import android.os.Debug;
 import android.os.IBinder;
 import android.util.Slog;
+import android.view.SurfaceControl;
 
 import java.io.PrintWriter;
 
@@ -245,6 +246,18 @@
     void onDisplayChanged(DisplayContent dc) {
         dc.reParentWindowToken(this);
         mDisplayContent = dc;
+
+        // TODO(b/36740756): One day this should perhaps be hooked
+        // up with goodToGo, so we don't move a window
+        // to another display before the window behind
+        // it is ready.
+        SurfaceControl.openTransaction();
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowState win = mChildren.get(i);
+            win.mWinAnimator.updateLayerStackInTransaction();
+        }
+        SurfaceControl.closeTransaction();
+
         super.onDisplayChanged(dc);
     }
 
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index ec36df1..57bb9fe 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -57,6 +57,8 @@
 static bool wakeup_init = false;
 static sem_t wakeup_sem;
 extern sp<IPower> gPowerHal;
+extern std::mutex gPowerHalMutex;
+extern bool getPowerHal();
 
 static void wakeup_callback(bool success)
 {
@@ -191,41 +193,26 @@
         return -1;
     }
 
-    if (gPowerHal == nullptr) {
-        ALOGE("gPowerHal not loaded");
-        return -1;
-    }
+    {
+        std::lock_guard<std::mutex> lock(gPowerHalMutex);
+        if (!getPowerHal()) {
+            ALOGE("Power Hal not loaded");
+            return -1;
+        }
 
-    gPowerHal->getPlatformLowPowerStats(
-        [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
-                Status status) {
-            if (status != Status::SUCCESS)
-                return;
-            for (size_t i = 0; i < states.size(); i++) {
-                int added;
-                const PowerStatePlatformSleepState& state = states[i];
+        Return<void> ret = gPowerHal->getPlatformLowPowerStats(
+            [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
+                    Status status) {
+                if (status != Status::SUCCESS)
+                    return;
+                for (size_t i = 0; i < states.size(); i++) {
+                    int added;
+                    const PowerStatePlatformSleepState& state = states[i];
 
-                added = snprintf(offset, remaining,
-                    "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
-                    i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
-                    state.totalTransitions);
-                if (added < 0) {
-                    break;
-                }
-                if (added > remaining) {
-                    added = remaining;
-                }
-                offset += added;
-                remaining -= added;
-                total_added += added;
-
-                for (size_t j = 0; j < state.voters.size(); j++) {
-                    const PowerStateVoter& voter = state.voters[j];
                     added = snprintf(offset, remaining,
-                            "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
-                            j + 1, voter.name.c_str(),
-                            voter.totalTimeInMsecVotedForSinceBoot,
-                            voter.totalNumberOfTimesVotedSinceBoot);
+                        "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                        i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+                        state.totalTransitions);
                     if (added < 0) {
                         break;
                     }
@@ -235,18 +222,42 @@
                     offset += added;
                     remaining -= added;
                     total_added += added;
-                }
 
-                if (remaining <= 0) {
-                    /* rewrite NULL character*/
-                    offset--;
-                    total_added--;
-                    ALOGE("PowerHal: buffer not enough");
-                    break;
+                    for (size_t j = 0; j < state.voters.size(); j++) {
+                        const PowerStateVoter& voter = state.voters[j];
+                        added = snprintf(offset, remaining,
+                                "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                                j + 1, voter.name.c_str(),
+                                voter.totalTimeInMsecVotedForSinceBoot,
+                                voter.totalNumberOfTimesVotedSinceBoot);
+                        if (added < 0) {
+                            break;
+                        }
+                        if (added > remaining) {
+                            added = remaining;
+                        }
+                        offset += added;
+                        remaining -= added;
+                        total_added += added;
+                    }
+
+                    if (remaining <= 0) {
+                        /* rewrite NULL character*/
+                        offset--;
+                        total_added--;
+                        ALOGE("PowerHal: buffer not enough");
+                        break;
+                    }
                 }
             }
+        );
+
+        if (!ret.isOk()) {
+            ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
+            gPowerHal = nullptr;
+            return -1;
         }
-    );
+    }
     *offset = 0;
     total_added += 1;
     return total_added;
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index fab309b..1bdcd7a 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -43,7 +43,7 @@
 using android::hardware::power::V1_0::IPower;
 using android::hardware::power::V1_0::PowerHint;
 using android::hardware::power::V1_0::Feature;
-using android::hardware::hidl_vec;
+using android::String8;
 
 namespace android {
 
@@ -56,7 +56,8 @@
 // ----------------------------------------------------------------------------
 
 static jobject gPowerManagerServiceObj;
-sp<IPower> gPowerHal;
+sp<IPower> gPowerHal = nullptr;
+std::mutex gPowerHalMutex;
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
 // Throttling interval for user activity calls.
@@ -74,11 +75,37 @@
     return false;
 }
 
+// Check validity of current handle to the power HAL service, and call getService() if necessary.
+// The caller must be holding gPowerHalMutex.
+bool getPowerHal() {
+    if (gPowerHal == nullptr) {
+        gPowerHal = IPower::getService();
+        if (gPowerHal != nullptr) {
+            ALOGI("Loaded power HAL service");
+        } else {
+            ALOGI("Couldn't load power HAL service");
+        }
+    }
+    return gPowerHal != nullptr;
+}
+
+// Check if a call to a power HAL function failed; if so, log the failure and invalidate the
+// current handle to the power HAL service. The caller must be holding gPowerHalMutex.
+static void processReturn(const Return<void> &ret, const char* functionName) {
+    if (!ret.isOk()) {
+        ALOGE("%s() failed: power HAL service not available.", functionName);
+        gPowerHal = nullptr;
+    }
+}
+
 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
     // Tell the power HAL when user activity occurs.
-    if (gPowerHal != nullptr) {
-        gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+    gPowerHalMutex.lock();
+    if (getPowerHal()) {
+        Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+        processReturn(ret, "powerHint");
     }
+    gPowerHalMutex.unlock();
 
     if (gPowerManagerServiceObj) {
         // Throttle calls into user activity by event type.
@@ -106,14 +133,13 @@
 }
 
 // ----------------------------------------------------------------------------
-//TODO(b/31632518)
+
 static void nativeInit(JNIEnv* env, jobject obj) {
     gPowerManagerServiceObj = env->NewGlobalRef(obj);
 
-    gPowerHal = IPower::getService();
-    if (gPowerHal == nullptr) {
-        ALOGE("Couldn't load PowerHAL module");
-    }
+    gPowerHalMutex.lock();
+    getPowerHal();
+    gPowerHalMutex.unlock();
 }
 
 static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
@@ -127,14 +153,12 @@
 }
 
 static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
-    if (gPowerHal != nullptr) {
-        if (enable) {
-            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
-            gPowerHal->setInteractive(true);
-        } else {
-            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
-            gPowerHal->setInteractive(false);
-        }
+    std::lock_guard<std::mutex> lock(gPowerHalMutex);
+    if (getPowerHal()) {
+        String8 err("Excessive delay in setInteractive(%s) while turning screen %s");
+        ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off"));
+        Return<void> ret = gPowerHal->setInteractive(enable);
+        processReturn(ret, "setInteractive");
     }
 }
 
@@ -149,20 +173,18 @@
 }
 
 static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
-    if (gPowerHal != nullptr) {
-        if(data)
-            gPowerHal->powerHint((PowerHint)hintId, data);
-        else {
-            gPowerHal->powerHint((PowerHint)hintId, 0);
-        }
+    std::lock_guard<std::mutex> lock(gPowerHalMutex);
+    if (getPowerHal()) {
+        Return<void> ret =  gPowerHal->powerHint((PowerHint)hintId, data);
+        processReturn(ret, "powerHint");
     }
 }
 
 static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
-    int data_param = data;
-
-    if (gPowerHal != nullptr) {
-        gPowerHal->setFeature((Feature)featureId, data_param ? true : false);
+    std::lock_guard<std::mutex> lock(gPowerHalMutex);
+    if (getPowerHal()) {
+        Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data));
+        processReturn(ret, "setFeature");
     }
 }
 
@@ -217,7 +239,6 @@
         gLastEventTime[i] = LLONG_MIN;
     }
     gPowerManagerServiceObj = NULL;
-    gPowerHal = NULL;
     return 0;
 }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index e7c91c0..bce87dc 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -105,9 +105,9 @@
         final UidRecord record2 = addActiveUidRecord(TEST_UID2, curProcStateSeq,
                 lastNetworkUpdatedProcStateSeq);
 
-        final CustomThread thread1 = new CustomThread(record1.lock);
+        final CustomThread thread1 = new CustomThread(record1.networkStateLock);
         thread1.startAndWait("Unexpected state for " + record1);
-        final CustomThread thread2 = new CustomThread(record2.lock);
+        final CustomThread thread2 = new CustomThread(record2.networkStateLock);
         thread2.startAndWait("Unexpected state for " + record2);
 
         mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, expectedProcStateSeq);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 1e038df..092c60b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -105,7 +105,7 @@
 public class ActivityManagerServiceTest {
     private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
 
-    private static final int TEST_UID = 111;
+    private static final int TEST_UID = 11111;
 
     private static final long TEST_PROC_STATE_SEQ1 = 555;
     private static final long TEST_PROC_STATE_SEQ2 = 556;
@@ -121,6 +121,7 @@
     @Mock private Context mContext;
     @Mock private AppOpsService mAppOpsService;
     @Mock private PackageManager mPackageManager;
+    @Mock private BatteryStatsImpl mBatteryStatsImpl;
 
     private TestInjector mInjector;
     private ActivityManagerService mAms;
@@ -149,20 +150,9 @@
     @MediumTest
     @Test
     public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
-        final UidRecord uidRec = new UidRecord(TEST_UID);
-        uidRec.waitingForNetwork = true;
-        mAms.mActiveUids.put(TEST_UID, uidRec);
 
-        final BatteryStatsImpl batteryStats = Mockito.mock(BatteryStatsImpl.class);
-        final ProcessRecord appRec = new ProcessRecord(batteryStats,
-                new ApplicationInfo(), TAG, TEST_UID);
-        appRec.thread = Mockito.mock(IApplicationThread.class);
-        mAms.mLruProcesses.add(appRec);
-
-        final ProcessRecord appRec2 = new ProcessRecord(batteryStats,
-                new ApplicationInfo(), TAG, TEST_UID + 1);
-        appRec2.thread = Mockito.mock(IApplicationThread.class);
-        mAms.mLruProcesses.add(appRec2);
+        final UidRecord uidRec = addUidRecord(TEST_UID);
+        addUidRecord(TEST_UID + 1);
 
         // Uid state is not moving from background to foreground or vice versa.
         verifySeqCounterAndInteractions(uidRec,
@@ -235,12 +225,51 @@
                 44, // exptectedCurProcStateSeq
                 -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
                 false); // expectNotify
+
+        // Verify when the uid doesn't have internet permission, then procStateSeq is not
+        // incremented.
+        uidRec.hasInternetPermission = false;
+        mAms.mWaitForNetworkTimeoutMs = 111;
+        mInjector.setNetworkRestrictedForUid(true);
+        verifySeqCounterAndInteractions(uidRec,
+                PROCESS_STATE_CACHED_ACTIVITY, // prevState
+                PROCESS_STATE_FOREGROUND_SERVICE, // curState
+                44, // expectedGlobalCounter
+                44, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+
+        // Verify procStateSeq is not incremented when the uid is not an application, regardless
+        // of the process state.
+        final int notAppUid = 111;
+        final UidRecord uidRec2 = addUidRecord(notAppUid);
+        verifySeqCounterAndInteractions(uidRec2,
+                PROCESS_STATE_CACHED_EMPTY, // prevState
+                PROCESS_STATE_TOP, // curState
+                44, // expectedGlobalCounter
+                0, // exptectedCurProcStateSeq
+                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+                false); // expectNotify
+    }
+
+    private UidRecord addUidRecord(int uid) {
+        final UidRecord uidRec = new UidRecord(uid);
+        uidRec.waitingForNetwork = true;
+        uidRec.hasInternetPermission = true;
+        mAms.mActiveUids.put(uid, uidRec);
+
+        final ProcessRecord appRec = new ProcessRecord(mBatteryStatsImpl,
+                new ApplicationInfo(), TAG, uid);
+        appRec.thread = Mockito.mock(IApplicationThread.class);
+        mAms.mLruProcesses.add(appRec);
+
+        return uidRec;
     }
 
     private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
             int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
             boolean expectNotify) throws Exception {
-        CustomThread thread = new CustomThread(uidRec.lock);
+        CustomThread thread = new CustomThread(uidRec.networkStateLock);
         thread.startAndWait("Unexpected state for " + uidRec);
 
         uidRec.setProcState = prevState;
@@ -720,7 +749,7 @@
         record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
         mAms.mActiveUids.put(Process.myUid(), record);
 
-        CustomThread thread = new CustomThread(record.lock, new Runnable() {
+        CustomThread thread = new CustomThread(record.networkStateLock, new Runnable() {
             @Override
             public void run() {
                 mAms.waitForNetworkStateUpdate(procStateSeqToWait);
@@ -730,8 +759,8 @@
         if (expectWait) {
             thread.startAndWait(errMsg, true);
             thread.assertTimedWaiting(errMsg);
-            synchronized (record.lock) {
-                record.lock.notifyAll();
+            synchronized (record.networkStateLock) {
+                record.networkStateLock.notifyAll();
             }
             thread.assertTerminated(errMsg);
             assertTrue(thread.mNotified);
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index b410400..7c37027 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.cloneShortcutList;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
@@ -884,7 +886,7 @@
                     entryName = ShortcutInfo.getResourceEntryName(entryName);
                 }
                 return Integer.parseInt(entryName.substring(1)) + ressIdOffset;
-            }).when(res).getIdentifier(anyString(), anyString(), anyString());
+            }).when(res).getIdentifier(anyStringOrNull(), anyStringOrNull(), anyStringOrNull());
             return res;
         }).when(mMockPackageManager).getResourcesForApplicationAsUser(anyString(), anyInt());
     }
@@ -1612,7 +1614,7 @@
                 eq(packageName),
                 eq(userId),
                 intentsCaptor.capture(),
-                any(Bundle.class));
+                anyOrNull(Bundle.class));
         return intentsCaptor.getValue();
     }
 
@@ -1671,7 +1673,7 @@
                 anyString(),
                 anyInt(),
                 any(Intent[].class),
-                any(Bundle.class));
+                anyOrNull(Bundle.class));
     }
 
     protected void assertStartShortcutThrowsException(@NonNull String packageName,
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4b3c2f8..796cc16 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllChooser;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDisabled;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic;
@@ -2832,7 +2834,8 @@
             // Not launchable.
             doReturn(ActivityManager.START_CLASS_NOT_FOUND)
                     .when(mMockActivityManagerInternal).startActivitiesAsPackage(
-                            anyString(), anyInt(), any(Intent[].class), any(Bundle.class));
+                            anyStringOrNull(), anyInt(),
+                            anyOrNull(Intent[].class), anyOrNull(Bundle.class));
             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
                     ActivityNotFoundException.class);
 
@@ -2840,7 +2843,8 @@
             doReturn(ActivityManager.START_CLASS_NOT_FOUND)
                     .when(mMockActivityManagerInternal)
                     .startActivitiesAsPackage(
-                            anyString(), anyInt(), any(Intent[].class), any(Bundle.class));
+                            anyStringOrNull(), anyInt(),
+                            anyOrNull(Intent[].class), anyOrNull(Bundle.class));
             assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
                     ActivityNotFoundException.class);
         });
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
index 0310e16..e9a329c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.pm;
 
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertForLauncherCallbackNoThrow;
 import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
@@ -775,7 +776,7 @@
                     /* resultIntent=*/ null));
 
             // The intent should be sent right away.
-            verify(mServiceContext, times(1)).sendIntentSender(any(IntentSender.class));
+            verify(mServiceContext, times(1)).sendIntentSender(anyOrNull(IntentSender.class));
         });
     }
 
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index f2bae4c..132ed98 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -58,6 +58,8 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
 import org.mockito.hamcrest.MockitoHamcrest;
 
@@ -733,6 +735,14 @@
         fail("Timed out for: " + message);
     }
 
+    public static final <T> T anyOrNull(Class<T> clazz) {
+        return ArgumentMatchers.argThat(value -> true);
+    }
+
+    public static final String anyStringOrNull() {
+        return ArgumentMatchers.argThat(value -> true);
+    }
+
     public static ShortcutListAsserter assertWith(List<ShortcutInfo> list) {
         return new ShortcutListAsserter(list);
     }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7a226a0..bb83633 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1390,6 +1390,13 @@
     public static final String KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY =
             "boosted_lte_earfcns_string_array";
 
+    /**
+     * Key identifying if voice call barring notification is required to be shown to the user.
+     * @hide
+     */
+    public static final String KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL =
+            "disable_voice_barring_notification_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -1625,6 +1632,7 @@
                 null);
         sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
         sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
+        sDefaults.putBoolean(KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
     }
 
     /**
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index da1d998..dca74ff 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -526,6 +526,12 @@
     }
 
     @Override
+    public ComponentName startForegroundService(Intent service) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** STOPSHIP remove when trial API is turned down */
+    @Override
     public ComponentName startServiceInForeground(Intent service,
             int id, Notification notification) {
         throw new UnsupportedOperationException();
@@ -544,6 +550,12 @@
 
     /** @hide */
     @Override
+    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide STOPSHIP removed when trial API is turned down */
+    @Override
     public ComponentName startServiceInForegroundAsUser(Intent service,
             int id, Notification notification, UserHandle user) {
         throw new UnsupportedOperationException();
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index e118889..80e3bad 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -233,7 +233,8 @@
             Map<String, ByteBuffer> bufferForPath) {
         FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
         for (FontConfig.Font font : family.getFonts()) {
-            FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, font.getFontName(),
+            String fullPathName = "/system/fonts/" + font.getFontName();
+            FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
                     font.getWeight(), font.isItalic());
         }
         fontFamily.freeze();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 5c28150..06272c8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1853,6 +1853,18 @@
     }
 
     @Override
+    public ComponentName startForegroundService(Intent service) {
+        // pass
+        return null;
+    }
+
+    @Override
+    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+        // pass
+        return null;
+    }
+
+    @Override
     public ComponentName startServiceInForeground(Intent service,
             int id, Notification notification) {
         // pass