Merge "Use callback to run binder service to avoid race"
diff --git a/Android.mk b/Android.mk
index 8fd63ee4..b847425 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1558,6 +1558,7 @@
 LOCAL_SOURCE_FILES_ALL_GENERATED := true
 LOCAL_SRC_FILES := \
     tools/streaming_proto/stream.proto \
+    cmds/am/proto/instrumentation_data.proto \
     $(call all-proto-files-under, core/proto) \
     $(call all-proto-files-under, libs/incident/proto)
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/api/current.txt b/api/current.txt
index 59e0fc7..c7b2537c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3609,11 +3609,11 @@
     method public android.transition.Scene getContentScene();
     method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
-    method public android.app.FragmentManager getFragmentManager();
+    method public deprecated android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
     method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
     method public int getMaxNumPictureInPictureActions();
     method public final android.media.session.MediaController getMediaController();
@@ -3653,7 +3653,7 @@
     method public void onActionModeStarted(android.view.ActionMode);
     method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
-    method public void onAttachFragment(android.app.Fragment);
+    method public deprecated void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method public void onBackPressed();
     method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence);
@@ -3795,8 +3795,8 @@
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int, android.os.Bundle);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
     method public boolean startActivityIfNeeded(android.content.Intent, int);
     method public boolean startActivityIfNeeded(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -4455,7 +4455,7 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+  public deprecated class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
     ctor public DialogFragment();
     method public void dismiss();
     method public void dismissAllowingStateLoss();
@@ -4573,7 +4573,7 @@
     method public void setSelectedGroup(int);
   }
 
-  public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
+  public deprecated class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
     ctor public Fragment();
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public final boolean equals(java.lang.Object);
@@ -4589,7 +4589,7 @@
     method public final java.lang.Object getHost();
     method public final int getId();
     method public final android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public final android.app.Fragment getParentFragment();
     method public android.transition.Transition getReenterTransition();
     method public final android.content.res.Resources getResources();
@@ -4684,11 +4684,11 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public static class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
+  public static deprecated class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
     ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
   }
 
-  public static class Fragment.SavedState implements android.os.Parcelable {
+  public static deprecated class Fragment.SavedState implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.ClassLoaderCreator<android.app.Fragment.SavedState> CREATOR;
@@ -4707,17 +4707,17 @@
     method public void setTitle(java.lang.CharSequence, java.lang.CharSequence);
   }
 
-  public static abstract interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
+  public static abstract deprecated interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
     method public abstract boolean onBreadCrumbClick(android.app.FragmentManager.BackStackEntry, int);
   }
 
-  public abstract class FragmentContainer {
+  public abstract deprecated class FragmentContainer {
     ctor public FragmentContainer();
     method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
-  public class FragmentController {
+  public deprecated class FragmentController {
     method public void attachHost(android.app.Fragment);
     method public static final android.app.FragmentController createController(android.app.FragmentHostCallback<?>);
     method public void dispatchActivityCreated();
@@ -4760,7 +4760,7 @@
     method public android.os.Parcelable saveAllState();
   }
 
-  public abstract class FragmentHostCallback<E> extends android.app.FragmentContainer {
+  public abstract deprecated class FragmentHostCallback<E> extends android.app.FragmentContainer {
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -4778,7 +4778,7 @@
     method public boolean onUseFragmentManagerInflaterFactory();
   }
 
-  public abstract class FragmentManager {
+  public abstract deprecated class FragmentManager {
     ctor public FragmentManager();
     method public abstract void addOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.FragmentTransaction beginTransaction();
@@ -4809,7 +4809,7 @@
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
-  public static abstract interface FragmentManager.BackStackEntry {
+  public static abstract deprecated interface FragmentManager.BackStackEntry {
     method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
     method public abstract int getBreadCrumbShortTitleRes();
     method public abstract java.lang.CharSequence getBreadCrumbTitle();
@@ -4818,7 +4818,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract deprecated class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -4836,14 +4836,14 @@
     method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
   }
 
-  public static abstract interface FragmentManager.OnBackStackChangedListener {
+  public static abstract deprecated interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
 
-  public class FragmentManagerNonConfig {
+  public deprecated class FragmentManagerNonConfig {
   }
 
-  public abstract class FragmentTransaction {
+  public abstract deprecated class FragmentTransaction {
     ctor public FragmentTransaction();
     method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
     method public abstract android.app.FragmentTransaction add(int, android.app.Fragment);
@@ -5049,7 +5049,7 @@
     method public void setSelection(int);
   }
 
-  public class ListFragment extends android.app.Fragment {
+  public deprecated class ListFragment extends android.app.Fragment {
     ctor public ListFragment();
     method public android.widget.ListAdapter getListAdapter();
     method public android.widget.ListView getListView();
@@ -5063,7 +5063,7 @@
     method public void setSelection(int);
   }
 
-  public abstract class LoaderManager {
+  public abstract deprecated class LoaderManager {
     ctor public LoaderManager();
     method public abstract void destroyLoader(int);
     method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -5073,7 +5073,7 @@
     method public abstract <D> android.content.Loader<D> restartLoader(int, android.os.Bundle, android.app.LoaderManager.LoaderCallbacks<D>);
   }
 
-  public static abstract interface LoaderManager.LoaderCallbacks<D> {
+  public static abstract deprecated interface LoaderManager.LoaderCallbacks<D> {
     method public abstract android.content.Loader<D> onCreateLoader(int, android.os.Bundle);
     method public abstract void onLoadFinished(android.content.Loader<D>, D);
     method public abstract void onLoaderReset(android.content.Loader<D>);
@@ -8533,7 +8533,7 @@
     ctor public AsyncQueryHandler.WorkerHandler(android.os.Looper);
   }
 
-  public abstract class AsyncTaskLoader<D> extends android.content.Loader {
+  public abstract deprecated class AsyncTaskLoader<D> extends android.content.Loader {
     ctor public AsyncTaskLoader(android.content.Context);
     method public void cancelLoadInBackground();
     method public boolean isLoadInBackgroundCanceled();
@@ -9273,7 +9273,7 @@
     method public void unregisterReceiver(android.content.BroadcastReceiver);
   }
 
-  public class CursorLoader extends android.content.AsyncTaskLoader {
+  public deprecated class CursorLoader extends android.content.AsyncTaskLoader {
     ctor public CursorLoader(android.content.Context);
     ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public void deliverResult(android.database.Cursor);
@@ -9879,7 +9879,7 @@
     ctor public IntentSender.SendIntentException(java.lang.Exception);
   }
 
-  public class Loader<D> {
+  public deprecated class Loader<D> {
     ctor public Loader(android.content.Context);
     method public void abandon();
     method public boolean cancelLoad();
@@ -9912,15 +9912,15 @@
     method public void unregisterOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
   }
 
-  public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+  public final deprecated class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
     ctor public Loader.ForceLoadContentObserver();
   }
 
-  public static abstract interface Loader.OnLoadCanceledListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCanceledListener<D> {
     method public abstract void onLoadCanceled(android.content.Loader<D>);
   }
 
-  public static abstract interface Loader.OnLoadCompleteListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCompleteListener<D> {
     method public abstract void onLoadComplete(android.content.Loader<D>, D);
   }
 
@@ -10574,6 +10574,7 @@
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
+    field public static final int FLAG_MATCH_PINNED_BY_ANY_LAUNCHER = 1024; // 0x400
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -12136,9 +12137,11 @@
     method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
     method public android.database.DatabaseErrorHandler getErrorHandler();
     method public long getIdleConnectionTimeout();
+    method public java.lang.String getJournalMode();
     method public int getLookasideSlotCount();
     method public int getLookasideSlotSize();
     method public int getOpenFlags();
+    method public java.lang.String getSynchronousMode();
   }
 
   public static final class SQLiteDatabase.OpenParams.Builder {
@@ -12150,8 +12153,10 @@
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setJournalMode(java.lang.String);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setSynchronousMode(java.lang.String);
   }
 
   public class SQLiteDatabaseCorruptException extends android.database.sqlite.SQLiteException {
@@ -12198,6 +12203,7 @@
   public abstract class SQLiteOpenHelper {
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
+    ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, int, android.database.sqlite.SQLiteDatabase.OpenParams);
     method public synchronized void close();
     method public java.lang.String getDatabaseName();
     method public android.database.sqlite.SQLiteDatabase getReadableDatabase();
@@ -15278,6 +15284,7 @@
     method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    method public void updateOutputConfiguration(android.hardware.camera2.params.OutputConfiguration) throws android.hardware.camera2.CameraAccessException;
   }
 
   public static abstract class CameraCaptureSession.CaptureCallback {
@@ -15919,9 +15926,11 @@
     method public void addSurface(android.view.Surface);
     method public int describeContents();
     method public void enableSurfaceSharing();
+    method public static int getMaxSharedSurfaceCount();
     method public android.view.Surface getSurface();
     method public int getSurfaceGroupId();
     method public java.util.List<android.view.Surface> getSurfaces();
+    method public void removeSurface(android.view.Surface);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
     field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff
@@ -32618,7 +32627,7 @@
     method public default void putStringSet(java.lang.String, java.util.Set<java.lang.String>);
   }
 
-  public abstract class PreferenceFragment extends android.app.Fragment {
+  public abstract deprecated class PreferenceFragment extends android.app.Fragment {
     ctor public PreferenceFragment();
     method public void addPreferencesFromIntent(android.content.Intent);
     method public void addPreferencesFromResource(int);
@@ -32629,7 +32638,7 @@
     method public void setPreferenceScreen(android.preference.PreferenceScreen);
   }
 
-  public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+  public static abstract deprecated interface PreferenceFragment.OnPreferenceStartFragmentCallback {
     method public abstract boolean onPreferenceStartFragment(android.preference.PreferenceFragment, android.preference.Preference);
   }
 
@@ -49984,7 +49993,7 @@
     method public abstract void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
   }
 
-  public class WebViewFragment extends android.app.Fragment {
+  public deprecated class WebViewFragment extends android.app.Fragment {
     ctor public WebViewFragment();
     method public android.webkit.WebView getWebView();
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 62e23c8..acb81ee 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3754,11 +3754,11 @@
     method public android.transition.Scene getContentScene();
     method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
-    method public android.app.FragmentManager getFragmentManager();
+    method public deprecated android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
     method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
     method public int getMaxNumPictureInPictureActions();
     method public final android.media.session.MediaController getMediaController();
@@ -3799,7 +3799,7 @@
     method public void onActionModeStarted(android.view.ActionMode);
     method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
-    method public void onAttachFragment(android.app.Fragment);
+    method public deprecated void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method public void onBackPressed();
     method public deprecated void onBackgroundVisibleBehindChanged(boolean);
@@ -3943,8 +3943,8 @@
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int, android.os.Bundle);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
     method public boolean startActivityIfNeeded(android.content.Intent, int);
     method public boolean startActivityIfNeeded(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -4628,7 +4628,7 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+  public deprecated class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
     ctor public DialogFragment();
     method public void dismiss();
     method public void dismissAllowingStateLoss();
@@ -4747,7 +4747,7 @@
     method public void setSelectedGroup(int);
   }
 
-  public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
+  public deprecated class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
     ctor public Fragment();
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public final boolean equals(java.lang.Object);
@@ -4763,7 +4763,7 @@
     method public final java.lang.Object getHost();
     method public final int getId();
     method public final android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public final android.app.Fragment getParentFragment();
     method public android.transition.Transition getReenterTransition();
     method public final android.content.res.Resources getResources();
@@ -4858,11 +4858,11 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public static class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
+  public static deprecated class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
     ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
   }
 
-  public static class Fragment.SavedState implements android.os.Parcelable {
+  public static deprecated class Fragment.SavedState implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.ClassLoaderCreator<android.app.Fragment.SavedState> CREATOR;
@@ -4881,17 +4881,17 @@
     method public void setTitle(java.lang.CharSequence, java.lang.CharSequence);
   }
 
-  public static abstract interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
+  public static abstract deprecated interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
     method public abstract boolean onBreadCrumbClick(android.app.FragmentManager.BackStackEntry, int);
   }
 
-  public abstract class FragmentContainer {
+  public abstract deprecated class FragmentContainer {
     ctor public FragmentContainer();
     method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
-  public class FragmentController {
+  public deprecated class FragmentController {
     method public void attachHost(android.app.Fragment);
     method public static final android.app.FragmentController createController(android.app.FragmentHostCallback<?>);
     method public void dispatchActivityCreated();
@@ -4934,7 +4934,7 @@
     method public android.os.Parcelable saveAllState();
   }
 
-  public abstract class FragmentHostCallback<E> extends android.app.FragmentContainer {
+  public abstract deprecated class FragmentHostCallback<E> extends android.app.FragmentContainer {
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -4952,7 +4952,7 @@
     method public boolean onUseFragmentManagerInflaterFactory();
   }
 
-  public abstract class FragmentManager {
+  public abstract deprecated class FragmentManager {
     ctor public FragmentManager();
     method public abstract void addOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.FragmentTransaction beginTransaction();
@@ -4983,7 +4983,7 @@
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
-  public static abstract interface FragmentManager.BackStackEntry {
+  public static abstract deprecated interface FragmentManager.BackStackEntry {
     method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
     method public abstract int getBreadCrumbShortTitleRes();
     method public abstract java.lang.CharSequence getBreadCrumbTitle();
@@ -4992,7 +4992,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract deprecated class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -5010,14 +5010,14 @@
     method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
   }
 
-  public static abstract interface FragmentManager.OnBackStackChangedListener {
+  public static abstract deprecated interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
 
-  public class FragmentManagerNonConfig {
+  public deprecated class FragmentManagerNonConfig {
   }
 
-  public abstract class FragmentTransaction {
+  public abstract deprecated class FragmentTransaction {
     ctor public FragmentTransaction();
     method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
     method public abstract android.app.FragmentTransaction add(int, android.app.Fragment);
@@ -5235,7 +5235,7 @@
     method public void setSelection(int);
   }
 
-  public class ListFragment extends android.app.Fragment {
+  public deprecated class ListFragment extends android.app.Fragment {
     ctor public ListFragment();
     method public android.widget.ListAdapter getListAdapter();
     method public android.widget.ListView getListView();
@@ -5249,7 +5249,7 @@
     method public void setSelection(int);
   }
 
-  public abstract class LoaderManager {
+  public abstract deprecated class LoaderManager {
     ctor public LoaderManager();
     method public abstract void destroyLoader(int);
     method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -5259,7 +5259,7 @@
     method public abstract <D> android.content.Loader<D> restartLoader(int, android.os.Bundle, android.app.LoaderManager.LoaderCallbacks<D>);
   }
 
-  public static abstract interface LoaderManager.LoaderCallbacks<D> {
+  public static abstract deprecated interface LoaderManager.LoaderCallbacks<D> {
     method public abstract android.content.Loader<D> onCreateLoader(int, android.os.Bundle);
     method public abstract void onLoadFinished(android.content.Loader<D>, D);
     method public abstract void onLoaderReset(android.content.Loader<D>);
@@ -9045,7 +9045,7 @@
     ctor public AsyncQueryHandler.WorkerHandler(android.os.Looper);
   }
 
-  public abstract class AsyncTaskLoader<D> extends android.content.Loader {
+  public abstract deprecated class AsyncTaskLoader<D> extends android.content.Loader {
     ctor public AsyncTaskLoader(android.content.Context);
     method public void cancelLoadInBackground();
     method public boolean isLoadInBackgroundCanceled();
@@ -9668,6 +9668,7 @@
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String SHORTCUT_SERVICE = "shortcut";
+    field public static final java.lang.String STATS_MANAGER = "stats";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
     field public static final java.lang.String STORAGE_STATS_SERVICE = "storagestats";
     field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth";
@@ -9807,7 +9808,7 @@
     method public void unregisterReceiver(android.content.BroadcastReceiver);
   }
 
-  public class CursorLoader extends android.content.AsyncTaskLoader {
+  public deprecated class CursorLoader extends android.content.AsyncTaskLoader {
     ctor public CursorLoader(android.content.Context);
     ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public void deliverResult(android.database.Cursor);
@@ -10442,7 +10443,7 @@
     ctor public IntentSender.SendIntentException(java.lang.Exception);
   }
 
-  public class Loader<D> {
+  public deprecated class Loader<D> {
     ctor public Loader(android.content.Context);
     method public void abandon();
     method public boolean cancelLoad();
@@ -10475,15 +10476,15 @@
     method public void unregisterOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
   }
 
-  public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+  public final deprecated class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
     ctor public Loader.ForceLoadContentObserver();
   }
 
-  public static abstract interface Loader.OnLoadCanceledListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCanceledListener<D> {
     method public abstract void onLoadCanceled(android.content.Loader<D>);
   }
 
-  public static abstract interface Loader.OnLoadCompleteListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCompleteListener<D> {
     method public abstract void onLoadComplete(android.content.Loader<D>, D);
   }
 
@@ -11192,6 +11193,7 @@
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
+    field public static final int FLAG_MATCH_PINNED_BY_ANY_LAUNCHER = 1024; // 0x400
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -12883,9 +12885,11 @@
     method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
     method public android.database.DatabaseErrorHandler getErrorHandler();
     method public long getIdleConnectionTimeout();
+    method public java.lang.String getJournalMode();
     method public int getLookasideSlotCount();
     method public int getLookasideSlotSize();
     method public int getOpenFlags();
+    method public java.lang.String getSynchronousMode();
   }
 
   public static final class SQLiteDatabase.OpenParams.Builder {
@@ -12897,8 +12901,10 @@
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setJournalMode(java.lang.String);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setSynchronousMode(java.lang.String);
   }
 
   public class SQLiteDatabaseCorruptException extends android.database.sqlite.SQLiteException {
@@ -12945,6 +12951,7 @@
   public abstract class SQLiteOpenHelper {
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
+    ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, int, android.database.sqlite.SQLiteDatabase.OpenParams);
     method public synchronized void close();
     method public java.lang.String getDatabaseName();
     method public android.database.sqlite.SQLiteDatabase getReadableDatabase();
@@ -16033,6 +16040,7 @@
     method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    method public void updateOutputConfiguration(android.hardware.camera2.params.OutputConfiguration) throws android.hardware.camera2.CameraAccessException;
   }
 
   public static abstract class CameraCaptureSession.CaptureCallback {
@@ -16680,10 +16688,12 @@
     method public void addSurface(android.view.Surface);
     method public int describeContents();
     method public void enableSurfaceSharing();
+    method public static int getMaxSharedSurfaceCount();
     method public int getRotation();
     method public android.view.Surface getSurface();
     method public int getSurfaceGroupId();
     method public java.util.List<android.view.Surface> getSurfaces();
+    method public void removeSurface(android.view.Surface);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
     field public static final int ROTATION_0 = 0; // 0x0
@@ -34829,11 +34839,13 @@
     method public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(java.lang.String, android.os.UserHandle);
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
+    method public boolean hasRestrictedProfiles();
     method public boolean hasUserRestriction(java.lang.String);
     method public boolean isDemoUser();
     method public boolean isManagedProfile();
     method public boolean isManagedProfile(int);
     method public boolean isQuietModeEnabled(android.os.UserHandle);
+    method public boolean isRestrictedProfile();
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
@@ -35502,7 +35514,7 @@
     method public default void putStringSet(java.lang.String, java.util.Set<java.lang.String>);
   }
 
-  public abstract class PreferenceFragment extends android.app.Fragment {
+  public abstract deprecated class PreferenceFragment extends android.app.Fragment {
     ctor public PreferenceFragment();
     method public void addPreferencesFromIntent(android.content.Intent);
     method public void addPreferencesFromResource(int);
@@ -35513,7 +35525,7 @@
     method public void setPreferenceScreen(android.preference.PreferenceScreen);
   }
 
-  public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+  public static abstract deprecated interface PreferenceFragment.OnPreferenceStartFragmentCallback {
     method public abstract boolean onPreferenceStartFragment(android.preference.PreferenceFragment, android.preference.Preference);
   }
 
@@ -48167,6 +48179,12 @@
     field public static final int[] WILD_CARD;
   }
 
+  public final class StatsManager {
+    method public byte[] getData(java.lang.String);
+    method public boolean addConfiguration(java.lang.String, byte[], java.lang.String, java.lang.String);
+    method public boolean removeConfiguration(java.lang.String);
+  }
+
   public class StringBuilderPrinter implements android.util.Printer {
     ctor public StringBuilderPrinter(java.lang.StringBuilder);
     method public void println(java.lang.String);
@@ -53910,7 +53928,7 @@
     method public abstract void setWebContentsDebuggingEnabled(boolean);
   }
 
-  public class WebViewFragment extends android.app.Fragment {
+  public deprecated class WebViewFragment extends android.app.Fragment {
     ctor public WebViewFragment();
     method public android.webkit.WebView getWebView();
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index abf5864..6701de3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3611,11 +3611,11 @@
     method public android.transition.Scene getContentScene();
     method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
-    method public android.app.FragmentManager getFragmentManager();
+    method public deprecated android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
     method public java.lang.Object getLastNonConfigurationInstance();
     method public android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public java.lang.String getLocalClassName();
     method public int getMaxNumPictureInPictureActions();
     method public final android.media.session.MediaController getMediaController();
@@ -3655,7 +3655,7 @@
     method public void onActionModeStarted(android.view.ActionMode);
     method public void onActivityReenter(int, android.content.Intent);
     method protected void onActivityResult(int, int, android.content.Intent);
-    method public void onAttachFragment(android.app.Fragment);
+    method public deprecated void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method public void onBackPressed();
     method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence);
@@ -3797,8 +3797,8 @@
     method public void startActivityForResult(android.content.Intent, int, android.os.Bundle);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int);
     method public void startActivityFromChild(android.app.Activity, android.content.Intent, int, android.os.Bundle);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
-    method public void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int);
+    method public deprecated void startActivityFromFragment(android.app.Fragment, android.content.Intent, int, android.os.Bundle);
     method public boolean startActivityIfNeeded(android.content.Intent, int);
     method public boolean startActivityIfNeeded(android.content.Intent, int, android.os.Bundle);
     method public void startIntentSenderForResult(android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -4484,7 +4484,7 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
+  public deprecated class DialogFragment extends android.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
     ctor public DialogFragment();
     method public void dismiss();
     method public void dismissAllowingStateLoss();
@@ -4602,7 +4602,7 @@
     method public void setSelectedGroup(int);
   }
 
-  public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
+  public deprecated class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
     ctor public Fragment();
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public final boolean equals(java.lang.Object);
@@ -4618,7 +4618,7 @@
     method public final java.lang.Object getHost();
     method public final int getId();
     method public final android.view.LayoutInflater getLayoutInflater();
-    method public android.app.LoaderManager getLoaderManager();
+    method public deprecated android.app.LoaderManager getLoaderManager();
     method public final android.app.Fragment getParentFragment();
     method public android.transition.Transition getReenterTransition();
     method public final android.content.res.Resources getResources();
@@ -4713,11 +4713,11 @@
     method public void unregisterForContextMenu(android.view.View);
   }
 
-  public static class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
+  public static deprecated class Fragment.InstantiationException extends android.util.AndroidRuntimeException {
     ctor public Fragment.InstantiationException(java.lang.String, java.lang.Exception);
   }
 
-  public static class Fragment.SavedState implements android.os.Parcelable {
+  public static deprecated class Fragment.SavedState implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.ClassLoaderCreator<android.app.Fragment.SavedState> CREATOR;
@@ -4736,17 +4736,17 @@
     method public void setTitle(java.lang.CharSequence, java.lang.CharSequence);
   }
 
-  public static abstract interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
+  public static abstract deprecated interface FragmentBreadCrumbs.OnBreadCrumbClickListener {
     method public abstract boolean onBreadCrumbClick(android.app.FragmentManager.BackStackEntry, int);
   }
 
-  public abstract class FragmentContainer {
+  public abstract deprecated class FragmentContainer {
     ctor public FragmentContainer();
     method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
-  public class FragmentController {
+  public deprecated class FragmentController {
     method public void attachHost(android.app.Fragment);
     method public static final android.app.FragmentController createController(android.app.FragmentHostCallback<?>);
     method public void dispatchActivityCreated();
@@ -4789,7 +4789,7 @@
     method public android.os.Parcelable saveAllState();
   }
 
-  public abstract class FragmentHostCallback<E> extends android.app.FragmentContainer {
+  public abstract deprecated class FragmentHostCallback<E> extends android.app.FragmentContainer {
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -4807,7 +4807,7 @@
     method public boolean onUseFragmentManagerInflaterFactory();
   }
 
-  public abstract class FragmentManager {
+  public abstract deprecated class FragmentManager {
     ctor public FragmentManager();
     method public abstract void addOnBackStackChangedListener(android.app.FragmentManager.OnBackStackChangedListener);
     method public abstract android.app.FragmentTransaction beginTransaction();
@@ -4838,7 +4838,7 @@
     field public static final int POP_BACK_STACK_INCLUSIVE = 1; // 0x1
   }
 
-  public static abstract interface FragmentManager.BackStackEntry {
+  public static abstract deprecated interface FragmentManager.BackStackEntry {
     method public abstract java.lang.CharSequence getBreadCrumbShortTitle();
     method public abstract int getBreadCrumbShortTitleRes();
     method public abstract java.lang.CharSequence getBreadCrumbTitle();
@@ -4847,7 +4847,7 @@
     method public abstract java.lang.String getName();
   }
 
-  public static abstract class FragmentManager.FragmentLifecycleCallbacks {
+  public static abstract deprecated class FragmentManager.FragmentLifecycleCallbacks {
     ctor public FragmentManager.FragmentLifecycleCallbacks();
     method public void onFragmentActivityCreated(android.app.FragmentManager, android.app.Fragment, android.os.Bundle);
     method public void onFragmentAttached(android.app.FragmentManager, android.app.Fragment, android.content.Context);
@@ -4865,14 +4865,14 @@
     method public void onFragmentViewDestroyed(android.app.FragmentManager, android.app.Fragment);
   }
 
-  public static abstract interface FragmentManager.OnBackStackChangedListener {
+  public static abstract deprecated interface FragmentManager.OnBackStackChangedListener {
     method public abstract void onBackStackChanged();
   }
 
-  public class FragmentManagerNonConfig {
+  public deprecated class FragmentManagerNonConfig {
   }
 
-  public abstract class FragmentTransaction {
+  public abstract deprecated class FragmentTransaction {
     ctor public FragmentTransaction();
     method public abstract android.app.FragmentTransaction add(android.app.Fragment, java.lang.String);
     method public abstract android.app.FragmentTransaction add(int, android.app.Fragment);
@@ -5078,7 +5078,7 @@
     method public void setSelection(int);
   }
 
-  public class ListFragment extends android.app.Fragment {
+  public deprecated class ListFragment extends android.app.Fragment {
     ctor public ListFragment();
     method public android.widget.ListAdapter getListAdapter();
     method public android.widget.ListView getListView();
@@ -5092,7 +5092,7 @@
     method public void setSelection(int);
   }
 
-  public abstract class LoaderManager {
+  public abstract deprecated class LoaderManager {
     ctor public LoaderManager();
     method public abstract void destroyLoader(int);
     method public abstract void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
@@ -5102,7 +5102,7 @@
     method public abstract <D> android.content.Loader<D> restartLoader(int, android.os.Bundle, android.app.LoaderManager.LoaderCallbacks<D>);
   }
 
-  public static abstract interface LoaderManager.LoaderCallbacks<D> {
+  public static abstract deprecated interface LoaderManager.LoaderCallbacks<D> {
     method public abstract android.content.Loader<D> onCreateLoader(int, android.os.Bundle);
     method public abstract void onLoadFinished(android.content.Loader<D>, D);
     method public abstract void onLoaderReset(android.content.Loader<D>);
@@ -8608,7 +8608,7 @@
     ctor public AsyncQueryHandler.WorkerHandler(android.os.Looper);
   }
 
-  public abstract class AsyncTaskLoader<D> extends android.content.Loader {
+  public abstract deprecated class AsyncTaskLoader<D> extends android.content.Loader {
     ctor public AsyncTaskLoader(android.content.Context);
     method public void cancelLoadInBackground();
     method public boolean isLoadInBackgroundCanceled();
@@ -9351,7 +9351,7 @@
     method public void unregisterReceiver(android.content.BroadcastReceiver);
   }
 
-  public class CursorLoader extends android.content.AsyncTaskLoader {
+  public deprecated class CursorLoader extends android.content.AsyncTaskLoader {
     ctor public CursorLoader(android.content.Context);
     ctor public CursorLoader(android.content.Context, android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public void deliverResult(android.database.Cursor);
@@ -9957,7 +9957,7 @@
     ctor public IntentSender.SendIntentException(java.lang.Exception);
   }
 
-  public class Loader<D> {
+  public deprecated class Loader<D> {
     ctor public Loader(android.content.Context);
     method public void abandon();
     method public boolean cancelLoad();
@@ -9990,15 +9990,15 @@
     method public void unregisterOnLoadCanceledListener(android.content.Loader.OnLoadCanceledListener<D>);
   }
 
-  public final class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
+  public final deprecated class Loader.ForceLoadContentObserver extends android.database.ContentObserver {
     ctor public Loader.ForceLoadContentObserver();
   }
 
-  public static abstract interface Loader.OnLoadCanceledListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCanceledListener<D> {
     method public abstract void onLoadCanceled(android.content.Loader<D>);
   }
 
-  public static abstract interface Loader.OnLoadCompleteListener<D> {
+  public static abstract deprecated interface Loader.OnLoadCompleteListener<D> {
     method public abstract void onLoadComplete(android.content.Loader<D>, D);
   }
 
@@ -10653,10 +10653,10 @@
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
     field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
-    field public static final int FLAG_MATCH_ALL_PINNED = 1024; // 0x400
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
+    field public static final int FLAG_MATCH_PINNED_BY_ANY_LAUNCHER = 1024; // 0x400
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -12226,9 +12226,11 @@
     method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
     method public android.database.DatabaseErrorHandler getErrorHandler();
     method public long getIdleConnectionTimeout();
+    method public java.lang.String getJournalMode();
     method public int getLookasideSlotCount();
     method public int getLookasideSlotSize();
     method public int getOpenFlags();
+    method public java.lang.String getSynchronousMode();
   }
 
   public static final class SQLiteDatabase.OpenParams.Builder {
@@ -12240,8 +12242,10 @@
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setJournalMode(java.lang.String);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
     method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
+    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setSynchronousMode(java.lang.String);
   }
 
   public class SQLiteDatabaseCorruptException extends android.database.sqlite.SQLiteException {
@@ -12335,6 +12339,7 @@
   public abstract class SQLiteOpenHelper {
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int);
     ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, int, android.database.DatabaseErrorHandler);
+    ctor public SQLiteOpenHelper(android.content.Context, java.lang.String, int, android.database.sqlite.SQLiteDatabase.OpenParams);
     method public synchronized void close();
     method public java.lang.String getDatabaseName();
     method public android.database.sqlite.SQLiteDatabase getReadableDatabase();
@@ -15420,6 +15425,7 @@
     method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
     method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    method public void updateOutputConfiguration(android.hardware.camera2.params.OutputConfiguration) throws android.hardware.camera2.CameraAccessException;
   }
 
   public static abstract class CameraCaptureSession.CaptureCallback {
@@ -16065,9 +16071,11 @@
     method public void addSurface(android.view.Surface);
     method public int describeContents();
     method public void enableSurfaceSharing();
+    method public static int getMaxSharedSurfaceCount();
     method public android.view.Surface getSurface();
     method public int getSurfaceGroupId();
     method public java.util.List<android.view.Surface> getSurfaces();
+    method public void removeSurface(android.view.Surface);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
     field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff
@@ -32887,7 +32895,7 @@
     method public default void putStringSet(java.lang.String, java.util.Set<java.lang.String>);
   }
 
-  public abstract class PreferenceFragment extends android.app.Fragment {
+  public abstract deprecated class PreferenceFragment extends android.app.Fragment {
     ctor public PreferenceFragment();
     method public void addPreferencesFromIntent(android.content.Intent);
     method public void addPreferencesFromResource(int);
@@ -32898,7 +32906,7 @@
     method public void setPreferenceScreen(android.preference.PreferenceScreen);
   }
 
-  public static abstract interface PreferenceFragment.OnPreferenceStartFragmentCallback {
+  public static abstract deprecated interface PreferenceFragment.OnPreferenceStartFragmentCallback {
     method public abstract boolean onPreferenceStartFragment(android.preference.PreferenceFragment, android.preference.Preference);
   }
 
@@ -41458,6 +41466,7 @@
   }
 
   public final class FileInfo implements android.os.Parcelable {
+    ctor public FileInfo(android.net.Uri, java.lang.String);
     method public int describeContents();
     method public java.lang.String getMimeType();
     method public android.net.Uri getUri();
@@ -41571,6 +41580,14 @@
     field public static final android.os.Parcelable.Creator<android.telephony.mbms.StreamingServiceInfo> CREATOR;
   }
 
+  public final class UriPathPair implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.net.Uri getContentUri();
+    method public android.net.Uri getFilePathUri();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.mbms.UriPathPair> CREATOR;
+  }
+
 }
 
 package android.telephony.mbms.vendor {
@@ -41602,6 +41619,23 @@
     method public void stopStreaming(int, java.lang.String) throws android.os.RemoteException;
   }
 
+  public class VendorUtils {
+    ctor public VendorUtils();
+    method public static android.content.ComponentName getAppReceiverFromPackageName(android.content.Context, java.lang.String);
+    field public static final java.lang.String ACTION_CLEANUP = "android.telephony.mbms.action.CLEANUP";
+    field public static final java.lang.String ACTION_DOWNLOAD_RESULT_INTERNAL = "android.telephony.mbms.action.DOWNLOAD_RESULT_INTERNAL";
+    field public static final java.lang.String ACTION_FILE_DESCRIPTOR_REQUEST = "android.telephony.mbms.action.FILE_DESCRIPTOR_REQUEST";
+    field public static final java.lang.String EXTRA_FD_COUNT = "android.telephony.mbms.extra.FD_COUNT";
+    field public static final java.lang.String EXTRA_FINAL_URI = "android.telephony.mbms.extra.FINAL_URI";
+    field public static final java.lang.String EXTRA_FREE_URI_LIST = "android.telephony.mbms.extra.FREE_URI_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_LIST = "android.telephony.mbms.extra.PAUSED_LIST";
+    field public static final java.lang.String EXTRA_PAUSED_URI_LIST = "android.telephony.mbms.extra.PAUSED_URI_LIST";
+    field public static final java.lang.String EXTRA_SERVICE_ID = "android.telephony.mbms.extra.SERVICE_ID";
+    field public static final java.lang.String EXTRA_TEMP_FILES_IN_USE = "android.telephony.mbms.extra.TEMP_FILES_IN_USE";
+    field public static final java.lang.String EXTRA_TEMP_FILE_ROOT = "android.telephony.mbms.extra.TEMP_FILE_ROOT";
+    field public static final java.lang.String EXTRA_TEMP_LIST = "android.telephony.mbms.extra.TEMP_LIST";
+  }
+
 }
 
 package android.test {
@@ -50632,7 +50666,7 @@
     method public abstract void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
   }
 
-  public class WebViewFragment extends android.app.Fragment {
+  public deprecated class WebViewFragment extends android.app.Fragment {
     ctor public WebViewFragment();
     method public android.webkit.WebView getWebView();
   }
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 93b9f58..d79b1a6 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -47,6 +47,16 @@
 
 /**
  * Runs the am instrument command
+ *
+ * Test Result Code:
+ * 1 - Test running
+ * 0 - Test passed
+ * -2 - assertion failure
+ * -1 - other exceptions
+ *
+ * Session Result Code:
+ * -1: Success
+ * other: Failure
  */
 public class Instrument {
     public static final String DEFAULT_LOG_DIR = "instrument-logs";
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 4ebca84..5fcb8a1 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -20,7 +20,7 @@
 cc_library_host_shared {
     name: "libstats_proto_host",
     srcs: [
-        "src/stats_events.proto",
+        "src/atoms.proto",
     ],
 
     shared_libs: [
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index a1f5bb1..d860363 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -20,7 +20,7 @@
     ../../core/java/android/os/IStatsManager.aidl \
     src/stats_log.proto \
     src/statsd_config.proto \
-    src/stats_events_copy.proto \
+    src/atoms_copy.proto \
     src/anomaly/AnomalyMonitor.cpp \
     src/condition/CombinationConditionTracker.cpp \
     src/condition/condition_util.cpp \
@@ -33,7 +33,7 @@
     src/external/ResourcePowerManagerPuller.cpp \
     src/external/CpuTimePerUidPuller.cpp \
     src/external/CpuTimePerUidFreqPuller.cpp \
-    src/external/StatsPullerManager.cpp \
+    src/external/StatsPullerManagerImpl.cpp \
     src/logd/LogEvent.cpp \
     src/logd/LogListener.cpp \
     src/logd/LogReader.cpp \
@@ -164,7 +164,8 @@
     tests/metrics/OringDurationTracker_test.cpp \
     tests/metrics/MaxDurationTracker_test.cpp \
     tests/metrics/CountMetricProducer_test.cpp \
-    tests/metrics/EventMetricProducer_test.cpp
+    tests/metrics/EventMetricProducer_test.cpp \
+    tests/metrics/ValueMetricProducer_test.cpp
 
 LOCAL_STATIC_LIBRARIES := \
     libgmock
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 8c70bb5..b764ce5 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -66,7 +66,7 @@
     }
 
     // Hard-coded logic to update the isolated uid's in the uid-map.
-    // The field numbers need to be currently updated by hand with stats_events.proto
+    // The field numbers need to be currently updated by hand with atoms.proto
     if (msg.GetTagId() == android::util::ISOLATED_UID_CHANGED) {
         status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
         bool is_create = msg.GetBool(3, &err);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 11c5de1..07b1c5c 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -18,6 +18,8 @@
 #include "Log.h"
 
 #include "StatsService.h"
+#include "config/ConfigKey.h"
+#include "config/ConfigManager.h"
 #include "storage/DropboxReader.h"
 
 #include <android-base/file.h>
@@ -39,6 +41,8 @@
 namespace os {
 namespace statsd {
 
+constexpr const char* kPermissionDump = "android.permission.DUMP";
+
 // ======================================================================
 /**
  * Watches for the death of the stats companion (system process).
@@ -67,8 +71,8 @@
 {
     mUidMap = new UidMap();
     mConfigManager = new ConfigManager();
-    mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) {
-      pushLog(log);
+    mProcessor = new StatsLogProcessor(mUidMap, [](const vector<uint8_t>& log) {
+        // TODO: Update how we send data out of StatsD.
     });
 
     mConfigManager->AddListener(mProcessor);
@@ -198,6 +202,10 @@
         if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
             return cmd_print_pulled_metrics(out, args);
         }
+
+        if (!args[0].compare(String8("send-broadcast"))) {
+            return cmd_trigger_broadcast(args);
+        }
     }
 
     print_cmd_help(out);
@@ -238,6 +246,19 @@
     fprintf(out, "                the UID parameter on eng builds. If UID is omitted the\n");
     fprintf(out, "                calling uid is used.\n");
     fprintf(out, "  NAME          The name of the configuration\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "usage: adb shell cmd stats send-broadcast PACKAGE CLASS\n");
+    fprintf(out, "  Send a broadcast that triggers one subscriber to fetch metrics.\n");
+    fprintf(out, "  PACKAGE        The name of the package to receive the broadcast.\n");
+    fprintf(out, "  CLASS          The name of the class to receive the broadcast.\n");
+}
+
+status_t StatsService::cmd_trigger_broadcast(Vector<String8>& args) {
+    auto sc = getStatsCompanionService();
+    sc->sendBroadcast(String16(args[1]), String16(args[2]));
+    ALOGD("StatsService::trigger broadcast succeeded");
+    return NO_ERROR;
 }
 
 status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
@@ -520,29 +541,51 @@
     mProcessor->OnLogEvent(event);
 }
 
-Status StatsService::requestPush() {
-    mProcessor->flush();
-    return Status::ok();
+Status StatsService::getData(const String16& key, vector<uint8_t>* output) {
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (checkCallingPermission(String16(kPermissionDump),
+                               reinterpret_cast<int32_t*>(ipc->getCallingPid()),
+                               reinterpret_cast<int32_t*>(ipc->getCallingUid()))) {
+        // TODO: Implement this.
+        return Status::ok();
+    } else {
+        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
+    }
 }
 
-Status StatsService::pushLog(const vector<uint8_t>& log) {
-    std::lock_guard<std::mutex> lock(mLock);
-    for (size_t i = 0; i < mCallbacks.size(); i++) {
-        mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log);
+Status StatsService::addConfiguration(const String16& key,
+                                      const vector <uint8_t>& config,
+                                      const String16& package, const String16& cls,
+                                      bool* success) {
+    IPCThreadState* ipc = IPCThreadState::self();
+    int32_t* uid = reinterpret_cast<int32_t*>(ipc->getCallingUid());
+    if (checkCallingPermission(String16(kPermissionDump),
+                               reinterpret_cast<int32_t*>(ipc->getCallingPid()), uid)) {
+        string keyString = string(String8(key).string());
+        ConfigKey configKey(*uid, keyString);
+        StatsdConfig cfg;
+        cfg.ParseFromArray(&config[0], config.size());
+        mConfigManager->UpdateConfig(configKey, cfg);
+        mConfigManager->SetConfigReceiver(configKey, string(String8(package).string()),
+                                          string(String8(cls).string()));
+        *success = true;
+        return Status::ok();
+    } else {
+        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
     }
-    return Status::ok();
 }
 
-Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) {
-    std::lock_guard<std::mutex> lock(mLock);
-    for (size_t i = 0; i < mCallbacks.size(); i++) {
-        if (mCallbacks[i] == callback) {
-           return Status::fromStatusT(-errno);
-        }
+Status StatsService::removeConfiguration(const String16& key, bool* success) {
+    IPCThreadState* ipc = IPCThreadState::self();
+    if (checkCallingPermission(String16(kPermissionDump),
+                               reinterpret_cast<int32_t*>(ipc->getCallingPid()),
+                               reinterpret_cast<int32_t*>(ipc->getCallingUid()))) {
+        // TODO: Implement this.
+        return Status::ok();
+    } else {
+        *success = false;
+        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
     }
-    mCallbacks.add(callback);
-    IInterface::asBinder(callback)->linkToDeath(this);
-    return Status::ok();
 }
 
 void StatsService::binderDied(const wp<IBinder>& who) {
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 1d7e5a61..fba8af7 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -71,20 +71,22 @@
     virtual void OnLogEvent(const LogEvent& event);
 
     /**
-     * Binder call to force trigger pushLog. This would be called by callback
-     * clients.
+     * Binder call for clients to request data for this configuration key.
      */
-    virtual Status requestPush() override;
+    virtual Status getData(const String16& key, vector<uint8_t>* output) override;
 
     /**
-     * Pushes stats log entries from statsd to callback clients.
+     * Binder call to let clients send a configuration and indicate they're interested when they
+     * should requestData for this configuration.
      */
-    Status pushLog(const vector<uint8_t>& log);
+    virtual Status addConfiguration(const String16& key, const vector <uint8_t>& config,
+                                   const String16& package, const String16& cls, bool* success)
+    override;
 
     /**
-     * Binder call to listen to statsd to send stats log entries.
+     * Binder call to allow clients to remove the specified configuration.
      */
-    virtual Status subscribeStatsLog(const sp<IStatsCallbacks>& callbacks) override;
+    virtual Status removeConfiguration(const String16& key, bool* success) override;
 
     // TODO: public for testing since statsd doesn't run when system starts. Change to private
     // later.
@@ -120,6 +122,11 @@
     void print_cmd_help(FILE* out);
 
     /**
+     * Trigger a broadcast.
+     */
+    status_t cmd_trigger_broadcast(Vector<String8>& args);
+
+    /**
      * Handle the config sub-command.
      */
     status_t cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
@@ -157,7 +164,7 @@
     /**
      * Fetches external metrics.
      */
-    StatsPullerManager& mStatsPullerManager = StatsPullerManager::GetInstance();
+    StatsPullerManager mStatsPullerManager;
 
     /**
      * Tracks the configurations that have been passed to statsd.
diff --git a/cmds/statsd/src/anomaly/DiscreteAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DiscreteAnomalyTracker.cpp
index 9c9bde9..6492177 100644
--- a/cmds/statsd/src/anomaly/DiscreteAnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/DiscreteAnomalyTracker.cpp
@@ -140,14 +140,8 @@
     mLastAlarmAtBucketIndex = mCurrentBucketIndex;
 
     if (mAlert.has_incidentd_details()) {
-        const Alert_IncidentdDetails& incident = mAlert.incidentd_details();
-        if (incident.has_alert_name()) {
-            ALOGW("An anomaly (%s) has occurred! Informing incidentd.",
-                  incident.alert_name().c_str());
-        } else {
-            // TODO: Can construct a name based on the criteria (and/or relay the criteria).
-            ALOGW("An anomaly (nameless) has occurred! Informing incidentd.");
-        }
+        // TODO: Can construct a name based on the criteria (and/or relay the criteria).
+        ALOGW("An anomaly (nameless) has occurred! Informing incidentd.");
         // TODO: Send incidentd_details.name and incidentd_details.incidentd_sections to incidentd
     } else {
         ALOGW("An anomaly has occurred! (But informing incidentd not requested.)");
diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/atoms.proto
similarity index 98%
rename from cmds/statsd/src/stats_events.proto
rename to cmds/statsd/src/atoms.proto
index 9ab07de..48b85c9 100644
--- a/cmds/statsd/src/stats_events.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -19,10 +19,10 @@
 // TODO: Not the right package and class name
 package android.os.statsd;
 option java_package = "com.android.os";
-option java_outer_classname = "StatsEventProto";
+option java_outer_classname = "AtomsProto";
 
 /**
- * The master event class. This message defines all of the available
+ * The master atom class. This message defines all of the available
  * raw stats log events from the Android system, also known as "atoms."
  *
  * This field contains a single oneof with all of the available messages.
@@ -30,12 +30,12 @@
  * generates the android.util.StatsLog class, which contains the constants
  * and methods that Android uses to log.
  *
- * This StatsEvent class is not actually built into the Android system.
+ * This Atom class is not actually built into the Android system.
  * Instead, statsd on Android constructs these messages synthetically,
  * in the format defined here and in stats_log.proto.
  */
-message StatsEvent {
-    // Pushed events start at 2.
+message Atom {
+    // Pushed atoms start at 2.
     oneof pushed {
         // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
         BleScanStateChanged ble_scan_state_changed = 2;
@@ -114,7 +114,7 @@
  *   - The types must be built-in protocol buffer types, namely, no sub-messages
  *     are allowed (yet).  The bytes type is also not allowed.
  *   - The CamelCase name of the message type should match the
- *     underscore_separated name as defined in StatsEvent.
+ *     underscore_separated name as defined in Atom.
  *   - If an atom represents work that can be attributed to an app, there can
  *     be exactly one WorkSource field. It must be field number 1.
  *   - A field that is a uid should be a string field, tagged with the [xxx]
@@ -397,7 +397,7 @@
         FULL = 1;
         WINDOW = 2;
     }
-    optional int32 type = 2;
+    optional Type type = 2;
 
     // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
     optional string tag = 3;
@@ -425,7 +425,7 @@
         FULL = 1;
         WINDOW = 2;
     }
-    optional int32 type = 2;
+    optional Type type = 2;
 
     enum State {
         OFF = 0;
@@ -852,7 +852,6 @@
 }
 
 /**
-<<<<<<< HEAD
  * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky
  * behavior in its own uid. However, the metrics of these isolated uid's almost always should be
  * attributed back to the parent (host) uid. One example is Chrome.
@@ -872,7 +871,6 @@
 }
 
 /*
-<<<<<<< HEAD
  * Pulls Cpu time per frequency.
  * Note: this should be pulled for gauge metric only, without condition.
  * The puller keeps internal state of last values. It should not be pulled by
diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/atoms_copy.proto
similarity index 98%
copy from cmds/statsd/src/stats_events.proto
copy to cmds/statsd/src/atoms_copy.proto
index 9ab07de..598c2bc 100644
--- a/cmds/statsd/src/stats_events.proto
+++ b/cmds/statsd/src/atoms_copy.proto
@@ -15,14 +15,16 @@
  */
 
 syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
 
 // TODO: Not the right package and class name
 package android.os.statsd;
 option java_package = "com.android.os";
-option java_outer_classname = "StatsEventProto";
+option java_outer_classname = "AtomsProto";
 
 /**
- * The master event class. This message defines all of the available
+ * The master atom class. This message defines all of the available
  * raw stats log events from the Android system, also known as "atoms."
  *
  * This field contains a single oneof with all of the available messages.
@@ -30,12 +32,12 @@
  * generates the android.util.StatsLog class, which contains the constants
  * and methods that Android uses to log.
  *
- * This StatsEvent class is not actually built into the Android system.
+ * This Atom class is not actually built into the Android system.
  * Instead, statsd on Android constructs these messages synthetically,
  * in the format defined here and in stats_log.proto.
  */
-message StatsEvent {
-    // Pushed events start at 2.
+message Atom {
+    // Pushed atoms start at 2.
     oneof pushed {
         // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
         BleScanStateChanged ble_scan_state_changed = 2;
@@ -114,7 +116,7 @@
  *   - The types must be built-in protocol buffer types, namely, no sub-messages
  *     are allowed (yet).  The bytes type is also not allowed.
  *   - The CamelCase name of the message type should match the
- *     underscore_separated name as defined in StatsEvent.
+ *     underscore_separated name as defined in Atom.
  *   - If an atom represents work that can be attributed to an app, there can
  *     be exactly one WorkSource field. It must be field number 1.
  *   - A field that is a uid should be a string field, tagged with the [xxx]
@@ -397,7 +399,7 @@
         FULL = 1;
         WINDOW = 2;
     }
-    optional int32 type = 2;
+    optional Type type = 2;
 
     // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
     optional string tag = 3;
@@ -425,7 +427,7 @@
         FULL = 1;
         WINDOW = 2;
     }
-    optional int32 type = 2;
+    optional Type type = 2;
 
     enum State {
         OFF = 0;
@@ -852,7 +854,6 @@
 }
 
 /**
-<<<<<<< HEAD
  * Logs creation or removal of an isolated uid. Isolated uid's are temporary uid's to sandbox risky
  * behavior in its own uid. However, the metrics of these isolated uid's almost always should be
  * attributed back to the parent (host) uid. One example is Chrome.
@@ -872,7 +873,6 @@
 }
 
 /*
-<<<<<<< HEAD
  * Pulls Cpu time per frequency.
  * Note: this should be pulled for gauge metric only, without condition.
  * The puller keeps internal state of last values. It should not be pulled by
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index d86ab57..6e8ed77 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -60,6 +60,14 @@
     }
 }
 
+void ConfigManager::SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls) {
+    mConfigReceivers[key] = pair<string, string>(pkg, cls);
+}
+
+void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
+    mConfigReceivers.erase(key);
+}
+
 void ConfigManager::RemoveConfig(const ConfigKey& key) {
     unordered_map<ConfigKey, StatsdConfig>::iterator it = mConfigs.find(key);
     if (it != mConfigs.end()) {
@@ -85,6 +93,7 @@
         if (it->first.GetUid() == uid) {
             removed.push_back(it->first);
             it = mConfigs.erase(it);
+            mConfigReceivers.erase(it->first);
         } else {
             it++;
         }
@@ -116,7 +125,7 @@
 static StatsdConfig build_fake_config() {
     // HACK: Hard code a test metric for counting screen on events...
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     int WAKE_LOCK_TAG_ID = 1111;  // put a fake id here to make testing easier.
     int WAKE_LOCK_UID_KEY_ID = 1;
@@ -147,33 +156,35 @@
 
     // Count Screen ON events.
     CountMetric* metric = config.add_count_metric();
-    metric->set_metric_id(1);
+    metric->set_name("1");
     metric->set_what("SCREEN_TURNED_ON");
     metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
 
     // Anomaly threshold for screen-on count.
-    Alert* alert = metric->add_alerts();
+    Alert* alert = config.add_alerts();
+    alert->set_name("1");
     alert->set_number_of_buckets(6);
     alert->set_trigger_if_sum_gt(10);
     alert->set_refractory_period_secs(30);
 
     // Count process state changes, slice by uid.
     metric = config.add_count_metric();
-    metric->set_metric_id(2);
+    metric->set_name("2");
     metric->set_what("PROCESS_STATE_CHANGE");
     metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     KeyMatcher* keyMatcher = metric->add_dimension();
     keyMatcher->set_key(UID_PROCESS_STATE_UID_KEY);
 
     // Anomaly threshold for background count.
-    alert = metric->add_alerts();
+    alert = config.add_alerts();
+    alert->set_name("2");
     alert->set_number_of_buckets(4);
     alert->set_trigger_if_sum_gt(30);
     alert->set_refractory_period_secs(20);
 
     // Count process state changes, slice by uid, while SCREEN_IS_OFF
     metric = config.add_count_metric();
-    metric->set_metric_id(3);
+    metric->set_name("3");
     metric->set_what("PROCESS_STATE_CHANGE");
     metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     keyMatcher = metric->add_dimension();
@@ -182,7 +193,7 @@
 
     // Count wake lock, slice by uid, while SCREEN_IS_ON and app in background
     metric = config.add_count_metric();
-    metric->set_metric_id(4);
+    metric->set_name("4");
     metric->set_what("APP_GET_WL");
     metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     keyMatcher = metric->add_dimension();
@@ -195,7 +206,7 @@
 
     // Duration of an app holding any wl, while screen on and app in background, slice by uid
     DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_metric_id(5);
+    durationMetric->set_name("5");
     durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     durationMetric->set_type(DurationMetric_AggregationType_DURATION_SUM);
     keyMatcher = durationMetric->add_dimension();
@@ -209,7 +220,7 @@
 
     // max Duration of an app holding any wl, while screen on and app in background, slice by uid
     durationMetric = config.add_duration_metric();
-    durationMetric->set_metric_id(6);
+    durationMetric->set_name("6");
     durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     durationMetric->set_type(DurationMetric_AggregationType_DURATION_MAX_SPARSE);
     keyMatcher = durationMetric->add_dimension();
@@ -223,7 +234,7 @@
 
     // Duration of an app holding any wl, while screen on and app in background
     durationMetric = config.add_duration_metric();
-    durationMetric->set_metric_id(7);
+    durationMetric->set_name("7");
     durationMetric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     durationMetric->set_type(DurationMetric_AggregationType_DURATION_MAX_SPARSE);
     durationMetric->set_what("WL_HELD_PER_APP_PER_NAME");
@@ -235,14 +246,14 @@
 
     // Duration of screen on time.
     durationMetric = config.add_duration_metric();
-    durationMetric->set_metric_id(8);
+    durationMetric->set_name("8");
     durationMetric->mutable_bucket()->set_bucket_size_millis(10 * 1000L);
     durationMetric->set_type(DurationMetric_AggregationType_DURATION_SUM);
     durationMetric->set_what("SCREEN_IS_ON");
 
     // Value metric to count KERNEL_WAKELOCK when screen turned on
     ValueMetric* valueMetric = config.add_value_metric();
-    valueMetric->set_metric_id(6);
+    valueMetric->set_name("6");
     valueMetric->set_what("KERNEL_WAKELOCK");
     valueMetric->set_value_field(1);
     valueMetric->set_condition("SCREEN_IS_ON");
@@ -253,12 +264,12 @@
 
     // Add an EventMetric to log process state change events.
     EventMetric* eventMetric = config.add_event_metric();
-    eventMetric->set_metric_id(9);
+    eventMetric->set_name("9");
     eventMetric->set_what("SCREEN_TURNED_ON");
 
     // Add an GaugeMetric.
     GaugeMetric* gaugeMetric = config.add_gauge_metric();
-    gaugeMetric->set_metric_id(10);
+    gaugeMetric->set_name("10");
     gaugeMetric->set_what("DEVICE_TEMPERATURE");
     gaugeMetric->set_gauge_field(DEVICE_TEMPERATURE_KEY);
     gaugeMetric->mutable_bucket()->set_bucket_size_millis(60 * 1000L);
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 5d73eaf..c21247f9 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -32,6 +32,7 @@
 using std::string;
 using std::unordered_map;
 using std::vector;
+using std::pair;
 
 /**
  * Keeps track of which configurations have been set from various sources.
@@ -64,6 +65,16 @@
     void UpdateConfig(const ConfigKey& key, const StatsdConfig& data);
 
     /**
+     * Sets the broadcast receiver for a configuration key.
+     */
+    void SetConfigReceiver(const ConfigKey& key, const string& pkg, const string& cls);
+
+    /**
+     * Erase any broadcast receiver associated with this config key.
+     */
+    void RemoveConfigReceiver(const ConfigKey& key);
+
+    /**
      * A configuration was removed.
      *
      * Reports this to listeners.
@@ -87,11 +98,17 @@
     void update_saved_configs();
 
     /**
-     * The Configs that have been set
+     * The Configs that have been set. Each config should
      */
     unordered_map<ConfigKey, StatsdConfig> mConfigs;
 
     /**
+     * Each config key can be subscribed by up to one receiver, specified as the package name and
+     * class name.
+     */
+    unordered_map<ConfigKey, pair<string, string>> mConfigReceivers;
+
+    /**
      * The ConfigListeners that will be told about changes.
      */
     vector<sp<ConfigListener>> mListeners;
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 67580d6..2e803c9 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -16,71 +16,39 @@
 
 #pragma once
 
-#include <android/os/IStatsCompanionService.h>
-#include <binder/IServiceManager.h>
-#include <utils/RefBase.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include <string>
-#include <unordered_map>
-#include <vector>
-#include "PullDataReceiver.h"
-#include "StatsPuller.h"
-#include "logd/LogEvent.h"
+#include "StatsPullerManagerImpl.h"
 
 namespace android {
 namespace os {
 namespace statsd {
 
-class StatsPullerManager : public virtual RefBase {
-public:
-    static StatsPullerManager& GetInstance();
+class StatsPullerManager{
+ public:
+  virtual ~StatsPullerManager() {}
 
-    void RegisterReceiver(int tagId, sp<PullDataReceiver> receiver, long intervalMs);
+  virtual void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, long intervalMs) {
+    mPullerManager.RegisterReceiver(tagId, receiver, intervalMs);
+  };
 
-    void UnRegisterReceiver(int tagId, sp<PullDataReceiver> receiver);
+  virtual void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) {
+    mPullerManager.UnRegisterReceiver(tagId, receiver);
+  };
 
-    // Verify if we know how to pull for this matcher
-    bool PullerForMatcherExists(int tagId);
+  // Verify if we know how to pull for this matcher
+  bool PullerForMatcherExists(int tagId) {
+    return mPullerManager.PullerForMatcherExists(tagId);
+  }
 
-    void OnAlarmFired();
+  void OnAlarmFired() {
+    mPullerManager.OnAlarmFired();
+  }
 
-    bool Pull(const int pullCode, vector<std::shared_ptr<LogEvent>>* data);
+  virtual bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+    return mPullerManager.Pull(tagId, data);
+  }
 
-private:
-    StatsPullerManager();
-
-    // use this to update alarm
-    sp<IStatsCompanionService> mStatsCompanionService = nullptr;
-
-    sp<IStatsCompanionService> get_stats_companion_service();
-
-    // mapping from simple matcher tagId to puller
-    std::map<int, std::shared_ptr<StatsPuller>> mPullers;
-
-      typedef struct {
-        // pull_interval_sec : last_pull_time_sec
-        std::pair<uint64_t, uint64_t> timeInfo;
-        sp<PullDataReceiver> receiver;
-      } ReceiverInfo;
-
-    // mapping from simple matcher tagId to receivers
-    std::map<int, std::vector<ReceiverInfo>> mReceivers;
-
-    Mutex mReceiversLock;
-
-    long mCurrentPullingInterval;
-
-    // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest
-    // bucket size. All pulled metrics start pulling based on this time, so that they can be
-    // correctly attributed to the correct buckets. Pulled data attach a timestamp which is the
-    // request time.
-    const long mPullStartTimeMs;
-
-    long get_pull_start_time_ms();
-
-    LogEvent parse_pulled_data(String16 data);
+ private:
+  StatsPullerManagerImpl& mPullerManager = StatsPullerManagerImpl::GetInstance();
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
similarity index 82%
rename from cmds/statsd/src/external/StatsPullerManager.cpp
rename to cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index 5a05b45..07d0b3e 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -25,7 +25,7 @@
 #include "CpuTimePerUidPuller.h"
 #include "ResourcePowerManagerPuller.h"
 #include "StatsCompanionServicePuller.h"
-#include "StatsPullerManager.h"
+#include "StatsPullerManagerImpl.h"
 #include "StatsService.h"
 #include "logd/LogEvent.h"
 #include "statslog.h"
@@ -37,12 +37,13 @@
 using std::shared_ptr;
 using std::string;
 using std::vector;
+using std::list;
 
 namespace android {
 namespace os {
 namespace statsd {
 
-StatsPullerManager::StatsPullerManager()
+StatsPullerManagerImpl::StatsPullerManagerImpl()
     : mCurrentPullingInterval(LONG_MAX), mPullStartTimeMs(get_pull_start_time_ms()) {
     shared_ptr<StatsPuller> statsCompanionServicePuller = make_shared<StatsCompanionServicePuller>();
     shared_ptr<StatsPuller> resourcePowerManagerPuller = make_shared<ResourcePowerManagerPuller>();
@@ -71,7 +72,7 @@
     mStatsCompanionService = StatsService::getStatsCompanionService();
 }
 
-bool StatsPullerManager::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
+bool StatsPullerManagerImpl::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
     if (DEBUG) ALOGD("Initiating pulling %d", tagId);
 
     if (mPullers.find(tagId) != mPullers.end()) {
@@ -82,26 +83,26 @@
     }
 }
 
-StatsPullerManager& StatsPullerManager::GetInstance() {
-    static StatsPullerManager instance;
+StatsPullerManagerImpl& StatsPullerManagerImpl::GetInstance() {
+    static StatsPullerManagerImpl instance;
     return instance;
 }
 
-bool StatsPullerManager::PullerForMatcherExists(int tagId) {
+bool StatsPullerManagerImpl::PullerForMatcherExists(int tagId) {
     return mPullers.find(tagId) != mPullers.end();
 }
 
-long StatsPullerManager::get_pull_start_time_ms() {
+long StatsPullerManagerImpl::get_pull_start_time_ms() {
     // TODO: limit and align pull intervals to 10min boundaries if this turns out to be a problem
     return time(nullptr) * 1000;
 }
 
-void StatsPullerManager::RegisterReceiver(int tagId, sp<PullDataReceiver> receiver,
-                                          long intervalMs) {
+void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp<PullDataReceiver> receiver,
+                                              long intervalMs) {
     AutoMutex _l(mReceiversLock);
-    vector<ReceiverInfo>& receivers = mReceivers[tagId];
+    auto& receivers = mReceivers[tagId];
     for (auto it = receivers.begin(); it != receivers.end(); it++) {
-        if (it->receiver.get() == receiver.get()) {
+        if (it->receiver == receiver) {
             VLOG("Receiver already registered of %d", (int)receivers.size());
             return;
         }
@@ -124,7 +125,7 @@
     VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
 }
 
-void StatsPullerManager::UnRegisterReceiver(int tagId, sp<PullDataReceiver> receiver) {
+void StatsPullerManagerImpl::UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) {
     AutoMutex _l(mReceiversLock);
     if (mReceivers.find(tagId) == mReceivers.end()) {
         VLOG("Unknown pull code or no receivers: %d", tagId);
@@ -132,7 +133,7 @@
     }
     auto& receivers = mReceivers.find(tagId)->second;
     for (auto it = receivers.begin(); it != receivers.end(); it++) {
-        if (receiver.get() == it->receiver.get()) {
+        if (receiver == it->receiver) {
             receivers.erase(it);
             VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
             return;
@@ -140,7 +141,7 @@
     }
 }
 
-void StatsPullerManager::OnAlarmFired() {
+void StatsPullerManagerImpl::OnAlarmFired() {
     AutoMutex _l(mReceiversLock);
 
     uint64_t currentTimeMs = time(nullptr) * 1000;
@@ -165,8 +166,13 @@
         vector<shared_ptr<LogEvent>> data;
         if (Pull(pullInfo.first, &data)) {
             for (const auto& receiverInfo : pullInfo.second) {
-                receiverInfo->receiver->onDataPulled(data);
-                receiverInfo->timeInfo.second = currentTimeMs;
+                sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
+                if (receiverPtr != nullptr) {
+                    receiverPtr->onDataPulled(data);
+                    receiverInfo->timeInfo.second = currentTimeMs;
+                } else {
+                    VLOG("receiver already gone.");
+                }
             }
         }
     }
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.h b/cmds/statsd/src/external/StatsPullerManagerImpl.h
new file mode 100644
index 0000000..0b9f21e
--- /dev/null
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/os/IStatsCompanionService.h>
+#include <binder/IServiceManager.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <list>
+#include "PullDataReceiver.h"
+#include "StatsPuller.h"
+#include "logd/LogEvent.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class StatsPullerManagerImpl : public virtual RefBase {
+public:
+    static StatsPullerManagerImpl& GetInstance();
+
+    void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, long intervalMs);
+
+    void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver);
+
+    // Verify if we know how to pull for this matcher
+    bool PullerForMatcherExists(int tagId);
+
+    void OnAlarmFired();
+
+    bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data);
+
+private:
+    StatsPullerManagerImpl();
+
+    // use this to update alarm
+    sp<IStatsCompanionService> mStatsCompanionService = nullptr;
+
+    sp<IStatsCompanionService> get_stats_companion_service();
+
+    // mapping from simple matcher tagId to puller
+    std::map<int, std::shared_ptr<StatsPuller>> mPullers;
+
+    typedef struct {
+        // pull_interval_sec : last_pull_time_sec
+        std::pair<uint64_t, uint64_t> timeInfo;
+        wp<PullDataReceiver> receiver;
+    } ReceiverInfo;
+
+    // mapping from simple matcher tagId to receivers
+    std::map<int, std::list<ReceiverInfo>> mReceivers;
+
+    Mutex mReceiversLock;
+
+    long mCurrentPullingInterval;
+
+    // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest
+    // bucket size. All pulled metrics start pulling based on this time, so that they can be
+    // correctly attributed to the correct buckets. Pulled data attach a timestamp which is the
+    // request time.
+    const long mPullStartTimeMs;
+
+    long get_pull_start_time_ms();
+
+    LogEvent parse_pulled_data(String16 data);
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 2252201..f9da68e 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -30,6 +30,7 @@
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
 using android::util::FIELD_TYPE_MESSAGE;
+using android::util::FIELD_TYPE_STRING;
 using android::util::ProtoOutputStream;
 using std::map;
 using std::string;
@@ -41,7 +42,7 @@
 namespace statsd {
 
 // for StatsLogReport
-const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_NAME = 1;
 const int FIELD_ID_START_REPORT_NANOS = 2;
 const int FIELD_ID_END_REPORT_NANOS = 3;
 const int FIELD_ID_COUNT_METRICS = 5;
@@ -74,17 +75,6 @@
         mBucketSizeNs = LLONG_MAX;
     }
 
-    mAnomalyTrackers.reserve(metric.alerts_size());
-    for (int i = 0; i < metric.alerts_size(); i++) {
-        const Alert& alert = metric.alerts(i);
-        if (alert.trigger_if_sum_gt() > 0 && alert.number_of_buckets() > 0) {
-            mAnomalyTrackers.push_back(std::make_unique<DiscreteAnomalyTracker>(alert));
-        } else {
-            ALOGW("Ignoring invalid count metric alert: threshold=%lld num_buckets= %d",
-                  alert.trigger_if_sum_gt(), alert.number_of_buckets());
-        }
-    }
-
     // TODO: use UidMap if uid->pkg_name is required
     mDimension.insert(mDimension.begin(), metric.dimension().begin(), metric.dimension().end());
 
@@ -96,7 +86,7 @@
 
     startNewProtoOutputStream(mStartTimeNs);
 
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
+    VLOG("metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
 
@@ -106,7 +96,7 @@
 
 void CountMetricProducer::startNewProtoOutputStream(long long startTime) {
     mProto = std::make_unique<ProtoOutputStream>();
-    mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
+    mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name());
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
     mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_COUNT_METRICS);
 }
@@ -115,7 +105,7 @@
 }
 
 void CountMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id());
+    VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str());
 }
 
 std::unique_ptr<std::vector<uint8_t>> CountMetricProducer::onDumpReport() {
@@ -125,7 +115,7 @@
     // If current bucket is still on-going, don't force dump current bucket.
     // In finish(), We can force dump current bucket.
     flushCounterIfNeeded(endTime);
-    VLOG("metric %lld dump report now...", mMetric.metric_id());
+    VLOG("metric %s dump report now...", mMetric.name().c_str());
 
     for (const auto& counter : mPastBuckets) {
         const HashableDimensionKey& hashableKey = counter.first;
@@ -175,7 +165,7 @@
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS,
                   (long long)mCurrentBucketStartTimeNs);
 
-    VLOG("metric %lld dump report now...", mMetric.metric_id());
+    VLOG("metric %s dump report now...", mMetric.name().c_str());
     std::unique_ptr<std::vector<uint8_t>> buffer = serializeProto();
 
     startNewProtoOutputStream(endTime);
@@ -188,7 +178,7 @@
 }
 
 void CountMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", mMetric.metric_id());
+    VLOG("Metric %s onConditionChanged", mMetric.name().c_str());
     mCondition = conditionMet;
 }
 
@@ -215,7 +205,7 @@
         count++;
     }
 
-    VLOG("metric %lld %s->%d", mMetric.metric_id(), eventKey.c_str(),
+    VLOG("metric %s %s->%d", mMetric.name().c_str(), eventKey.c_str(),
          (*mCurrentSlicedCounter)[eventKey]);
 }
 
@@ -237,7 +227,7 @@
         info.mCount = counter.second;
         auto& bucketList = mPastBuckets[counter.first];
         bucketList.push_back(info);
-        VLOG("metric %lld, dump key value: %s -> %d", mMetric.metric_id(), counter.first.c_str(),
+        VLOG("metric %s, dump key value: %s -> %d", mMetric.name().c_str(), counter.first.c_str(),
              counter.second);
         mByteSize += sizeof(info);
     }
@@ -252,7 +242,7 @@
 
     mCurrentBucketStartTimeNs = mCurrentBucketStartTimeNs + numBucketsForward * mBucketSizeNs;
     mCurrentBucketNum += numBucketsForward;
-    VLOG("metric %lld: new bucket start time: %lld", mMetric.metric_id(),
+    VLOG("metric %s: new bucket start time: %lld", mMetric.name().c_str(),
          (long long)mCurrentBucketStartTimeNs);
 }
 
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 74ce9cd..aaf3ec2 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -29,6 +29,7 @@
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
 using android::util::FIELD_TYPE_MESSAGE;
+using android::util::FIELD_TYPE_STRING;
 using android::util::ProtoOutputStream;
 using std::string;
 using std::unordered_map;
@@ -39,7 +40,7 @@
 namespace statsd {
 
 // for StatsLogReport
-const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_NAME = 1;
 const int FIELD_ID_START_REPORT_NANOS = 2;
 const int FIELD_ID_END_REPORT_NANOS = 3;
 const int FIELD_ID_DURATION_METRICS = 6;
@@ -91,7 +92,7 @@
 
     startNewProtoOutputStream(mStartTimeNs);
 
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
+    VLOG("metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
 
@@ -101,7 +102,7 @@
 
 void DurationMetricProducer::startNewProtoOutputStream(long long startTime) {
     mProto = std::make_unique<ProtoOutputStream>();
-    mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
+    mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name());
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
     mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
 }
@@ -126,7 +127,7 @@
 }
 
 void DurationMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id());
+    VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str());
     // Now for each of the on-going event, check if the condition has changed for them.
     flushIfNeeded(eventTime);
     for (auto& pair : mCurrentSlicedDuration) {
@@ -135,7 +136,7 @@
 }
 
 void DurationMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", mMetric.metric_id());
+    VLOG("Metric %s onConditionChanged", mMetric.name().c_str());
     mCondition = conditionMet;
     // TODO: need to populate the condition change time from the event which triggers the condition
     // change, instead of using current time.
@@ -167,7 +168,7 @@
     // If current bucket is still on-going, don't force dump current bucket.
     // In finish(), We can force dump current bucket.
     flushIfNeeded(endTime);
-    VLOG("metric %lld dump report now...", mMetric.metric_id());
+    VLOG("metric %s dump report now...", mMetric.name().c_str());
 
     for (const auto& pair : mPastBuckets) {
         const HashableDimensionKey& hashableKey = pair.first;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index a65092f..74ba40b 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -28,6 +28,7 @@
 using android::util::FIELD_TYPE_FLOAT;
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
+using android::util::FIELD_TYPE_STRING;
 using android::util::FIELD_TYPE_MESSAGE;
 using android::util::ProtoOutputStream;
 using std::map;
@@ -40,7 +41,7 @@
 namespace statsd {
 
 // for StatsLogReport
-const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_NAME = 1;
 const int FIELD_ID_START_REPORT_NANOS = 2;
 const int FIELD_ID_END_REPORT_NANOS = 3;
 const int FIELD_ID_EVENT_METRICS = 4;
@@ -48,7 +49,7 @@
 const int FIELD_ID_DATA = 1;
 // for EventMetricData
 const int FIELD_ID_TIMESTAMP_NANOS = 1;
-const int FIELD_ID_STATS_EVENTS = 2;
+const int FIELD_ID_ATOMS = 2;
 
 EventMetricProducer::EventMetricProducer(const EventMetric& metric, const int conditionIndex,
                                          const sp<ConditionWizard>& wizard,
@@ -62,7 +63,7 @@
 
     startNewProtoOutputStream(mStartTimeNs);
 
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
+    VLOG("metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
 
@@ -74,7 +75,7 @@
     mProto = std::make_unique<ProtoOutputStream>();
     // TODO: We need to auto-generate the field IDs for StatsLogReport, EventMetricData,
     // and StatsEvent.
-    mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
+    mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name());
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
     mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS);
 }
@@ -91,7 +92,7 @@
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS, endTime);
 
     size_t bufferSize = mProto->size();
-    VLOG("metric %lld dump report now... proto size: %zu ", mMetric.metric_id(), bufferSize);
+    VLOG("metric %s dump report now... proto size: %zu ", mMetric.name().c_str(), bufferSize);
     std::unique_ptr<std::vector<uint8_t>> buffer = serializeProto();
 
     startNewProtoOutputStream(endTime);
@@ -101,7 +102,7 @@
 }
 
 void EventMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) {
-    VLOG("Metric %lld onConditionChanged", mMetric.metric_id());
+    VLOG("Metric %s onConditionChanged", mMetric.name().c_str());
     mCondition = conditionMet;
 }
 
@@ -116,7 +117,7 @@
     long long wrapperToken =
             mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_TIMESTAMP_NANOS, (long long)event.GetTimestampNs());
-    long long eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_STATS_EVENTS);
+    long long eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
     event.ToProto(*mProto);
     mProto->end(eventToken);
     mProto->end(wrapperToken);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index fafeee4..ed18f89 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -30,6 +30,7 @@
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
 using android::util::FIELD_TYPE_MESSAGE;
+using android::util::FIELD_TYPE_STRING;
 using android::util::ProtoOutputStream;
 using std::map;
 using std::string;
@@ -41,7 +42,7 @@
 namespace statsd {
 
 // for StatsLogReport
-const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_NAME = 1;
 const int FIELD_ID_START_REPORT_NANOS = 2;
 const int FIELD_ID_END_REPORT_NANOS = 3;
 const int FIELD_ID_GAUGE_METRICS = 8;
@@ -89,7 +90,7 @@
 
     startNewProtoOutputStream(mStartTimeNs);
 
-    VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
+    VLOG("metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
 
@@ -99,7 +100,7 @@
 
 void GaugeMetricProducer::startNewProtoOutputStream(long long startTime) {
     mProto = std::make_unique<ProtoOutputStream>();
-    mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
+    mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name());
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
     mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_GAUGE_METRICS);
 }
@@ -108,7 +109,7 @@
 }
 
 std::unique_ptr<std::vector<uint8_t>> GaugeMetricProducer::onDumpReport() {
-    VLOG("gauge metric %lld dump report now...", mMetric.metric_id());
+    VLOG("gauge metric %s dump report now...", mMetric.name().c_str());
 
     // Dump current bucket if it's stale.
     // If current bucket is still on-going, don't force dump current bucket.
@@ -176,7 +177,7 @@
 
 void GaugeMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) {
     AutoMutex _l(mLock);
-    VLOG("Metric %lld onConditionChanged", mMetric.metric_id());
+    VLOG("Metric %s onConditionChanged", mMetric.name().c_str());
     mCondition = conditionMet;
 
     // Push mode. Nothing to do.
@@ -200,7 +201,7 @@
 }
 
 void GaugeMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id());
+    VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str());
 }
 
 long GaugeMetricProducer::getGauge(const LogEvent& event) {
@@ -277,14 +278,14 @@
         bucketList.push_back(info);
         mByteSize += sizeof(info);
 
-        VLOG("gauge metric %lld, dump key value: %s -> %ld", mMetric.metric_id(),
+        VLOG("gauge metric %s, dump key value: %s -> %ld", mMetric.name().c_str(),
              slice.first.c_str(), slice.second);
     }
     // Reset counters
     mCurrentSlicedBucket.clear();
 
     mCurrentBucketStartTimeNs = mCurrentBucketStartTimeNs + numBucketsForward * mBucketSizeNs;
-    VLOG("metric %lld: new bucket start time: %lld", mMetric.metric_id(),
+    VLOG("metric %s: new bucket start time: %lld", mMetric.name().c_str(),
          (long long)mCurrentBucketStartTimeNs);
 }
 
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index d80672d..f9e4deb 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -81,7 +81,7 @@
     static const uint64_t kDefaultGaugemBucketSizeNs = 1000 * 1000 * 1000;
     const GaugeMetric mMetric;
 
-    StatsPullerManager& mStatsPullerManager = StatsPullerManager::GetInstance();
+    StatsPullerManager mStatsPullerManager;
     // tagId for pulled data. -1 if this is not pulled
     const int mPullTagId;
 
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 5bd10fa..a35070b 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -29,8 +29,10 @@
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
 using android::util::FIELD_TYPE_MESSAGE;
+using android::util::FIELD_TYPE_STRING;
 using android::util::ProtoOutputStream;
 using std::list;
+using std::make_pair;
 using std::make_shared;
 using std::map;
 using std::shared_ptr;
@@ -42,7 +44,7 @@
 namespace statsd {
 
 // for StatsLogReport
-const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_NAME = 1;
 const int FIELD_ID_START_REPORT_NANOS = 2;
 const int FIELD_ID_END_REPORT_NANOS = 3;
 const int FIELD_ID_VALUE_METRICS = 7;
@@ -62,13 +64,23 @@
 const int FIELD_ID_END_BUCKET_NANOS = 2;
 const int FIELD_ID_VALUE = 3;
 
+static const uint64_t kDefaultBucketSizeMillis = 60 * 60 * 1000L;
+
 // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
 ValueMetricProducer::ValueMetricProducer(const ValueMetric& metric, const int conditionIndex,
                                          const sp<ConditionWizard>& wizard, const int pullTagId,
-                                         const uint64_t startTimeNs)
-    : MetricProducer(startTimeNs, conditionIndex, wizard), mMetric(metric), mPullTagId(pullTagId) {
+                                         const uint64_t startTimeNs,
+                                         shared_ptr<StatsPullerManager> statsPullerManager)
+    : MetricProducer(startTimeNs, conditionIndex, wizard),
+      mMetric(metric),
+      mStatsPullerManager(statsPullerManager),
+      mPullTagId(pullTagId) {
     // TODO: valuemetric for pushed events may need unlimited bucket length
-    mBucketSizeNs = mMetric.bucket().bucket_size_millis() * 1000 * 1000;
+    if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
+        mBucketSizeNs = mMetric.bucket().bucket_size_millis() * 1000 * 1000;
+    } else {
+        mBucketSizeNs = kDefaultBucketSizeMillis * 1000 * 1000;
+    }
 
     mDimension.insert(mDimension.begin(), metric.dimension().begin(), metric.dimension().end());
 
@@ -79,23 +91,35 @@
     }
 
     if (!metric.has_condition() && mPullTagId != -1) {
-        mStatsPullerManager.RegisterReceiver(mPullTagId, this,
-                                             metric.bucket().bucket_size_millis());
+        VLOG("Setting up periodic pulling for %d", mPullTagId);
+        mStatsPullerManager->RegisterReceiver(mPullTagId, this,
+                                              metric.bucket().bucket_size_millis());
     }
 
     startNewProtoOutputStream(mStartTimeNs);
 
-    VLOG("value metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
+    VLOG("value metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(),
          (long long)mBucketSizeNs, (long long)mStartTimeNs);
 }
 
+// for testing
+ValueMetricProducer::ValueMetricProducer(const ValueMetric& metric, const int conditionIndex,
+                                         const sp<ConditionWizard>& wizard, const int pullTagId,
+                                         const uint64_t startTimeNs)
+    : ValueMetricProducer(metric, conditionIndex, wizard, pullTagId, startTimeNs,
+                          make_shared<StatsPullerManager>()) {
+}
+
 ValueMetricProducer::~ValueMetricProducer() {
     VLOG("~ValueMetricProducer() called");
+    if (mPullTagId != -1) {
+        mStatsPullerManager->UnRegisterReceiver(mPullTagId, this);
+    }
 }
 
 void ValueMetricProducer::startNewProtoOutputStream(long long startTime) {
     mProto = std::make_unique<ProtoOutputStream>();
-    mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
+    mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name());
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
     mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_VALUE_METRICS);
 }
@@ -106,11 +130,11 @@
 }
 
 void ValueMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id());
+    VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str());
 }
 
 std::unique_ptr<std::vector<uint8_t>> ValueMetricProducer::onDumpReport() {
-    VLOG("metric %lld dump report now...", mMetric.metric_id());
+    VLOG("metric %s dump report now...", mMetric.name().c_str());
 
     for (const auto& pair : mPastBuckets) {
         const HashableDimensionKey& hashableKey = pair.first;
@@ -159,7 +183,7 @@
     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS,
                   (long long)mCurrentBucketStartTimeNs);
 
-    VLOG("metric %lld dump report now...", mMetric.metric_id());
+    VLOG("metric %s dump report now...", mMetric.name().c_str());
     std::unique_ptr<std::vector<uint8_t>> buffer = serializeProto();
 
     startNewProtoOutputStream(time(nullptr) * NS_PER_SEC);
@@ -177,14 +201,14 @@
 
     if (mPullTagId != -1) {
         if (mCondition == true) {
-            mStatsPullerManager.RegisterReceiver(mPullTagId, this,
-                                                 mMetric.bucket().bucket_size_millis());
-        } else if (mCondition == ConditionState::kFalse) {
-            mStatsPullerManager.UnRegisterReceiver(mPullTagId, this);
+            mStatsPullerManager->RegisterReceiver(mPullTagId, this,
+                                                  mMetric.bucket().bucket_size_millis());
+        } else if (mCondition == false) {
+            mStatsPullerManager->UnRegisterReceiver(mPullTagId, this);
         }
 
         vector<shared_ptr<LogEvent>> allData;
-        if (mStatsPullerManager.Pull(mPullTagId, &allData)) {
+        if (mStatsPullerManager->Pull(mPullTagId, &allData)) {
             if (allData.size() == 0) {
                 return;
             }
@@ -199,11 +223,15 @@
 
 void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
     AutoMutex _l(mLock);
-    if (mCondition == ConditionState::kTrue || !mMetric.has_condition()) {
+    if (mCondition == true || !mMetric.has_condition()) {
         if (allData.size() == 0) {
             return;
         }
         uint64_t eventTime = allData.at(0)->GetTimestampNs();
+        // alarm is not accurate and might drift.
+        if (eventTime > mCurrentBucketStartTimeNs + mBucketSizeNs * 3 / 2) {
+            flush_if_needed(eventTime);
+        }
         for (const auto& data : allData) {
             onMatchedLogEvent(0, *data, true);
         }
@@ -226,24 +254,36 @@
 
     long value = get_value(event);
 
-    if (scheduledPull) {
-        if (interval.raw.size() > 0) {
-            interval.raw.back().second = value;
-        } else {
-            interval.raw.push_back(std::make_pair(value, value));
-        }
-        mNextSlicedBucket[eventKey].raw[0].first = value;
-    } else {
-        if (mCondition == ConditionState::kTrue) {
-            interval.raw.push_back(std::make_pair(value, 0));
-        } else {
-            if (interval.raw.size() != 0) {
+    if (mPullTagId != -1) {
+        if (scheduledPull) {
+            // scheduled pull always sets beginning of current bucket and end
+            // of next bucket
+            if (interval.raw.size() > 0) {
                 interval.raw.back().second = value;
+            } else {
+                interval.raw.push_back(make_pair(value, value));
+            }
+            Interval& nextInterval = mNextSlicedBucket[eventKey];
+            if (nextInterval.raw.size() == 0) {
+                nextInterval.raw.push_back(make_pair(value, 0));
+            } else {
+                nextInterval.raw.front().first = value;
+            }
+        } else {
+            if (mCondition == true) {
+                interval.raw.push_back(make_pair(value, 0));
+            } else {
+                if (interval.raw.size() != 0) {
+                    interval.raw.back().second = value;
+                } else {
+                    interval.tainted = true;
+                    VLOG("Data on condition true missing!");
+                }
             }
         }
-    }
-    if (mPullTagId == -1) {
+    } else {
         flush_if_needed(eventTimeNs);
+        interval.raw.push_back(make_pair(value, 0));
     }
 }
 
@@ -253,7 +293,7 @@
     if (err == NO_ERROR) {
         return val;
     } else {
-        VLOG("Can't find value in message.");
+        VLOG("Can't find value in message. %s", event.ToString().c_str());
         return 0;
     }
 }
@@ -271,13 +311,21 @@
     info.mBucketStartNs = mCurrentBucketStartTimeNs;
     info.mBucketEndNs = mCurrentBucketStartTimeNs + mBucketSizeNs;
 
+    int tainted = 0;
     for (const auto& slice : mCurrentSlicedBucket) {
         long value = 0;
-        for (const auto& pair : slice.second.raw) {
-            value += pair.second - pair.first;
+        if (mPullTagId != -1) {
+            for (const auto& pair : slice.second.raw) {
+                value += (pair.second - pair.first);
+            }
+        } else {
+            for (const auto& pair : slice.second.raw) {
+                value += pair.first;
+            }
         }
+        tainted += slice.second.tainted;
         info.mValue = value;
-        VLOG(" %s, %ld", slice.first.c_str(), value);
+        VLOG(" %s, %ld, %d", slice.first.c_str(), value, tainted);
         // it will auto create new vector of ValuebucketInfo if the key is not found.
         auto& bucketList = mPastBuckets[slice.first];
         bucketList.push_back(info);
@@ -292,7 +340,7 @@
         VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
     }
     mCurrentBucketStartTimeNs = mCurrentBucketStartTimeNs + numBucketsForward * mBucketSizeNs;
-    VLOG("metric %lld: new bucket start time: %lld", mMetric.metric_id(),
+    VLOG("metric %s: new bucket start time: %lld", mMetric.name().c_str(),
          (long long)mCurrentBucketStartTimeNs);
 }
 
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index ef9868b..c6c87f5 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <gtest/gtest_prod.h>
 #include <utils/threads.h>
 #include <list>
 #include "../condition/ConditionTracker.h"
@@ -71,7 +72,13 @@
 private:
     const ValueMetric mMetric;
 
-    StatsPullerManager& mStatsPullerManager = StatsPullerManager::GetInstance();
+    std::shared_ptr<StatsPullerManager> mStatsPullerManager;
+
+    // for testing
+    ValueMetricProducer(const ValueMetric& valueMetric, const int conditionIndex,
+                        const sp<ConditionWizard>& wizard, const int pullTagId,
+                        const uint64_t startTimeNs,
+                        std::shared_ptr<StatsPullerManager> statsPullerManager);
 
     Mutex mLock;
 
@@ -81,6 +88,7 @@
     // internal state of a bucket.
     typedef struct {
         std::vector<std::pair<long, long>> raw;
+        bool tainted;
     } Interval;
 
     std::unordered_map<HashableDimensionKey, Interval> mCurrentSlicedBucket;
@@ -97,6 +105,10 @@
     void flush_if_needed(const uint64_t eventTimeNs);
 
     size_t mByteSize;
+
+    FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents);
+    FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
+    FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index a4d3098..43c21a8 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -173,7 +173,6 @@
 }
 
 void MaxDurationTracker::onSlicedConditionMayChange(const uint64_t timestamp) {
-    //  VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id());
     // Now for each of the on-going event, check if the condition has changed for them.
     for (auto& pair : mInfos) {
         if (pair.second.state == kStopped) {
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index ca9cdfb..c2044d8 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -195,7 +195,7 @@
     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
                                 config.event_metric_size() + config.value_metric_size();
     allMetricProducers.reserve(allMetricsCount);
-    StatsPullerManager& statsPullerManager = StatsPullerManager::GetInstance();
+    StatsPullerManager statsPullerManager;
     uint64_t startTimeNs = time(nullptr) * NS_PER_SEC;
 
     // Build MetricProducers for each metric defined in config.
@@ -203,7 +203,7 @@
     for (int i = 0; i < config.count_metric_size(); i++) {
         const CountMetric& metric = config.count_metric(i);
         if (!metric.has_what()) {
-            ALOGW("cannot find what in CountMetric %lld", metric.metric_id());
+            ALOGW("cannot find what in CountMetric %s", metric.name().c_str());
             return false;
         }
 
@@ -293,8 +293,8 @@
     for (int i = 0; i < config.event_metric_size(); i++) {
         int metricIndex = allMetricProducers.size();
         const EventMetric& metric = config.event_metric(i);
-        if (!metric.has_metric_id() || !metric.has_what()) {
-            ALOGW("cannot find the metric id or what in config");
+        if (!metric.has_name() || !metric.has_what()) {
+            ALOGW("cannot find the metric name or what in config");
             return false;
         }
         int trackerIndex;
@@ -320,7 +320,7 @@
     for (int i = 0; i < config.value_metric_size(); i++) {
         const ValueMetric& metric = config.value_metric(i);
         if (!metric.has_what()) {
-            ALOGW("cannot find what in ValueMetric %lld", metric.metric_id());
+            ALOGW("cannot find what in ValueMetric %s", metric.name().c_str());
             return false;
         }
 
@@ -360,7 +360,7 @@
     for (int i = 0; i < config.gauge_metric_size(); i++) {
         const GaugeMetric& metric = config.gauge_metric(i);
         if (!metric.has_what()) {
-            ALOGW("cannot find what in ValueMetric %lld", metric.metric_id());
+            ALOGW("cannot find what in ValueMetric %s", metric.name().c_str());
             return false;
         }
 
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index e089d065..edf3af0 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -21,7 +21,7 @@
 #include <vector>
 
 #include "../condition/ConditionTracker.h"
-#include "../external/StatsPullerManager.h"
+#include "../external/StatsPullerManagerImpl.h"
 #include "../matchers/LogMatchingTracker.h"
 
 namespace android {
diff --git a/cmds/statsd/src/stats_events_copy.proto b/cmds/statsd/src/stats_events_copy.proto
deleted file mode 100644
index 898856b..0000000
--- a/cmds/statsd/src/stats_events_copy.proto
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// STOPSHIP: this is a duplicate of stats_event.proto with LITE_RUNTIME added
-// to produce device side lite proto. We should move statsd to soong so that
-// we can generate full and lite library from the same proto file.
-syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
-
-// TODO: Not the right package and class name
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEventProto";
-
-/**
- * The master event class. This message defines all of the available
- * raw stats log events from the Android system, also known as "atoms."
- *
- * This field contains a single oneof with all of the available messages.
- * The stats-log-api-gen tool runs as part of the Android build and
- * generates the android.util.StatsLog class, which contains the constants
- * and methods that Android uses to log.
- *
- * This StatsEvent class is not actually built into the Android system.
- * Instead, statsd on Android constructs these messages synthetically,
- * in the format defined here and in stats_log.proto.
- */
-message StatsEvent {
-    oneof event {
-        // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
-        BleScanStateChanged ble_scan_state_changed = 2;
-        BleUnoptimizedScanStateChanged ble_unoptimized_scan_state_changed = 3;
-        BleScanResultReceived ble_scan_result_received = 4;
-        SensorStateChanged sensor_state_changed = 5;
-        GpsScanStateChanged gps_scan_state_changed = 6; // TODO: untested
-        SyncStateChanged sync_state_changed = 7;
-        ScheduledJobStateChanged scheduled_job_state_changed = 8;
-        ScreenBrightnessChanged screen_brightness_changed = 9;
-        // 10-20 are temporarily reserved for wakelocks etc.
-        UidWakelockStateChanged uid_wakelock_state_changed = 11;
-        LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 12;
-        BatterySaverModeStateChanged battery_saver_mode_state_changed = 21;
-        DeviceIdleModeStateChanged device_idle_mode_state_changed = 22;
-        AudioStateChanged audio_state_changed = 23;
-        MediaCodecActivityChanged media_codec_activity_changed = 24;
-        CameraStateChanged camera_state_changed = 25;
-        FlashlightStateChanged flashlight_state_changed = 26;
-        UidProcessStateChanged uid_process_state_changed = 27;
-        ProcessLifeCycleStateChanged process_life_cycle_state_changed = 28;
-        ScreenStateChanged screen_state_changed = 29;
-        DeviceTemperatureReported device_temperature_reported = 33;
-        // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
-    }
-}
-
-/**
- * A WorkSource represents the chained attribution of applications that
- * resulted in a particular bit of work being done.
- */
-message WorkSource {
-    // TODO
-}
-
-/*
- * *****************************************************************************
- * Below are all of the individual atoms that are logged by Android via statsd
- * and Westworld.
- *
- * RULES:
- *   - The field ids for each atom must start at 1, and count upwards by 1.
- *     Skipping field ids is not allowed.
- *   - These form an API, so renaming, renumbering or removing fields is
- *     not allowed between android releases.  (This is not currently enforced,
- *     but there will be a tool to enforce this restriction).
- *   - The types must be built-in protocol buffer types, namely, no sub-messages
- *     are allowed (yet).  The bytes type is also not allowed.
- *   - The CamelCase name of the message type should match the
- *     underscore_separated name as defined in StatsEvent.
- *   - If an atom represents work that can be attributed to an app, there can
- *     be exactly one WorkSource field. It must be field number 1.
- *   - A field that is a uid should be a string field, tagged with the [xxx]
- *     annotation. The generated code on android will be represented by UIDs,
- *     and those UIDs will be translated in xxx to those strings.
- *
- * CONVENTIONS:
- *   - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange.
- *   - If there is a UID, it goes first. Think in an object-oriented fashion.
- * *****************************************************************************
- */
-
-/**
- * Logs the temperature of the device, in tenths of a degree Celsius.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message DeviceTemperatureReported {
-    // Temperature in tenths of a degree C.
-    optional int32 temperature = 1;
-}
-
-/**
- * Logs when the screen state changes.
- *
- * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenStateChanged {
-    // TODO: Use the real screen state.
-    enum State {
-        STATE_UNKNOWN = 0;
-        STATE_OFF = 1;
-        STATE_ON = 2;
-        STATE_DOZE = 3;
-        STATE_DOZE_SUSPEND = 4;
-        STATE_VR = 5;
-    }
-    // New screen state.
-    optional State display_state = 1;
-}
-
-/**
- * Logs that the state of a process state, as per the activity manager, has changed.
- *
- * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message UidProcessStateChanged {
-    optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation
-
-    // The state.
-    // TODO: Use the real (mapped) process states.
-    optional int32 state = 2;
-}
-
-/**
- * Logs that a process started, finished, crashed, or ANRed.
- *
- * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ProcessLifeCycleStateChanged {
-    // TODO: Use the real (mapped) process states.
-    optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation
-
-    // TODO: What is this?
-    optional string name = 2;
-
-    // The state.
-    // TODO: Use an enum.
-    optional int32 event = 3;
-}
-
-
-
-/**
- * Logs when the ble scan state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BleScanStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs when an unoptimized ble scan state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-// TODO: Consider changing to tracking per-scanner-id (log from AppScanStats).
-message BleUnoptimizedScanStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs reporting of a ble scan finding results.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-// TODO: Consider changing to tracking per-scanner-id (log from AppScanStats).
-message BleScanResultReceived {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Number of ble scan results returned.
-    optional int32 num_of_results = 2;
-}
-
-/**
- * Logs when a sensor state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message SensorStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // TODO: Is there a way to get the actual name of the sensor?
-    // The id (int) of the sensor.
-    optional int32 sensor_id = 2;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 3;
-}
-
-
-/**
- * Logs when GPS state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message GpsScanStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-
-/**
- * Logs when a sync manager sync state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message SyncStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Name of the sync (as named in the app)
-    optional string name = 2;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 3;
-}
-
-/**
- * Logs when a job scheduler job state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message ScheduledJobStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Name of the job (as named in the app)
-    optional string name = 2;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 3;
-
-    // TODO: Consider adding the stopReason (int)
-}
-
-/**
- * Logs when the audio state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message AudioStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs when the video codec state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message MediaCodecActivityChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs when the flashlight state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message FlashlightStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs when the camera state changes.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message CameraStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 2;
-}
-
-/**
- * Logs that the state of a wakelock (per app and per wakelock name) has changed.
- *
- * Logged from:
- *   TODO
- */
-message WakelockChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Type of wakelock.
-    enum Type {
-        PARTIAL = 0;
-        FULL = 1;
-        WINDOW = 2;
-    }
-    optional int32 type = 2;
-
-    // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
-    optional string tag = 3;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 4;
-}
-
-/**
- * Logs when an app is holding a wakelock, regardless of the wakelock's name.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message UidWakelockStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Type of wakelock.
-    enum Type {
-        PARTIAL = 0;
-        FULL = 1;
-        WINDOW = 2;
-    }
-    optional int32 type = 2;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 3;
-}
-
-/**
- * Logs when a partial wakelock is considered 'long' (over 1 min).
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message LongPartialWakelockStateChanged {
-    // TODO: Add attribution instead of uid?
-    optional int32 uid = 1;
-
-    // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
-    optional string tag = 2;
-
-    // TODO: I have no idea what this is.
-    optional string history_tag = 3;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 4;
-}
-
-/**
- * Logs Battery Saver state change.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message BatterySaverModeStateChanged {
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 1;
-}
-
-/**
- * Logs Doze mode state change.
- *
- * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message DeviceIdleModeStateChanged {
-    // TODO: Use the enum matching BatteryStats.DEVICE_IDLE_MODE_.
-    optional int32 state = 1;
-}
-
-/**
- * Logs screen brightness level.
- *
- * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
- */
-message ScreenBrightnessChanged {
-    // Screen brightness level. Should be in [-1, 255] according to PowerManager.java.
-    optional int32 level = 1;
-}
\ No newline at end of file
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 1e37ff8..4f5df55 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -22,7 +22,7 @@
 option java_package = "com.android.os";
 option java_outer_classname = "StatsLog";
 
-import "frameworks/base/cmds/statsd/src/stats_events_copy.proto";
+import "frameworks/base/cmds/statsd/src/atoms_copy.proto";
 
 message KeyValuePair {
   optional int32 key = 1;
@@ -38,7 +38,7 @@
 message EventMetricData {
   optional int64 timestamp_nanos = 1;
 
-  optional StatsEvent stats_events = 2;
+  optional Atom atom = 2;
 }
 
 message CountBucketInfo {
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index a07f76a..7648a91 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -112,58 +112,59 @@
 }
 
 message Alert {
-  message IncidentdDetails {
-    optional string alert_name = 1;
-    repeated int32 incidentd_sections = 2;
+    optional string name = 1;
+
+    optional string metric_name = 2;
+
+    message IncidentdDetails {
+        repeated int32 section = 1;
   }
-  optional IncidentdDetails incidentd_details = 1;
+  optional IncidentdDetails incidentd_details = 3;
 
-  optional int32 number_of_buckets = 3;
+  optional int32 number_of_buckets = 4;
 
-  optional int32 refractory_period_secs = 4;
+  optional int32 refractory_period_secs = 5;
 
-  optional int64 trigger_if_sum_gt = 5;
+  optional int64 trigger_if_sum_gt = 6;
 
-  optional int32 refractory_period_in_buckets = 6;
+  optional int32 refractory_period_in_buckets = 7;
 }
 
 message EventMetric {
-  optional int64 metric_id = 1;
+    optional string name = 1;
 
-  optional string what = 2;
+    optional string what = 2;
 
-  optional string condition = 3;
+    optional string condition = 3;
 
-  repeated EventConditionLink links = 4;
+    repeated EventConditionLink links = 4;
 }
 
 message CountMetric {
-  optional int64 metric_id = 1;
+    optional string name = 1;
 
-  optional string what = 2;
+    optional string what = 2;
 
-  optional string condition = 3;
+    optional string condition = 3;
 
-  repeated KeyMatcher dimension = 4;
+    repeated KeyMatcher dimension = 4;
 
-  optional Bucket bucket = 5;
+    optional Bucket bucket = 5;
 
-  repeated Alert alerts = 6;
+    optional bool include_in_output = 6;
 
-  optional bool include_in_output = 7;
-
-  repeated EventConditionLink links = 8;
+    repeated EventConditionLink links = 7;
 }
 
 message DurationMetric {
-  optional int64 metric_id = 1;
+    optional string name = 1;
 
-  optional string what = 2;
+    optional string what = 2;
 
-  enum AggregationType {
-    DURATION_SUM = 1;
+    enum AggregationType {
+        DURATION_SUM = 1;
 
-    DURATION_MAX_SPARSE = 2;
+        DURATION_MAX_SPARSE = 2;
   }
   optional AggregationType type = 3;
 
@@ -173,50 +174,42 @@
 
   optional Bucket bucket = 6;
 
-  repeated Alert alerts = 7;
-
-  repeated EventConditionLink links = 8;
+  repeated EventConditionLink links = 7;
 }
 
 message GaugeMetric {
-  optional int64 metric_id = 1;
+    optional string name = 1;
 
-  optional string what = 2;
+    optional string what = 2;
 
-  optional int32 gauge_field = 3;
+    optional int32 gauge_field = 3;
 
-  optional string condition = 4;
+    optional string condition = 4;
 
-  repeated KeyMatcher dimension = 5;
+    repeated KeyMatcher dimension = 5;
 
-  optional Bucket bucket = 6;
+    optional Bucket bucket = 6;
 
-  repeated Alert alerts = 7;
-
-  repeated EventConditionLink links = 8;
+    repeated EventConditionLink links = 7;
 }
 
 message ValueMetric {
-  optional int64 metric_id = 1;
+    optional string name = 1;
 
-  optional string what = 2;
+    optional string what = 2;
 
-  optional int32 value_field = 3;
+    optional int32 value_field = 3;
 
-  optional string condition = 4;
+    optional string condition = 4;
 
-  repeated KeyMatcher dimension = 5;
+    repeated KeyMatcher dimension = 5;
 
-  optional Bucket bucket = 6;
+    optional Bucket bucket = 6;
 
-  repeated Alert alerts = 7;
+    repeated EventConditionLink links = 7;
 
-  repeated EventConditionLink links = 8;
-
-  enum Operation {
-    SUM = 1;
-  }
-  optional Operation operation = 9 [default = SUM];
+    enum Operation { SUM = 1; }
+    optional Operation operation = 9 [default = SUM];
 }
 
 message EventConditionLink {
@@ -227,21 +220,21 @@
 };
 
 message StatsdConfig {
-  optional int64 config_id = 1;
+    optional string name = 1;
 
-  repeated EventMetric event_metric = 2;
+    repeated EventMetric event_metric = 2;
 
-  repeated CountMetric count_metric = 3;
+    repeated CountMetric count_metric = 3;
 
-  repeated ValueMetric value_metric = 4;
+    repeated ValueMetric value_metric = 4;
 
-  repeated DurationMetric duration_metric = 5;
+    repeated GaugeMetric gauge_metric = 5;
 
-  repeated GaugeMetric gauge_metric = 6;
+    repeated DurationMetric duration_metric = 6;
 
-  repeated LogEntryMatcher log_entry_matcher = 7;
+    repeated LogEntryMatcher log_entry_matcher = 7;
 
-  repeated Condition condition = 8;
+    repeated Condition condition = 8;
 
-  repeated Alert alerts = 9;
+    repeated Alert alerts = 9;
 }
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
index aa896ca..fad5de6 100644
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ b/cmds/statsd/tests/ConfigManager_test.cpp
@@ -30,7 +30,7 @@
 namespace statsd {
 
 static ostream& operator<<(ostream& os, const StatsdConfig& config) {
-    return os << "StatsdConfig{id=" << config.config_id() << "}";
+    return os << "StatsdConfig{name=" << config.name().c_str() << "}";
 }
 
 }  // namespace statsd
@@ -56,8 +56,8 @@
 /**
  * Validate that the StatsdConfig is the one we wanted.
  */
-MATCHER_P(StatsdConfigEq, configId, "") {
-    return arg.config_id() == configId;
+MATCHER_P(StatsdConfigEq, name, "") {
+    return arg.name() == name;
 }
 
 /**
@@ -70,13 +70,13 @@
     manager->AddListener(listener);
 
     StatsdConfig config91;
-    config91.set_config_id(91);
+    config91.set_name("91");
     StatsdConfig config92;
-    config92.set_config_id(92);
+    config92.set_name("92");
     StatsdConfig config93;
-    config93.set_config_id(93);
+    config93.set_name("93");
     StatsdConfig config94;
-    config94.set_config_id(94);
+    config94.set_name("94");
 
     {
         InSequence s;
@@ -85,27 +85,27 @@
         // TODO: Remove this when we get rid of the fake one, and make this
         // test loading one from disk somewhere.
         EXPECT_CALL(*(listener.get()),
-                    OnConfigUpdated(ConfigKeyEq(0, "fake"), StatsdConfigEq(12345)))
+                    OnConfigUpdated(ConfigKeyEq(0, "fake"), StatsdConfigEq("12345")))
                 .RetiresOnSaturation();
         manager->Startup();
 
         // Add another one
-        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq(91)))
+        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq("91")))
                 .RetiresOnSaturation();
         manager->UpdateConfig(ConfigKey(1, "zzz"), config91);
 
         // Update It
-        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq(92)))
+        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "zzz"), StatsdConfigEq("92")))
                 .RetiresOnSaturation();
         manager->UpdateConfig(ConfigKey(1, "zzz"), config92);
 
         // Add one with the same uid but a different name
-        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "yyy"), StatsdConfigEq(93)))
+        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, "yyy"), StatsdConfigEq("93")))
                 .RetiresOnSaturation();
         manager->UpdateConfig(ConfigKey(1, "yyy"), config93);
 
         // Add one with the same name but a different uid
-        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(2, "zzz"), StatsdConfigEq(94)))
+        EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(2, "zzz"), StatsdConfigEq("94")))
                 .RetiresOnSaturation();
         manager->UpdateConfig(ConfigKey(2, "zzz"), config94);
 
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 7333785..caa1cf4 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -41,7 +41,7 @@
 
 StatsdConfig buildGoodConfig() {
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
     eventMatcher->set_name("SCREEN_IS_ON");
@@ -76,7 +76,7 @@
 
 StatsdConfig buildCircleMatchers() {
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
     eventMatcher->set_name("SCREEN_IS_ON");
@@ -102,7 +102,7 @@
 
 StatsdConfig buildMissingMatchers() {
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
     eventMatcher->set_name("SCREEN_IS_ON");
@@ -128,7 +128,7 @@
 
 StatsdConfig buildDimensionMetricsWithMultiTags() {
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
     eventMatcher->set_name("BATTERY_VERY_LOW");
@@ -150,7 +150,7 @@
 
     // Count process state changes, slice by uid, while SCREEN_IS_OFF
     CountMetric* metric = config.add_count_metric();
-    metric->set_metric_id(3);
+    metric->set_name("3");
     metric->set_what("BATTERY_LOW");
     metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
     KeyMatcher* keyMatcher = metric->add_dimension();
@@ -161,7 +161,7 @@
 
 StatsdConfig buildCircleConditions() {
     StatsdConfig config;
-    config.set_config_id(12345L);
+    config.set_name("12345");
 
     LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
     eventMatcher->set_name("SCREEN_IS_ON");
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 5a4ee73..d07a84d 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -40,7 +40,7 @@
     int tagId = 1;
 
     CountMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
     metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
 
     LogEvent event1(tagId, bucketStartTimeNs + 1);
@@ -92,7 +92,7 @@
     int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
 
     CountMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
     metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
     metric.set_condition("SCREEN_ON");
 
@@ -129,7 +129,7 @@
     int64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
 
     CountMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
     metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
     metric.set_condition("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON");
     EventConditionLink* link = metric.add_links();
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 76dbc73..0971d26 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -38,7 +38,7 @@
     uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
 
     EventMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
 
     LogEvent event1(1 /*tag id*/, bucketStartTimeNs + 1);
     LogEvent event2(1 /*tag id*/, bucketStartTimeNs + 2);
@@ -61,7 +61,7 @@
     uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
 
     EventMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
     metric.set_condition("SCREEN_ON");
 
     LogEvent event1(1, bucketStartTimeNs + 1);
@@ -87,7 +87,7 @@
     uint64_t bucketSizeNs = 30 * 1000 * 1000 * 1000LL;
 
     EventMetric metric;
-    metric.set_metric_id(1);
+    metric.set_name("1");
     metric.set_condition("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON");
     EventConditionLink* link = metric.add_links();
     link->set_condition("APP_IN_BACKGROUND_PER_UID");
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
new file mode 100644
index 0000000..72b4194
--- /dev/null
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -0,0 +1,299 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "metrics_test_helper.h"
+#include "src/metrics/ValueMetricProducer.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <vector>
+
+using namespace testing;
+using android::sp;
+using std::set;
+using std::unordered_map;
+using std::vector;
+using std::shared_ptr;
+using std::make_shared;
+
+#ifdef __ANDROID__
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/*
+ * Tests pulled atoms with no conditions
+ */
+TEST(ValueMetricProducerTest, TestNonDimensionalEvents) {
+    int64_t bucketStartTimeNs = 10000000000;
+    int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
+
+    int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
+    int64_t bucket3StartTimeNs = bucketStartTimeNs + 2*bucketSizeNs;
+
+    ValueMetric metric;
+    metric.set_name("1");
+    metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
+    metric.set_value_field(2);
+
+    int tagId = 1;
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    // TODO: pending refactor of StatsPullerManager
+    // For now we still need this so that it doesn't do real pulling.
+    shared_ptr<MockStatsPullerManager> pullerManager = make_shared<StrictMock<MockStatsPullerManager>>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+
+    ValueMetricProducer valueProducer(metric, -1 /*-1 meaning no condition*/, wizard,tagId,
+                                      bucketStartTimeNs, pullerManager);
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+    auto list = event->GetAndroidLogEventList();
+    *list << 1;
+    *list << 11;
+    event->init();
+    allData.push_back(event);
+
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 11, 11
+    EXPECT_EQ(11, curInterval.raw.front().first);
+    EXPECT_EQ(11, curInterval.raw.front().second);
+    ValueMetricProducer::Interval nextInterval = valueProducer.mNextSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, nextInterval.raw.size());
+    // value is 11, 0
+    EXPECT_EQ(11, nextInterval.raw.front().first);
+    EXPECT_EQ(0, nextInterval.raw.front().second);
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    list = event->GetAndroidLogEventList();
+    *list << 1;
+    *list << 22;
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 22, 0
+    EXPECT_EQ(22, curInterval.raw.front().first);
+    EXPECT_EQ(0, curInterval.raw.front().second);
+    EXPECT_EQ(0UL, valueProducer.mNextSlicedBucket.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(11, valueProducer.mPastBuckets.begin()->second.back().mValue);
+
+    allData.clear();
+    event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
+    list = event->GetAndroidLogEventList();
+    *list << 1;
+    *list << 33;
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 33, 0
+    EXPECT_EQ(33, curInterval.raw.front().first);
+    EXPECT_EQ(0, curInterval.raw.front().second);
+    EXPECT_EQ(0UL, valueProducer.mNextSlicedBucket.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(11, valueProducer.mPastBuckets.begin()->second.back().mValue);
+}
+
+/*
+ * Test pulled event with non sliced condition.
+ */
+TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
+    int64_t bucketStartTimeNs = 10000000000;
+    int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
+
+    int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
+    int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
+
+    ValueMetric metric;
+    metric.set_name("1");
+    metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
+    metric.set_value_field(2);
+    metric.set_condition("SCREEN_ON");
+
+    int tagId = 1;
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    shared_ptr<MockStatsPullerManager> pullerManager = make_shared<StrictMock<MockStatsPullerManager>>();
+    EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+    EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
+
+    EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Invoke([] (int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+        int64_t bucketStartTimeNs = 10000000000;
+        int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
+
+        int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
+        int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
+        data->clear();
+        shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+        auto list = event->GetAndroidLogEventList();
+        *list << 1;
+        *list << 100;
+        event->init();
+        data->push_back(event);
+        return true;
+    }))
+    .WillOnce(Invoke([] (int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+        int64_t bucketStartTimeNs = 10000000000;
+        int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
+
+        int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
+        int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
+        data->clear();
+        shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
+        auto list = event->GetAndroidLogEventList();
+        *list << 1;
+        *list << 120;
+        event->init();
+        data->push_back(event);
+        return true;
+    }));
+
+    ValueMetricProducer valueProducer(metric, 1, wizard,tagId,
+                                      bucketStartTimeNs, pullerManager);
+
+    valueProducer.onConditionChanged(true, bucketStartTimeNs + 10);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 100, 0
+    EXPECT_EQ(100, curInterval.raw.front().first);
+    EXPECT_EQ(0, curInterval.raw.front().second);
+    EXPECT_EQ(0UL, valueProducer.mNextSlicedBucket.size());
+    EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+    vector<shared_ptr<LogEvent>> allData;
+    allData.clear();
+    shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+    auto list = event->GetAndroidLogEventList();
+    *list << 1;
+    *list << 110;
+    event->init();
+    allData.push_back(event);
+    valueProducer.onDataPulled(allData);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 110, 0
+    EXPECT_EQ(110, curInterval.raw.front().first);
+    EXPECT_EQ(0, curInterval.raw.front().second);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValue);
+
+    valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 110, 120
+    EXPECT_EQ(110, curInterval.raw.front().first);
+    EXPECT_EQ(120, curInterval.raw.front().second);
+}
+
+TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
+    int64_t bucketStartTimeNs = 10000000000;
+    int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL;
+
+    int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
+    int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
+
+    ValueMetric metric;
+    metric.set_name("1");
+    metric.mutable_bucket()->set_bucket_size_millis(bucketSizeNs / 1000000);
+    metric.set_value_field(2);
+
+    int tagId = 1;
+
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    shared_ptr<MockStatsPullerManager> pullerManager = make_shared<StrictMock<MockStatsPullerManager>>();
+
+    ValueMetricProducer valueProducer(metric, -1, wizard,-1,
+                                      bucketStartTimeNs, pullerManager);
+
+    shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+    auto list = event1->GetAndroidLogEventList();
+    *list << 1;
+    *list << 10;
+    event1->init();
+    shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+    auto list2 = event2->GetAndroidLogEventList();
+    *list2 << 1;
+    *list2 << 20;
+    event2->init();
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1, false);
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(1UL, curInterval.raw.size());
+    // value is 10, 0
+    EXPECT_EQ(10, curInterval.raw.front().first);
+    EXPECT_EQ(0, curInterval.raw.front().second);
+    EXPECT_EQ(0UL, valueProducer.mNextSlicedBucket.size());
+
+    valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2, false);
+
+    // has one slice
+    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+    // has one raw pair
+    EXPECT_EQ(2UL, curInterval.raw.size());
+    // value is 10, 20
+    EXPECT_EQ(10, curInterval.raw.front().first);
+    EXPECT_EQ(20, curInterval.raw.back().first);
+    EXPECT_EQ(0UL, valueProducer.mNextSlicedBucket.size());
+
+    valueProducer.flush_if_needed(bucket3StartTimeNs);
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().mValue);
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index 5fd7d62..fa221aa 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include "src/condition/ConditionWizard.h"
+#include "src/external/StatsPullerManager.h"
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -30,6 +31,13 @@
                            const std::map<std::string, HashableDimensionKey>& conditionParameters));
 };
 
+class MockStatsPullerManager : public StatsPullerManager {
+public:
+    MOCK_METHOD3(RegisterReceiver, void(int tagId, wp<PullDataReceiver> receiver, long intervalMs));
+    MOCK_METHOD2(UnRegisterReceiver, void(int tagId, wp<PullDataReceiver> receiver));
+    MOCK_METHOD2(Pull, bool(const int pullCode, vector<std::shared_ptr<LogEvent>>* data));
+};
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a8863bf..99f3dee 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -193,10 +193,13 @@
  * <a name="Fragments"></a>
  * <h3>Fragments</h3>
  *
- * <p>Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB}, Activity
- * implementations can make use of the {@link Fragment} class to better
+ * <p>The {@link android.support.v4.app.FragmentActivity} subclass
+ * can make use of the {@link android.support.v4.app.Fragment} class to better
  * modularize their code, build more sophisticated user interfaces for larger
- * screens, and help scale their application between small and large screens.
+ * screens, and help scale their application between small and large screens.</p>
+ *
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/components/fragments.html">Fragments</a> developer guide.</p>
  *
  * <a name="ActivityLifecycle"></a>
  * <h3>Activity Lifecycle</h3>
@@ -915,7 +918,10 @@
 
     /**
      * Return the LoaderManager for this activity, creating it if needed.
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentActivity#getSupportLoaderManager()}
      */
+    @Deprecated
     public LoaderManager getLoaderManager() {
         return mFragments.getLoaderManager();
     }
@@ -2395,7 +2401,10 @@
     /**
      * Return the FragmentManager for interacting with fragments associated
      * with this activity.
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()}
      */
+    @Deprecated
     public FragmentManager getFragmentManager() {
         return mFragments.getFragmentManager();
     }
@@ -2404,7 +2413,11 @@
      * Called when a Fragment is being attached to this activity, immediately
      * after the call to its {@link Fragment#onAttach Fragment.onAttach()}
      * method and before {@link Fragment#onCreate Fragment.onCreate()}.
+     *
+     * @deprecated Use {@link
+     * android.support.v4.app.FragmentActivity#onAttachFragment(android.support.v4.app.Fragment)}
      */
+    @Deprecated
     public void onAttachFragment(Fragment fragment) {
     }
 
@@ -5106,7 +5119,11 @@
      *
      * @see Fragment#startActivity
      * @see Fragment#startActivityForResult
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentActivity#startActivityFromFragment(
+     * android.support.v4.app.Fragment,Intent,int)}
      */
+    @Deprecated
     public void startActivityFromFragment(@NonNull Fragment fragment,
             @RequiresPermission Intent intent, int requestCode) {
         startActivityFromFragment(fragment, intent, requestCode, null);
@@ -5131,7 +5148,11 @@
      *
      * @see Fragment#startActivity
      * @see Fragment#startActivityForResult
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentActivity#startActivityFromFragment(
+     * android.support.v4.app.Fragment,Intent,int,Bundle)}
      */
+    @Deprecated
     public void startActivityFromFragment(@NonNull Fragment fragment,
             @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
         startActivityForResult(fragment.mWho, intent, requestCode, options);
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
index f99d1a8..0643414 100644
--- a/core/java/android/app/DexLoadReporter.java
+++ b/core/java/android/app/DexLoadReporter.java
@@ -19,7 +19,6 @@
 import android.os.FileUtils;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.system.ErrnoException;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -27,8 +26,6 @@
 import dalvik.system.BaseDexClassLoader;
 import dalvik.system.VMRuntime;
 
-import libcore.io.Libcore;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -155,23 +152,12 @@
             return;
         }
 
-        File realDexPath;
-        try {
-            // Secondary dex profiles are stored in the oat directory, next to the real dex file
-            // and have the same name with 'cur.prof' appended. We use the realpath because that
-            // is what installd is using when processing the dex file.
-            // NOTE: Keep in sync with installd.
-            realDexPath = new File(Libcore.os.realpath(dexPath));
-        } catch (ErrnoException ex) {
-            Slog.e(TAG, "Failed to get the real path of secondary dex " + dexPath
-                    + ":" + ex.getMessage());
-            // Do not continue with registration if we could not retrieve the real path.
-            return;
-        }
-
+        // Secondary dex profiles are stored in the oat directory, next to dex file
+        // and have the same name with 'cur.prof' appended.
         // NOTE: Keep this in sync with installd expectations.
-        File secondaryProfileDir = new File(realDexPath.getParent(), "oat");
-        File secondaryProfile = new File(secondaryProfileDir, realDexPath.getName() + ".cur.prof");
+        File dexPathFile = new File(dexPath);
+        File secondaryProfileDir = new File(dexPathFile.getParent(), "oat");
+        File secondaryProfile = new File(secondaryProfileDir, dexPathFile.getName() + ".cur.prof");
 
         // Create the profile if not already there.
         // Returns true if the file was created, false if the file already exists.
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index 7e0e4d8..a0fb6ee 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -136,7 +136,10 @@
  *
  * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
  *      embed}
+ *
+ * @deprecated Use {@link android.support.v4.app.DialogFragment}
  */
+@Deprecated
 public class DialogFragment extends Fragment
         implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 9377345..a92684b 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -256,7 +256,10 @@
  * <p>After each call to this function, a new entry is on the stack, and
  * pressing back will pop it to return the user to whatever previous state
  * the activity UI was in.
+ *
+ * @deprecated Use {@link android.support.v4.app.Fragment}
  */
+@Deprecated
 public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
     private static final ArrayMap<String, Class<?>> sClassMap =
             new ArrayMap<String, Class<?>>();
@@ -414,7 +417,10 @@
      * State information that has been retrieved from a fragment instance
      * through {@link FragmentManager#saveFragmentInstanceState(Fragment)
      * FragmentManager.saveFragmentInstanceState}.
+     *
+     * @deprecated Use {@link android.support.v4.app.Fragment.SavedState}
      */
+    @Deprecated
     public static class SavedState implements Parcelable {
         final Bundle mState;
 
@@ -458,7 +464,10 @@
     /**
      * Thrown by {@link Fragment#instantiate(Context, String, Bundle)} when
      * there is an instantiation failure.
+     *
+     * @deprecated Use {@link android.support.v4.app.Fragment.InstantiationException}
      */
+    @Deprecated
     static public class InstantiationException extends AndroidRuntimeException {
         public InstantiationException(String msg, Exception cause) {
             super(msg, cause);
@@ -1031,7 +1040,10 @@
 
     /**
      * Return the LoaderManager for this fragment, creating it if needed.
+     *
+     * @deprecated Use {@link android.support.v4.app.Fragment#getLoaderManager()}
      */
+    @Deprecated
     public LoaderManager getLoaderManager() {
         if (mLoaderManager != null) {
             return mLoaderManager;
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index d0aa0fd..e3e47ae 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -65,7 +65,10 @@
 
     /**
      * Interface to intercept clicks on the bread crumbs.
+     *
+     * @deprecated This widget is no longer supported.
      */
+    @Deprecated
     public interface OnBreadCrumbClickListener {
         /**
          * Called when a bread crumb is clicked.
diff --git a/core/java/android/app/FragmentContainer.java b/core/java/android/app/FragmentContainer.java
index f8836bc8..a1dd32f 100644
--- a/core/java/android/app/FragmentContainer.java
+++ b/core/java/android/app/FragmentContainer.java
@@ -24,7 +24,10 @@
 
 /**
  * Callbacks to a {@link Fragment}'s container.
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentContainer}
  */
+@Deprecated
 public abstract class FragmentContainer {
     /**
      * Return the view with the given resource ID. May return {@code null} if the
diff --git a/core/java/android/app/FragmentController.java b/core/java/android/app/FragmentController.java
index cff94d8..cbb58d4 100644
--- a/core/java/android/app/FragmentController.java
+++ b/core/java/android/app/FragmentController.java
@@ -37,7 +37,10 @@
  * <p>
  * It is the responsibility of the host to take care of the Fragment's lifecycle.
  * The methods provided by {@link FragmentController} are for that purpose.
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentController}
  */
+@Deprecated
 public class FragmentController {
     private final FragmentHostCallback<?> mHost;
 
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index 5ef23e6..1edc68e 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -37,7 +37,10 @@
  * Fragments may be hosted by any object; such as an {@link Activity}. In order to
  * host fragments, implement {@link FragmentHostCallback}, overriding the methods
  * applicable to the host.
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentHostCallback}
  */
+@Deprecated
 public abstract class FragmentHostCallback<E> extends FragmentContainer {
     private final Activity mActivity;
     final Context mContext;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 0d5cd02..12e60b8 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -74,7 +74,10 @@
  * {@link android.support.v4.app.FragmentActivity}.  See the blog post
  * <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">
  * Fragments For All</a> for more details.
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentManager}
  */
+@Deprecated
 public abstract class FragmentManager {
     /**
      * Representation of an entry on the fragment back stack, as created
@@ -86,7 +89,10 @@
      * <p>Note that you should never hold on to a BackStackEntry object;
      * the identifier as returned by {@link #getId} is the only thing that
      * will be persisted across activity instances.
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentManager.BackStackEntry}
      */
+    @Deprecated
     public interface BackStackEntry {
         /**
          * Return the unique identifier for the entry.  This is the only
@@ -129,7 +135,10 @@
 
     /**
      * Interface to watch for changes to the back stack.
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentManager.OnBackStackChangedListener}
      */
+    @Deprecated
     public interface OnBackStackChangedListener {
         /**
          * Called whenever the contents of the back stack change.
@@ -428,7 +437,10 @@
     /**
      * Callback interface for listening to fragment state changes that happen
      * within a given FragmentManager.
+     *
+     * @deprecated Use {@link android.support.v4.app.FragmentManager.FragmentLifecycleCallbacks}
      */
+    @Deprecated
     public abstract static class FragmentLifecycleCallbacks {
         /**
          * Called right before the fragment's {@link Fragment#onAttach(Context)} method is called.
diff --git a/core/java/android/app/FragmentManagerNonConfig.java b/core/java/android/app/FragmentManagerNonConfig.java
index 50d3797..beb1a15 100644
--- a/core/java/android/app/FragmentManagerNonConfig.java
+++ b/core/java/android/app/FragmentManagerNonConfig.java
@@ -27,7 +27,10 @@
  * and passed to the state save and restore process for fragments in
  * {@link FragmentController#retainNonConfig()} and
  * {@link FragmentController#restoreAllState(Parcelable, FragmentManagerNonConfig)}.</p>
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentManagerNonConfig}
  */
+@Deprecated
 public class FragmentManagerNonConfig {
     private final List<Fragment> mFragments;
     private final List<FragmentManagerNonConfig> mChildNonConfigs;
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index c910e90..0f4a7fb 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -21,7 +21,10 @@
  * <a href="{@docRoot}guide/components/fragments.html">Fragments</a> developer
  * guide.</p>
  * </div>
+ *
+ * @deprecated Use {@link android.support.v4.app.FragmentTransaction}
  */
+@Deprecated
 public abstract class FragmentTransaction {
     /**
      * Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
diff --git a/core/java/android/app/ListFragment.java b/core/java/android/app/ListFragment.java
index 0b96d84..90b77b3 100644
--- a/core/java/android/app/ListFragment.java
+++ b/core/java/android/app/ListFragment.java
@@ -144,7 +144,10 @@
  *
  * @see #setListAdapter
  * @see android.widget.ListView
+ *
+ * @deprecated Use {@link android.support.v4.app.ListFragment}
  */
+@Deprecated
 public class ListFragment extends Fragment {
     final private Handler mHandler = new Handler();
 
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 56dfc58..7969684 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -54,11 +54,17 @@
  * <p>For more information about using loaders, read the
  * <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
  * </div>
+ *
+ * @deprecated Use {@link android.support.v4.app.LoaderManager}
  */
+@Deprecated
 public abstract class LoaderManager {
     /**
      * Callback interface for a client to interact with the manager.
+     *
+     * @deprecated Use {@link android.support.v4.app.LoaderManager.LoaderCallbacks}
      */
+    @Deprecated
     public interface LoaderCallbacks<D> {
         /**
          * Instantiate and return a new Loader for the given ID.
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d813d66..e48946f 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -137,6 +137,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
 import android.util.Log;
+import android.util.StatsManager;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.WindowManager;
@@ -452,6 +453,13 @@
                   ctx.mMainThread.getHandler().getLooper());
             }});
 
+        registerService(Context.STATS_MANAGER, StatsManager.class,
+                new StaticServiceFetcher<StatsManager>() {
+                    @Override
+                    public StatsManager createService() throws ServiceNotFoundException {
+                        return new StatsManager();
+                    }});
+
         registerService(Context.STATUS_BAR_SERVICE, StatusBarManager.class,
                 new CachedServiceFetcher<StatusBarManager>() {
             @Override
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 0f006b6..8686944 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -152,6 +152,9 @@
             public void onClick(View view) {
                 if (mTimePicker.validateInput()) {
                     TimePickerDialog.this.onClick(TimePickerDialog.this, BUTTON_POSITIVE);
+                    // Clearing focus forces the dialog to commit any pending
+                    // changes, e.g. typed text in a NumberPicker.
+                    mTimePicker.clearFocus();
                     dismiss();
                 }
             }
diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java
index 1ce89d2..fdf8c07 100644
--- a/core/java/android/app/slice/Slice.java
+++ b/core/java/android/app/slice/Slice.java
@@ -113,6 +113,14 @@
      */
     public static final String HINT_HIDDEN = "hidden";
     /**
+     * Hint to indicate that this content has a toggle action associated with it. To indicate that
+     * the toggle is on, use {@link #HINT_SELECTED}. When the toggle state changes, the intent
+     * associated with it will be sent along with an extra {@link #EXTRA_TOGGLE_STATE} which can be
+     * retrieved to see the new state of the toggle.
+     * @hide
+     */
+    public static final String HINT_TOGGLE = "toggle";
+    /**
      * Hint to indicate that this slice is incomplete and an update will be sent once
      * loading is complete. Slices which contain HINT_PARTIAL will not be cached by the
      * OS and should not be cached by apps.
@@ -125,6 +133,11 @@
      * @hide
      */
     public static final String HINT_ALT         = "alt";
+    /**
+     * Key to retrieve an extra added to an intent when a control is changed.
+     * @hide
+     */
+    public static final String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE";
 
     private final SliceItem[] mItems;
     private final @SliceHint String[] mHints;
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index b7545bf..6e9f09c 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -49,7 +49,10 @@
  *      fragment}
  *
  * @param <D> the data type to be loaded.
+ *
+ * @deprecated Use {@link android.support.v4.content.AsyncTaskLoader}
  */
+@Deprecated
 public abstract class AsyncTaskLoader<D> extends Loader<D> {
     static final String TAG = "AsyncTaskLoader";
     static final boolean DEBUG = false;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 72f75112..19e24ad 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4044,6 +4044,13 @@
     public static final String STATS_COMPANION_SERVICE = "statscompanion";
 
     /**
+     * Use with {@link #getSystemService} to retrieve an {@link android.stats.StatsManager}.
+     * @hide
+     */
+    @SystemApi
+    public static final String STATS_MANAGER = "stats";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a {@link
      * android.content.om.OverlayManager} for managing overlay packages.
      *
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index c78871c..33386e5 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -38,7 +38,10 @@
  * in the desired paramters with {@link #setUri(Uri)}, {@link #setSelection(String)},
  * {@link #setSelectionArgs(String[])}, {@link #setSortOrder(String)},
  * and {@link #setProjection(String[])}.
+ *
+ * @deprecated Use {@link android.support.v4.content.CursorLoader}
  */
+@Deprecated
 public class CursorLoader extends AsyncTaskLoader<Cursor> {
     final ForceLoadContentObserver mObserver;
 
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index dd729a3..bad452c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1728,6 +1728,9 @@
      * <p>
      * Output: If {@link #EXTRA_RETURN_RESULT}, returns whether the install
      * succeeded.
+     * <p>
+     * Requires {@link android.Manifest.permission#REQUEST_DELETE_PACKAGES}
+     * since {@link Build.VERSION_CODES#P}.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 3faf13b..80f9a14 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -48,7 +48,10 @@
  * </div>
  *
  * @param <D> The result returned when the load is complete
+ *
+ * @deprecated Use {@link android.support.v4.content.Loader}
  */
+@Deprecated
 public class Loader<D> {
     int mId;
     OnLoadCompleteListener<D> mListener;
@@ -66,7 +69,10 @@
      * is told it has changed.  You do not normally need to use this yourself;
      * it is used for you by {@link CursorLoader} to take care of executing
      * an update when the cursor's backing data changes.
+     *
+     * @deprecated Use {@link android.support.v4.content.Loader.ForceLoadContentObserver}
      */
+    @Deprecated
     public final class ForceLoadContentObserver extends ContentObserver {
         public ForceLoadContentObserver() {
             super(new Handler());
@@ -90,7 +96,10 @@
      * to find out when a Loader it is managing has completed so that this can
      * be reported to its client.  This interface should only be used if a
      * Loader is not being used in conjunction with LoaderManager.
+     *
+     * @deprecated Use {@link android.support.v4.content.Loader.OnLoadCompleteListener}
      */
+    @Deprecated
     public interface OnLoadCompleteListener<D> {
         /**
          * Called on the thread that created the Loader when the load is complete.
@@ -108,7 +117,10 @@
      * to find out when a Loader it is managing has been canceled so that it
      * can schedule the next Loader.  This interface should only be used if a
      * Loader is not being used in conjunction with LoaderManager.
+     *
+     * @deprecated Use {@link android.support.v4.content.Loader.OnLoadCanceledListener}
      */
+    @Deprecated
     public interface OnLoadCanceledListener<D> {
         /**
          * Called on the thread that created the Loader when the load is canceled.
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 05c5556..9e54e23 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -282,13 +282,13 @@
         public static final int FLAG_GET_MANIFEST = FLAG_MATCH_MANIFEST;
 
         /**
-         * @hide include all pinned shortcuts by any launchers, not just by the caller,
+         * Include all pinned shortcuts by any launchers, not just by the caller,
          * in the result.
-         * If the caller doesn't havve the {@link android.Manifest.permission#ACCESS_SHORTCUTS}
-         * permission, this flag will be ignored.
+         *
+         * The caller must be the selected assistant app to use this flag, or have the system
+         * {@code ACCESS_SHORTCUTS} permission.
          */
-        @TestApi
-        public static final int FLAG_MATCH_ALL_PINNED = 1 << 10;
+        public static final int FLAG_MATCH_PINNED_BY_ANY_LAUNCHER = 1 << 10;
 
         /**
          * FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST
@@ -302,7 +302,7 @@
          * @hide
          */
         public static final int FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED =
-                FLAG_MATCH_ALL_KINDS | FLAG_MATCH_ALL_PINNED;
+                FLAG_MATCH_ALL_KINDS | FLAG_MATCH_PINNED_BY_ANY_LAUNCHER;
 
         /** @hide kept for unit tests */
         @Deprecated
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 5673361..86288396 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -444,6 +444,9 @@
      * @param packageName The package to uninstall.
      * @param statusReceiver Where to deliver the result.
      */
+    @RequiresPermission(anyOf = {
+            Manifest.permission.DELETE_PACKAGES,
+            Manifest.permission.REQUEST_DELETE_PACKAGES})
     public void uninstall(@NonNull String packageName, @NonNull IntentSender statusReceiver) {
         uninstall(packageName, 0 /*flags*/, statusReceiver);
     }
@@ -476,6 +479,9 @@
      * @param versionedPackage The versioned package to uninstall.
      * @param statusReceiver Where to deliver the result.
      */
+    @RequiresPermission(anyOf = {
+            Manifest.permission.DELETE_PACKAGES,
+            Manifest.permission.REQUEST_DELETE_PACKAGES})
     public void uninstall(@NonNull VersionedPackage versionedPackage,
             @NonNull IntentSender statusReceiver) {
         uninstall(versionedPackage, 0 /*flags*/, statusReceiver);
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index b692039..2c93a7f 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -289,14 +289,19 @@
 
     private void setWalModeFromConfiguration() {
         if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
-            boolean walEnabled =
+            final boolean walEnabled =
                     (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
-            if (walEnabled || mConfiguration.useCompatibilityWal) {
+            // Use compatibility WAL unless an app explicitly set journal/synchronous mode
+            final boolean useCompatibilityWal = mConfiguration.journalMode == null
+                    && mConfiguration.syncMode == null && mConfiguration.useCompatibilityWal;
+            if (walEnabled || useCompatibilityWal) {
                 setJournalMode("WAL");
                 setSyncMode(SQLiteGlobal.getWALSyncMode());
             } else {
-                setJournalMode(SQLiteGlobal.getDefaultJournalMode());
-                setSyncMode(SQLiteGlobal.getDefaultSyncMode());
+                setJournalMode(mConfiguration.journalMode == null
+                        ? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode);
+                setSyncMode(mConfiguration.syncMode == null
+                        ? SQLiteGlobal.getDefaultSyncMode() : mConfiguration.syncMode);
             }
         }
     }
@@ -310,12 +315,10 @@
     }
 
     private static String canonicalizeSyncMode(String value) {
-        if (value.equals("0")) {
-            return "OFF";
-        } else if (value.equals("1")) {
-            return "NORMAL";
-        } else if (value.equals("2")) {
-            return "FULL";
+        switch (value) {
+            case "0": return "OFF";
+            case "1": return "NORMAL";
+            case "2": return "FULL";
         }
         return value;
     }
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 83b8dc7..863fb19 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -262,7 +262,8 @@
 
     private SQLiteDatabase(final String path, final int openFlags,
             CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
-            int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs) {
+            int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs,
+            String journalMode, String syncMode) {
         mCursorFactory = cursorFactory;
         mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
         mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
@@ -285,6 +286,8 @@
             }
         }
         mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
+        mConfigurationLocked.journalMode = journalMode;
+        mConfigurationLocked.syncMode = syncMode;
         mConfigurationLocked.useCompatibilityWal = SQLiteGlobal.isCompatibilityWalSupported();
     }
 
@@ -721,7 +724,7 @@
         SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
                 openParams.mCursorFactory, openParams.mErrorHandler,
                 openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
-                openParams.mIdleConnectionTimeout);
+                openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode);
         db.open();
         return db;
     }
@@ -747,7 +750,8 @@
      */
     public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
             @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) {
-        SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1);
+        SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1, null,
+                null);
         db.open();
         return db;
     }
@@ -2302,17 +2306,21 @@
         private final DatabaseErrorHandler mErrorHandler;
         private final int mLookasideSlotSize;
         private final int mLookasideSlotCount;
-        private long mIdleConnectionTimeout;
+        private final long mIdleConnectionTimeout;
+        private final String mJournalMode;
+        private final String mSyncMode;
 
         private OpenParams(int openFlags, CursorFactory cursorFactory,
                 DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
-                long idleConnectionTimeout) {
+                long idleConnectionTimeout, String journalMode, String syncMode) {
             mOpenFlags = openFlags;
             mCursorFactory = cursorFactory;
             mErrorHandler = errorHandler;
             mLookasideSlotSize = lookasideSlotSize;
             mLookasideSlotCount = lookasideSlotCount;
             mIdleConnectionTimeout = idleConnectionTimeout;
+            mJournalMode = journalMode;
+            mSyncMode = syncMode;
         }
 
         /**
@@ -2379,6 +2387,28 @@
         }
 
         /**
+         * Returns <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>.
+         * This journal mode will only be used if {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING}
+         * flag is not set, otherwise a platform will use "WAL" journal mode.
+         * @see Builder#setJournalMode(String)
+         */
+        @Nullable
+        public String getJournalMode() {
+            return mJournalMode;
+        }
+
+        /**
+         * Returns <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>.
+         * This value will only be used when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag
+         * is not set, otherwise a system wide default will be used.
+         * @see Builder#setSynchronousMode(String)
+         */
+        @Nullable
+        public String getSynchronousMode() {
+            return mSyncMode;
+        }
+
+        /**
          * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with
          * {@code this} parameters.
          * @hide
@@ -2398,6 +2428,8 @@
             private int mOpenFlags;
             private CursorFactory mCursorFactory;
             private DatabaseErrorHandler mErrorHandler;
+            private String mJournalMode;
+            private String mSyncMode;
 
             public Builder() {
             }
@@ -2408,6 +2440,8 @@
                 mOpenFlags = params.mOpenFlags;
                 mCursorFactory = params.mCursorFactory;
                 mErrorHandler = params.mErrorHandler;
+                mJournalMode = params.mJournalMode;
+                mSyncMode = params.mSyncMode;
             }
 
             /**
@@ -2539,6 +2573,30 @@
                 return this;
             }
 
+
+            /**
+             * Sets <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>
+             * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set.
+             */
+            @NonNull
+            public Builder setJournalMode(@NonNull  String journalMode) {
+                Preconditions.checkNotNull(journalMode);
+                mJournalMode = journalMode;
+                return this;
+            }
+
+            /**
+             * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>
+             * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set.
+             * @return
+             */
+            @NonNull
+            public Builder setSynchronousMode(@NonNull String syncMode) {
+                Preconditions.checkNotNull(syncMode);
+                mSyncMode = syncMode;
+                return this;
+            }
+
             /**
              * Creates an instance of {@link OpenParams} with the options that were previously set
              * on this builder
@@ -2546,7 +2604,7 @@
             @NonNull
             public OpenParams build() {
                 return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize,
-                        mLookasideSlotCount, mIdleConnectionTimeout);
+                        mLookasideSlotCount, mIdleConnectionTimeout, mJournalMode, mSyncMode);
             }
         }
     }
@@ -2561,4 +2619,6 @@
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DatabaseOpenFlags {}
+
 }
+
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 905da724..a14df1e 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -120,6 +120,18 @@
     public boolean useCompatibilityWal;
 
     /**
+     * Journal mode to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} is not set.
+     * <p>Default is returned by {@link SQLiteGlobal#getDefaultJournalMode()}
+     */
+    public String journalMode;
+
+    /**
+     * Synchronous mode to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} is not set.
+     * <p>Default is returned by {@link SQLiteGlobal#getDefaultSyncMode()}
+     */
+    public String syncMode;
+
+    /**
      * Creates a database configuration with the required parameters for opening a
      * database and default values for all other parameters.
      *
@@ -180,6 +192,8 @@
         lookasideSlotCount = other.lookasideSlotCount;
         idleConnectionTimeoutMs = other.idleConnectionTimeoutMs;
         useCompatibilityWal = other.useCompatibilityWal;
+        journalMode = other.journalMode;
+        syncMode = other.syncMode;
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index cc9e0f4..d4699a8 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -17,6 +17,8 @@
 package android.database.sqlite;
 
 import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.database.DatabaseErrorHandler;
 import android.database.SQLException;
@@ -24,6 +26,8 @@
 import android.os.FileUtils;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.File;
 
 /**
@@ -69,7 +73,8 @@
      *     {@link #onUpgrade} will be used to upgrade the database; if the database is
      *     newer, {@link #onDowngrade} will be used to downgrade the database
      */
-    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
+    public SQLiteOpenHelper(@NonNull Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version) {
         this(context, name, factory, version, null);
     }
 
@@ -90,12 +95,33 @@
      * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
      * corruption, or null to use the default error handler.
      */
-    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
-            DatabaseErrorHandler errorHandler) {
+    public SQLiteOpenHelper(@NonNull Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version,
+            @Nullable DatabaseErrorHandler errorHandler) {
         this(context, name, factory, version, 0, errorHandler);
     }
 
     /**
+     * Create a helper object to create, open, and/or manage a database.
+     * This method always returns very quickly.  The database is not actually
+     * created or opened until one of {@link #getWritableDatabase} or
+     * {@link #getReadableDatabase} is called.
+     *
+     * @param context to use to open or create the database
+     * @param name of the database file, or null for an in-memory database
+     * @param version number of the database (starting at 1); if the database is older,
+     *     {@link #onUpgrade} will be used to upgrade the database; if the database is
+     *     newer, {@link #onDowngrade} will be used to downgrade the database
+     * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}.
+     *        Please note that {@link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be
+     *        set when the helper opens the database
+     */
+    public SQLiteOpenHelper(@NonNull Context context, @Nullable String name, int version,
+            @NonNull SQLiteDatabase.OpenParams openParams) {
+        this(context, name, version, 0, openParams.toBuilder());
+    }
+
+    /**
      * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)}
      * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old
      * versions of this database that are no longer supported. If a database with older version that
@@ -118,17 +144,27 @@
      * @see #onUpgrade(SQLiteDatabase, int, int)
      * @hide
      */
-    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
-            int minimumSupportedVersion, DatabaseErrorHandler errorHandler) {
+    public SQLiteOpenHelper(@NonNull Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version,
+            int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) {
+        this(context, name, version, minimumSupportedVersion,
+                new SQLiteDatabase.OpenParams.Builder());
+        mOpenParamsBuilder.setCursorFactory(factory);
+        mOpenParamsBuilder.setErrorHandler(errorHandler);
+    }
+
+    private SQLiteOpenHelper(@NonNull Context context, @Nullable String name, int version,
+            int minimumSupportedVersion,
+            @NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {
+        Preconditions.checkNotNull(context);
+        Preconditions.checkNotNull(openParamsBuilder);
         if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
 
         mContext = context;
         mName = name;
         mNewVersion = version;
         mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion);
-        mOpenParamsBuilder = new SQLiteDatabase.OpenParams.Builder();
-        mOpenParamsBuilder.setCursorFactory(factory);
-        mOpenParamsBuilder.setErrorHandler(errorHandler);
+        mOpenParamsBuilder = openParamsBuilder;
         mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY);
     }
 
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index da771e4..ff69bd8 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -249,7 +249,7 @@
      * <p>This function can also be called in case where multiple surfaces share the same
      * OutputConfiguration, and one of the surfaces becomes available after the {@link
      * CameraCaptureSession} is created. In that case, the application must first create the
-     * OutputConfiguration with the available Surface, then enable furture surface sharing via
+     * OutputConfiguration with the available Surface, then enable further surface sharing via
      * {@link OutputConfiguration#enableSurfaceSharing}, before creating the CameraCaptureSession.
      * After the CameraCaptureSession is created, and once the extra Surface becomes available, the
      * application must then call {@link OutputConfiguration#addSurface} before finalizing the
@@ -645,6 +645,44 @@
     public abstract Surface getInputSurface();
 
     /**
+     * Update {@link OutputConfiguration} after configuration finalization see
+     * {@link #finalizeOutputConfigurations}.
+     *
+     * <p>Any {@link OutputConfiguration} that has been modified via calls to
+     * {@link OutputConfiguration#addSurface} or {@link OutputConfiguration#removeSurface} must be
+     * updated. After the update call returns without throwing exceptions any newly added surfaces
+     * can be referenced in subsequent capture requests.</p>
+     *
+     * <p>Surfaces that get removed must not be part of any active repeating or single/burst
+     * request or have any pending results. Consider updating any repeating requests first via
+     * {@link #setRepeatingRequest} or {@link #setRepeatingBurst} and then wait for the last frame
+     * number when the sequence completes {@link CaptureCallback#onCaptureSequenceCompleted}
+     * before calling updateOutputConfiguration to remove a previously active Surface.</p>
+     *
+     * <p>Surfaces that get added must not be part of any other registered
+     * {@link OutputConfiguration}.</p>
+     *
+     * @param config Modified output configuration.
+     *
+     * @throws CameraAccessException if the camera device is no longer connected or has
+     *                               encountered a fatal error.
+     * @throws IllegalArgumentException if an attempt was made to add a {@link Surface} already
+     *                               in use by another buffer-producing API, such as MediaCodec or
+     *                               a different camera device or {@link OutputConfiguration}; or
+     *                               new surfaces are not compatible (see
+     *                               {@link OutputConfiguration#enableSurfaceSharing}); or a
+     *                               {@link Surface} that was removed from the modified
+     *                               {@link OutputConfiguration} still has pending requests.
+     * @throws IllegalStateException if this session is no longer active, either because the session
+     *                               was explicitly closed, a new session has been created
+     *                               or the camera device has been closed.
+     */
+    public void updateOutputConfiguration(OutputConfiguration config)
+        throws CameraAccessException {
+        throw new UnsupportedOperationException("Subclasses must override this method");
+    }
+
+    /**
      * Close this capture session asynchronously.
      *
      * <p>Closing a session frees up the target output Surfaces of the session for reuse with either
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index c7654c9..374789c 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -314,6 +314,20 @@
     }
 
     @Override
+    public void updateOutputConfiguration(OutputConfiguration config)
+            throws CameraAccessException {
+        synchronized (mDeviceImpl.mInterfaceLock) {
+            checkNotClosed();
+
+            if (DEBUG) {
+                Log.v(TAG, mIdString + "updateOutputConfiguration");
+            }
+
+            mDeviceImpl.updateOutputConfiguration(config);
+        }
+    }
+
+    @Override
     public boolean isReprocessable() {
         return mInput != null;
     }
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index fec7fd9..8c4dbfa 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -235,6 +235,13 @@
     }
 
     @Override
+    public void updateOutputConfiguration(OutputConfiguration config)
+            throws CameraAccessException {
+        throw new UnsupportedOperationException("Constrained high speed session doesn't support"
+                + " this method");
+    }
+
+    @Override
     public void close() {
         mSessionImpl.close();
     }
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index bfeb14d..6787d84 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -764,6 +764,24 @@
         }
     }
 
+    public void updateOutputConfiguration(OutputConfiguration config)
+            throws CameraAccessException {
+        synchronized(mInterfaceLock) {
+            int streamId = -1;
+            for (int i = 0; i < mConfiguredOutputs.size(); i++) {
+                if (config.getSurface() == mConfiguredOutputs.valueAt(i).getSurface()) {
+                    streamId = mConfiguredOutputs.keyAt(i);
+                    break;
+                }
+            }
+            if (streamId == -1) {
+                throw new IllegalArgumentException("Invalid output configuration");
+            }
+
+            mRemoteDevice.updateOutputConfiguration(streamId, config);
+        }
+    }
+
     public void tearDown(Surface surface) throws CameraAccessException {
         if (surface == null) throw new IllegalArgumentException("Surface is null");
 
diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
index 27087a2..0978ff8 100644
--- a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
+++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java
@@ -215,6 +215,16 @@
         }
     }
 
+    public void updateOutputConfiguration(int streamId, OutputConfiguration config)
+            throws CameraAccessException {
+        try {
+            mRemoteDevice.updateOutputConfiguration(streamId, config);
+        } catch (Throwable t) {
+            CameraManager.throwAsPublicException(t);
+            throw new UnsupportedOperationException("Unexpected exception", t);
+        }
+    }
+
     public void finalizeOutputConfigurations(int streamId, OutputConfiguration deferredConfig)
             throws CameraAccessException {
         try {
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 49d4096..119cca8 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -646,6 +646,11 @@
     }
 
     @Override
+    public void updateOutputConfiguration(int streamId, OutputConfiguration config) {
+        // TODO: b/63912484 implement updateOutputConfiguration.
+    }
+
+    @Override
     public void waitUntilIdle() throws RemoteException {
         if (DEBUG) {
             Log.d(TAG, "waitUntilIdle called.");
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 2b317d6..7409671 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -42,6 +42,53 @@
  * A class for describing camera output, which contains a {@link Surface} and its specific
  * configuration for creating capture session.
  *
+ * <p>There are several ways to instantiate, modify and use OutputConfigurations. The most common
+ * and recommended usage patterns are summarized in the following list:</p>
+ *<ul>
+ * <li>Passing a {@link Surface} to the constructor and using the OutputConfiguration instance as
+ * argument to {@link CameraDevice#createCaptureSessionByOutputConfigurations}. This is the most
+ * frequent usage and clients should consider it first before other more complicated alternatives.
+ * </li>
+ *
+ * <li>Passing only a surface source class as an argument to the constructor. This is usually
+ * followed by a call to create a capture session
+ * (see {@link CameraDevice#createCaptureSessionByOutputConfigurations} and a {@link Surface} add
+ * call {@link #addSurface} with a valid {@link Surface}. The sequence completes with
+ * {@link CameraCaptureSession#finalizeOutputConfigurations}. This is the deferred usage case which
+ * aims to enhance performance by allowing the resource-intensive capture session create call to
+ * execute in parallel with any {@link Surface} initialization, such as waiting for a
+ * {@link android.view.SurfaceView} to be ready as part of the UI initialization.</li>
+ *
+ * <li>The third and most complex usage pattern inlvolves surface sharing. Once instantiated an
+ * OutputConfiguration can be enabled for surface sharing via {@link #enableSurfaceSharing}. This
+ * must be done before creating a new capture session and enables calls to
+ * {@link CameraCaptureSession#updateOutputConfiguration}. An OutputConfiguration with enabled
+ * surface sharing can be modified via {@link #addSurface} or {@link #removeSurface}. The updates
+ * to this OutputConfiguration will only come into effect after
+ * {@link CameraCaptureSession#updateOutputConfiguration} returns without throwing exceptions.
+ * Such updates can be done as long as the session is active. Clients should always consider the
+ * additional requirements and limitations placed on the output surfaces (for more details see
+ * {@link #enableSurfaceSharing}, {@link #addSurface}, {@link #removeSurface},
+ * {@link CameraCaptureSession#updateOutputConfiguration}). A trade-off exists between additional
+ * complexity and flexibility. If exercised correctly surface sharing can switch between different
+ * output surfaces without interrupting any ongoing repeating capture requests. This saves time and
+ * can significantly improve the user experience.</li>
+ *
+ * <li>Surface sharing can be used in combination with deferred surfaces. The rules from both cases
+ * are combined and clients must call {@link #enableSurfaceSharing} before creating a capture
+ * session. Attach and/or remove output surfaces via  {@link #addSurface}/{@link #removeSurface} and
+ * finalize the configuration using {@link CameraCaptureSession#finalizeOutputConfigurations}.
+ * {@link CameraCaptureSession#updateOutputConfiguration} can be called after the configuration
+ * finalize method returns without exceptions.</li>
+ *
+ * </ul>
+ *
+ * <p>Please note that surface sharing is currently only enabled for outputs that use the
+ * {@link ImageFormat#PRIVATE} format. This includes surface sources like
+ * {@link android.view.SurfaceView}, {@link android.media.MediaRecorder},
+ * {@link android.graphics.SurfaceTexture} and {@link android.media.ImageReader}, configured using
+ * the aforementioned format.</p>
+ *
  * @see CameraDevice#createCaptureSessionByOutputConfigurations
  *
  */
@@ -123,7 +170,7 @@
      * {@link OutputConfiguration#addSurface} should not exceed this value.</p>
      *
      */
-    private static final int MAX_SURFACES_COUNT = 2;
+    private static final int MAX_SURFACES_COUNT = 4;
 
     /**
      * Create a new {@link OutputConfiguration} instance with a {@link Surface},
@@ -280,7 +327,10 @@
      * <p>For advanced use cases, a camera application may require more streams than the combination
      * guaranteed by {@link CameraDevice#createCaptureSession}. In this case, more than one
      * compatible surface can be attached to an OutputConfiguration so that they map to one
-     * camera stream, and the outputs share memory buffers when possible. </p>
+     * camera stream, and the outputs share memory buffers when possible. Due to buffer sharing
+     * clients should be careful when adding surface outputs that modify their input data. If such
+     * case exists, camera clients should have an additional mechanism to synchronize read and write
+     * access between individual consumers.</p>
      *
      * <p>Two surfaces are compatible in the below cases:</p>
      *
@@ -301,9 +351,9 @@
      * CameraDevice#createCaptureSessionByOutputConfigurations}. Calling this function after {@link
      * CameraDevice#createCaptureSessionByOutputConfigurations} has no effect.</p>
      *
-     * <p>Up to 2 surfaces can be shared for an OutputConfiguration. The supported surfaces for
-     * sharing must be of type SurfaceTexture, SurfaceView, MediaRecorder, MediaCodec, or
-     * implementation defined ImageReader.</p>
+     * <p>Up to {@link #getMaxSharedSurfaceCount} surfaces can be shared for an OutputConfiguration.
+     * The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView,
+     * MediaRecorder, MediaCodec, or implementation defined ImageReader.</p>
      */
     public void enableSurfaceSharing() {
         mIsShared = true;
@@ -329,8 +379,10 @@
      * <p> This function can be called before or after {@link
      * CameraDevice#createCaptureSessionByOutputConfigurations}. If it's called after,
      * the application must finalize the capture session with
-     * {@link CameraCaptureSession#finalizeOutputConfigurations}.
-     * </p>
+     * {@link CameraCaptureSession#finalizeOutputConfigurations}. It is possible to call this method
+     * after the output configurations have been finalized only in cases of enabled surface sharing
+     * see {@link #enableSurfaceSharing}. The modified output configuration must be updated with
+     * {@link CameraCaptureSession#updateOutputConfiguration}.</p>
      *
      * <p> If the OutputConfiguration was constructed with a deferred surface by {@link
      * OutputConfiguration#OutputConfiguration(Size, Class)}, the added surface must be obtained
@@ -388,6 +440,31 @@
     }
 
     /**
+     * Remove a surface from this OutputConfiguration.
+     *
+     * <p> Surfaces added via calls to {@link #addSurface} can also be removed from the
+     *  OutputConfiguration. The only notable exception is the surface associated with
+     *  the OutputConfigration see {@link #getSurface} which was passed as part of the constructor
+     *  or was added first in the deferred case
+     *  {@link OutputConfiguration#OutputConfiguration(Size, Class)}.</p>
+     *
+     * @param surface The surface to be removed.
+     *
+     * @throws IllegalArgumentException If the surface is associated with this OutputConfiguration
+     *                                  (see {@link #getSurface}) or the surface didn't get added
+     *                                  with {@link #addSurface}.
+     */
+    public void removeSurface(@NonNull Surface surface) {
+        if (getSurface() == surface) {
+            throw new IllegalArgumentException(
+                    "Cannot remove surface associated with this output configuration");
+        }
+        if (!mSurfaces.remove(surface)) {
+            throw new IllegalArgumentException("Surface is not part of this output configuration");
+        }
+    }
+
+    /**
      * Create a new {@link OutputConfiguration} instance with another {@link OutputConfiguration}
      * instance.
      *
@@ -447,6 +524,17 @@
     }
 
     /**
+     * Get the maximum supported shared {@link Surface} count.
+     *
+     * @return the maximum number of surfaces that can be added per each OutputConfiguration.
+     *
+     * @see #enableSurfaceSharing
+     */
+    public static int getMaxSharedSurfaceCount() {
+        return MAX_SURFACES_COUNT;
+    }
+
+    /**
      * Get the {@link Surface} associated with this {@link OutputConfiguration}.
      *
      * If more than one surface is associated with this {@link OutputConfiguration}, return the
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.aidl b/core/java/android/hardware/display/BrightnessChangeEvent.aidl
new file mode 100644
index 0000000..942e0db
--- /dev/null
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+parcelable BrightnessChangeEvent;
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
new file mode 100644
index 0000000..fe24e32
--- /dev/null
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Data about a brightness settings change.
+ * TODO make this SystemAPI
+ * @hide
+ */
+public final class BrightnessChangeEvent implements Parcelable {
+    /** Brightness in nits */
+    public int brightness;
+
+    /** Timestamp of the change {@see System.currentTimeMillis()} */
+    public long timeStamp;
+
+    /** Package name of focused activity when brightness was changed. */
+    public String packageName;
+
+    /** User id of of the user running when brightness was changed.
+     * @hide */
+    public int userId;
+
+    /** Lux values of recent sensor data */
+    public float[] luxValues;
+
+    /** Timestamps of the lux sensor readings {@see System.currentTimeMillis()} */
+    public long[] luxTimestamps;
+
+    /** Most recent battery level when brightness was changed or Float.NaN */
+    public float batteryLevel;
+
+    /** Color filter active to provide night mode */
+    public boolean nightMode;
+
+    /** If night mode color filter is active this will be the temperature in kelvin */
+    public int colorTemperature;
+
+    /** Brightness level before slider adjustment */
+    public int lastBrightness;
+
+    public BrightnessChangeEvent() {
+    }
+
+    private BrightnessChangeEvent(Parcel source) {
+        brightness = source.readInt();
+        timeStamp = source.readLong();
+        packageName = source.readString();
+        userId = source.readInt();
+        luxValues = source.createFloatArray();
+        luxTimestamps = source.createLongArray();
+        batteryLevel = source.readFloat();
+        nightMode = source.readBoolean();
+        colorTemperature = source.readInt();
+        lastBrightness = source.readInt();
+    }
+
+    public static final Creator<BrightnessChangeEvent> CREATOR =
+            new Creator<BrightnessChangeEvent>() {
+                public BrightnessChangeEvent createFromParcel(Parcel source) {
+                    return new BrightnessChangeEvent(source);
+                }
+                public BrightnessChangeEvent[] newArray(int size) {
+                    return new BrightnessChangeEvent[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(brightness);
+        dest.writeLong(timeStamp);
+        dest.writeString(packageName);
+        dest.writeInt(userId);
+        dest.writeFloatArray(luxValues);
+        dest.writeLongArray(luxTimestamps);
+        dest.writeFloat(batteryLevel);
+        dest.writeBoolean(nightMode);
+        dest.writeInt(colorTemperature);
+        dest.writeInt(lastBrightness);
+    }
+}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index b2af44e..ef77d6e 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -30,6 +30,7 @@
 import android.view.WindowManagerPolicy;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Manages the properties of attached displays.
@@ -615,6 +616,21 @@
     }
 
     /**
+     * Fetch {@link BrightnessChangeEvent}s.
+     * @hide until we make it a system api.
+     */
+    public List<BrightnessChangeEvent> getBrightnessEvents() {
+        return mGlobal.getBrightnessEvents();
+    }
+
+    /**
+     * @hide STOPSHIP - remove when adaptive brightness accepts curves.
+     */
+    public void setBrightness(int brightness) {
+        mGlobal.setBrightness(brightness);
+    }
+
+    /**
      * Listens for changes in available display devices.
      */
     public interface DisplayListener {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index a8a4eb6..d93d0e4 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -17,6 +17,7 @@
 package android.hardware.display;
 
 import android.content.Context;
+import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -37,6 +38,8 @@
 import android.view.Surface;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Manager communication with the display manager service on behalf of
@@ -456,6 +459,33 @@
         }
     }
 
+    /**
+     * Retrieves brightness change events.
+     */
+    public List<BrightnessChangeEvent> getBrightnessEvents() {
+        try {
+            ParceledListSlice<BrightnessChangeEvent> events = mDm.getBrightnessEvents();
+            if (events == null) {
+                return Collections.emptyList();
+            }
+            return events.getList();
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set brightness but don't add a BrightnessChangeEvent
+     * STOPSHIP remove when adaptive brightness accepts curves.
+     */
+    public void setBrightness(int brightness) {
+        try {
+            mDm.setBrightness(brightness);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
         @Override
         public void onDisplayEvent(int displayId, int event) {
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 5053884..b796cf9 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.display;
 
+import android.content.pm.ParceledListSlice;
 import android.graphics.Point;
 import android.hardware.display.IDisplayManagerCallback;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -81,4 +82,11 @@
 
     // Get a stable metric for the device's display size. No permissions required.
     Point getStableDisplaySize();
+
+    // Requires BRIGHTNESS_SLIDER_USAGE permission.
+    ParceledListSlice getBrightnessEvents();
+
+    // STOPSHIP remove when adaptive brightness code is updated to accept curves.
+    // Requires BRIGHTNESS_SLIDER_USAGE permission.
+    void setBrightness(int brightness);
 }
diff --git a/core/java/android/net/metrics/NetworkEvent.java b/core/java/android/net/metrics/NetworkEvent.java
index 4df3bf0..1999e78 100644
--- a/core/java/android/net/metrics/NetworkEvent.java
+++ b/core/java/android/net/metrics/NetworkEvent.java
@@ -60,29 +60,25 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType {}
 
-    public final int netId;
     public final @EventType int eventType;
     public final long durationMs;
 
-    public NetworkEvent(int netId, @EventType int eventType, long durationMs) {
-        this.netId = netId;
+    public NetworkEvent(@EventType int eventType, long durationMs) {
         this.eventType = eventType;
         this.durationMs = durationMs;
     }
 
-    public NetworkEvent(int netId, @EventType int eventType) {
-        this(netId, eventType, 0);
+    public NetworkEvent(@EventType int eventType) {
+        this(eventType, 0);
     }
 
     private NetworkEvent(Parcel in) {
-        netId = in.readInt();
         eventType = in.readInt();
         durationMs = in.readLong();
     }
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
         out.writeInt(eventType);
         out.writeLong(durationMs);
     }
@@ -105,8 +101,8 @@
 
     @Override
     public String toString() {
-        return String.format("NetworkEvent(%d, %s, %dms)",
-                netId, Decoder.constants.get(eventType), durationMs);
+        return String.format("NetworkEvent(%s, %dms)",
+                Decoder.constants.get(eventType), durationMs);
     }
 
     final static class Decoder {
diff --git a/core/java/android/net/metrics/WakeupEvent.java b/core/java/android/net/metrics/WakeupEvent.java
index cbf3fc8..8f1a5c4 100644
--- a/core/java/android/net/metrics/WakeupEvent.java
+++ b/core/java/android/net/metrics/WakeupEvent.java
@@ -16,6 +16,10 @@
 
 package android.net.metrics;
 
+import android.net.MacAddress;
+
+import java.util.StringJoiner;
+
 /**
  * An event logged when NFLOG notifies userspace of a wakeup packet for
  * watched interfaces.
@@ -23,12 +27,35 @@
  */
 public class WakeupEvent {
     public String iface;
-    public long timestampMs;
     public int uid;
+    public int ethertype;
+    public byte[] dstHwAddr;
+    public String srcIp;
+    public String dstIp;
+    public int ipNextHeader;
+    public int srcPort;
+    public int dstPort;
+    public long timestampMs;
 
     @Override
     public String toString() {
-        return String.format("WakeupEvent(%tT.%tL, %s, uid: %d)",
-                timestampMs, timestampMs, iface, uid);
+        StringJoiner j = new StringJoiner(", ", "WakeupEvent(", ")");
+        j.add(String.format("%tT.%tL", timestampMs, timestampMs));
+        j.add(iface);
+        j.add("uid: " + Integer.toString(uid));
+        j.add("eth=0x" + Integer.toHexString(ethertype));
+        j.add("dstHw=" + MacAddress.stringAddrFromByteAddr(dstHwAddr));
+        if (ipNextHeader > 0) {
+            j.add("ipNxtHdr=" + ipNextHeader);
+            j.add("srcIp=" + srcIp);
+            j.add("dstIp=" + dstIp);
+            if (srcPort > -1) {
+                j.add("srcPort=" + srcPort);
+            }
+            if (dstPort > -1) {
+                j.add("dstPort=" + dstPort);
+            }
+        }
+        return j.toString();
     }
 }
diff --git a/core/java/android/net/metrics/WakeupStats.java b/core/java/android/net/metrics/WakeupStats.java
index 97e83f9..1ba9777 100644
--- a/core/java/android/net/metrics/WakeupStats.java
+++ b/core/java/android/net/metrics/WakeupStats.java
@@ -16,8 +16,12 @@
 
 package android.net.metrics;
 
+import android.net.MacAddress;
 import android.os.Process;
 import android.os.SystemClock;
+import android.util.SparseIntArray;
+
+import java.util.StringJoiner;
 
 /**
  * An event logged per interface and that aggregates WakeupEvents for that interface.
@@ -38,6 +42,13 @@
     public long noUidWakeups = 0;
     public long durationSec = 0;
 
+    public long l2UnicastCount = 0;
+    public long l2MulticastCount = 0;
+    public long l2BroadcastCount = 0;
+
+    public final SparseIntArray ethertypes = new SparseIntArray();
+    public final SparseIntArray ipNextHeaders = new SparseIntArray();
+
     public WakeupStats(String iface) {
         this.iface = iface;
     }
@@ -68,20 +79,56 @@
                 }
                 break;
         }
+
+        switch (MacAddress.macAddressType(ev.dstHwAddr)) {
+            case UNICAST:
+                l2UnicastCount++;
+                break;
+            case MULTICAST:
+                l2MulticastCount++;
+                break;
+            case BROADCAST:
+                l2BroadcastCount++;
+                break;
+            default:
+                break;
+        }
+
+        increment(ethertypes, ev.ethertype);
+        if (ev.ipNextHeader >= 0) {
+            increment(ipNextHeaders, ev.ipNextHeader);
+        }
     }
 
     @Override
     public String toString() {
         updateDuration();
-        return new StringBuilder()
-                .append("WakeupStats(").append(iface)
-                .append(", total: ").append(totalWakeups)
-                .append(", root: ").append(rootWakeups)
-                .append(", system: ").append(systemWakeups)
-                .append(", apps: ").append(applicationWakeups)
-                .append(", non-apps: ").append(nonApplicationWakeups)
-                .append(", no uid: ").append(noUidWakeups)
-                .append(", ").append(durationSec).append("s)")
-                .toString();
+        StringJoiner j = new StringJoiner(", ", "WakeupStats(", ")");
+        j.add(iface);
+        j.add("" + durationSec + "s");
+        j.add("total: " + totalWakeups);
+        j.add("root: " + rootWakeups);
+        j.add("system: " + systemWakeups);
+        j.add("apps: " + applicationWakeups);
+        j.add("non-apps: " + nonApplicationWakeups);
+        j.add("no uid: " + noUidWakeups);
+        j.add(String.format("l2 unicast/multicast/broadcast: %d/%d/%d",
+                l2UnicastCount, l2MulticastCount, l2BroadcastCount));
+        for (int i = 0; i < ethertypes.size(); i++) {
+            int eth = ethertypes.keyAt(i);
+            int count = ethertypes.valueAt(i);
+            j.add(String.format("ethertype 0x%x: %d", eth, count));
+        }
+        for (int i = 0; i < ipNextHeaders.size(); i++) {
+            int proto = ipNextHeaders.keyAt(i);
+            int count = ipNextHeaders.valueAt(i);
+            j.add(String.format("ipNxtHdr %d: %d", proto, count));
+        }
+        return j.toString();
+    }
+
+    private static void increment(SparseIntArray counters, int key) {
+        int newcount = counters.get(key, 0) + 1;
+        counters.put(key, newcount);
     }
 }
diff --git a/core/java/android/os/IStatsCompanionService.aidl b/core/java/android/os/IStatsCompanionService.aidl
index c0a95cc..3314f60 100644
--- a/core/java/android/os/IStatsCompanionService.aidl
+++ b/core/java/android/os/IStatsCompanionService.aidl
@@ -53,4 +53,7 @@
 
     /** Pull the specified data. Results will be sent to statsd when complete. */
     StatsLogEventWrapper[] pullData(int pullCode);
+
+    /** Send a broadcast to the specified pkg and class that it should getData now. */
+    oneway void sendBroadcast(String pkg, String cls);
 }
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 480296c..a6c3009 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -65,13 +65,26 @@
     oneway void informOnePackageRemoved(in String app, in int uid);
 
     /**
-     * Trigger pushLog to force push stats log entries from statsd on client side.
+     * Fetches data for the specified configuration key. Returns a byte array representing proto
+     * wire-encoded of ConfigMetricsReport.
      */
-    void requestPush();
+    byte[] getData(in String key);
 
     /**
-     * Listen to statsd to send stats log entries.
-     * TODO: Limit callbacks with specific configurations.
+     * Sets a configuration with the specified config key and subscribes to updates for this
+     * configuration key. Broadcasts will be sent if this configuration needs to be collected.
+     * The configuration must be a wire-encoded StatsDConfig. The caller specifies the name of the
+     * package and class that should receive these broadcasts.
+     *
+     * Returns if this configuration was correctly registered.
      */
-    void subscribeStatsLog(IStatsCallbacks callbacks);
+    boolean addConfiguration(in String configKey, in byte[] config, in String pkg, in String cls);
+
+    /**
+     * Removes the configuration with the matching config key. No-op if this config key does not
+     * exist.
+     *
+     * Returns if this configuration key was removed.
+     */
+    boolean removeConfiguration(in String configKey);
 }
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index e426356..5d96fd3 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -94,4 +94,5 @@
     boolean isUserUnlocked(int userId);
     boolean isUserRunning(int userId);
     boolean isUserNameSet(int userHandle);
+    boolean hasRestrictedProfiles();
 }
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index e8ebf63..6381b56 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -27,6 +27,8 @@
  * Representation of a user on the device.
  */
 public final class UserHandle implements Parcelable {
+    // NOTE: keep logic in sync with system/core/libcutils/multiuser.c
+
     /**
      * @hide Range of uids allocated for a user.
      */
@@ -88,6 +90,19 @@
      */
     public static final boolean MU_ENABLED = true;
 
+    /** @hide */
+    public static final int ERR_GID = -1;
+    /** @hide */
+    public static final int AID_ROOT = android.os.Process.ROOT_UID;
+    /** @hide */
+    public static final int AID_APP_START = android.os.Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static final int AID_APP_END = android.os.Process.LAST_APPLICATION_UID;
+    /** @hide */
+    public static final int AID_SHARED_GID_START = android.os.Process.FIRST_SHARED_APPLICATION_GID;
+    /** @hide */
+    public static final int AID_CACHE_GID_START = android.os.Process.FIRST_APPLICATION_CACHE_GID;
+
     final int mHandle;
 
     /**
@@ -197,13 +212,20 @@
         return getUid(userId, Process.SHARED_USER_GID);
     }
 
-    /**
-     * Returns the shared app gid for a given uid or appId.
-     * @hide
-     */
-    public static int getSharedAppGid(int id) {
-        return Process.FIRST_SHARED_APPLICATION_GID + (id % PER_USER_RANGE)
-                - Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static int getSharedAppGid(int uid) {
+        return getSharedAppGid(getUserId(uid), getAppId(uid));
+    }
+
+    /** @hide */
+    public static int getSharedAppGid(int userId, int appId) {
+        if (appId >= AID_APP_START && appId <= AID_APP_END) {
+            return (appId - AID_APP_START) + AID_SHARED_GID_START;
+        } else if (appId >= AID_ROOT && appId <= AID_APP_START) {
+            return appId;
+        } else {
+            return -1;
+        }
     }
 
     /**
@@ -219,13 +241,18 @@
         return appId;
     }
 
-    /**
-     * Returns the cache GID for a given UID or appId.
-     * @hide
-     */
-    public static int getCacheAppGid(int id) {
-        return Process.FIRST_APPLICATION_CACHE_GID + (id % PER_USER_RANGE)
-                - Process.FIRST_APPLICATION_UID;
+    /** @hide */
+    public static int getCacheAppGid(int uid) {
+        return getCacheAppGid(getUserId(uid), getAppId(uid));
+    }
+
+    /** @hide */
+    public static int getCacheAppGid(int userId, int appId) {
+        if (appId >= AID_APP_START && appId <= AID_APP_END) {
+            return getUid(userId, (appId - AID_APP_START) + AID_CACHE_GID_START);
+        } else {
+            return -1;
+        }
     }
 
     /**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index de52736..22967af 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1049,12 +1049,22 @@
     }
 
     /**
-     * Used to check if the user making this call is linked to another user. Linked users may have
+     * @hide
+     * @deprecated Use {@link #isRestrictedProfile()}
+     */
+    @Deprecated
+    public boolean isLinkedUser() {
+        return isRestrictedProfile();
+    }
+
+    /**
+     * Returns whether the caller is running as restricted profile. Restricted profile may have
      * a reduced number of available apps, app restrictions and account restrictions.
      * @return whether the user making this call is a linked user
      * @hide
      */
-    public boolean isLinkedUser() {
+    @SystemApi
+    public boolean isRestrictedProfile() {
         try {
             return mService.isRestricted();
         } catch (RemoteException re) {
@@ -1075,6 +1085,20 @@
     }
 
     /**
+     * Returns whether the calling user has at least one restricted profile associated with it.
+     * @return
+     * @hide
+     */
+    @SystemApi
+    public boolean hasRestrictedProfiles() {
+        try {
+            return mService.hasRestrictedProfiles();
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Checks if a user is a guest user.
      * @return whether user is a guest user.
      * @hide
@@ -1094,6 +1118,7 @@
         return user != null && user.isGuest();
     }
 
+
     /**
      * Checks if the calling app is running in a demo user. When running in a demo user,
      * apps can be more helpful to the user, or explain their features in more detail.
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index 73fa01e..4c556ef 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -23,7 +23,6 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -105,7 +104,10 @@
  *
  * @see Preference
  * @see PreferenceScreen
+ *
+ * @deprecated Use {@link android.support.v7.preference.PreferenceFragmentCompat}
  */
+@Deprecated
 public abstract class PreferenceFragment extends Fragment implements
         PreferenceManager.OnPreferenceTreeClickListener {
 
@@ -146,7 +148,11 @@
      * Interface that PreferenceFragment's containing activity should
      * implement to be able to process preference items that wish to
      * switch to a new fragment.
+     *
+     * @deprecated Use {@link
+     * android.support.v7.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback}
      */
+    @Deprecated
     public interface OnPreferenceStartFragmentCallback {
         /**
          * Called when the user has clicked on a Preference that has
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
old mode 100755
new mode 100644
index 1bef2b3..16e7f30
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -66,6 +66,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.speech.tts.TextToSpeech;
+import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 import android.util.AndroidException;
 import android.util.ArrayMap;
@@ -2113,6 +2114,9 @@
      * functions for accessing individual settings entries.
      */
     public static final class System extends NameValueTable {
+        // NOTE: If you add new settings here, be sure to add them to
+        // com.android.providers.settings.SettingsProtoDumpUtil#dumpProtoSystemSettingsLocked.
+
         private static final float DEFAULT_FONT_SCALE = 1.0f;
 
         /** @hide */
@@ -4562,6 +4566,9 @@
      * APIs for those values, not modified directly by applications.
      */
     public static final class Secure extends NameValueTable {
+        // NOTE: If you add new settings here, be sure to add them to
+        // com.android.providers.settings.SettingsProtoDumpUtil#dumpProtoSecureSettingsLocked.
+
         /**
          * The content:// style URL for this table
          */
@@ -7564,6 +7571,9 @@
      * explicitly modify through the system UI or specialized APIs for those values.
      */
     public static final class Global extends NameValueTable {
+        // NOTE: If you add new settings here, be sure to add them to
+        // com.android.providers.settings.SettingsProtoDumpUtil#dumpProtoGlobalSettingsLocked.
+
         /**
          * The content:// style URL for global secure settings items.  Not public.
          */
@@ -10144,12 +10154,17 @@
         public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
 
         /**
-         * Whether the Volte is enabled
+         * Whether the Volte is enabled. If this setting is not set then we use the Carrier Config
+         * value {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
          * <p>
          * Type: int (0 for false, 1 for true)
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#ENHANCED_4G_MODE_ENABLED}
+         * instead.
          */
-        public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
+        @Deprecated
+        public static final String ENHANCED_4G_MODE_ENABLED =
+                SubscriptionManager.ENHANCED_4G_MODE_ENABLED;
 
         /**
          * Whether VT (Video Telephony over IMS) is enabled
@@ -10157,8 +10172,10 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#VT_IMS_ENABLED} instead.
          */
-        public static final String VT_IMS_ENABLED = "vt_ims_enabled";
+        @Deprecated
+        public static final String VT_IMS_ENABLED = SubscriptionManager.VT_IMS_ENABLED;
 
         /**
          * Whether WFC is enabled
@@ -10166,8 +10183,10 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#WFC_IMS_ENABLED} instead.
          */
-        public static final String WFC_IMS_ENABLED = "wfc_ims_enabled";
+        @Deprecated
+        public static final String WFC_IMS_ENABLED = SubscriptionManager.WFC_IMS_ENABLED;
 
         /**
          * WFC mode on home/non-roaming network.
@@ -10175,8 +10194,10 @@
          * Type: int - 2=Wi-Fi preferred, 1=Cellular preferred, 0=Wi-Fi only
          *
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#WFC_IMS_MODE} instead.
          */
-        public static final String WFC_IMS_MODE = "wfc_ims_mode";
+        @Deprecated
+        public static final String WFC_IMS_MODE = SubscriptionManager.WFC_IMS_MODE;
 
         /**
          * WFC mode on roaming network.
@@ -10184,8 +10205,11 @@
          * Type: int - see {@link #WFC_IMS_MODE} for values
          *
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#WFC_IMS_ROAMING_MODE}
+         * instead.
          */
-        public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
+        @Deprecated
+        public static final String WFC_IMS_ROAMING_MODE = SubscriptionManager.WFC_IMS_ROAMING_MODE;
 
         /**
          * Whether WFC roaming is enabled
@@ -10193,8 +10217,12 @@
          * Type: int (0 for false, 1 for true)
          *
          * @hide
+         * @deprecated Use {@link android.telephony.SubscriptionManager#WFC_IMS_ROAMING_ENABLED}
+         * instead
          */
-        public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
+        @Deprecated
+        public static final String WFC_IMS_ROAMING_ENABLED =
+                SubscriptionManager.WFC_IMS_ROAMING_ENABLED;
 
         /**
          * Whether user can enable/disable LTE as a preferred network. A carrier might control
@@ -10875,7 +10903,7 @@
 
         /** User preferred subscriptions setting.
           * This holds the details of the user selected subscription from the card and
-          * the activation status. Each settings string have the coma separated values
+          * the activation status. Each settings string have the comma separated values
           * iccId,appType,appId,activationStatus,3gppIndex,3gpp2Index
           * @hide
          */
diff --git a/core/java/android/util/StatsManager.java b/core/java/android/util/StatsManager.java
new file mode 100644
index 0000000..55b33a6
--- /dev/null
+++ b/core/java/android/util/StatsManager.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.os.IBinder;
+import android.os.IStatsManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+/**
+ * API for StatsD clients to send configurations and retrieve data.
+ *
+ * @hide
+ */
+@SystemApi
+public final class StatsManager {
+    IStatsManager mService;
+    private static final String TAG = "StatsManager";
+
+    /**
+     * Constructor for StatsManagerClient.
+     *
+     * @hide
+     */
+    public StatsManager() {
+    }
+
+    /**
+     * Clients can send a configuration and simultaneously registers the name of a broadcast
+     * receiver that listens for when it should request data.
+     *
+     * @param configKey An arbitrary string that allows clients to track the configuration.
+     * @param config    Wire-encoded StatsDConfig proto that specifies metrics (and all
+     *                  dependencies eg, conditions and matchers).
+     * @param pkg       The package name to receive the broadcast.
+     * @param cls       The name of the class that receives the broadcast.
+     * @return true if successful
+     */
+    @RequiresPermission(Manifest.permission.DUMP)
+    public boolean addConfiguration(String configKey, byte[] config, String pkg, String cls) {
+        synchronized (this) {
+            try {
+                IStatsManager service = getIStatsManagerLocked();
+                if (service == null) {
+                    throw new RuntimeException("StatsD service connection lost");
+                }
+                return service.addConfiguration(configKey, config, pkg, cls);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Failed to connect to statsd when getting data");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Remove a configuration from logging.
+     *
+     * @param configKey Configuration key to remove.
+     * @return true if successful
+     */
+    @RequiresPermission(Manifest.permission.DUMP)
+    public boolean removeConfiguration(String configKey) {
+        synchronized (this) {
+            try {
+                IStatsManager service = getIStatsManagerLocked();
+                if (service == null) {
+                    throw new RuntimeException("StatsD service connection lost");
+                }
+                return service.removeConfiguration(configKey);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Failed to connect to statsd when getting data");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Clients can request data with a binder call.
+     *
+     * @param configKey Configuration key to retrieve data from.
+     * @return Serialized ConfigMetricsReport proto. Returns null on failure.
+     */
+    @RequiresPermission(Manifest.permission.DUMP)
+    public byte[] getData(String configKey) {
+        synchronized (this) {
+            try {
+                IStatsManager service = getIStatsManagerLocked();
+                if (service == null) {
+                    throw new RuntimeException("StatsD service connection lost");
+                }
+                return service.getData(configKey);
+            } catch (RemoteException e) {
+                Slog.d(TAG, "Failed to connecto statsd when getting data");
+                return null;
+            }
+        }
+    }
+
+    private class StatsdDeathRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            synchronized (this) {
+                mService = null;
+            }
+        }
+    }
+
+    private IStatsManager getIStatsManagerLocked() throws RemoteException {
+        if (mService != null) {
+            return mService;
+        }
+        mService = IStatsManager.Stub.asInterface(ServiceManager.getService("stats"));
+        if (mService != null) {
+            mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
+        }
+        return mService;
+    }
+}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 107013a..2ad6e02 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -235,7 +235,9 @@
             if (mSmartSelection == null || !Objects.equals(mLocale, locale)) {
                 destroySmartSelectionIfExistsLocked();
                 final ParcelFileDescriptor fd = getFdLocked(locale);
-                mSmartSelection = new SmartSelection(fd.getFd());
+                final int modelFd = fd.getFd();
+                mVersion = SmartSelection.getVersion(modelFd);
+                mSmartSelection = new SmartSelection(modelFd);
                 closeAndLogError(fd);
                 mLocale = locale;
             }
@@ -256,18 +258,26 @@
     @GuardedBy("mSmartSelectionLock") // Do not call outside this lock.
     private ParcelFileDescriptor getFdLocked(Locale locale) throws FileNotFoundException {
         ParcelFileDescriptor updateFd;
+        int updateVersion = -1;
         try {
             updateFd = ParcelFileDescriptor.open(
                     new File(UPDATED_MODEL_FILE_PATH), ParcelFileDescriptor.MODE_READ_ONLY);
+            if (updateFd != null) {
+                updateVersion = SmartSelection.getVersion(updateFd.getFd());
+            }
         } catch (FileNotFoundException e) {
             updateFd = null;
         }
         ParcelFileDescriptor factoryFd;
+        int factoryVersion = -1;
         try {
             final String factoryModelFilePath = getFactoryModelFilePathsLocked().get(locale);
             if (factoryModelFilePath != null) {
                 factoryFd = ParcelFileDescriptor.open(
                         new File(factoryModelFilePath), ParcelFileDescriptor.MODE_READ_ONLY);
+                if (factoryFd != null) {
+                    factoryVersion = SmartSelection.getVersion(factoryFd.getFd());
+                }
             } else {
                 factoryFd = null;
             }
@@ -303,15 +313,11 @@
             return factoryFd;
         }
 
-        final int updateVersion = SmartSelection.getVersion(updateFdInt);
-        final int factoryVersion = SmartSelection.getVersion(factoryFd.getFd());
         if (updateVersion > factoryVersion) {
             closeAndLogError(factoryFd);
-            mVersion = updateVersion;
             return updateFd;
         } else {
             closeAndLogError(updateFd);
-            mVersion = factoryVersion;
             return factoryFd;
         }
     }
diff --git a/core/java/android/webkit/WebViewFragment.java b/core/java/android/webkit/WebViewFragment.java
index d803f62d..e5b7c8d 100644
--- a/core/java/android/webkit/WebViewFragment.java
+++ b/core/java/android/webkit/WebViewFragment.java
@@ -27,7 +27,10 @@
  * A fragment that displays a WebView.
  * <p>
  * The WebView is automically paused or resumed when the Fragment is paused or resumed.
+ *
+ * @deprecated Manually call {@link WebView#onPause()} and {@link WebView#onResume()}
  */
+@Deprecated
 public class WebViewFragment extends Fragment {
     private WebView mWebView;
     private boolean mIsWebViewAvailable;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 170582b..e0c897d 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3866,6 +3866,7 @@
     private void onTouchDown(MotionEvent ev) {
         mHasPerformedLongPress = false;
         mActivePointerId = ev.getPointerId(0);
+        hideSelector();
 
         if (mTouchMode == TOUCH_MODE_OVERFLING) {
             // Stopped the fling. It is a scroll.
@@ -5226,17 +5227,21 @@
         }
 
         mRecycler.fullyDetachScrapViews();
+        boolean selectorOnScreen = false;
         if (!inTouchMode && mSelectedPosition != INVALID_POSITION) {
             final int childIndex = mSelectedPosition - mFirstPosition;
             if (childIndex >= 0 && childIndex < getChildCount()) {
                 positionSelector(mSelectedPosition, getChildAt(childIndex));
+                selectorOnScreen = true;
             }
         } else if (mSelectorPosition != INVALID_POSITION) {
             final int childIndex = mSelectorPosition - mFirstPosition;
             if (childIndex >= 0 && childIndex < getChildCount()) {
-                positionSelector(INVALID_POSITION, getChildAt(childIndex));
+                positionSelector(mSelectorPosition, getChildAt(childIndex));
+                selectorOnScreen = true;
             }
-        } else {
+        }
+        if (!selectorOnScreen) {
             mSelectorRect.setEmpty();
         }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 7451d31..d477ffd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3842,14 +3842,10 @@
                 mProcessTextIntentActionsHandler.onInitializeMenu(menu);
             }
 
-            if (menu.hasVisibleItems() || mode.getCustomView() != null) {
-                if (mHasSelection && !mTextView.hasTransientState()) {
-                    mTextView.setHasTransientState(true);
-                }
-                return true;
-            } else {
-                return false;
+            if (mHasSelection && !mTextView.hasTransientState()) {
+                mTextView.setHasTransientState(true);
             }
+            return true;
         }
 
         private Callback getCustomCallback() {
diff --git a/core/java/com/android/internal/util/RingBuffer.java b/core/java/com/android/internal/util/RingBuffer.java
index ad84353..c22be2c 100644
--- a/core/java/com/android/internal/util/RingBuffer.java
+++ b/core/java/com/android/internal/util/RingBuffer.java
@@ -45,6 +45,17 @@
         return (int) Math.min(mBuffer.length, (long) mCursor);
     }
 
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    public void clear() {
+        for (int i = 0; i < size(); ++i) {
+            mBuffer[i] = null;
+        }
+        mCursor = 0;
+    }
+
     public void append(T t) {
         mBuffer[indexOf(mCursor++)] = t;
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index fb8b9f7..3552e43 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -28,10 +28,6 @@
         "-Wunused",
         "-Wunreachable-code",
 
-        // necessary for Clang as the GL bindings need to turn
-        // off a GCC warning that Clang doesn't know.
-        "-Wno-unknown-pragmas",
-
         // TODO: Linear blending should be enabled by default, but we are
         // TODO: making it an opt-in while it's a work in progress
         //"-DANDROID_ENABLE_LINEAR_BLENDING",
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 6163588..a9d75fd 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/jni/android_opengl_EGLExt.cpp b/core/jni/android_opengl_EGLExt.cpp
index df1aa20..75a25fe 100644
--- a/core/jni/android_opengl_EGLExt.cpp
+++ b/core/jni/android_opengl_EGLExt.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 6d4f6ec..ee5b594 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index e630cfca..da7d0f0 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index ab9cbb1..391ae53 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 8f71a6d..09dce32 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES/gl.h>
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index f83d204..99922cf 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES2/gl2.h>
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index b649daf..adc635e 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES3/gl3.h>
diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp
index 07d920f..512f562 100644
--- a/core/jni/android_opengl_GLES31.cpp
+++ b/core/jni/android_opengl_GLES31.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <stdint.h>
diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp
index 723dd4c..5543fca 100644
--- a/core/jni/android_opengl_GLES31Ext.cpp
+++ b/core/jni/android_opengl_GLES31Ext.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <GLES3/gl31.h>
diff --git a/core/jni/android_opengl_GLES32.cpp b/core/jni/android_opengl_GLES32.cpp
index 62a6e6c..2f1e31e 100644
--- a/core/jni/android_opengl_GLES32.cpp
+++ b/core/jni/android_opengl_GLES32.cpp
@@ -17,7 +17,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include <stdint.h>
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index ac23eca..40ff7e4 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -18,7 +18,6 @@
 // This source file is automatically generated
 
 #pragma GCC diagnostic ignored "-Wunused-variable"
-#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
 #pragma GCC diagnostic ignored "-Wunused-function"
 
 #include "jni.h"
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 55ea285..4c3e937 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -20,12 +20,12 @@
 
 import "frameworks/base/libs/incident/proto/android/privacy.proto";
 import "frameworks/base/libs/incident/proto/android/section.proto";
-import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/os/cpuinfo.proto";
 import "frameworks/base/core/proto/android/os/incidentheader.proto";
 import "frameworks/base/core/proto/android/os/kernelwake.proto";
 import "frameworks/base/core/proto/android/os/pagetypeinfo.proto";
 import "frameworks/base/core/proto/android/os/procrank.proto";
+import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
 import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto";
 import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
@@ -86,7 +86,11 @@
         (section).args = "netstats --proto"
     ];
 
-    optional android.providers.settings.SettingsServiceDumpProto settings = 3002;
+    optional android.providers.settings.SettingsServiceDumpProto settings = 3002 [
+        (section).type = SECTION_DUMPSYS,
+        (section).args = "settings --proto"
+    ];
+
     optional android.service.appwidget.AppWidgetServiceDumpProto appwidget = 3003;
     optional android.service.notification.NotificationServiceDumpProto notification = 3004 [
         (section).type = SECTION_DUMPSYS,
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 3411c6a..764288c 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -39,9 +39,10 @@
     optional SystemSettingsProto system_settings = 3;
 }
 
+// Note: it's a conscious decision to add each setting as a separate field. This
+// allows annotating each setting with its own privacy tag.
 message GlobalSettingsProto {
-    // Historical operations
-    repeated SettingsOperationProto historical_op = 1;
+    repeated SettingsOperationProto historical_operations = 1;
 
     optional SettingProto add_users_when_locked = 2;
     optional SettingProto enable_accessibility_global_gesture_enabled = 3;
@@ -54,6 +55,7 @@
     optional SettingProto radio_nfc = 10;
     optional SettingProto airplane_mode_radios = 11;
     optional SettingProto airplane_mode_toggleable_radios = 12;
+    optional SettingProto bluetooth_class_of_device = 293;
     optional SettingProto bluetooth_disabled_profiles = 13;
     optional SettingProto bluetooth_interoperability_list = 14;
     optional SettingProto wifi_sleep_policy = 15;
@@ -86,6 +88,7 @@
     optional SettingProto data_roaming = 42;
     optional SettingProto mdc_initial_max_retry = 43;
     optional SettingProto force_allow_on_external = 44;
+    optional SettingProto euicc_provisioned = 294;
     optional SettingProto development_force_resizable_activities = 45;
     optional SettingProto development_enable_freeform_windows_support = 46;
     optional SettingProto development_settings_enabled = 47;
@@ -99,6 +102,11 @@
     optional SettingProto hdmi_system_audio_control_enabled = 55;
     optional SettingProto hdmi_control_auto_wakeup_enabled = 56;
     optional SettingProto hdmi_control_auto_device_off_enabled = 57;
+    optional SettingProto location_background_throttle_interval_ms = 295;
+    optional SettingProto location_background_throttle_proximity_alert_interval_ms = 296;
+    optional SettingProto location_background_throttle_package_whitelist = 297;
+    optional SettingProto wifi_scan_background_throttle_interval_ms = 298;
+    optional SettingProto wifi_scan_background_throttle_package_whitelist = 299;
     optional SettingProto mhl_input_switching_enabled = 58;
     optional SettingProto mhl_power_charge_enabled = 59;
     optional SettingProto mobile_data = 60;
@@ -109,6 +117,7 @@
     optional SettingProto netstats_time_cache_max_age = 65;
     optional SettingProto netstats_global_alert_bytes = 66;
     optional SettingProto netstats_sample_enabled = 67;
+    optional SettingProto netstats_augment_enabled = 300;
     optional SettingProto netstats_dev_bucket_duration = 68;
     optional SettingProto netstats_dev_persist_bytes = 69;
     optional SettingProto netstats_dev_rotate_age = 70;
@@ -156,6 +165,7 @@
     optional SettingProto tether_supported = 113;
     optional SettingProto tether_dun_required = 114;
     optional SettingProto tether_dun_apn = 115;
+    optional SettingProto tether_offload_disabled = 301;
     optional SettingProto carrier_app_whitelist = 116;
     optional SettingProto usb_mass_storage_enabled = 117;
     optional SettingProto use_google_mail = 118;
@@ -166,6 +176,9 @@
     optional SettingProto network_switch_notification_daily_limit = 123;
     optional SettingProto network_switch_notification_rate_limit_millis = 124;
     optional SettingProto network_avoid_bad_wifi = 125;
+    optional SettingProto network_metered_multipath_preference = 302;
+    optional SettingProto network_watchlist_last_report_time = 303;
+    optional SettingProto wifi_badging_thresholds = 304;
     optional SettingProto wifi_display_on = 126;
     optional SettingProto wifi_display_certification_on = 127;
     optional SettingProto wifi_display_wps_config = 128;
@@ -179,7 +192,14 @@
     optional SettingProto wifi_on = 136;
     optional SettingProto wifi_scan_always_available = 137;
     optional SettingProto wifi_wakeup_enabled = 138;
+    optional SettingProto wifi_wakeup_available = 305;
+    optional SettingProto network_scoring_ui_enabled = 306;
+    optional SettingProto speed_label_cache_eviction_age_millis = 307;
+    optional SettingProto recommended_network_evaluator_cache_expiry_ms = 308;
     optional SettingProto network_recommendations_enabled = 139;
+    optional SettingProto network_recommendations_package = 286;
+    optional SettingProto use_open_wifi_package = 309;
+    optional SettingProto network_recommendation_request_timeout_ms = 310;
     optional SettingProto ble_scan_always_available = 140;
     optional SettingProto wifi_saved_state = 141;
     optional SettingProto wifi_supplicant_scan_interval_ms = 142;
@@ -219,15 +239,19 @@
     optional SettingProto sys_storage_threshold_percentage = 176;
     optional SettingProto sys_storage_threshold_max_bytes = 177;
     optional SettingProto sys_storage_full_threshold_bytes = 178;
+    optional SettingProto sys_storage_cache_percentage = 311;
+    optional SettingProto sys_storage_cache_max_bytes = 312;
     optional SettingProto sync_max_retry_delay_in_seconds = 179;
     optional SettingProto connectivity_change_delay = 180;
     optional SettingProto connectivity_sampling_interval_in_seconds = 181;
     optional SettingProto pac_change_delay = 182;
     optional SettingProto captive_portal_mode = 183;
+    optional SettingProto captive_portal_detection_enabled = 313;
     optional SettingProto captive_portal_server = 184;
     optional SettingProto captive_portal_https_url = 185;
     optional SettingProto captive_portal_http_url = 186;
     optional SettingProto captive_portal_fallback_url = 187;
+    optional SettingProto captive_portal_other_fallback_urls = 314;
     optional SettingProto captive_portal_use_https = 188;
     optional SettingProto captive_portal_user_agent = 189;
     optional SettingProto nsd_on = 190;
@@ -243,21 +267,33 @@
     optional SettingProto global_http_proxy_pac = 200;
     optional SettingProto set_global_http_proxy = 201;
     optional SettingProto default_dns_server = 202;
+    // The requested Private DNS mode and an accompanying specifier.
+    optional SettingProto private_dns_mode = 315;
+    optional SettingProto private_dns_specifier = 316;
     optional SettingProto bluetooth_headset_priority_prefix = 203;
     optional SettingProto bluetooth_a2dp_sink_priority_prefix = 204;
     optional SettingProto bluetooth_a2dp_src_priority_prefix = 205;
+    optional SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
+    optional SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
     optional SettingProto bluetooth_input_device_priority_prefix = 206;
     optional SettingProto bluetooth_map_priority_prefix = 207;
     optional SettingProto bluetooth_map_client_priority_prefix = 208;
     optional SettingProto bluetooth_pbap_client_priority_prefix = 209;
     optional SettingProto bluetooth_sap_priority_prefix = 210;
     optional SettingProto bluetooth_pan_priority_prefix = 211;
+    optional SettingProto activity_manager_constants = 317;
     optional SettingProto device_idle_constants = 212;
     optional SettingProto device_idle_constants_watch = 213;
+    optional SettingProto battery_saver_constants = 318;
+    optional SettingProto anomaly_detection_constants = 319;
+    optional SettingProto always_on_display_constants = 320;
     optional SettingProto app_idle_constants = 214;
+    optional SettingProto power_manager_constants = 321;
     optional SettingProto alarm_manager_constants = 215;
     optional SettingProto job_scheduler_constants = 216;
     optional SettingProto shortcut_manager_constants = 217;
+    optional SettingProto device_policy_constants = 322;
+    optional SettingProto text_classifier_constants = 323;
     optional SettingProto window_animation_scale = 218;
     optional SettingProto transition_animation_scale = 219;
     optional SettingProto animator_duration_scale = 220;
@@ -287,6 +323,10 @@
     optional SettingProto cert_pin_update_metadata_url = 244;
     optional SettingProto intent_firewall_update_content_url = 245;
     optional SettingProto intent_firewall_update_metadata_url = 246;
+    optional SettingProto lang_id_update_content_url = 324;
+    optional SettingProto lang_id_update_metadata_url = 325;
+    optional SettingProto smart_selection_update_content_url = 326;
+    optional SettingProto smart_selection_update_metadata_url = 327;
     optional SettingProto selinux_status = 247;
     optional SettingProto development_force_rtl = 248;
     optional SettingProto low_battery_sound_timeout = 249;
@@ -308,13 +348,24 @@
     optional SettingProto lte_service_forced = 265;
     optional SettingProto ephemeral_cookie_max_size_bytes = 266;
     optional SettingProto enable_ephemeral_feature = 267;
+    optional SettingProto instant_app_dexopt_enabled = 328;
     optional SettingProto installed_instant_app_min_cache_period = 268;
+    optional SettingProto installed_instant_app_max_cache_period = 289;
+    optional SettingProto uninstalled_instant_app_min_cache_period = 290;
+    optional SettingProto uninstalled_instant_app_max_cache_period = 291;
+    optional SettingProto unused_static_shared_lib_min_cache_period = 292;
     optional SettingProto allow_user_switching_when_system_user_locked = 269;
     optional SettingProto boot_count = 270;
     optional SettingProto safe_boot_disallowed = 271;
     optional SettingProto device_demo_mode = 272;
+    optional SettingProto network_access_timeout_ms = 329;
     optional SettingProto database_downgrade_reason = 274;
+    optional SettingProto database_creation_buildid = 330;
     optional SettingProto contacts_database_wal_enabled = 275;
+    optional SettingProto location_settings_link_to_permissions_enabled = 331;
+    optional SettingProto backup_refactored_service_disabled = 332;
+    optional SettingProto euicc_factory_reset_timeout_millis = 333;
+    optional SettingProto storage_settings_clobber_threshold = 334;
     optional SettingProto multi_sim_voice_call_subscription = 276;
     optional SettingProto multi_sim_voice_prompt = 277;
     optional SettingProto multi_sim_data_call_subscription = 278;
@@ -324,19 +375,20 @@
     optional SettingProto contact_metadata_sync_enabled = 282;
     optional SettingProto enable_cellular_on_boot = 283;
     optional SettingProto max_notification_enqueue_rate = 284;
+    optional SettingProto show_notification_channel_warnings = 335;
     optional SettingProto cell_on = 285;
-    optional SettingProto network_recommendations_package = 286;
-    optional SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
-    optional SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
-    optional SettingProto installed_instant_app_max_cache_period = 289;
-    optional SettingProto uninstalled_instant_app_min_cache_period = 290;
-    optional SettingProto uninstalled_instant_app_max_cache_period = 291;
-    optional SettingProto unused_static_shared_lib_min_cache_period = 292;
+    optional SettingProto show_temperature_warning = 336;
+    optional SettingProto warning_temperature = 337;
+    optional SettingProto enable_diskstats_logging = 338;
+    optional SettingProto enable_cache_quota_calculation = 339;
+    optional SettingProto enable_deletion_helper_no_threshold_toggle = 340;
+    optional SettingProto notification_snooze_options = 341;
+
+    // Next tag = 342;
 }
 
 message SecureSettingsProto {
-    // Historical operations
-    repeated SettingsOperationProto historical_op = 1;
+    repeated SettingsOperationProto historical_operations = 1;
 
     optional SettingProto android_id = 2;
     optional SettingProto default_input_method = 3;
@@ -347,6 +399,10 @@
     optional SettingProto autofill_service = 8;
     optional SettingProto bluetooth_hci_log = 9;
     optional SettingProto user_setup_complete = 10;
+    // Whether the current user has been set up via setup wizard (0 = false,
+    // 1 = true). This value differs from USER_SETUP_COMPLETE in that it can be
+    // reset back to 0 in case SetupWizard has been re-enabled on TV devices.
+    optional SettingProto tv_user_setup_complete = 170;
     optional SettingProto completed_category_prefix = 11;
     optional SettingProto enabled_input_methods = 12;
     optional SettingProto disabled_system_input_methods = 13;
@@ -354,10 +410,12 @@
     optional SettingProto always_on_vpn_app = 15;
     optional SettingProto always_on_vpn_lockdown = 16;
     optional SettingProto install_non_market_apps = 17;
+    optional SettingProto unknown_sources_default_reversed = 171;
     optional SettingProto location_mode = 18;
     optional SettingProto location_previous_mode = 19;
     optional SettingProto lock_to_app_exit_locked = 20;
     optional SettingProto lock_screen_lock_after_timeout = 21;
+    optional SettingProto lock_screen_allow_private_notifications = 172;
     optional SettingProto lock_screen_allow_remote_input = 22;
     optional SettingProto show_note_about_notification_hiding = 23;
     optional SettingProto trust_agents_initialized = 24;
@@ -366,6 +424,11 @@
     optional SettingProto parental_control_redirect_url = 27;
     optional SettingProto settings_classname = 28;
     optional SettingProto accessibility_enabled = 29;
+    optional SettingProto accessibility_shortcut_enabled = 173;
+    optional SettingProto accessibility_shortcut_on_lock_screen = 174;
+    optional SettingProto accessibility_shortcut_dialog_shown = 175;
+    optional SettingProto accessibility_shortcut_target_service = 176;
+    optional SettingProto accessibility_button_target_component = 177;
     optional SettingProto touch_exploration_enabled = 30;
     optional SettingProto enabled_accessibility_services = 31;
     optional SettingProto touch_exploration_granted_accessibility_services = 32;
@@ -375,7 +438,9 @@
     optional SettingProto accessibility_screen_reader_url = 36;
     optional SettingProto accessibility_web_content_key_bindings = 37;
     optional SettingProto accessibility_display_magnification_enabled = 38;
+    optional SettingProto accessibility_display_magnification_navbar_enabled = 178;
     optional SettingProto accessibility_display_magnification_scale = 39;
+    optional SettingProto accessibility_display_magnification_auto_update = 179;
     optional SettingProto accessibility_soft_keyboard_mode = 40;
     optional SettingProto accessibility_captioning_enabled = 41;
     optional SettingProto accessibility_captioning_locale = 42;
@@ -448,6 +513,7 @@
     optional SettingProto doze_enabled = 109;
     optional SettingProto doze_always_on = 110;
     optional SettingProto doze_pulse_on_pick_up = 111;
+    optional SettingProto doze_pulse_on_long_press = 180;
     optional SettingProto doze_pulse_on_double_tap = 112;
     optional SettingProto ui_night_mode = 113;
     optional SettingProto screensaver_enabled = 114;
@@ -470,6 +536,7 @@
     optional SettingProto immersive_mode_confirmations = 131;
     optional SettingProto print_service_search_uri = 132;
     optional SettingProto payment_service_search_uri = 133;
+    optional SettingProto autofill_service_search_uri = 181;
     optional SettingProto skip_first_use_hints = 134;
     optional SettingProto unsafe_volume_music_active_ms = 135;
     optional SettingProto lock_screen_show_notifications = 136;
@@ -482,10 +549,18 @@
     optional SettingProto camera_gesture_disabled = 143;
     optional SettingProto camera_double_tap_power_gesture_disabled = 144;
     optional SettingProto camera_double_twist_to_flip_enabled = 145;
+    optional SettingProto camera_lift_trigger_enabled = 182;
+    optional SettingProto assist_gesture_enabled = 183;
+    optional SettingProto assist_gesture_sensitivity = 184;
+    optional SettingProto assist_gesture_silence_alerts_enabled = 185;
+    optional SettingProto assist_gesture_wake_enabled = 186;
+    optional SettingProto assist_gesture_setup_complete = 187;
     optional SettingProto night_display_activated = 146;
     optional SettingProto night_display_auto_mode = 147;
+    optional SettingProto night_display_color_temperature = 188;
     optional SettingProto night_display_custom_start_time = 148;
     optional SettingProto night_display_custom_end_time = 149;
+    optional SettingProto night_display_last_activated_time = 189;
     optional SettingProto brightness_use_twilight = 150;
     optional SettingProto enabled_vr_listeners = 151;
     optional SettingProto vr_display_mode = 152;
@@ -495,6 +570,7 @@
     optional SettingProto automatic_storage_manager_days_to_retain = 156;
     optional SettingProto automatic_storage_manager_bytes_cleared = 157;
     optional SettingProto automatic_storage_manager_last_run = 158;
+    optional SettingProto automatic_storage_manager_turned_off_by_policy = 190;
     optional SettingProto system_navigation_keys_enabled = 159;
     optional SettingProto downloads_backup_enabled = 160;
     optional SettingProto downloads_backup_allow_metered = 161;
@@ -504,13 +580,18 @@
     optional SettingProto demo_user_setup_complete = 165;
     optional SettingProto instant_apps_enabled = 166;
     optional SettingProto device_paired = 167;
+    optional SettingProto package_verifier_state = 191;
+    optional SettingProto cmas_additional_broadcast_pkg = 192;
     optional SettingProto notification_badging = 168;
+    optional SettingProto qs_auto_added_tiles = 193;
+    optional SettingProto lockdown_in_power_menu = 194;
     optional SettingProto backup_manager_constants = 169;
+
+    // Next tag = 195
 }
 
 message SystemSettingsProto {
-    // Historical operations
-    repeated SettingsOperationProto historical_op = 1;
+    repeated SettingsOperationProto historical_operations = 1;
 
     optional SettingProto end_button_behavior = 2;
     optional SettingProto advanced_settings = 3;
@@ -518,6 +599,7 @@
     optional SettingProto bluetooth_discoverability_timeout = 5;
     optional SettingProto font_scale = 6;
     optional SettingProto system_locales = 7;
+    optional SettingProto display_color_mode = 67;
     optional SettingProto screen_off_timeout = 8;
     optional SettingProto screen_brightness = 9;
     optional SettingProto screen_brightness_for_vr = 10;
@@ -534,8 +616,17 @@
     optional SettingProto volume_alarm = 21;
     optional SettingProto volume_notification = 22;
     optional SettingProto volume_bluetooth_sco = 23;
+    optional SettingProto volume_accessibility = 68;
     optional SettingProto volume_master = 24;
     optional SettingProto master_mono = 25;
+    // Whether silent mode should allow vibration feedback. This is used
+    // internally in AudioService and the Sound settings activity to coordinate
+    // decoupling of vibrate and silent modes. This setting will likely be
+    // removed in a future release with support for audio/vibe feedback
+    // profiles.
+    // Not used anymore. On devices with vibrator, the user explicitly selects
+    // silent or vibrate mode. Kept for use by legacy database upgrade code in
+    // DatabaseHelper.
     optional SettingProto vibrate_in_silent = 26;
     optional SettingProto append_for_last_audible = 27;
     optional SettingProto ringtone = 28;
@@ -566,6 +657,10 @@
     optional SettingProto notification_light_pulse = 53;
     optional SettingProto pointer_location = 54;
     optional SettingProto show_touches = 55;
+    // Log raw orientation data from {@link
+    // com.android.server.policy.WindowOrientationListener} for use with the
+    // orientationplot.py tool.
+    // 0 = no, 1 = yes
     optional SettingProto window_orientation_listener_log = 56;
     optional SettingProto lockscreen_sounds_enabled = 57;
     optional SettingProto lockscreen_disabled = 58;
@@ -576,7 +671,10 @@
     optional SettingProto pointer_speed = 63;
     optional SettingProto lock_to_app_enabled = 64;
     optional SettingProto egg_mode = 65;
+    optional SettingProto show_battery_percent = 69;
     optional SettingProto when_to_make_wifi_calls = 66;
+
+    // Next tag = 70;
 }
 
 message SettingProto {
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index d442acf..d3b2cde 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -145,7 +145,7 @@
     optional bool is_holding_display_suspend_blocker = 39;
     // Settings and configuration
     optional PowerServiceSettingsAndConfigurationDumpProto settings_and_configuration = 40;
-    // Sleep timeout in ms
+    // Sleep timeout in ms. This can be -1.
     optional sint32 sleep_timeout_ms = 41;
     // Screen off timeout in ms
     optional int32 screen_off_timeout_ms = 42;
@@ -263,7 +263,7 @@
     optional float maximum_screen_dim_ratio_config = 24;
     // The screen off timeout setting value in milliseconds.
     optional int32 screen_off_timeout_setting_ms = 25;
-    // The sleep timeout setting value in milliseconds.
+    // The sleep timeout setting value in milliseconds. Default value is -1.
     optional sint32 sleep_timeout_setting_ms = 26;
     // The maximum allowable screen off timeout according to the device administration policy.
     optional int32 maximum_screen_off_timeout_from_device_admin_ms = 27;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7af1b46..86103e4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -307,6 +307,8 @@
     <protected-broadcast android:name="android.intent.action.DREAMING_STOPPED" />
     <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
 
+    <protected-broadcast android:name="com.android.server.stats.action.TRIGGER_COLLECTION" />
+
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_SCAN" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.START_PNO" />
     <protected-broadcast android:name="com.android.server.WifiManager.action.DELAYED_DRIVER_STOP" />
@@ -2776,8 +2778,9 @@
         android:protectionLevel="signature|appop" />
 
     <!-- Allows an application to request deleting packages. Apps
-         targeting APIs greater than 25 must hold this permission in
-         order to use {@link android.content.Intent#ACTION_UNINSTALL_PACKAGE}.
+         targeting APIs {@link android.os.Build.VERSION_CODES#P} or greater must hold this
+         permission in order to use {@link android.content.Intent#ACTION_UNINSTALL_PACKAGE} or
+         {@link android.content.pm.PackageInstaller#uninstall}.
          <p>Protection level: normal
     -->
     <permission android:name="android.permission.REQUEST_DELETE_PACKAGES"
@@ -2907,6 +2910,13 @@
     <permission android:name="android.permission.CONFIGURE_DISPLAY_COLOR_MODE"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to collect usage infomation about brightness slider changes.
+         <p>Not for use by third-party applications.</p>
+         TODO: make a System API
+         @hide -->
+    <permission android:name="android.permission.BRIGHTNESS_SLIDER_USAGE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an application to control VPN.
          <p>Not for use by third-party applications.</p>
          @hide -->
diff --git a/core/res/res/drawable-hdpi/ic_print.png b/core/res/res/drawable-hdpi/ic_print.png
deleted file mode 100644
index aaff3dd..0000000
--- a/core/res/res/drawable-hdpi/ic_print.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_print_error.png b/core/res/res/drawable-hdpi/ic_print_error.png
deleted file mode 100644
index 7846a78..0000000
--- a/core/res/res/drawable-hdpi/ic_print_error.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_print.png b/core/res/res/drawable-mdpi/ic_print.png
deleted file mode 100644
index a3954b5..0000000
--- a/core/res/res/drawable-mdpi/ic_print.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_print_error.png b/core/res/res/drawable-mdpi/ic_print_error.png
deleted file mode 100644
index 44109eb..0000000
--- a/core/res/res/drawable-mdpi/ic_print_error.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_print.png b/core/res/res/drawable-xhdpi/ic_print.png
deleted file mode 100644
index 6b55a14..0000000
--- a/core/res/res/drawable-xhdpi/ic_print.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_print_error.png b/core/res/res/drawable-xhdpi/ic_print_error.png
deleted file mode 100644
index c3faa42..0000000
--- a/core/res/res/drawable-xhdpi/ic_print_error.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/ic_print.xml b/core/res/res/drawable/ic_print.xml
new file mode 100644
index 0000000..7aa2513
--- /dev/null
+++ b/core/res/res/drawable/ic_print.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M19,8L5,8c-1.66,0 -3,1.34 -3,3v6h4v4h12v-4h4v-6c0,-1.66 -1.34,-3 -3,-3zM16,19L8,19v-5h8v5zM19,12c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM18,3L6,3v4h12L18,3z"
+        android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_print_error.xml b/core/res/res/drawable/ic_print_error.xml
new file mode 100644
index 0000000..37e5152
--- /dev/null
+++ b/core/res/res/drawable/ic_print_error.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2017 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:pathData="M15.73,3L8.27,3L3,8.27v7.46L8.27,21h7.46L21,15.73L21,8.27L15.73,3zM12,17.3c-0.72,0 -1.3,-0.58 -1.3,-1.3 0,-0.72 0.58,-1.3 1.3,-1.3 0.72,0 1.3,0.58 1.3,1.3 0,0.72 -0.58,1.3 -1.3,1.3zM13,13h-2L11,7h2v6z"
+        android:fillColor="#FFFFFF"/>
+</vector>
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/database/SQLiteOpenHelperTest.java b/core/tests/coretests/src/android/database/SQLiteOpenHelperTest.java
index 75eeb93..9ed3f11b 100644
--- a/core/tests/coretests/src/android/database/SQLiteOpenHelperTest.java
+++ b/core/tests/coretests/src/android/database/SQLiteOpenHelperTest.java
@@ -16,6 +16,7 @@
 
 package android.database;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -61,6 +62,10 @@
             super(context, name, null, 1);
         }
 
+        TestHelper(Context context, String name, int version, SQLiteDatabase.OpenParams params) {
+            super(context, name, version, params);
+        }
+
         @Override
         public void onCreate(SQLiteDatabase db) {
         }
@@ -168,4 +173,25 @@
         }
         assertTrue("No dbstat found for " + dbName, dbStatFound);
     }
+
+    @Test
+    public void testOpenParamsConstructor() {
+        SQLiteDatabase.OpenParams params = new SQLiteDatabase.OpenParams.Builder()
+                .setJournalMode("DELETE")
+                .setSynchronousMode("OFF")
+                .build();
+
+        TestHelper helper = new TestHelper(mContext, "openhelper_test_constructor", 1, params);
+        mHelpersToClose.add(helper);
+
+        String journalMode = DatabaseUtils
+                .stringForQuery(helper.getReadableDatabase(), "PRAGMA journal_mode", null);
+
+        assertEquals("DELETE", journalMode.toUpperCase());
+        String syncMode = DatabaseUtils
+                .stringForQuery(helper.getReadableDatabase(), "PRAGMA synchronous", null);
+
+        assertEquals("0", syncMode);
+    }
+
 }
diff --git a/core/tests/coretests/src/android/os/UserHandleTest.java b/core/tests/coretests/src/android/os/UserHandleTest.java
new file mode 100644
index 0000000..af559fd
--- /dev/null
+++ b/core/tests/coretests/src/android/os/UserHandleTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static android.os.UserHandle.ERR_GID;
+import static android.os.UserHandle.getAppId;
+import static android.os.UserHandle.getCacheAppGid;
+import static android.os.UserHandle.getSharedAppGid;
+import static android.os.UserHandle.getUid;
+import static android.os.UserHandle.getUserId;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class UserHandleTest {
+    // NOTE: keep logic in sync with system/core/libcutils/tests/multiuser_test.cpp
+
+    @Test
+    public void testMerge() throws Exception {
+        EXPECT_EQ(0, multiuser_get_uid(0, 0));
+        EXPECT_EQ(1000, multiuser_get_uid(0, 1000));
+        EXPECT_EQ(10000, multiuser_get_uid(0, 10000));
+        EXPECT_EQ(50000, multiuser_get_uid(0, 50000));
+        EXPECT_EQ(1000000, multiuser_get_uid(10, 0));
+        EXPECT_EQ(1001000, multiuser_get_uid(10, 1000));
+        EXPECT_EQ(1010000, multiuser_get_uid(10, 10000));
+        EXPECT_EQ(1050000, multiuser_get_uid(10, 50000));
+    }
+
+    @Test
+    public void testSplitUser() throws Exception {
+        EXPECT_EQ(0, multiuser_get_user_id(0));
+        EXPECT_EQ(0, multiuser_get_user_id(1000));
+        EXPECT_EQ(0, multiuser_get_user_id(10000));
+        EXPECT_EQ(0, multiuser_get_user_id(50000));
+        EXPECT_EQ(10, multiuser_get_user_id(1000000));
+        EXPECT_EQ(10, multiuser_get_user_id(1001000));
+        EXPECT_EQ(10, multiuser_get_user_id(1010000));
+        EXPECT_EQ(10, multiuser_get_user_id(1050000));
+    }
+
+    @Test
+    public void testSplitApp() throws Exception {
+        EXPECT_EQ(0, multiuser_get_app_id(0));
+        EXPECT_EQ(1000, multiuser_get_app_id(1000));
+        EXPECT_EQ(10000, multiuser_get_app_id(10000));
+        EXPECT_EQ(50000, multiuser_get_app_id(50000));
+        EXPECT_EQ(0, multiuser_get_app_id(1000000));
+        EXPECT_EQ(1000, multiuser_get_app_id(1001000));
+        EXPECT_EQ(10000, multiuser_get_app_id(1010000));
+        EXPECT_EQ(50000, multiuser_get_app_id(1050000));
+    }
+
+    @Test
+    public void testCache() throws Exception {
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 0));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 1000));
+        EXPECT_EQ(20000, multiuser_get_cache_gid(0, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 50000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 0));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 1000));
+        EXPECT_EQ(1020000, multiuser_get_cache_gid(10, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 50000));
+    }
+
+    @Test
+    public void testShared() throws Exception {
+        EXPECT_EQ(0, multiuser_get_shared_gid(0, 0));
+        EXPECT_EQ(1000, multiuser_get_shared_gid(0, 1000));
+        EXPECT_EQ(50000, multiuser_get_shared_gid(0, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 50000));
+        EXPECT_EQ(0, multiuser_get_shared_gid(10, 0));
+        EXPECT_EQ(1000, multiuser_get_shared_gid(10, 1000));
+        EXPECT_EQ(50000, multiuser_get_shared_gid(10, 10000));
+        EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(10, 50000));
+    }
+
+    private static void EXPECT_EQ(int expected, int actual) {
+        assertEquals(expected, actual);
+    }
+
+    private static int multiuser_get_uid(int userId, int appId) {
+        return getUid(userId, appId);
+    }
+
+    private static int multiuser_get_cache_gid(int userId, int appId) {
+        return getCacheAppGid(userId, appId);
+    }
+
+    private static int multiuser_get_shared_gid(int userId, int appId) {
+        return getSharedAppGid(userId, appId);
+    }
+
+    private static int multiuser_get_user_id(int uid) {
+        return getUserId(uid);
+    }
+
+    private static int multiuser_get_app_id(int uid) {
+        return getAppId(uid);
+    }
+}
diff --git a/core/tests/coretests/src/android/view/FocusFinderTest.java b/core/tests/coretests/src/android/view/FocusFinderTest.java
index 6f1dd7c..2732a04 100644
--- a/core/tests/coretests/src/android/view/FocusFinderTest.java
+++ b/core/tests/coretests/src/android/view/FocusFinderTest.java
@@ -117,8 +117,8 @@
 
         // at edge
         rect2.offset(0, 1);
-        assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
-        assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_LEFT, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_RIGHT, rect1, rect2);
 
         // just beyond
         rect2.offset(0, 1);
@@ -133,8 +133,8 @@
 
         // at top edge
         rect2.offset(0, -1);
-        assertBeamsOverlap(View.FOCUS_LEFT, rect1, rect2);
-        assertBeamsOverlap(View.FOCUS_RIGHT, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_LEFT, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_RIGHT, rect1, rect2);
 
         // just beyond top edge
         rect2.offset(0, -1);
@@ -154,8 +154,8 @@
 
         // at edge
         rect2.offset(1, 0);
-        assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
-        assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_UP, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_DOWN, rect1, rect2);
 
         // just beyond
         rect2.offset(1, 0);
@@ -170,8 +170,8 @@
 
         // at edge
         rect2.offset(-1, 0);
-        assertBeamsOverlap(View.FOCUS_UP, rect1, rect2);
-        assertBeamsOverlap(View.FOCUS_DOWN, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_UP, rect1, rect2);
+        assertBeamsDontOverlap(View.FOCUS_DOWN, rect1, rect2);
 
         // just beyond edge
         rect2.offset(-1, 0);
@@ -445,7 +445,7 @@
         assertBetterCandidate(View.FOCUS_LEFT,
                 //       L    T    R    B
                 new Rect(150, 0,   200,  50),   // src
-                new Rect(0,   50,  50,   50),   // better, (way further, but in beam)
+                new Rect(0,   0,   50,   50),   // better, (way further, but in beam)
                 new Rect(49,  99,  149,  101)); // worse, even though it is closer 
     }
 
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 0245570..0e460b9 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -637,6 +637,41 @@
     }
 
     @Test
+    public void testSelectionHandles_visibleEvenWithEmptyMenu() {
+        ((TextView) mActivity.findViewById(R.id.textview)).setCustomSelectionActionModeCallback(
+                new ActionMode.Callback() {
+                    @Override
+                    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                        menu.clear();
+                        return true;
+                    }
+
+                    @Override
+                    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                        menu.clear();
+                        return true;
+                    }
+
+                    @Override
+                    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                        return false;
+                    }
+
+                    @Override
+                    public void onDestroyActionMode(ActionMode mode) {}
+                });
+        final String text = "abcd efg hijk lmn";
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('f')));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .check(matches(isDisplayed()));
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .check(matches(isDisplayed()));
+    }
+
+    @Test
     public void testSetSelectionAndActionMode() throws Throwable {
         final TextView textView = mActivity.findViewById(R.id.textview);
         final ActionMode.Callback amCallback = mock(ActionMode.Callback.class);
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index c4bb72c..635432d 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -28,6 +28,8 @@
     String requestPrivateKey(String alias);
     byte[] getCertificate(String alias);
     byte[] getCaCertificates(String alias);
+    boolean isUserSelectable(String alias);
+    void setUserSelectable(String alias, boolean isUserSelectable);
 
     // APIs used by CertInstaller and DevicePolicyManager
     String installCaCertificate(in byte[] caCertificate);
diff --git a/legacy-test/src/com/android/internal/util/Predicate.java b/legacy-test/src/com/android/internal/util/Predicate.java
index 1b5eaff..e87f489 100644
--- a/legacy-test/src/com/android/internal/util/Predicate.java
+++ b/legacy-test/src/com/android/internal/util/Predicate.java
@@ -27,6 +27,7 @@
  * strongly encouraged to state this fact clearly in their API documentation.
  *
  * @deprecated Use {@code java.util.function.Predicate} instead.
+ *             This must not be used outside frameworks/base/test-runner.
  */
 @Deprecated
 public interface Predicate<T> {
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index 91756e7..5aea04d 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -245,22 +245,19 @@
     // last call to dumpData(). In other words if there's a dumpData(), draw frame,
     // dumpData(), the last dumpData() should only log 1 frame.
 
-    FILE* file = fdopen(fd, "a");
-    fprintf(file, "\n\tDraw\tPrepare\tProcess\tExecute\n");
+    dprintf(fd, "\n\tDraw\tPrepare\tProcess\tExecute\n");
 
     for (size_t i = 0; i < mFrameSource.size(); i++) {
         if (mFrameSource[i][FrameInfoIndex::IntendedVsync] <= mLastFrameLogged) {
             continue;
         }
         mLastFrameLogged = mFrameSource[i][FrameInfoIndex::IntendedVsync];
-        fprintf(file, "\t%3.2f\t%3.2f\t%3.2f\t%3.2f\n",
+        dprintf(fd, "\t%3.2f\t%3.2f\t%3.2f\t%3.2f\n",
                 durationMS(i, FrameInfoIndex::IntendedVsync, FrameInfoIndex::SyncStart),
                 durationMS(i, FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart),
                 durationMS(i, FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers),
                 durationMS(i, FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted));
     }
-
-    fflush(file);
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 5b67693..afdd339 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -174,24 +174,22 @@
 }
 
 void JankTracker::dumpFrames(int fd) {
-    FILE* file = fdopen(fd, "a");
-    fprintf(file, "\n\n---PROFILEDATA---\n");
+    dprintf(fd, "\n\n---PROFILEDATA---\n");
     for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) {
-        fprintf(file, "%s", FrameInfoNames[i].c_str());
-        fprintf(file, ",");
+        dprintf(fd, "%s", FrameInfoNames[i].c_str());
+        dprintf(fd, ",");
     }
     for (size_t i = 0; i < mFrames.size(); i++) {
         FrameInfo& frame = mFrames[i];
         if (frame[FrameInfoIndex::SyncStart] == 0) {
             continue;
         }
-        fprintf(file, "\n");
+        dprintf(fd, "\n");
         for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) {
-            fprintf(file, "%" PRId64 ",", frame[i]);
+            dprintf(fd, "%" PRId64 ",", frame[i]);
         }
     }
-    fprintf(file, "\n---PROFILEDATA---\n\n");
-    fflush(file);
+    dprintf(fd, "\n---PROFILEDATA---\n\n");
 }
 
 void JankTracker::reset() {
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index c22364b..a33b287 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -18,7 +18,6 @@
 
 #include "Layer.h"
 #include "RenderThread.h"
-#include "pipeline/skia/ShaderCache.h"
 #include "renderstate/RenderState.h"
 
 #include <GrContextOptions.h>
@@ -128,8 +127,6 @@
         }
         contextOptions->fExecutor = mTaskProcessor.get();
     }
-
-    contextOptions->fPersistentCache = &skiapipeline::ShaderCache::get();
 }
 
 void CacheManager::trimMemory(TrimMemoryMode mode) {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 574bb02..05a9b75 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,7 +16,6 @@
 
 #include "RenderThread.h"
 
-#include "pipeline/skia/ShaderCache.h"
 #include "CanvasContext.h"
 #include "EglManager.h"
 #include "OpenGLReadback.h"
@@ -106,7 +105,6 @@
     mRenderState = new RenderState(*this);
     mVkManager = new VulkanManager(*this);
     mCacheManager = new CacheManager(mDisplayInfo);
-    uirenderer::skiapipeline::ShaderCache::get().initShaderDiskCache();
 }
 
 void RenderThread::dumpGraphicsMemory(int fd) {
@@ -141,10 +139,8 @@
             break;
     }
 
-    FILE* file = fdopen(fd, "a");
-    fprintf(file, "\n%s\n", cachesOutput.string());
-    fprintf(file, "\nPipeline=%s\n", pipeline.string());
-    fflush(file);
+    dprintf(fd, "\n%s\n", cachesOutput.string());
+    dprintf(fd, "\nPipeline=%s\n", pipeline.string());
 }
 
 Readback& RenderThread::readback() {
diff --git a/media/java/android/media/BufferingParams.java b/media/java/android/media/BufferingParams.java
index 681271b..521e897 100644
--- a/media/java/android/media/BufferingParams.java
+++ b/media/java/android/media/BufferingParams.java
@@ -26,170 +26,68 @@
 /**
  * Structure for source buffering management params.
  *
- * Used by {@link MediaPlayer#getDefaultBufferingParams()},
- * {@link MediaPlayer#getBufferingParams()} and
+ * Used by {@link MediaPlayer#getBufferingParams()} and
  * {@link MediaPlayer#setBufferingParams(BufferingParams)}
  * to control source buffering behavior.
  *
  * <p>There are two stages of source buffering in {@link MediaPlayer}: initial buffering
  * (when {@link MediaPlayer} is being prepared) and rebuffering (when {@link MediaPlayer}
- * is playing back source). {@link BufferingParams} includes mode and corresponding
- * watermarks for each stage of source buffering. The watermarks could be either size
- * based (in milliseconds), or time based (in kilobytes) or both, depending on the mode.
+ * is playing back source). {@link BufferingParams} includes corresponding marks for each
+ * stage of source buffering. The marks are time based (in milliseconds).
  *
- * <p>There are 4 buffering modes: {@link #BUFFERING_MODE_NONE},
- * {@link #BUFFERING_MODE_TIME_ONLY}, {@link #BUFFERING_MODE_SIZE_ONLY} and
- * {@link #BUFFERING_MODE_TIME_THEN_SIZE}.
- * {@link MediaPlayer} source component has default buffering modes which can be queried
- * by calling {@link MediaPlayer#getDefaultBufferingParams()}.
- * Users should always use those default modes or their downsized version when trying to
- * change buffering params. For example, {@link #BUFFERING_MODE_TIME_THEN_SIZE} can be
- * downsized to {@link #BUFFERING_MODE_NONE}, {@link #BUFFERING_MODE_TIME_ONLY} or
- * {@link #BUFFERING_MODE_SIZE_ONLY}. But {@link #BUFFERING_MODE_TIME_ONLY} can not be
- * downsized to {@link #BUFFERING_MODE_SIZE_ONLY}.
+ * <p>{@link MediaPlayer} source component has default marks which can be queried by
+ * calling {@link MediaPlayer#getBufferingParams()} before any change is made by
+ * {@link MediaPlayer#setBufferingParams()}.
  * <ul>
- * <li><strong>initial buffering stage:</strong> has one watermark which is used when
- * {@link MediaPlayer} is being prepared. When cached data amount exceeds this watermark,
- * {@link MediaPlayer} is prepared.</li>
- * <li><strong>rebuffering stage:</strong> has two watermarks, low and high, which are
- * used when {@link MediaPlayer} is playing back content.
+ * <li><strong>initial buffering:</strong> initialMarkMs is used when
+ * {@link MediaPlayer} is being prepared. When cached data amount exceeds this mark
+ * {@link MediaPlayer} is prepared. </li>
+ * <li><strong>rebuffering during playback:</strong> resumePlaybackMarkMs is used when
+ * {@link MediaPlayer} is playing back content.
  * <ul>
- * <li> When cached data amount exceeds high watermark, {@link MediaPlayer} will pause
- * buffering. Buffering will resume when cache runs below some limit which could be low
- * watermark or some intermediate value decided by the source component.</li>
- * <li> When cached data amount runs below low watermark, {@link MediaPlayer} will paused
- * playback. Playback will resume when cached data amount exceeds high watermark
- * or reaches end of stream.</li>
- * </ul>
+ * <li> {@link MediaPlayer} has internal mark, namely pausePlaybackMarkMs, to decide when
+ * to pause playback if cached data amount runs low. This internal mark varies based on
+ * type of data source. </li>
+ * <li> When cached data amount exceeds resumePlaybackMarkMs, {@link MediaPlayer} will
+ * resume playback if it has been paused due to low cached data amount. The internal mark
+ * pausePlaybackMarkMs shall be less than resumePlaybackMarkMs. </li>
+ * <li> {@link MediaPlayer} has internal mark, namely pauseRebufferingMarkMs, to decide
+ * when to pause rebuffering. Apparently, this internal mark shall be no less than
+ * resumePlaybackMarkMs. </li>
+ * <li> {@link MediaPlayer} has internal mark, namely resumeRebufferingMarkMs, to decide
+ * when to resume buffering. This internal mark varies based on type of data source. This
+ * mark shall be larger than pausePlaybackMarkMs, and less than pauseRebufferingMarkMs.
+ * </li>
+ * </ul> </li>
  * </ul>
  * <p>Users should use {@link Builder} to change {@link BufferingParams}.
  * @hide
  */
 public final class BufferingParams implements Parcelable {
-    /**
-     * This mode indicates that source buffering is not supported.
-     */
-    public static final int BUFFERING_MODE_NONE = 0;
-    /**
-     * This mode indicates that only time based source buffering is supported. This means
-     * the watermark(s) are time based.
-     */
-    public static final int BUFFERING_MODE_TIME_ONLY = 1;
-    /**
-     * This mode indicates that only size based source buffering is supported. This means
-     * the watermark(s) are size based.
-     */
-    public static final int BUFFERING_MODE_SIZE_ONLY = 2;
-    /**
-     * This mode indicates that both time and size based source buffering are supported,
-     * and time based calculation precedes size based. Size based calculation will be used
-     * only when time information is not available from the source.
-     */
-    public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3;
-
-    /** @hide */
-    @IntDef(
-        value = {
-                BUFFERING_MODE_NONE,
-                BUFFERING_MODE_TIME_ONLY,
-                BUFFERING_MODE_SIZE_ONLY,
-                BUFFERING_MODE_TIME_THEN_SIZE,
-        }
-    )
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface BufferingMode {}
-
-    private static final int BUFFERING_NO_WATERMARK = -1;
+    private static final int BUFFERING_NO_MARK = -1;
 
     // params
-    private int mInitialBufferingMode = BUFFERING_MODE_NONE;
-    private int mRebufferingMode = BUFFERING_MODE_NONE;
+    private int mInitialMarkMs = BUFFERING_NO_MARK;
 
-    private int mInitialWatermarkMs = BUFFERING_NO_WATERMARK;
-    private int mInitialWatermarkKB = BUFFERING_NO_WATERMARK;
-
-    private int mRebufferingWatermarkLowMs = BUFFERING_NO_WATERMARK;
-    private int mRebufferingWatermarkHighMs = BUFFERING_NO_WATERMARK;
-    private int mRebufferingWatermarkLowKB = BUFFERING_NO_WATERMARK;
-    private int mRebufferingWatermarkHighKB = BUFFERING_NO_WATERMARK;
+    private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
 
     private BufferingParams() {
     }
 
     /**
-     * Return the initial buffering mode used when {@link MediaPlayer} is being prepared.
-     * @return one of the values that can be set in {@link Builder#setInitialBufferingMode(int)}
+     * Return initial buffering mark in milliseconds.
+     * @return initial buffering mark in milliseconds
      */
-    public int getInitialBufferingMode() {
-        return mInitialBufferingMode;
+    public int getInitialMarkMs() {
+        return mInitialMarkMs;
     }
 
     /**
-     * Return the rebuffering mode used when {@link MediaPlayer} is playing back source.
-     * @return one of the values that can be set in {@link Builder#setRebufferingMode(int)}
+     * Return the mark in milliseconds for resuming playback.
+     * @return the mark for resuming playback in milliseconds
      */
-    public int getRebufferingMode() {
-        return mRebufferingMode;
-    }
-
-    /**
-     * Return the time based initial buffering watermark in milliseconds.
-     * It is meaningful only when initial buffering mode obatined from
-     * {@link #getInitialBufferingMode()} is time based.
-     * @return time based initial buffering watermark in milliseconds
-     */
-    public int getInitialBufferingWatermarkMs() {
-        return mInitialWatermarkMs;
-    }
-
-    /**
-     * Return the size based initial buffering watermark in kilobytes.
-     * It is meaningful only when initial buffering mode obatined from
-     * {@link #getInitialBufferingMode()} is size based.
-     * @return size based initial buffering watermark in kilobytes
-     */
-    public int getInitialBufferingWatermarkKB() {
-        return mInitialWatermarkKB;
-    }
-
-    /**
-     * Return the time based low watermark in milliseconds for rebuffering.
-     * It is meaningful only when rebuffering mode obatined from
-     * {@link #getRebufferingMode()} is time based.
-     * @return time based low watermark for rebuffering in milliseconds
-     */
-    public int getRebufferingWatermarkLowMs() {
-        return mRebufferingWatermarkLowMs;
-    }
-
-    /**
-     * Return the time based high watermark in milliseconds for rebuffering.
-     * It is meaningful only when rebuffering mode obatined from
-     * {@link #getRebufferingMode()} is time based.
-     * @return time based high watermark for rebuffering in milliseconds
-     */
-    public int getRebufferingWatermarkHighMs() {
-        return mRebufferingWatermarkHighMs;
-    }
-
-    /**
-     * Return the size based low watermark in kilobytes for rebuffering.
-     * It is meaningful only when rebuffering mode obatined from
-     * {@link #getRebufferingMode()} is size based.
-     * @return size based low watermark for rebuffering in kilobytes
-     */
-    public int getRebufferingWatermarkLowKB() {
-        return mRebufferingWatermarkLowKB;
-    }
-
-    /**
-     * Return the size based high watermark in kilobytes for rebuffering.
-     * It is meaningful only when rebuffering mode obatined from
-     * {@link #getRebufferingMode()} is size based.
-     * @return size based high watermark for rebuffering in kilobytes
-     */
-    public int getRebufferingWatermarkHighKB() {
-        return mRebufferingWatermarkHighKB;
+    public int getResumePlaybackMarkMs() {
+        return mResumePlaybackMarkMs;
     }
 
     /**
@@ -200,27 +98,19 @@
      * <pre class="prettyprint">
      * BufferingParams myParams = mediaplayer.getDefaultBufferingParams();
      * myParams = new BufferingParams.Builder(myParams)
-     *             .setInitialBufferingWatermarkMs(10000)
-     *             .build();
+     *         .setInitialMarkMs(10000)
+     *         .setResumePlaybackMarkMs(15000)
+     *         .build();
      * mediaplayer.setBufferingParams(myParams);
      * </pre>
      */
     public static class Builder {
-        private int mInitialBufferingMode = BUFFERING_MODE_NONE;
-        private int mRebufferingMode = BUFFERING_MODE_NONE;
-
-        private int mInitialWatermarkMs = BUFFERING_NO_WATERMARK;
-        private int mInitialWatermarkKB = BUFFERING_NO_WATERMARK;
-
-        private int mRebufferingWatermarkLowMs = BUFFERING_NO_WATERMARK;
-        private int mRebufferingWatermarkHighMs = BUFFERING_NO_WATERMARK;
-        private int mRebufferingWatermarkLowKB = BUFFERING_NO_WATERMARK;
-        private int mRebufferingWatermarkHighKB = BUFFERING_NO_WATERMARK;
+        private int mInitialMarkMs = BUFFERING_NO_MARK;
+        private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
 
         /**
          * Constructs a new Builder with the defaults.
-         * By default, both initial buffering mode and rebuffering mode are
-         * {@link BufferingParams#BUFFERING_MODE_NONE}, and all watermarks are -1.
+         * By default, all marks are -1.
          */
         public Builder() {
         }
@@ -231,16 +121,8 @@
          * in the new Builder.
          */
         public Builder(BufferingParams bp) {
-            mInitialBufferingMode = bp.mInitialBufferingMode;
-            mRebufferingMode = bp.mRebufferingMode;
-
-            mInitialWatermarkMs = bp.mInitialWatermarkMs;
-            mInitialWatermarkKB = bp.mInitialWatermarkKB;
-
-            mRebufferingWatermarkLowMs = bp.mRebufferingWatermarkLowMs;
-            mRebufferingWatermarkHighMs = bp.mRebufferingWatermarkHighMs;
-            mRebufferingWatermarkLowKB = bp.mRebufferingWatermarkLowKB;
-            mRebufferingWatermarkHighKB = bp.mRebufferingWatermarkHighKB;
+            mInitialMarkMs = bp.mInitialMarkMs;
+            mResumePlaybackMarkMs = bp.mResumePlaybackMarkMs;
         }
 
         /**
@@ -250,179 +132,37 @@
          * @return a new {@link BufferingParams} object
          */
         public BufferingParams build() {
-            if (isTimeBasedMode(mRebufferingMode)
-                    && mRebufferingWatermarkLowMs > mRebufferingWatermarkHighMs) {
-                throw new IllegalStateException("Illegal watermark:"
-                        + mRebufferingWatermarkLowMs + " : " + mRebufferingWatermarkHighMs);
-            }
-            if (isSizeBasedMode(mRebufferingMode)
-                    && mRebufferingWatermarkLowKB > mRebufferingWatermarkHighKB) {
-                throw new IllegalStateException("Illegal watermark:"
-                        + mRebufferingWatermarkLowKB + " : " + mRebufferingWatermarkHighKB);
-            }
-
             BufferingParams bp = new BufferingParams();
-            bp.mInitialBufferingMode = mInitialBufferingMode;
-            bp.mRebufferingMode = mRebufferingMode;
+            bp.mInitialMarkMs = mInitialMarkMs;
+            bp.mResumePlaybackMarkMs = mResumePlaybackMarkMs;
 
-            bp.mInitialWatermarkMs = mInitialWatermarkMs;
-            bp.mInitialWatermarkKB = mInitialWatermarkKB;
-
-            bp.mRebufferingWatermarkLowMs = mRebufferingWatermarkLowMs;
-            bp.mRebufferingWatermarkHighMs = mRebufferingWatermarkHighMs;
-            bp.mRebufferingWatermarkLowKB = mRebufferingWatermarkLowKB;
-            bp.mRebufferingWatermarkHighKB = mRebufferingWatermarkHighKB;
             return bp;
         }
 
-        private boolean isTimeBasedMode(int mode) {
-            return (mode == BUFFERING_MODE_TIME_ONLY || mode == BUFFERING_MODE_TIME_THEN_SIZE);
-        }
-
-        private boolean isSizeBasedMode(int mode) {
-            return (mode == BUFFERING_MODE_SIZE_ONLY || mode == BUFFERING_MODE_TIME_THEN_SIZE);
-        }
-
         /**
-         * Sets the initial buffering mode.
-         * @param mode one of {@link BufferingParams#BUFFERING_MODE_NONE},
-         *     {@link BufferingParams#BUFFERING_MODE_TIME_ONLY},
-         *     {@link BufferingParams#BUFFERING_MODE_SIZE_ONLY},
-         *     {@link BufferingParams#BUFFERING_MODE_TIME_THEN_SIZE},
+         * Sets the time based mark in milliseconds for initial buffering.
+         * @param markMs time based mark in milliseconds
          * @return the same Builder instance.
          */
-        public Builder setInitialBufferingMode(@BufferingMode int mode) {
-            switch (mode) {
-                case BUFFERING_MODE_NONE:
-                case BUFFERING_MODE_TIME_ONLY:
-                case BUFFERING_MODE_SIZE_ONLY:
-                case BUFFERING_MODE_TIME_THEN_SIZE:
-                     mInitialBufferingMode = mode;
-                     break;
-                default:
-                     throw new IllegalArgumentException("Illegal buffering mode " + mode);
-            }
+        public Builder setInitialMarkMs(int markMs) {
+            mInitialMarkMs = markMs;
             return this;
         }
 
         /**
-         * Sets the rebuffering mode.
-         * @param mode one of {@link BufferingParams#BUFFERING_MODE_NONE},
-         *     {@link BufferingParams#BUFFERING_MODE_TIME_ONLY},
-         *     {@link BufferingParams#BUFFERING_MODE_SIZE_ONLY},
-         *     {@link BufferingParams#BUFFERING_MODE_TIME_THEN_SIZE},
+         * Sets the time based mark in milliseconds for resuming playback.
+         * @param markMs time based mark in milliseconds for resuming playback
          * @return the same Builder instance.
          */
-        public Builder setRebufferingMode(@BufferingMode int mode) {
-            switch (mode) {
-                case BUFFERING_MODE_NONE:
-                case BUFFERING_MODE_TIME_ONLY:
-                case BUFFERING_MODE_SIZE_ONLY:
-                case BUFFERING_MODE_TIME_THEN_SIZE:
-                     mRebufferingMode = mode;
-                     break;
-                default:
-                     throw new IllegalArgumentException("Illegal buffering mode " + mode);
-            }
-            return this;
-        }
-
-        /**
-         * Sets the time based watermark in milliseconds for initial buffering.
-         * @param watermarkMs time based watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setInitialBufferingWatermarkMs(int watermarkMs) {
-            mInitialWatermarkMs = watermarkMs;
-            return this;
-        }
-
-        /**
-         * Sets the size based watermark in kilobytes for initial buffering.
-         * @param watermarkKB size based watermark in kilobytes
-         * @return the same Builder instance.
-         */
-        public Builder setInitialBufferingWatermarkKB(int watermarkKB) {
-            mInitialWatermarkKB = watermarkKB;
-            return this;
-        }
-
-        /**
-         * Sets the time based low watermark in milliseconds for rebuffering.
-         * @param watermarkMs time based low watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarkLowMs(int watermarkMs) {
-            mRebufferingWatermarkLowMs = watermarkMs;
-            return this;
-        }
-
-        /**
-         * Sets the time based high watermark in milliseconds for rebuffering.
-         * @param watermarkMs time based high watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarkHighMs(int watermarkMs) {
-            mRebufferingWatermarkHighMs = watermarkMs;
-            return this;
-        }
-
-        /**
-         * Sets the size based low watermark in milliseconds for rebuffering.
-         * @param watermarkKB size based low watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarkLowKB(int watermarkKB) {
-            mRebufferingWatermarkLowKB = watermarkKB;
-            return this;
-        }
-
-        /**
-         * Sets the size based high watermark in milliseconds for rebuffering.
-         * @param watermarkKB size based high watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarkHighKB(int watermarkKB) {
-            mRebufferingWatermarkHighKB = watermarkKB;
-            return this;
-        }
-
-        /**
-         * Sets the time based low and high watermarks in milliseconds for rebuffering.
-         * @param lowWatermarkMs time based low watermark in milliseconds
-         * @param highWatermarkMs time based high watermark in milliseconds
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarksMs(int lowWatermarkMs, int highWatermarkMs) {
-            mRebufferingWatermarkLowMs = lowWatermarkMs;
-            mRebufferingWatermarkHighMs = highWatermarkMs;
-            return this;
-        }
-
-        /**
-         * Sets the size based low and high watermarks in kilobytes for rebuffering.
-         * @param lowWatermarkKB size based low watermark in kilobytes
-         * @param highWatermarkKB size based high watermark in kilobytes
-         * @return the same Builder instance.
-         */
-        public Builder setRebufferingWatermarksKB(int lowWatermarkKB, int highWatermarkKB) {
-            mRebufferingWatermarkLowKB = lowWatermarkKB;
-            mRebufferingWatermarkHighKB = highWatermarkKB;
+        public Builder setResumePlaybackMarkMs(int markMs) {
+            mResumePlaybackMarkMs = markMs;
             return this;
         }
     }
 
     private BufferingParams(Parcel in) {
-        mInitialBufferingMode = in.readInt();
-        mRebufferingMode = in.readInt();
-
-        mInitialWatermarkMs = in.readInt();
-        mInitialWatermarkKB = in.readInt();
-
-        mRebufferingWatermarkLowMs = in.readInt();
-        mRebufferingWatermarkHighMs = in.readInt();
-        mRebufferingWatermarkLowKB = in.readInt();
-        mRebufferingWatermarkHighKB = in.readInt();
+        mInitialMarkMs = in.readInt();
+        mResumePlaybackMarkMs = in.readInt();
     }
 
     public static final Parcelable.Creator<BufferingParams> CREATOR =
@@ -446,15 +186,7 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mInitialBufferingMode);
-        dest.writeInt(mRebufferingMode);
-
-        dest.writeInt(mInitialWatermarkMs);
-        dest.writeInt(mInitialWatermarkKB);
-
-        dest.writeInt(mRebufferingWatermarkLowMs);
-        dest.writeInt(mRebufferingWatermarkHighMs);
-        dest.writeInt(mRebufferingWatermarkLowKB);
-        dest.writeInt(mRebufferingWatermarkHighKB);
+        dest.writeInt(mInitialMarkMs);
+        dest.writeInt(mResumePlaybackMarkMs);
     }
 }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 17af44b..649c091 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1698,21 +1698,9 @@
     public native boolean isPlaying();
 
     /**
-     * Gets the default buffering management params.
-     * Calling it only after {@code setDataSource} has been called.
-     * Each type of data source might have different set of default params.
-     *
-     * @return the default buffering management params supported by the source component.
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized, or {@code setDataSource} has not been called.
-     * @hide
-     */
-    @NonNull
-    public native BufferingParams getDefaultBufferingParams();
-
-    /**
      * Gets the current buffering management params used by the source component.
      * Calling it only after {@code setDataSource} has been called.
+     * Each type of data source might have different set of default params.
      *
      * @return the current buffering management params used by the source component.
      * @throws IllegalStateException if the internal player engine has not been
@@ -1727,8 +1715,7 @@
      * The object sets its internal BufferingParams to the input, except that the input is
      * invalid or not supported.
      * Call it only after {@code setDataSource} has been called.
-     * Users should only use supported mode returned by {@link #getDefaultBufferingParams()}
-     * or its downsized version as described in {@link BufferingParams}.
+     * The input is a hint to MediaPlayer.
      *
      * @param params the buffering management params.
      *
diff --git a/media/jni/android_media_BufferingParams.h b/media/jni/android_media_BufferingParams.h
index 24c51f5..b004672 100644
--- a/media/jni/android_media_BufferingParams.h
+++ b/media/jni/android_media_BufferingParams.h
@@ -29,14 +29,8 @@
         jclass      clazz;
         jmethodID   constructID;
 
-        jfieldID    initial_buffering_mode;
-        jfieldID    rebuffering_mode;
-        jfieldID    initial_watermark_ms;
-        jfieldID    initial_watermark_kb;
-        jfieldID    rebuffering_watermark_low_ms;
-        jfieldID    rebuffering_watermark_high_ms;
-        jfieldID    rebuffering_watermark_low_kb;
-        jfieldID    rebuffering_watermark_high_kb;
+        jfieldID    initial_mark_ms;
+        jfieldID    resume_playback_mark_ms;
 
         void init(JNIEnv *env) {
             jclass lclazz = env->FindClass("android/media/BufferingParams");
@@ -51,14 +45,8 @@
 
             constructID = env->GetMethodID(clazz, "<init>", "()V");
 
-            initial_buffering_mode = env->GetFieldID(clazz, "mInitialBufferingMode", "I");
-            rebuffering_mode = env->GetFieldID(clazz, "mRebufferingMode", "I");
-            initial_watermark_ms = env->GetFieldID(clazz, "mInitialWatermarkMs", "I");
-            initial_watermark_kb = env->GetFieldID(clazz, "mInitialWatermarkKB", "I");
-            rebuffering_watermark_low_ms = env->GetFieldID(clazz, "mRebufferingWatermarkLowMs", "I");
-            rebuffering_watermark_high_ms = env->GetFieldID(clazz, "mRebufferingWatermarkHighMs", "I");
-            rebuffering_watermark_low_kb = env->GetFieldID(clazz, "mRebufferingWatermarkLowKB", "I");
-            rebuffering_watermark_high_kb = env->GetFieldID(clazz, "mRebufferingWatermarkHighKB", "I");
+            initial_mark_ms = env->GetFieldID(clazz, "mInitialMarkMs", "I");
+            resume_playback_mark_ms = env->GetFieldID(clazz, "mResumePlaybackMarkMs", "I");
 
             env->DeleteLocalRef(lclazz);
         }
@@ -70,22 +58,10 @@
     };
 
     void fillFromJobject(JNIEnv *env, const fields_t& fields, jobject params) {
-        settings.mInitialBufferingMode =
-            (BufferingMode)env->GetIntField(params, fields.initial_buffering_mode);
-        settings.mRebufferingMode =
-            (BufferingMode)env->GetIntField(params, fields.rebuffering_mode);
-        settings.mInitialWatermarkMs =
-            env->GetIntField(params, fields.initial_watermark_ms);
-        settings.mInitialWatermarkKB =
-            env->GetIntField(params, fields.initial_watermark_kb);
-        settings.mRebufferingWatermarkLowMs =
-            env->GetIntField(params, fields.rebuffering_watermark_low_ms);
-        settings.mRebufferingWatermarkHighMs =
-            env->GetIntField(params, fields.rebuffering_watermark_high_ms);
-        settings.mRebufferingWatermarkLowKB =
-            env->GetIntField(params, fields.rebuffering_watermark_low_kb);
-        settings.mRebufferingWatermarkHighKB =
-            env->GetIntField(params, fields.rebuffering_watermark_high_kb);
+        settings.mInitialMarkMs =
+            env->GetIntField(params, fields.initial_mark_ms);
+        settings.mResumePlaybackMarkMs =
+            env->GetIntField(params, fields.resume_playback_mark_ms);
     }
 
     jobject asJobject(JNIEnv *env, const fields_t& fields) {
@@ -93,14 +69,8 @@
         if (params == NULL) {
             return NULL;
         }
-        env->SetIntField(params, fields.initial_buffering_mode, (jint)settings.mInitialBufferingMode);
-        env->SetIntField(params, fields.rebuffering_mode, (jint)settings.mRebufferingMode);
-        env->SetIntField(params, fields.initial_watermark_ms, (jint)settings.mInitialWatermarkMs);
-        env->SetIntField(params, fields.initial_watermark_kb, (jint)settings.mInitialWatermarkKB);
-        env->SetIntField(params, fields.rebuffering_watermark_low_ms, (jint)settings.mRebufferingWatermarkLowMs);
-        env->SetIntField(params, fields.rebuffering_watermark_high_ms, (jint)settings.mRebufferingWatermarkHighMs);
-        env->SetIntField(params, fields.rebuffering_watermark_low_kb, (jint)settings.mRebufferingWatermarkLowKB);
-        env->SetIntField(params, fields.rebuffering_watermark_high_kb, (jint)settings.mRebufferingWatermarkHighKB);
+        env->SetIntField(params, fields.initial_mark_ms, (jint)settings.mInitialMarkMs);
+        env->SetIntField(params, fields.resume_playback_mark_ms, (jint)settings.mResumePlaybackMarkMs);
 
         return params;
     }
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index cfa3cc36..eda22d5 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -371,25 +371,6 @@
 }
 
 static jobject
-android_media_MediaPlayer_getDefaultBufferingParams(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    BufferingParams bp;
-    BufferingSettings &settings = bp.settings;
-    process_media_player_call(
-            env, thiz, mp->getDefaultBufferingSettings(&settings),
-            "java/lang/IllegalStateException", "unexpected error");
-    ALOGV("getDefaultBufferingSettings:{%s}", settings.toString().string());
-
-    return bp.asJobject(env, gBufferingParamsFields);
-}
-
-static jobject
 android_media_MediaPlayer_getBufferingParams(JNIEnv *env, jobject thiz)
 {
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
@@ -1436,7 +1417,6 @@
     {"_setDataSource",      "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
     {"_setDataSource",      "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
     {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
-    {"getDefaultBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer_getDefaultBufferingParams},
     {"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer_getBufferingParams},
     {"setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer_setBufferingParams},
     {"_prepare",            "()V",                              (void *)android_media_MediaPlayer_prepare},
diff --git a/packages/PrintSpooler/res/drawable/ic_print.xml b/packages/PrintSpooler/res/drawable/ic_print.xml
deleted file mode 100644
index e5e4d075..0000000
--- a/packages/PrintSpooler/res/drawable/ic_print.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@*android:drawable/ic_print"
-    android:tint="?android:attr/colorAccent" />
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index a9a6cbd..7c2e55f 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -122,7 +122,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        getActionBar().setIcon(R.drawable.ic_print);
+        getActionBar().setIcon(com.android.internal.R.drawable.ic_print);
 
         setContentView(R.layout.select_printer_activity);
 
diff --git a/packages/SettingsLib/Android.mk b/packages/SettingsLib/Android.mk
index 1ad4fea..99f7f71 100644
--- a/packages/SettingsLib/Android.mk
+++ b/packages/SettingsLib/Android.mk
@@ -5,14 +5,20 @@
 
 LOCAL_MODULE := SettingsLib
 
+LOCAL_JAVA_LIBRARIES := \
+    android-support-annotations
+
 LOCAL_SHARED_ANDROID_LIBRARIES := \
-    android-support-annotations \
     android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
     android-support-v14-preference
 
+LOCAL_SHARED_JAVA_LIBRARIES := \
+    apptoolkit-lifecycle-common \
+    apptoolkit-lifecycle-runtime
+
 LOCAL_STATIC_JAVA_LIBRARY := legacy-android-test
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
diff --git a/packages/SettingsLib/common.mk b/packages/SettingsLib/common.mk
index 46b66c4..b9abde2 100644
--- a/packages/SettingsLib/common.mk
+++ b/packages/SettingsLib/common.mk
@@ -14,8 +14,10 @@
 #
 
 ifeq ($(LOCAL_USE_AAPT2),true)
+LOCAL_STATIC_JAVA_LIBRARIES += \
+    android-support-annotations
+
 LOCAL_STATIC_ANDROID_LIBRARIES += \
-    android-support-annotations \
     android-support-v4 \
     SettingsLib
 else
diff --git a/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
index 90124f1..8e29e50 100644
--- a/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/CustomEditTextPreference.java
@@ -49,8 +49,13 @@
     }
 
     public EditText getEditText() {
-        return mFragment != null ? (EditText) mFragment.getDialog().findViewById(android.R.id.edit)
-                : null;
+        if (mFragment != null) {
+            final Dialog dialog = mFragment.getDialog();
+            if (dialog != null) {
+                return (EditText) dialog.findViewById(android.R.id.edit);
+            }
+        }
+        return null;
     }
 
     public boolean isDialogOpen() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
index 78a9064..f2cd103 100644
--- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java
@@ -22,12 +22,15 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Build;
+import android.system.Os;
+import android.system.StructUtsname;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.Log;
+import android.support.annotation.VisibleForTesting;
 
 import java.io.BufferedReader;
 import java.io.FileReader;
@@ -45,7 +48,6 @@
 public class DeviceInfoUtils {
     private static final String TAG = "DeviceInfoUtils";
 
-    private static final String FILENAME_PROC_VERSION = "/proc/version";
     private static final String FILENAME_MSV = "/sys/board_properties/soc/msv";
 
     /**
@@ -63,43 +65,36 @@
         }
     }
 
-    public static String getFormattedKernelVersion() {
-        try {
-            return formatKernelVersion(readLine(FILENAME_PROC_VERSION));
-        } catch (IOException e) {
-            Log.e(TAG, "IO Exception when getting kernel version for Device Info screen",
-                    e);
-
-            return "Unavailable";
-        }
+    public static String getFormattedKernelVersion(Context context) {
+            return formatKernelVersion(context, Os.uname());
     }
 
-    public static String formatKernelVersion(String rawKernelVersion) {
-        // Example (see tests for more):
-        // Linux version 4.9.29-g958411d (android-build@xyz) (Android clang version 3.8.256229 \
-        //       (based on LLVM 3.8.256229)) #1 SMP PREEMPT Wed Jun 7 00:06:03 CST 2017
-        // Linux version 4.9.29-geb63318482a7 (android-build@xyz) (gcc version 4.9.x 20150123 \
-        //       (prerelease) (GCC) ) #1 SMP PREEMPT Thu Jun 1 03:41:57 UTC 2017
-        final String PROC_VERSION_REGEX =
-                "Linux version (\\S+) " + /* group 1: "3.0.31-g6fb96c9" */
-                "\\((\\S+?)\\) " +        /* group 2: "(x@y.com) " */
-                "\\((.+?)\\) " +          /* group 3:  kernel toolchain version information */
-                "(#\\d+) " +              /* group 4: "#1" */
-                "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
-                "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 5: "Thu Jun 28 11:02:39 PDT 2012" */
-
-        Matcher m = Pattern.compile(PROC_VERSION_REGEX).matcher(rawKernelVersion);
-        if (!m.matches()) {
-            Log.e(TAG, "Regex did not match on /proc/version: " + rawKernelVersion);
-            return "Unavailable";
-        } else if (m.groupCount() < 4) {
-            Log.e(TAG, "Regex match on /proc/version only returned " + m.groupCount()
-                    + " groups");
-            return "Unavailable";
+    @VisibleForTesting
+    static String formatKernelVersion(Context context, StructUtsname uname) {
+        if (uname == null) {
+            return context.getString(R.string.status_unavailable);
         }
-        return m.group(1) + " ("+ m.group(3) + ")\n" +   // 3.0.31-g6fb96c9 (toolchain version)
-                m.group(2) + " " + m.group(4) + "\n" +   // x@y.com #1
-                m.group(5);                              // Thu Jun 28 11:02:39 PDT 2012
+        // Example:
+        // 4.9.29-g958411d
+        // #1 SMP PREEMPT Wed Jun 7 00:06:03 CST 2017
+        final String VERSION_REGEX =
+                "(#\\d+) " +              /* group 1: "#1" */
+                "(?:.*?)?" +              /* ignore: optional SMP, PREEMPT, and any CONFIG_FLAGS */
+                "((Sun|Mon|Tue|Wed|Thu|Fri|Sat).+)"; /* group 2: "Thu Jun 28 11:02:39 PDT 2012" */
+        Matcher m = Pattern.compile(VERSION_REGEX).matcher(uname.version);
+        if (!m.matches()) {
+            Log.e(TAG, "Regex did not match on uname version " + uname.version);
+            return context.getString(R.string.status_unavailable);
+        }
+
+        // Example output:
+        // 4.9.29-g958411d
+        // #1 Wed Jun 7 00:06:03 CST 2017
+        return new StringBuilder().append(uname.release)
+                .append("\n")
+                .append(m.group(1))
+                .append(" ")
+                .append(m.group(2)).toString();
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
index b2351a9..451e561 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/Lifecycle.java
@@ -15,11 +15,18 @@
  */
 package com.android.settingslib.core.lifecycle;
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_ANY;
+
 import android.annotation.UiThread;
+import android.arch.lifecycle.LifecycleOwner;
+import android.arch.lifecycle.LifecycleRegistry;
+import android.arch.lifecycle.OnLifecycleEvent;
 import android.content.Context;
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.preference.PreferenceScreen;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -44,18 +51,46 @@
 /**
  * Dispatcher for lifecycle events.
  */
-public class Lifecycle {
+public class Lifecycle extends LifecycleRegistry {
+    private static final String TAG = "LifecycleObserver";
 
-    protected final List<LifecycleObserver> mObservers = new ArrayList<>();
+    private final List<LifecycleObserver> mObservers = new ArrayList<>();
+    private final LifecycleProxy mProxy = new LifecycleProxy();
+
+    /**
+     * Creates a new LifecycleRegistry for the given provider.
+     * <p>
+     * You should usually create this inside your LifecycleOwner class's constructor and hold
+     * onto the same instance.
+     *
+     * @param provider The owner LifecycleOwner
+     */
+    public Lifecycle(@NonNull LifecycleOwner provider) {
+        super(provider);
+        addObserver(mProxy);
+    }
 
     /**
      * Registers a new observer of lifecycle events.
      */
     @UiThread
-    public <T extends LifecycleObserver> T addObserver(T observer) {
+    @Override
+    public void addObserver(android.arch.lifecycle.LifecycleObserver observer) {
         ThreadUtils.ensureMainThread();
-        mObservers.add(observer);
-        return observer;
+        super.addObserver(observer);
+        if (observer instanceof LifecycleObserver) {
+            mObservers.add((LifecycleObserver) observer);
+        }
+    }
+
+    @UiThread
+    @Override
+    public void removeObserver(android.arch.lifecycle.LifecycleObserver observer) {
+        ThreadUtils.ensureMainThread();
+        super.removeObserver(observer);
+        if (observer instanceof LifecycleObserver) {
+            mObservers.remove(observer);
+        }
     }
 
     public void onAttach(Context context) {
@@ -67,6 +102,8 @@
         }
     }
 
+    // This method is not called from the proxy because it does not have access to the
+    // savedInstanceState
     public void onCreate(Bundle savedInstanceState) {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
@@ -76,7 +113,7 @@
         }
     }
 
-    public void onStart() {
+    private void onStart() {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
             if (observer instanceof OnStart) {
@@ -94,7 +131,7 @@
         }
     }
 
-    public void onResume() {
+    private void onResume() {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
             if (observer instanceof OnResume) {
@@ -103,7 +140,7 @@
         }
     }
 
-    public void onPause() {
+    private void onPause() {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
             if (observer instanceof OnPause) {
@@ -121,7 +158,7 @@
         }
     }
 
-    public void onStop() {
+    private void onStop() {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
             if (observer instanceof OnStop) {
@@ -130,7 +167,7 @@
         }
     }
 
-    public void onDestroy() {
+    private void onDestroy() {
         for (int i = 0, size = mObservers.size(); i < size; i++) {
             final LifecycleObserver observer = mObservers.get(i);
             if (observer instanceof OnDestroy) {
@@ -168,4 +205,34 @@
         }
         return false;
     }
+
+    private class LifecycleProxy
+            implements android.arch.lifecycle.LifecycleObserver {
+        @OnLifecycleEvent(ON_ANY)
+        public void onLifecycleEvent(LifecycleOwner owner, Event event) {
+            switch (event) {
+                case ON_CREATE:
+                    // onCreate is called directly since we don't have savedInstanceState here
+                    break;
+                case ON_START:
+                    onStart();
+                    break;
+                case ON_RESUME:
+                    onResume();
+                    break;
+                case ON_PAUSE:
+                    onPause();
+                    break;
+                case ON_STOP:
+                    onStop();
+                    break;
+                case ON_DESTROY:
+                    onDestroy();
+                    break;
+                case ON_ANY:
+                    Log.wtf(TAG, "Should not receive an 'ANY' event!");
+                    break;
+            }
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
index 6c41072..ec8a8b5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/LifecycleObserver.java
@@ -17,6 +17,9 @@
 
 /**
  * Observer of lifecycle events.
+ * @deprecated use {@link android.arch.lifecycle.LifecycleObserver} instead
  */
-public interface LifecycleObserver {
+@Deprecated
+public interface LifecycleObserver extends
+        android.arch.lifecycle.LifecycleObserver {
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
index 727bec7..8b062f8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableActivity.java
@@ -15,8 +15,16 @@
  */
 package com.android.settingslib.core.lifecycle;
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.annotation.Nullable;
 import android.app.Activity;
+import android.arch.lifecycle.LifecycleOwner;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.view.Menu;
@@ -25,17 +33,19 @@
 /**
  * {@link Activity} that has hooks to observe activity lifecycle events.
  */
-public class ObservableActivity extends Activity {
+public class ObservableActivity extends Activity implements LifecycleOwner {
 
-    private final Lifecycle mLifecycle = new Lifecycle();
+    private final Lifecycle mLifecycle = new Lifecycle(this);
 
-    protected Lifecycle getLifecycle() {
+    public Lifecycle getLifecycle() {
         return mLifecycle;
     }
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         mLifecycle.onAttach(this);
+        mLifecycle.onCreate(savedInstanceState);
+        mLifecycle.handleLifecycleEvent(ON_CREATE);
         super.onCreate(savedInstanceState);
     }
 
@@ -43,36 +53,38 @@
     public void onCreate(@Nullable Bundle savedInstanceState,
             @Nullable PersistableBundle persistentState) {
         mLifecycle.onAttach(this);
+        mLifecycle.onCreate(savedInstanceState);
+        mLifecycle.handleLifecycleEvent(ON_CREATE);
         super.onCreate(savedInstanceState, persistentState);
     }
 
     @Override
     protected void onStart() {
-        mLifecycle.onStart();
+        mLifecycle.handleLifecycleEvent(ON_START);
         super.onStart();
     }
 
     @Override
     protected void onResume() {
-        mLifecycle.onResume();
+        mLifecycle.handleLifecycleEvent(ON_RESUME);
         super.onResume();
     }
 
     @Override
     protected void onPause() {
-        mLifecycle.onPause();
+        mLifecycle.handleLifecycleEvent(ON_PAUSE);
         super.onPause();
     }
 
     @Override
     protected void onStop() {
-        mLifecycle.onStop();
+        mLifecycle.handleLifecycleEvent(ON_STOP);
         super.onStop();
     }
 
     @Override
     protected void onDestroy() {
-        mLifecycle.onDestroy();
+        mLifecycle.handleLifecycleEvent(ON_DESTROY);
         super.onDestroy();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
index 315bedc..dc95384 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableDialogFragment.java
@@ -15,9 +15,17 @@
  */
 package com.android.settingslib.core.lifecycle;
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.app.DialogFragment;
+import android.arch.lifecycle.LifecycleOwner;
 import android.content.Context;
-import android.support.annotation.VisibleForTesting;
+import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -25,9 +33,9 @@
 /**
  * {@link DialogFragment} that has hooks to observe fragment lifecycle events.
  */
-public class ObservableDialogFragment extends DialogFragment {
+public class ObservableDialogFragment extends DialogFragment implements LifecycleOwner {
 
-    protected final Lifecycle mLifecycle = createLifecycle();
+    protected final Lifecycle mLifecycle = new Lifecycle(this);
 
     @Override
     public void onAttach(Context context) {
@@ -36,32 +44,39 @@
     }
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mLifecycle.onCreate(savedInstanceState);
+        mLifecycle.handleLifecycleEvent(ON_CREATE);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
     public void onStart() {
-        mLifecycle.onStart();
+        mLifecycle.handleLifecycleEvent(ON_START);
         super.onStart();
     }
 
     @Override
     public void onResume() {
-        mLifecycle.onResume();
+        mLifecycle.handleLifecycleEvent(ON_RESUME);
         super.onResume();
     }
 
     @Override
     public void onPause() {
-        mLifecycle.onPause();
+        mLifecycle.handleLifecycleEvent(ON_PAUSE);
         super.onPause();
     }
 
     @Override
     public void onStop() {
-        mLifecycle.onStop();
+        mLifecycle.handleLifecycleEvent(ON_STOP);
         super.onStop();
     }
 
     @Override
     public void onDestroy() {
-        mLifecycle.onDestroy();
+        mLifecycle.handleLifecycleEvent(ON_DESTROY);
         super.onDestroy();
     }
 
@@ -86,9 +101,8 @@
         return lifecycleHandled;
     }
 
-    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
-    /** @return a new lifecycle. */
-    public static Lifecycle createLifecycle() {
-        return new Lifecycle();
+    @Override
+    public Lifecycle getLifecycle() {
+        return mLifecycle;
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
index 3a00eba..925eda6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservableFragment.java
@@ -16,19 +16,27 @@
 
 package com.android.settingslib.core.lifecycle;
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.annotation.CallSuper;
 import android.app.Fragment;
+import android.arch.lifecycle.LifecycleOwner;
 import android.content.Context;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
-public class ObservableFragment extends Fragment {
+public class ObservableFragment extends Fragment implements LifecycleOwner {
 
-    private final Lifecycle mLifecycle = new Lifecycle();
+    private final Lifecycle mLifecycle = new Lifecycle(this);
 
-    protected Lifecycle getLifecycle() {
+    public Lifecycle getLifecycle() {
         return mLifecycle;
     }
 
@@ -43,6 +51,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         mLifecycle.onCreate(savedInstanceState);
+        mLifecycle.handleLifecycleEvent(ON_CREATE);
         super.onCreate(savedInstanceState);
     }
 
@@ -56,35 +65,35 @@
     @CallSuper
     @Override
     public void onStart() {
-        mLifecycle.onStart();
+        mLifecycle.handleLifecycleEvent(ON_START);
         super.onStart();
     }
 
     @CallSuper
     @Override
-    public void onStop() {
-        mLifecycle.onStop();
-        super.onStop();
-    }
-
-    @CallSuper
-    @Override
     public void onResume() {
-        mLifecycle.onResume();
+        mLifecycle.handleLifecycleEvent(ON_RESUME);
         super.onResume();
     }
 
     @CallSuper
     @Override
     public void onPause() {
-        mLifecycle.onPause();
+        mLifecycle.handleLifecycleEvent(ON_PAUSE);
         super.onPause();
     }
 
     @CallSuper
     @Override
+    public void onStop() {
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
     public void onDestroy() {
-        mLifecycle.onDestroy();
+        mLifecycle.handleLifecycleEvent(ON_DESTROY);
         super.onDestroy();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
index 76e5c85..abd7755 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/ObservablePreferenceFragment.java
@@ -16,7 +16,15 @@
 package com.android.settingslib.core.lifecycle;
 
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_CREATE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_DESTROY;
+import static android.arch.lifecycle.Lifecycle.Event.ON_PAUSE;
+import static android.arch.lifecycle.Lifecycle.Event.ON_RESUME;
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
+
 import android.annotation.CallSuper;
+import android.arch.lifecycle.LifecycleOwner;
 import android.content.Context;
 import android.os.Bundle;
 import android.support.v14.preference.PreferenceFragment;
@@ -28,11 +36,12 @@
 /**
  * {@link PreferenceFragment} that has hooks to observe fragment lifecycle events.
  */
-public abstract class ObservablePreferenceFragment extends PreferenceFragment {
+public abstract class ObservablePreferenceFragment extends PreferenceFragment
+        implements LifecycleOwner {
 
-    private final Lifecycle mLifecycle = new Lifecycle();
+    private final Lifecycle mLifecycle = new Lifecycle(this);
 
-    protected Lifecycle getLifecycle() {
+    public Lifecycle getLifecycle() {
         return mLifecycle;
     }
 
@@ -47,6 +56,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         mLifecycle.onCreate(savedInstanceState);
+        mLifecycle.handleLifecycleEvent(ON_CREATE);
         super.onCreate(savedInstanceState);
     }
 
@@ -66,35 +76,35 @@
     @CallSuper
     @Override
     public void onStart() {
-        mLifecycle.onStart();
+        mLifecycle.handleLifecycleEvent(ON_START);
         super.onStart();
     }
 
     @CallSuper
     @Override
-    public void onStop() {
-        mLifecycle.onStop();
-        super.onStop();
-    }
-
-    @CallSuper
-    @Override
     public void onResume() {
-        mLifecycle.onResume();
+        mLifecycle.handleLifecycleEvent(ON_RESUME);
         super.onResume();
     }
 
     @CallSuper
     @Override
     public void onPause() {
-        mLifecycle.onPause();
+        mLifecycle.handleLifecycleEvent(ON_PAUSE);
         super.onPause();
     }
 
     @CallSuper
     @Override
+    public void onStop() {
+        mLifecycle.handleLifecycleEvent(ON_STOP);
+        super.onStop();
+    }
+
+    @CallSuper
+    @Override
     public void onDestroy() {
-        mLifecycle.onDestroy();
+        mLifecycle.handleLifecycleEvent(ON_DESTROY);
         super.onDestroy();
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
index 152cbac..e28c387 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnAttach.java
@@ -17,6 +17,10 @@
 
 import android.content.Context;
 
+/**
+ * @deprecated pass {@link Context} in constructor instead
+ */
+@Deprecated
 public interface OnAttach {
     void onAttach(Context context);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
index 44cbf8d..ad7068e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnCreate.java
@@ -16,8 +16,14 @@
 package com.android.settingslib.core.lifecycle.events;
 
 
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
 import android.os.Bundle;
 
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event) }
+ */
+@Deprecated
 public interface OnCreate {
     void onCreate(Bundle savedInstanceState);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
index ffa3d16..c37286e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnDestroy.java
@@ -15,6 +15,13 @@
  */
 package com.android.settingslib.core.lifecycle.events;
 
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
+
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event) }
+ */
+@Deprecated
 public interface OnDestroy {
     void onDestroy();
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
index 4a71105..a5ab39c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnPause.java
@@ -15,6 +15,13 @@
  */
 package com.android.settingslib.core.lifecycle.events;
 
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
+
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event) }
+ */
+@Deprecated
 public interface OnPause {
     void onPause();
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
index 8dd24e9..1effba4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnResume.java
@@ -15,6 +15,13 @@
  */
 package com.android.settingslib.core.lifecycle.events;
 
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
+
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event)}
+ */
+@Deprecated
 public interface OnResume {
     void onResume();
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
index c88ddaa..07b8460 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStart.java
@@ -15,7 +15,13 @@
  */
 package com.android.settingslib.core.lifecycle.events;
 
-public interface OnStart {
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
 
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event) }
+ */
+@Deprecated
+public interface OnStart {
     void onStart();
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
index 32f61d9..d6a5967 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/lifecycle/events/OnStop.java
@@ -15,7 +15,13 @@
  */
 package com.android.settingslib.core.lifecycle.events;
 
-public interface OnStop {
+import android.arch.lifecycle.Lifecycle;
+import android.arch.lifecycle.OnLifecycleEvent;
 
+/**
+ * @deprecated use {@link OnLifecycleEvent(Lifecycle.Event) }
+ */
+@Deprecated
+public interface OnStop {
     void onStop();
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
index 17c7d13..7e37493 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib;
 
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -31,6 +32,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -59,6 +61,16 @@
         verify(editText).requestFocus();
     }
 
+    @Test
+    public void getEditText_noDialog_shouldNotCrash() {
+        ReflectionHelpers.setField(mPreference, "mFragment",
+                mock(CustomEditTextPreference.CustomPreferenceDialogFragment.class));
+
+        mPreference.getEditText();
+
+        // no crash
+    }
+
     private static class TestPreference extends CustomEditTextPreference {
         public TestPreference(Context context) {
             super(context);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java
new file mode 100644
index 0000000..82604f7
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/DeviceInfoUtilsTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.system.StructUtsname;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DeviceInfoUtilsTest {
+
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        mContext = RuntimeEnvironment.application;
+    }
+
+    @Test
+    public void formatKernelVersion_regularInputVersion_shouldStripOptionalValues() {
+        final String sysName = "Linux";
+        final String nodeName = "localhost";
+        final String release = "4.4.88-g134be430baab";
+        final String version = "#1 SMP PREEMPT Tue Dec 31 12:00:00 UTC 2017";
+        final String machine = "aarch64";
+        final StructUtsname uname = new StructUtsname(sysName, nodeName, release, version, machine);
+
+        final String expected = release + "\n" + "#1 Tue Dec 31 12:00:00 UTC 2017";
+
+        assertThat(DeviceInfoUtils.formatKernelVersion(mContext, uname)).isEqualTo(expected);
+    }
+
+    @Test
+    public void formatKernelVersion_nonRegularInputVersion_shouldBeUnavailable() {
+        final String sysName = "Linux";
+        final String nodeName = "localhost";
+        final String release = "4.4.88-g134be430baab";
+        final String version = "%@%!asd%#@!$" + "\n " + "fasdfasdfa13ta";
+        final String machine = "aarch64";
+        final StructUtsname uname = new StructUtsname(sysName, nodeName, release, version, machine);
+
+        final String expected = mContext.getString(R.string.status_unavailable);
+
+        assertThat(DeviceInfoUtils.formatKernelVersion(mContext, uname)).isEqualTo(expected);
+    }
+
+    @Test
+    public void formatKernelVersion_nullInputVersion_shouldBeUnavailable() {
+        final String expected = mContext.getString(R.string.status_unavailable);
+
+        assertThat(DeviceInfoUtils.formatKernelVersion(mContext, null)).isEqualTo(expected);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
index 1290391..adb4832 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/LifecycleTest.java
@@ -15,6 +15,10 @@
  */
 package com.android.settingslib.core.lifecycle;
 
+import static android.arch.lifecycle.Lifecycle.Event.ON_START;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.Context;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -32,6 +36,7 @@
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -39,12 +44,12 @@
 import org.robolectric.android.controller.FragmentController;
 import org.robolectric.annotation.Config;
 
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(SettingsLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class LifecycleTest {
 
+    private Lifecycle mLifecycle;
+
     public static class TestDialogFragment extends ObservableDialogFragment {
 
         final TestObserver mFragObserver;
@@ -139,6 +144,11 @@
         }
     }
 
+    @Before
+    public void setUp() {
+        mLifecycle = new Lifecycle(() -> mLifecycle);
+    }
+
     @Test
     public void runThroughActivityLifecycles_shouldObserveEverything() {
         ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
@@ -212,9 +222,8 @@
 
     @Test
     public void addObserverDuringObserve_shoudNotCrash() {
-        Lifecycle lifecycle = new Lifecycle();
-        lifecycle.addObserver(new OnStartObserver(lifecycle));
-        lifecycle.onStart();
+        mLifecycle.addObserver(new OnStartObserver(mLifecycle));
+        mLifecycle.handleLifecycleEvent(ON_START);
     }
 
     private static class OptionItemAccepter implements LifecycleObserver, OnOptionsItemSelected {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
index 3f0eca5..5d5733e4 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/development/LogpersistPreferenceControllerTest.java
@@ -44,7 +44,7 @@
         shadows = SystemPropertiesTestImpl.class)
 public class LogpersistPreferenceControllerTest {
 
-    private Lifecycle mLifecycle = new Lifecycle();
+    private Lifecycle mLifecycle;
 
     @Mock
     private ListPreference mListPreference;
@@ -57,6 +57,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         SystemProperties.set("ro.debuggable", "1");
+        mLifecycle = new Lifecycle(() -> mLifecycle);
         mController = new AbstractLogpersistPreferenceController(RuntimeEnvironment.application,
                 mLifecycle) {
             @Override
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
index 97fda99..75b6c5f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceMixinTest.java
@@ -16,6 +16,14 @@
 
 package com.android.settingslib.widget;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.PreferenceManager;
 import android.support.v7.preference.PreferenceScreen;
@@ -32,13 +40,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(SettingsLibRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class FooterPreferenceMixinTest {
@@ -54,7 +55,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mLifecycle = new Lifecycle();
+        mLifecycle = new Lifecycle(() -> mLifecycle);
         when(mFragment.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
         when(mFragment.getPreferenceManager().getContext())
                 .thenReturn(ShadowApplication.getInstance().getApplicationContext());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 1557d91..7428149 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1836,20 +1836,10 @@
         }
 
         if (upgradeVersion < 116) {
-            if (mUserHandle == UserHandle.USER_SYSTEM) {
-                db.beginTransaction();
-                SQLiteStatement stmt = null;
-                try {
-                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
-                            + " VALUES(?,?);");
-                    loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                            ImsConfig.FeatureValueConstants.ON);
-                    db.setTransactionSuccessful();
-                } finally {
-                    db.endTransaction();
-                    if (stmt != null) stmt.close();
-                }
-            }
+            /*
+             * To control the default value by carrier config manager, initializing
+             * ENHANCED_4G_MODE_ENABLED has been removed.
+             */
             upgradeVersion = 116;
         }
 
@@ -2633,9 +2623,6 @@
 
             loadSetting(stmt, Settings.Global.DEVICE_NAME, getDefaultDeviceName());
 
-            loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED,
-                    ImsConfig.FeatureValueConstants.ON);
-
             /*
              * IMPORTANT: Do not add any more upgrade steps here as the global,
              * secure, and system settings are no longer stored in a database
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 67fb4d9..41b205b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -37,9 +37,11 @@
         // Global settings
         SettingsState globalSettings = settingsRegistry.getSettingsLocked(
                 SettingsProvider.SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
-        long globalSettingsToken = proto.start(SettingsServiceDumpProto.GLOBAL_SETTINGS);
-        dumpProtoGlobalSettingsLocked(globalSettings, proto);
-        proto.end(globalSettingsToken);
+        if (globalSettings != null) {
+            long globalSettingsToken = proto.start(SettingsServiceDumpProto.GLOBAL_SETTINGS);
+            dumpProtoGlobalSettingsLocked(globalSettings, proto);
+            proto.end(globalSettingsToken);
+        }
 
         // Per-user settings
         SparseBooleanArray users = settingsRegistry.getKnownUsersLocked();
@@ -67,19 +69,26 @@
 
         SettingsState secureSettings = settingsRegistry.getSettingsLocked(
                 SettingsProvider.SETTINGS_TYPE_SECURE, user.getIdentifier());
-        long secureSettingsToken = proto.start(UserSettingsProto.SECURE_SETTINGS);
-        dumpProtoSecureSettingsLocked(secureSettings, proto);
-        proto.end(secureSettingsToken);
+        if (secureSettings != null) {
+            long secureSettingsToken = proto.start(UserSettingsProto.SECURE_SETTINGS);
+            dumpProtoSecureSettingsLocked(secureSettings, proto);
+            proto.end(secureSettingsToken);
+        }
 
         SettingsState systemSettings = settingsRegistry.getSettingsLocked(
                 SettingsProvider.SETTINGS_TYPE_SYSTEM, user.getIdentifier());
-        long systemSettingsToken = proto.start(UserSettingsProto.SYSTEM_SETTINGS);
-        dumpProtoSystemSettingsLocked(systemSettings, proto);
-        proto.end(systemSettingsToken);
+        if (systemSettings != null) {
+            long systemSettingsToken = proto.start(UserSettingsProto.SYSTEM_SETTINGS);
+            dumpProtoSystemSettingsLocked(systemSettings, proto);
+            proto.end(systemSettingsToken);
+        }
     }
 
     private static void dumpProtoGlobalSettingsLocked(
             @NonNull SettingsState s, @NonNull ProtoOutputStream p) {
+        s.dumpHistoricalOperations(p, GlobalSettingsProto.HISTORICAL_OPERATIONS);
+
+        // This uses the same order as in Settings.Global.
         dumpSetting(s, p,
                 Settings.Global.ADD_USERS_WHEN_LOCKED,
                 GlobalSettingsProto.ADD_USERS_WHEN_LOCKED);
@@ -114,6 +123,9 @@
                 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                 GlobalSettingsProto.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
         dumpSetting(s, p,
+                Settings.Global.BLUETOOTH_CLASS_OF_DEVICE,
+                GlobalSettingsProto.BLUETOOTH_CLASS_OF_DEVICE);
+        dumpSetting(s, p,
                 Settings.Global.BLUETOOTH_DISABLED_PROFILES,
                 GlobalSettingsProto.BLUETOOTH_DISABLED_PROFILES);
         dumpSetting(s, p,
@@ -194,6 +206,7 @@
         dumpSetting(s, p,
                 Settings.Global.CDMA_SUBSCRIPTION_MODE,
                 GlobalSettingsProto.CDMA_SUBSCRIPTION_MODE);
+        // Settings.Global.DEFAULT_RESTRICT_BACKGROUND_DATA intentionally excluded.
         dumpSetting(s, p,
                 Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
                 GlobalSettingsProto.DATA_ACTIVITY_TIMEOUT_MOBILE);
@@ -209,6 +222,10 @@
         dumpSetting(s, p,
                 Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                 GlobalSettingsProto.FORCE_ALLOW_ON_EXTERNAL);
+        // Settings.Global.DEFAULT_SM_DP_PLUS intentionally excluded.
+        dumpSetting(s, p,
+                Settings.Global.EUICC_PROVISIONED,
+                GlobalSettingsProto.EUICC_PROVISIONED);
         dumpSetting(s, p,
                 Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
                 GlobalSettingsProto.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
@@ -236,6 +253,7 @@
         dumpSetting(s, p,
                 Settings.Global.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE,
                 GlobalSettingsProto.DOWNLOAD_RECOMMENDED_MAX_BYTES_OVER_MOBILE);
+        // Settings.Global.INSTALL_NON_MARKET_APPS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Global.HDMI_CONTROL_ENABLED,
                 GlobalSettingsProto.HDMI_CONTROL_ENABLED);
@@ -249,6 +267,21 @@
                 Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
                 GlobalSettingsProto.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED);
         dumpSetting(s, p,
+                Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
+                GlobalSettingsProto.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS);
+        dumpSetting(s, p,
+                Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS,
+                GlobalSettingsProto.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS);
+        dumpSetting(s, p,
+                Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
+                GlobalSettingsProto.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
+        dumpSetting(s, p,
+                Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS,
+                GlobalSettingsProto.WIFI_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS);
+        dumpSetting(s, p,
+                Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
+                GlobalSettingsProto.WIFI_SCAN_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
+        dumpSetting(s, p,
                 Settings.Global.MHL_INPUT_SWITCHING_ENABLED,
                 GlobalSettingsProto.MHL_INPUT_SWITCHING_ENABLED);
         dumpSetting(s, p,
@@ -279,6 +312,9 @@
                 Settings.Global.NETSTATS_SAMPLE_ENABLED,
                 GlobalSettingsProto.NETSTATS_SAMPLE_ENABLED);
         dumpSetting(s, p,
+                Settings.Global.NETSTATS_AUGMENT_ENABLED,
+                GlobalSettingsProto.NETSTATS_AUGMENT_ENABLED);
+        dumpSetting(s, p,
                 Settings.Global.NETSTATS_DEV_BUCKET_DURATION,
                 GlobalSettingsProto.NETSTATS_DEV_BUCKET_DURATION);
         dumpSetting(s, p,
@@ -420,6 +456,9 @@
                 Settings.Global.TETHER_DUN_APN,
                 GlobalSettingsProto.TETHER_DUN_APN);
         dumpSetting(s, p,
+                Settings.Global.TETHER_OFFLOAD_DISABLED,
+                GlobalSettingsProto.TETHER_OFFLOAD_DISABLED);
+        dumpSetting(s, p,
                 Settings.Global.CARRIER_APP_WHITELIST,
                 GlobalSettingsProto.CARRIER_APP_WHITELIST);
         dumpSetting(s, p,
@@ -450,6 +489,15 @@
                 Settings.Global.NETWORK_AVOID_BAD_WIFI,
                 GlobalSettingsProto.NETWORK_AVOID_BAD_WIFI);
         dumpSetting(s, p,
+                Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE,
+                GlobalSettingsProto.NETWORK_METERED_MULTIPATH_PREFERENCE);
+        dumpSetting(s, p,
+                Settings.Global.NETWORK_WATCHLIST_LAST_REPORT_TIME,
+                GlobalSettingsProto.NETWORK_WATCHLIST_LAST_REPORT_TIME);
+        dumpSetting(s, p,
+                Settings.Global.WIFI_BADGING_THRESHOLDS,
+                GlobalSettingsProto.WIFI_BADGING_THRESHOLDS);
+        dumpSetting(s, p,
                 Settings.Global.WIFI_DISPLAY_ON,
                 GlobalSettingsProto.WIFI_DISPLAY_ON);
         dumpSetting(s, p,
@@ -489,12 +537,30 @@
                 Settings.Global.WIFI_WAKEUP_ENABLED,
                 GlobalSettingsProto.WIFI_WAKEUP_ENABLED);
         dumpSetting(s, p,
+                Settings.Global.WIFI_WAKEUP_AVAILABLE,
+                GlobalSettingsProto.WIFI_WAKEUP_AVAILABLE);
+        dumpSetting(s, p,
+                Settings.Global.NETWORK_SCORING_UI_ENABLED,
+                GlobalSettingsProto.NETWORK_SCORING_UI_ENABLED);
+        dumpSetting(s, p,
+                Settings.Global.SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS,
+                GlobalSettingsProto.SPEED_LABEL_CACHE_EVICTION_AGE_MILLIS);
+        dumpSetting(s, p,
                 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
                 GlobalSettingsProto.NETWORK_RECOMMENDATIONS_ENABLED);
         dumpSetting(s, p,
                 Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE,
                 GlobalSettingsProto.NETWORK_RECOMMENDATIONS_PACKAGE);
         dumpSetting(s, p,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE,
+                GlobalSettingsProto.USE_OPEN_WIFI_PACKAGE);
+        dumpSetting(s, p,
+                Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS,
+                GlobalSettingsProto.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS);
+        dumpSetting(s, p,
+                Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
+                GlobalSettingsProto.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS);
+        dumpSetting(s, p,
                 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
                 GlobalSettingsProto.BLE_SCAN_ALWAYS_AVAILABLE);
         dumpSetting(s, p,
@@ -612,6 +678,12 @@
                 Settings.Global.SYS_STORAGE_FULL_THRESHOLD_BYTES,
                 GlobalSettingsProto.SYS_STORAGE_FULL_THRESHOLD_BYTES);
         dumpSetting(s, p,
+                Settings.Global.SYS_STORAGE_CACHE_PERCENTAGE,
+                GlobalSettingsProto.SYS_STORAGE_CACHE_PERCENTAGE);
+        dumpSetting(s, p,
+                Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES,
+                GlobalSettingsProto.SYS_STORAGE_CACHE_MAX_BYTES);
+        dumpSetting(s, p,
                 Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
                 GlobalSettingsProto.SYNC_MAX_RETRY_DELAY_IN_SECONDS);
         dumpSetting(s, p,
@@ -627,6 +699,9 @@
                 Settings.Global.CAPTIVE_PORTAL_MODE,
                 GlobalSettingsProto.CAPTIVE_PORTAL_MODE);
         dumpSetting(s, p,
+                Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED,
+                GlobalSettingsProto.CAPTIVE_PORTAL_DETECTION_ENABLED);
+        dumpSetting(s, p,
                 Settings.Global.CAPTIVE_PORTAL_SERVER,
                 GlobalSettingsProto.CAPTIVE_PORTAL_SERVER);
         dumpSetting(s, p,
@@ -639,6 +714,9 @@
                 Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL,
                 GlobalSettingsProto.CAPTIVE_PORTAL_FALLBACK_URL);
         dumpSetting(s, p,
+                Settings.Global.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS,
+                GlobalSettingsProto.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS);
+        dumpSetting(s, p,
                 Settings.Global.CAPTIVE_PORTAL_USE_HTTPS,
                 GlobalSettingsProto.CAPTIVE_PORTAL_USE_HTTPS);
         dumpSetting(s, p,
@@ -684,6 +762,12 @@
                 Settings.Global.DEFAULT_DNS_SERVER,
                 GlobalSettingsProto.DEFAULT_DNS_SERVER);
         dumpSetting(s, p,
+                Settings.Global.PRIVATE_DNS_MODE,
+                GlobalSettingsProto.PRIVATE_DNS_MODE);
+        dumpSetting(s, p,
+                Settings.Global.PRIVATE_DNS_SPECIFIER,
+                GlobalSettingsProto.PRIVATE_DNS_SPECIFIER);
+        dumpSetting(s, p,
                 Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX,
                 GlobalSettingsProto.BLUETOOTH_HEADSET_PRIORITY_PREFIX);
         dumpSetting(s, p,
@@ -717,12 +801,27 @@
                 Settings.Global.BLUETOOTH_PAN_PRIORITY_PREFIX,
                 GlobalSettingsProto.BLUETOOTH_PAN_PRIORITY_PREFIX);
         dumpSetting(s, p,
+                Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
+                GlobalSettingsProto.ACTIVITY_MANAGER_CONSTANTS);
+        dumpSetting(s, p,
                 Settings.Global.DEVICE_IDLE_CONSTANTS,
                 GlobalSettingsProto.DEVICE_IDLE_CONSTANTS);
         dumpSetting(s, p,
+                Settings.Global.BATTERY_SAVER_CONSTANTS,
+                GlobalSettingsProto.BATTERY_SAVER_CONSTANTS);
+        dumpSetting(s, p,
+                Settings.Global.ANOMALY_DETECTION_CONSTANTS,
+                GlobalSettingsProto.ANOMALY_DETECTION_CONSTANTS);
+        dumpSetting(s, p,
+                Settings.Global.ALWAYS_ON_DISPLAY_CONSTANTS,
+                GlobalSettingsProto.ALWAYS_ON_DISPLAY_CONSTANTS);
+        dumpSetting(s, p,
                 Settings.Global.APP_IDLE_CONSTANTS,
                 GlobalSettingsProto.APP_IDLE_CONSTANTS);
         dumpSetting(s, p,
+                Settings.Global.POWER_MANAGER_CONSTANTS,
+                GlobalSettingsProto.POWER_MANAGER_CONSTANTS);
+        dumpSetting(s, p,
                 Settings.Global.ALARM_MANAGER_CONSTANTS,
                 GlobalSettingsProto.ALARM_MANAGER_CONSTANTS);
         dumpSetting(s, p,
@@ -732,6 +831,12 @@
                 Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
                 GlobalSettingsProto.SHORTCUT_MANAGER_CONSTANTS);
         dumpSetting(s, p,
+                Settings.Global.DEVICE_POLICY_CONSTANTS,
+                GlobalSettingsProto.DEVICE_POLICY_CONSTANTS);
+        dumpSetting(s, p,
+                Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
+                GlobalSettingsProto.TEXT_CLASSIFIER_CONSTANTS);
+        dumpSetting(s, p,
                 Settings.Global.WINDOW_ANIMATION_SCALE,
                 GlobalSettingsProto.WINDOW_ANIMATION_SCALE);
         dumpSetting(s, p,
@@ -764,6 +869,7 @@
         dumpSetting(s, p,
                 Settings.Global.WAIT_FOR_DEBUGGER,
                 GlobalSettingsProto.WAIT_FOR_DEBUGGER);
+        // Settings.Global.SHOW_PROCESSES intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Global.LOW_POWER_MODE,
                 GlobalSettingsProto.LOW_POWER_MODE);
@@ -819,6 +925,18 @@
                 Settings.Global.INTENT_FIREWALL_UPDATE_METADATA_URL,
                 GlobalSettingsProto.INTENT_FIREWALL_UPDATE_METADATA_URL);
         dumpSetting(s, p,
+                Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
+                GlobalSettingsProto.LANG_ID_UPDATE_CONTENT_URL);
+        dumpSetting(s, p,
+                Settings.Global.LANG_ID_UPDATE_METADATA_URL,
+                GlobalSettingsProto.LANG_ID_UPDATE_METADATA_URL);
+        dumpSetting(s, p,
+                Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
+                GlobalSettingsProto.SMART_SELECTION_UPDATE_CONTENT_URL);
+        dumpSetting(s, p,
+                Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
+                GlobalSettingsProto.SMART_SELECTION_UPDATE_METADATA_URL);
+        dumpSetting(s, p,
                 Settings.Global.SELINUX_STATUS,
                 GlobalSettingsProto.SELINUX_STATUS);
         dumpSetting(s, p,
@@ -882,11 +1000,8 @@
                 Settings.Global.ENABLE_EPHEMERAL_FEATURE,
                 GlobalSettingsProto.ENABLE_EPHEMERAL_FEATURE);
         dumpSetting(s, p,
-                Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
-                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
-        dumpSetting(s, p,
-                Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
-                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+                Settings.Global.INSTANT_APP_DEXOPT_ENABLED,
+                GlobalSettingsProto.INSTANT_APP_DEXOPT_ENABLED);
         dumpSetting(s, p,
                 Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
                 GlobalSettingsProto.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
@@ -894,6 +1009,12 @@
                 Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
                 GlobalSettingsProto.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
         dumpSetting(s, p,
+                Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
+        dumpSetting(s, p,
+                Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+                GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+        dumpSetting(s, p,
                 Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
                 GlobalSettingsProto.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD);
         dumpSetting(s, p,
@@ -909,12 +1030,30 @@
                 Settings.Global.DEVICE_DEMO_MODE,
                 GlobalSettingsProto.DEVICE_DEMO_MODE);
         dumpSetting(s, p,
+                Settings.Global.NETWORK_ACCESS_TIMEOUT_MS,
+                GlobalSettingsProto.NETWORK_ACCESS_TIMEOUT_MS);
+        dumpSetting(s, p,
                 Settings.Global.DATABASE_DOWNGRADE_REASON,
                 GlobalSettingsProto.DATABASE_DOWNGRADE_REASON);
         dumpSetting(s, p,
+                Settings.Global.DATABASE_CREATION_BUILDID,
+                GlobalSettingsProto.DATABASE_CREATION_BUILDID);
+        dumpSetting(s, p,
                 Settings.Global.CONTACTS_DATABASE_WAL_ENABLED,
                 GlobalSettingsProto.CONTACTS_DATABASE_WAL_ENABLED);
         dumpSetting(s, p,
+                Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
+                GlobalSettingsProto.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED);
+        dumpSetting(s, p,
+                Settings.Global.BACKUP_REFACTORED_SERVICE_DISABLED,
+                GlobalSettingsProto.BACKUP_REFACTORED_SERVICE_DISABLED);
+        dumpSetting(s, p,
+                Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+                GlobalSettingsProto.EUICC_FACTORY_RESET_TIMEOUT_MILLIS);
+        dumpSetting(s, p,
+                Settings.Global.STORAGE_SETTINGS_CLOBBER_THRESHOLD,
+                GlobalSettingsProto.STORAGE_SETTINGS_CLOBBER_THRESHOLD);
+        dumpSetting(s, p,
                 Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
                 GlobalSettingsProto.MULTI_SIM_VOICE_CALL_SUBSCRIPTION);
         dumpSetting(s, p,
@@ -932,6 +1071,7 @@
         dumpSetting(s, p,
                 Settings.Global.NEW_CONTACT_AGGREGATOR,
                 GlobalSettingsProto.NEW_CONTACT_AGGREGATOR);
+        // Settings.Global.CONTACT_METADATA_SYNC intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Global.CONTACT_METADATA_SYNC_ENABLED,
                 GlobalSettingsProto.CONTACT_METADATA_SYNC_ENABLED);
@@ -942,8 +1082,31 @@
                 Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
                 GlobalSettingsProto.MAX_NOTIFICATION_ENQUEUE_RATE);
         dumpSetting(s, p,
+                Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
+                GlobalSettingsProto.SHOW_NOTIFICATION_CHANNEL_WARNINGS);
+        dumpSetting(s, p,
                 Settings.Global.CELL_ON,
                 GlobalSettingsProto.CELL_ON);
+        dumpSetting(s, p,
+                Settings.Global.SHOW_TEMPERATURE_WARNING,
+                GlobalSettingsProto.SHOW_TEMPERATURE_WARNING);
+        dumpSetting(s, p,
+                Settings.Global.WARNING_TEMPERATURE,
+                GlobalSettingsProto.WARNING_TEMPERATURE);
+        dumpSetting(s, p,
+                Settings.Global.ENABLE_DISKSTATS_LOGGING,
+                GlobalSettingsProto.ENABLE_DISKSTATS_LOGGING);
+        dumpSetting(s, p,
+                Settings.Global.ENABLE_CACHE_QUOTA_CALCULATION,
+                GlobalSettingsProto.ENABLE_CACHE_QUOTA_CALCULATION);
+        dumpSetting(s, p,
+                Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE,
+                GlobalSettingsProto.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE);
+        // The list of snooze options for notifications. This is encoded as a key=value list,
+        // separated by commas.
+        dumpSetting(s, p,
+                Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
+                GlobalSettingsProto.NOTIFICATION_SNOOZE_OPTIONS);
     }
 
     /** Dump a single {@link SettingsState.Setting} to a proto buf */
@@ -966,9 +1129,19 @@
 
     static void dumpProtoSecureSettingsLocked(
             @NonNull SettingsState s, @NonNull ProtoOutputStream p) {
+        s.dumpHistoricalOperations(p, SecureSettingsProto.HISTORICAL_OPERATIONS);
+
+        // This uses the same order as in Settings.Secure.
+
+        // Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED intentionally excluded since it's deprecated.
+        // Settings.Secure.BUGREPORT_IN_POWER_MENU intentionally excluded since it's deprecated.
+        // Settings.Secure.ADB_ENABLED intentionally excluded since it's deprecated.
+        // Settings.Secure.ALLOW_MOCK_LOCATION intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.ANDROID_ID,
                 SecureSettingsProto.ANDROID_ID);
+        // Settings.Secure.BLUETOOTH_ON intentionally excluded since it's deprecated.
+        // Settings.Secure.DATA_ROAMING intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.DEFAULT_INPUT_METHOD,
                 SecureSettingsProto.DEFAULT_INPUT_METHOD);
@@ -987,9 +1160,16 @@
         dumpSetting(s, p,
                 Settings.Secure.AUTOFILL_SERVICE,
                 SecureSettingsProto.AUTOFILL_SERVICE);
+        // Settings.Secure.DEVICE_PROVISIONED intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.USER_SETUP_COMPLETE,
                 SecureSettingsProto.USER_SETUP_COMPLETE);
+        // Whether the current user has been set up via setup wizard (0 = false, 1 = true). This
+        // value differs from USER_SETUP_COMPLETE in that it can be reset back to 0 in case
+        // SetupWizard has been re-enabled on TV devices.
+        dumpSetting(s, p,
+                Settings.Secure.TV_USER_SETUP_COMPLETE,
+                SecureSettingsProto.TV_USER_SETUP_COMPLETE);
         dumpSetting(s, p,
                 Settings.Secure.COMPLETED_CATEGORY_PREFIX,
                 SecureSettingsProto.COMPLETED_CATEGORY_PREFIX);
@@ -1002,6 +1182,7 @@
         dumpSetting(s, p,
                 Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
                 SecureSettingsProto.SHOW_IME_WITH_HARD_KEYBOARD);
+        // Settings.Secure.HTTP_PROXY intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.ALWAYS_ON_VPN_APP,
                 SecureSettingsProto.ALWAYS_ON_VPN_APP);
@@ -1012,17 +1193,33 @@
                 Settings.Secure.INSTALL_NON_MARKET_APPS,
                 SecureSettingsProto.INSTALL_NON_MARKET_APPS);
         dumpSetting(s, p,
+                Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED,
+                SecureSettingsProto.UNKNOWN_SOURCES_DEFAULT_REVERSED);
+        // Settings.Secure.LOCATION_PROVIDERS_ALLOWED intentionally excluded since it's deprecated.
+        dumpSetting(s, p,
                 Settings.Secure.LOCATION_MODE,
                 SecureSettingsProto.LOCATION_MODE);
         dumpSetting(s, p,
                 Settings.Secure.LOCATION_PREVIOUS_MODE,
                 SecureSettingsProto.LOCATION_PREVIOUS_MODE);
+        // Settings.Secure.LOCK_BIOMETRIC_WEAK_FLAGS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
                 SecureSettingsProto.LOCK_TO_APP_EXIT_LOCKED);
+        // Settings.Secure.LOCK_PATTERN_ENABLED intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_PATTERN_VISIBLE intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_PATTERN_TACTICLE_FEEDBACK_ENABLED intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
                 SecureSettingsProto.LOCK_SCREEN_LOCK_AFTER_TIMEOUT);
+        // Settings.Secure.LOCK_SCREEN_OWNER_INFO intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_SCREEN_STICKY_APPWIDGET intentionally excluded since it's deprecated.
+        // Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED intentionally excluded since it's deprecated.
+        dumpSetting(s, p,
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                SecureSettingsProto.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
         dumpSetting(s, p,
                 Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
                 SecureSettingsProto.LOCK_SCREEN_ALLOW_REMOTE_INPUT);
@@ -1032,6 +1229,8 @@
         dumpSetting(s, p,
                 Settings.Secure.TRUST_AGENTS_INITIALIZED,
                 SecureSettingsProto.TRUST_AGENTS_INITIALIZED);
+        // Settings.Secure.LOGGING_ID intentionally excluded since it's deprecated.
+        // Settings.Secure.NETWORK_PREFERENCE intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.PARENTAL_CONTROL_ENABLED,
                 SecureSettingsProto.PARENTAL_CONTROL_ENABLED);
@@ -1044,10 +1243,27 @@
         dumpSetting(s, p,
                 Settings.Secure.SETTINGS_CLASSNAME,
                 SecureSettingsProto.SETTINGS_CLASSNAME);
+        // Settings.Secure.USB_MASS_STORAGE_ENABLED intentionally excluded since it's deprecated.
+        // Settings.Secure.USE_GOOGLE_MAIL intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.ACCESSIBILITY_ENABLED,
                 SecureSettingsProto.ACCESSIBILITY_ENABLED);
         dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED,
+                SecureSettingsProto.ACCESSIBILITY_SHORTCUT_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
+                SecureSettingsProto.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+                SecureSettingsProto.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+                SecureSettingsProto.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
+                SecureSettingsProto.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
+        dumpSetting(s, p,
                 Settings.Secure.TOUCH_EXPLORATION_ENABLED,
                 SecureSettingsProto.TOUCH_EXPLORATION_ENABLED);
         dumpSetting(s, p,
@@ -1066,9 +1282,15 @@
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
                 SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
         dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+                SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
+        dumpSetting(s, p,
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                 SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE);
         dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
+                SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE);
+        dumpSetting(s, p,
                 Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
                 SecureSettingsProto.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
         dumpSetting(s, p,
@@ -1134,6 +1356,7 @@
         dumpSetting(s, p,
                 Settings.Secure.DISPLAY_DENSITY_FORCED,
                 SecureSettingsProto.DISPLAY_DENSITY_FORCED);
+        // Settings.Secure.TTS_USE_DEFAULTS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.TTS_DEFAULT_RATE,
                 SecureSettingsProto.TTS_DEFAULT_RATE);
@@ -1143,15 +1366,37 @@
         dumpSetting(s, p,
                 Settings.Secure.TTS_DEFAULT_SYNTH,
                 SecureSettingsProto.TTS_DEFAULT_SYNTH);
+        // Settings.Secure.TTS_DEFAULT_LANG intentionally excluded since it's deprecated.
+        // Settings.Secure.TTS_DEFAULT_COUNTRY intentionally excluded since it's deprecated.
+        // Settings.Secure.TTS_DEFAULT_VARIANT intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.TTS_DEFAULT_LOCALE,
                 SecureSettingsProto.TTS_DEFAULT_LOCALE);
         dumpSetting(s, p,
                 Settings.Secure.TTS_ENABLED_PLUGINS,
                 SecureSettingsProto.TTS_ENABLED_PLUGINS);
+        // Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_ON intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_AP_COUNT intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_ON intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_WATCH_LIST intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_PING_COUNT intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT intentionally excluded since it's deprecated.
+        // Settings.Secure.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
                 SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS);
+        // Settings.Secure.BACKGROUND_DATA intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS,
                 SecureSettingsProto.ALLOWED_GEOLOCATION_ORIGINS);
@@ -1179,6 +1424,7 @@
         dumpSetting(s, p,
                 Settings.Secure.LAST_SETUP_SHOWN,
                 SecureSettingsProto.LAST_SETUP_SHOWN);
+        // Settings.Secure.WIFI_IDLE_MS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY,
                 SecureSettingsProto.SEARCH_GLOBAL_SEARCH_ACTIVITY);
@@ -1285,6 +1531,9 @@
                 Settings.Secure.DOZE_PULSE_ON_PICK_UP,
                 SecureSettingsProto.DOZE_PULSE_ON_PICK_UP);
         dumpSetting(s, p,
+                Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
+                SecureSettingsProto.DOZE_PULSE_ON_LONG_PRESS);
+        dumpSetting(s, p,
                 Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
                 SecureSettingsProto.DOZE_PULSE_ON_DOUBLE_TAP);
         dumpSetting(s, p,
@@ -1351,6 +1600,9 @@
                 Settings.Secure.PAYMENT_SERVICE_SEARCH_URI,
                 SecureSettingsProto.PAYMENT_SERVICE_SEARCH_URI);
         dumpSetting(s, p,
+                Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
+                SecureSettingsProto.AUTOFILL_SERVICE_SEARCH_URI);
+        dumpSetting(s, p,
                 Settings.Secure.SKIP_FIRST_USE_HINTS,
                 SecureSettingsProto.SKIP_FIRST_USE_HINTS);
         dumpSetting(s, p,
@@ -1387,18 +1639,42 @@
                 Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
                 SecureSettingsProto.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED);
         dumpSetting(s, p,
+                Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED,
+                SecureSettingsProto.CAMERA_LIFT_TRIGGER_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_GESTURE_ENABLED,
+                SecureSettingsProto.ASSIST_GESTURE_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+                SecureSettingsProto.ASSIST_GESTURE_SENSITIVITY);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
+                SecureSettingsProto.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
+                SecureSettingsProto.ASSIST_GESTURE_WAKE_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
+                SecureSettingsProto.ASSIST_GESTURE_SETUP_COMPLETE);
+        dumpSetting(s, p,
                 Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
                 SecureSettingsProto.NIGHT_DISPLAY_ACTIVATED);
         dumpSetting(s, p,
                 Settings.Secure.NIGHT_DISPLAY_AUTO_MODE,
                 SecureSettingsProto.NIGHT_DISPLAY_AUTO_MODE);
         dumpSetting(s, p,
+                Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
+                SecureSettingsProto.NIGHT_DISPLAY_COLOR_TEMPERATURE);
+        dumpSetting(s, p,
                 Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
                 SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_START_TIME);
         dumpSetting(s, p,
                 Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
                 SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_END_TIME);
         dumpSetting(s, p,
+                Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
+                SecureSettingsProto.NIGHT_DISPLAY_LAST_ACTIVATED_TIME);
+        dumpSetting(s, p,
                 Settings.Secure.ENABLED_VR_LISTENERS,
                 SecureSettingsProto.ENABLED_VR_LISTENERS);
         dumpSetting(s, p,
@@ -1423,6 +1699,9 @@
                 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
                 SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_LAST_RUN);
         dumpSetting(s, p,
+                Settings.Secure.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY,
+                SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY);
+        dumpSetting(s, p,
                 Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
                 SecureSettingsProto.SYSTEM_NAVIGATION_KEYS_ENABLED);
         dumpSetting(s, p,
@@ -1438,33 +1717,76 @@
                 Settings.Secure.DEVICE_PAIRED,
                 SecureSettingsProto.DEVICE_PAIRED);
         dumpSetting(s, p,
+                Settings.Secure.PACKAGE_VERIFIER_STATE,
+                SecureSettingsProto.PACKAGE_VERIFIER_STATE);
+        dumpSetting(s, p,
+                Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
+                SecureSettingsProto.CMAS_ADDITIONAL_BROADCAST_PKG);
+        dumpSetting(s, p,
                 Settings.Secure.NOTIFICATION_BADGING,
                 SecureSettingsProto.NOTIFICATION_BADGING);
         dumpSetting(s, p,
+                Settings.Secure.QS_AUTO_ADDED_TILES,
+                SecureSettingsProto.QS_AUTO_ADDED_TILES);
+        dumpSetting(s, p,
+                Settings.Secure.LOCKDOWN_IN_POWER_MENU,
+                SecureSettingsProto.LOCKDOWN_IN_POWER_MENU);
+        dumpSetting(s, p,
                 Settings.Secure.BACKUP_MANAGER_CONSTANTS,
                 SecureSettingsProto.BACKUP_MANAGER_CONSTANTS);
     }
 
     private static void dumpProtoSystemSettingsLocked(
             @NonNull SettingsState s, @NonNull ProtoOutputStream p) {
+        s.dumpHistoricalOperations(p, SystemSettingsProto.HISTORICAL_OPERATIONS);
+
+        // This uses the same order as in Settings.System.
+
+        // Settings.System.STAY_ON_WHILE_PLUGGED_IN intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.END_BUTTON_BEHAVIOR,
                 SystemSettingsProto.END_BUTTON_BEHAVIOR);
         dumpSetting(s, p,
                 Settings.System.ADVANCED_SETTINGS,
                 SystemSettingsProto.ADVANCED_SETTINGS);
+        // Settings.System.AIRPLANE_MODE_ON intentionally excluded since it's deprecated.
+        // Settings.System.RADIO_BLUETOOTH intentionally excluded since it's deprecated.
+        // Settings.System.RADIO_WIFI intentionally excluded since it's deprecated.
+        // Settings.System.RADIO_WIMAX intentionally excluded since it's deprecated.
+        // Settings.System.RADIO_CELL intentionally excluded since it's deprecated.
+        // Settings.System.RADIO_NFC intentionally excluded since it's deprecated.
+        // Settings.System.AIRPLANE_MODE_RADIOS intentionally excluded since it's deprecated.
+        // Settings.System.AIRPLANE_MODE_TOGGLABLE_RADIOS intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_SLEEP_POLICY intentionally excluded since it's deprecated.
+        // Settings.System.MODE_RINGER intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_USE_STATIC_IP intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_STATIC_IP intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_STATIC_GATEWAY intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_STATIC_NETMASK intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_STATIC_DNS1 intentionally excluded since it's deprecated.
+        // Settings.System.WIFI_STATIC_DNS2 intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.BLUETOOTH_DISCOVERABILITY,
                 SystemSettingsProto.BLUETOOTH_DISCOVERABILITY);
         dumpSetting(s, p,
                 Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
                 SystemSettingsProto.BLUETOOTH_DISCOVERABILITY_TIMEOUT);
+        // Settings.System.LOCK_PATTERN_ENABLED intentionally excluded since it's deprecated.
+        // Settings.System.LOCK_PATTERN_VISIBLE intentionally excluded since it's deprecated.
+        // Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED intentionally excluded since it's deprecated.
+        // Settings.System.NEXT_ALARM_FORMATTED intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.FONT_SCALE,
                 SystemSettingsProto.FONT_SCALE);
         dumpSetting(s, p,
                 Settings.System.SYSTEM_LOCALES,
                 SystemSettingsProto.SYSTEM_LOCALES);
+        // Settings.System.DEBUG_APP intentionally excluded since it's deprecated.
+        // Settings.System.WAIT_FOR_DEBUGGER intentionally excluded since it's deprecated.
+        // Settings.System.DIM_SCREEN intentionally excluded since it's deprecated.
+        dumpSetting(s, p,
+                Settings.System.DISPLAY_COLOR_MODE,
+                SystemSettingsProto.DISPLAY_COLOR_MODE);
         dumpSetting(s, p,
                 Settings.System.SCREEN_OFF_TIMEOUT,
                 SystemSettingsProto.SCREEN_OFF_TIMEOUT);
@@ -1480,6 +1802,8 @@
         dumpSetting(s, p,
                 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
                 SystemSettingsProto.SCREEN_AUTO_BRIGHTNESS_ADJ);
+        // Settings.System.SHOW_PROCESSES intentionally excluded since it's deprecated.
+        // Settings.System.ALWAYS_FINISH_ACTIVITIES intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
                 SystemSettingsProto.MODE_RINGER_STREAMS_AFFECTED);
@@ -1514,11 +1838,15 @@
                 Settings.System.VOLUME_BLUETOOTH_SCO,
                 SystemSettingsProto.VOLUME_BLUETOOTH_SCO);
         dumpSetting(s, p,
+                Settings.System.VOLUME_ACCESSIBILITY,
+                SystemSettingsProto.VOLUME_ACCESSIBILITY);
+        dumpSetting(s, p,
                 Settings.System.VOLUME_MASTER,
                 SystemSettingsProto.VOLUME_MASTER);
         dumpSetting(s, p,
                 Settings.System.MASTER_MONO,
                 SystemSettingsProto.MASTER_MONO);
+        // Settings.System.NOTIFICATIONS_USE_RING_VOLUME intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.VIBRATE_IN_SILENT,
                 SystemSettingsProto.VIBRATE_IN_SILENT);
@@ -1561,6 +1889,9 @@
         dumpSetting(s, p,
                 Settings.System.SHOW_GTALK_SERVICE_STATUS,
                 SystemSettingsProto.SHOW_GTALK_SERVICE_STATUS);
+        // Settings.System.WALLPAPER_ACTIVITY intentionally excluded since it's deprecated.
+        // Settings.System.AUTO_TIME intentionally excluded since it's deprecated.
+        // Settings.System.AUTO_TIME_ZONE intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.TIME_12_24,
                 SystemSettingsProto.TIME_12_24);
@@ -1570,6 +1901,9 @@
         dumpSetting(s, p,
                 Settings.System.SETUP_WIZARD_HAS_RUN,
                 SystemSettingsProto.SETUP_WIZARD_HAS_RUN);
+        // Settings.System.WINDOW_ANIMATION_SCALE intentionally excluded since it's deprecated.
+        // Settings.System.TRANSITION_ANIMATION_SCALE intentionally excluded since it's deprecated.
+        // Settings.System.ANIMATOR_ANIMATION_SCALE intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.ACCELEROMETER_ROTATION,
                 SystemSettingsProto.ACCELEROMETER_ROTATION);
@@ -1600,6 +1934,7 @@
         dumpSetting(s, p,
                 Settings.System.HAPTIC_FEEDBACK_ENABLED,
                 SystemSettingsProto.HAPTIC_FEEDBACK_ENABLED);
+        // Settings.System.SHOW_WEB_SUGGESTIONS intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.NOTIFICATION_LIGHT_PULSE,
                 SystemSettingsProto.NOTIFICATION_LIGHT_PULSE);
@@ -1612,12 +1947,21 @@
         dumpSetting(s, p,
                 Settings.System.WINDOW_ORIENTATION_LISTENER_LOG,
                 SystemSettingsProto.WINDOW_ORIENTATION_LISTENER_LOG);
+        // Settings.System.POWER_SOUNDS_ENABLED intentionally excluded since it's deprecated.
+        // Settings.System.DOCK_SOUNDS_ENABLED intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
                 SystemSettingsProto.LOCKSCREEN_SOUNDS_ENABLED);
         dumpSetting(s, p,
                 Settings.System.LOCKSCREEN_DISABLED,
                 SystemSettingsProto.LOCKSCREEN_DISABLED);
+        // Settings.System.LOW_BATTERY_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.DESK_DOCK_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.DESK_UNDOCK_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.CAR_DOCK_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.CAR_UNDOCK_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.LOCK_SOUND intentionally excluded since it's deprecated.
+        // Settings.System.UNLOCK_SOUND intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.SIP_RECEIVE_CALLS,
                 SystemSettingsProto.SIP_RECEIVE_CALLS);
@@ -1630,6 +1974,7 @@
         dumpSetting(s, p,
                 Settings.System.SIP_ADDRESS_ONLY,
                 SystemSettingsProto.SIP_ADDRESS_ONLY);
+        // Settings.System.SIP_ASK_ME_EACH_TIME intentionally excluded since it's deprecated.
         dumpSetting(s, p,
                 Settings.System.POINTER_SPEED,
                 SystemSettingsProto.POINTER_SPEED);
@@ -1640,7 +1985,12 @@
                 Settings.System.EGG_MODE,
                 SystemSettingsProto.EGG_MODE);
         dumpSetting(s, p,
+                Settings.System.SHOW_BATTERY_PERCENT,
+                SystemSettingsProto.SHOW_BATTERY_PERCENT);
+        dumpSetting(s, p,
                 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
                 SystemSettingsProto.WHEN_TO_MAKE_WIFI_CALLS);
+        // The rest of the settings were moved to Settings.Secure, and are thus excluded here since
+        // they're deprecated from Settings.System.
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 36f9b84..258c96c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.backup.BackupManager;
@@ -657,7 +658,6 @@
 
         synchronized (mLock) {
             SettingsProtoDumpUtil.dumpProtoLocked(mSettingsRegistry, proto);
-
         }
 
         proto.flush();
@@ -2284,6 +2284,7 @@
             return users;
         }
 
+        @Nullable
         public SettingsState getSettingsLocked(int type, int userId) {
             final int key = makeKey(type, userId);
             return peekSettingsStateLocked(key);
@@ -2578,6 +2579,7 @@
             ssaidSettings.deleteSettingLocked(Integer.toString(uid));
         }
 
+        @Nullable
         private SettingsState peekSettingsStateLocked(int key) {
             SettingsState settingsState = mSettingsStates.get(key);
             if (settingsState != null) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 4151ada..f901bca 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -434,8 +434,9 @@
      * Dump historical operations as a proto buf.
      *
      * @param proto The proto buf stream to dump to
+     * @param fieldId The repeated field ID to use to save an operation to.
      */
-    void dumpProtoHistoricalOperations(@NonNull ProtoOutputStream proto) {
+    void dumpHistoricalOperations(@NonNull ProtoOutputStream proto, long fieldId) {
         synchronized (mLock) {
             if (mHistoricalOperations == null) {
                 return;
@@ -448,7 +449,8 @@
                     index = operationCount + index;
                 }
                 HistoricalOperation operation = mHistoricalOperations.get(index);
-                long settingsOperationToken = proto.start(GlobalSettingsProto.HISTORICAL_OP);
+
+                final long token = proto.start(fieldId);
                 proto.write(SettingsOperationProto.TIMESTAMP, operation.mTimestamp);
                 proto.write(SettingsOperationProto.OPERATION, operation.mOperation);
                 if (operation.mSetting != null) {
@@ -457,7 +459,7 @@
                     // add is what the current data is).
                     proto.write(SettingsOperationProto.SETTING, operation.mSetting.getName());
                 }
-                proto.end(settingsOperationToken);
+                proto.end(token);
             }
         }
     }
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 3d9a2dc..fac254a 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -13,30 +13,36 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<RelativeLayout
+<com.android.systemui.HardwareUiLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/volume_dialog"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
-    android:background="@drawable/volume_dialog_background"
-    android:paddingTop="@dimen/volume_dialog_padding_top"
+    android:layout_height="match_parent"
     android:theme="@style/qs_theme"
-    android:translationZ="4dp" >
-
-    <LinearLayout
-        android:id="@+id/volume_dialog_content"
-        android:layout_width="match_parent"
+    android:clipChildren="false" >
+    <RelativeLayout
+        android:id="@+id/volume_dialog"
+        android:layout_width="@dimen/volume_dialog_panel_width"
         android:layout_height="wrap_content"
-        android:orientation="vertical" >
+        android:layout_gravity="center_vertical|end"
+        android:paddingTop="@dimen/volume_row_padding_bottom"
+        android:layout_margin="12dp"
+        android:background="?android:attr/actionBarItemBackground"
+        android:translationZ="8dp" >
 
         <LinearLayout
-            android:id="@+id/volume_dialog_rows"
+            android:id="@+id/volume_dialog_content"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical" >
-            <!-- volume rows added and removed here! :-) -->
-        </LinearLayout>
-    </LinearLayout>
 
-</RelativeLayout>
+            <LinearLayout
+                android:id="@+id/volume_dialog_rows"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical" >
+                <!-- volume rows added and removed here! :-) -->
+            </LinearLayout>
+        </LinearLayout>
+
+    </RelativeLayout>
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index 7328d05..bf76e78 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -19,8 +19,8 @@
     android:layout_height="@dimen/volume_row_height"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:orientation="vertical"
-    android:paddingBottom="@dimen/volume_row_padding_bottom" >
+    android:theme="@style/qs_theme"
+    android:orientation="vertical" >
 
     <TextView
         android:id="@+id/volume_row_header"
@@ -28,7 +28,8 @@
         android:layout_height="wrap_content"
         android:ellipsize="end"
         android:maxLines="1"
-        android:textAppearance="@style/TextAppearance.Volume.Header"
+        android:textColor="?android:attr/colorControlNormal"
+        android:textAppearance="?android:attr/textAppearanceSmall"
         android:paddingStart="@dimen/volume_row_header_padding_start" />
 
     <LinearLayout
@@ -53,4 +54,9 @@
                 android:paddingStart="@dimen/volume_row_slider_padding_start"/>
     </LinearLayout>
 
+    <Space
+        android:id="@+id/spacer"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/volume_row_padding_bottom"/>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c678111f..f0bad2a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -240,7 +240,7 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
-    <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
+    <dimen name="volume_dialog_panel_width">315dp</dimen>
 
     <!-- Gravity for the notification panel -->
     <integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 039e13c..2e4a5a4 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -16,16 +16,21 @@
 
 package com.android.systemui;
 
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
@@ -37,13 +42,15 @@
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
  * Class to send information from overview to launcher with a binder.
  */
-public class OverviewProxyService implements CallbackController<OverviewProxyListener> {
+public class OverviewProxyService implements CallbackController<OverviewProxyListener>, Dumpable {
 
     private static final String TAG = "OverviewProxyService";
     private static final long BACKOFF_MILLIS = 5000;
@@ -51,6 +58,7 @@
     private final Context mContext;
     private final Handler mHandler;
     private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
+    private final ComponentName mLauncherComponentName;
     private final DeviceProvisionedController mDeviceProvisionedController
             = Dependency.get(DeviceProvisionedController.class);
     private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
@@ -71,6 +79,14 @@
         }
     };
 
+    private final BroadcastReceiver mLauncherAddedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Reconnect immediately, instead of waiting for resume to arrive.
+            startConnectionToCurrentUser();
+        }
+    };
+
     private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -115,18 +131,23 @@
         };
 
     // This is the death handler for the binder from the launcher service
-    private final IBinder.DeathRecipient mOverviewServiceDeathRcpt = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            startConnectionToCurrentUser();
-        }
-    };
+    private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
+            = this::startConnectionToCurrentUser;
 
     public OverviewProxyService(Context context) {
         mContext = context;
         mHandler = new Handler();
         mConnectionBackoffAttempts = 0;
+        mLauncherComponentName = ComponentName
+                .unflattenFromString(context.getString(R.string.config_overviewServiceComponent));
         mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
+
+        // Listen for the package update changes.
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addDataScheme("package");
+        filter.addDataSchemeSpecificPart(mLauncherComponentName.getPackageName(),
+                PatternMatcher.PATTERN_LITERAL);
+        mContext.registerReceiver(mLauncherAddedReceiver, filter);
     }
 
     public void startConnectionToCurrentUser() {
@@ -146,8 +167,7 @@
         }
         mHandler.removeCallbacks(mConnectionRunnable);
         Intent launcherServiceIntent = new Intent();
-        launcherServiceIntent.setComponent(ComponentName.unflattenFromString(
-                mContext.getString(R.string.config_overviewServiceComponent)));
+        launcherServiceIntent.setComponent(mLauncherComponentName);
         boolean bound = mContext.bindServiceAsUser(launcherServiceIntent,
                 mOverviewServiceConnection, Context.BIND_AUTO_CREATE,
                 UserHandle.getUserHandleForUid(mDeviceProvisionedController.getCurrentUser()));
@@ -189,6 +209,15 @@
         }
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println(TAG + " state:");
+        pw.print("  mConnectionBackoffAttempts="); pw.println(mConnectionBackoffAttempts);
+        pw.print("  isCurrentUserSetup="); pw.println(mDeviceProvisionedController
+                .isCurrentUserSetup());
+        pw.print("  isConnected="); pw.println(mOverviewProxy != null);
+    }
+
     public interface OverviewProxyListener {
         void onConnectionChanged(boolean isConnected);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index d82f9cd..00e8b1a 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -80,7 +80,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
 import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
+import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
 
 import java.util.ArrayList;
 import java.util.List;
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 e3ed581..6775615 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -6838,6 +6838,15 @@
             return false;
         }
 
+        if (mIsOccluded && !isDozing()) {
+            boolean devicePublic = isLockscreenPublicMode(mCurrentUserId);
+            boolean userPublic = devicePublic || isLockscreenPublicMode(sbn.getUserId());
+            boolean needsRedaction = needsRedaction(entry);
+            if (userPublic && needsRedaction) {
+                return false;
+            }
+        }
+
         if (sbn.getNotification().fullScreenIntent != null) {
             if (mAccessibilityManager.isTouchExplorationEnabled()) {
                 if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SystemUIInterpolators.java b/packages/SystemUI/src/com/android/systemui/volume/SystemUIInterpolators.java
new file mode 100644
index 0000000..5ad8840
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/SystemUIInterpolators.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import android.animation.TimeInterpolator;
+
+public class SystemUIInterpolators {
+    public static final class LogDecelerateInterpolator implements TimeInterpolator {
+        private final float mBase;
+        private final float mDrift;
+        private final float mTimeScale;
+        private final float mOutputScale;
+
+        public LogDecelerateInterpolator() {
+            this(400f, 1.4f, 0);
+        }
+
+        private LogDecelerateInterpolator(float base, float timeScale, float drift) {
+            mBase = base;
+            mDrift = drift;
+            mTimeScale = 1f / timeScale;
+
+            mOutputScale = 1f / computeLog(1f);
+        }
+
+        private float computeLog(float t) {
+            return 1f - (float) Math.pow(mBase, -t * mTimeScale) + (mDrift * t);
+        }
+
+        @Override
+        public float getInterpolation(float t) {
+            return computeLog(t) * mOutputScale;
+        }
+    }
+
+    public static final class LogAccelerateInterpolator implements TimeInterpolator {
+        private final int mBase;
+        private final int mDrift;
+        private final float mLogScale;
+
+        public LogAccelerateInterpolator() {
+            this(100, 0);
+        }
+
+        private LogAccelerateInterpolator(int base, int drift) {
+            mBase = base;
+            mDrift = drift;
+            mLogScale = 1f / computeLog(1, mBase, mDrift);
+        }
+
+        private static float computeLog(float t, int base, int drift) {
+            return (float) -Math.pow(base, -t) + 1 + (drift * t);
+        }
+
+        @Override
+        public float getInterpolation(float t) {
+            return 1 - computeLog(1 - t, mBase, mDrift) * mLogScale;
+        }
+    }
+
+    public interface Callback {
+        void onAnimatingChanged(boolean animating);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index ee8f18e..4dff9bd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -62,7 +62,6 @@
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
             | ActivityInfo.CONFIG_ASSETS_PATHS);
-    private final Extension mExtension;
     private VolumeDialog mDialog;
     private VolumePolicy mVolumePolicy = new VolumePolicy(
             DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT,  // volumeDownToEnterSilent
@@ -79,7 +78,7 @@
         // Allow plugins to reference the VolumeDialogController.
         Dependency.get(PluginDependencyProvider.class)
                 .allowPluginDependency(VolumeDialogController.class);
-        mExtension = Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
+        Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
                 .withPlugin(VolumeDialog.class)
                 .withDefault(this::createDefault)
                 .withCallback(dialog -> {
@@ -151,7 +150,7 @@
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
         if (mConfigChanges.applyNewConfig(mContext.getResources())) {
-            mExtension.reload();
+            mController.mCallbacks.onConfigurationChanged();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 1ecaa13..4b8f581 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -19,6 +19,8 @@
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
 
+import static com.android.systemui.volume.Events.DISMISS_REASON_TOUCH_OUTSIDE;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.animation.ObjectAnimator;
 import android.annotation.NonNull;
@@ -26,11 +28,11 @@
 import android.app.Dialog;
 import android.app.KeyguardManager;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Color;
-import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.media.AudioManager;
@@ -41,12 +43,10 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.provider.Settings.Global;
-import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.view.ContextThemeWrapper;
-import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.AccessibilityDelegate;
@@ -54,7 +54,6 @@
 import android.view.View.OnClickListener;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
-import android.view.ViewGroup.MarginLayoutParams;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -68,12 +67,13 @@
 
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.HardwareUiLayout;
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.VolumeDialog;
 import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.VolumeDialogController.State;
 import com.android.systemui.plugins.VolumeDialogController.StreamState;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -89,8 +89,6 @@
 public class VolumeDialogImpl implements VolumeDialog {
     private static final String TAG = Util.logTag(VolumeDialogImpl.class);
 
-    public static final String SHOW_FULL_ZEN = "sysui_show_full_zen";
-
     private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
     private static final int UPDATE_ANIMATION_DURATION = 80;
 
@@ -99,6 +97,7 @@
     private final VolumeDialogController mController;
 
     private Window mWindow;
+    private HardwareUiLayout mHardwareLayout;
     private CustomDialog mDialog;
     private ViewGroup mDialogView;
     private ViewGroup mDialogRowsView;
@@ -107,16 +106,11 @@
     private ConfigurableTexts mConfigurableTexts;
     private final SparseBooleanArray mDynamic = new SparseBooleanArray();
     private final KeyguardManager mKeyguard;
-    private final AudioManager mAudioManager;
     private final AccessibilityManager mAccessibilityMgr;
-    private int mExpandButtonAnimationDuration;
     private final Object mSafetyWarningLock = new Object();
     private final Accessibility mAccessibility = new Accessibility();
     private final ColorStateList mActiveSliderTint;
     private final ColorStateList mInactiveSliderTint;
-    private VolumeDialogMotion mMotion;
-    private int mWindowType;
-    private final ZenModeController mZenModeController;
 
     private boolean mShowing;
     private boolean mShowA11yStream;
@@ -127,19 +121,12 @@
     private boolean mSilentMode = VolumePrefs.DEFAULT_ENABLE_SILENT_MODE;
     private State mState;
     private SafetyWarningDialog mSafetyWarning;
-    private Callback mCallback;
-    private boolean mPendingStateChanged;
-    private boolean mPendingRecheckAll;
-    private long mCollapseTime;
     private boolean mHovering = false;
-    private int mDensity;
 
     public VolumeDialogImpl(Context context) {
         mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
-        mZenModeController = Dependency.get(ZenModeController.class);
         mController = Dependency.get(VolumeDialogController.class);
         mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mAccessibilityMgr =
                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         mActiveSliderTint = ColorStateList.valueOf(Utils.getColorAccent(mContext));
@@ -147,18 +134,12 @@
     }
 
     public void init(int windowType, Callback callback) {
-        mCallback = callback;
-        mWindowType = windowType;
-
         initDialog();
 
         mAccessibility.init();
 
         mController.addCallback(mControllerCallbackH, mHandler);
         mController.getState();
-
-        final Configuration currentConfig = mContext.getResources().getConfiguration();
-        mDensity = currentConfig.densityDpi;
     }
 
     @Override
@@ -177,25 +158,16 @@
         mWindow = mDialog.getWindow();
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
         mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-        mDialog.setCanceledOnTouchOutside(true);
-        final Resources res = mContext.getResources();
-        final WindowManager.LayoutParams lp = mWindow.getAttributes();
-        lp.type = mWindowType;
-        lp.format = PixelFormat.TRANSLUCENT;
-        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
-        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-        lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
-        lp.gravity = Gravity.TOP;
-        lp.windowAnimations = -1;
-        mWindow.setAttributes(lp);
-        mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
+        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+        mWindow.addFlags(
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+        mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
 
         mDialog.setContentView(R.layout.volume_dialog);
         mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
@@ -209,26 +181,11 @@
                 return true;
             }
         });
+        mHardwareLayout = HardwareUiLayout.get(mDialogView);
+        mHardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE));
 
         mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
         mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
-        updateWindowWidthH();
-
-        mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView,
-                new VolumeDialogMotion.Callback() {
-                    @Override
-                    public void onAnimatingChanged(boolean animating) {
-                        if (animating) return;
-                        if (mPendingStateChanged) {
-                            mHandler.sendEmptyMessage(H.STATE_CHANGED);
-                            mPendingStateChanged = false;
-                        }
-                        if (mPendingRecheckAll) {
-                            mHandler.sendEmptyMessage(H.RECHECK_ALL);
-                            mPendingRecheckAll = false;
-                        }
-                    }
-                });
 
         if (mRows.isEmpty()) {
             addRow(AudioManager.STREAM_MUSIC,
@@ -250,28 +207,12 @@
         } else {
             addExistingRows();
         }
-        mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
     }
 
     private ColorStateList loadColorStateList(int colorResId) {
         return ColorStateList.valueOf(mContext.getColor(colorResId));
     }
 
-    private void updateWindowWidthH() {
-        final ViewGroup.MarginLayoutParams lp =
-                (ViewGroup.MarginLayoutParams) mDialogView.getLayoutParams();
-        final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
-        if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
-        int w = dm.widthPixels;
-        final int max = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
-        if (w > max) {
-            w = max;
-        }
-        lp.width = w - lp.getMarginEnd() - lp.getMarginStart();
-        mDialogView.setLayoutParams(lp);
-    }
-
     public void setStreamImportant(int stream, boolean important) {
         mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
     }
@@ -315,6 +256,7 @@
             final VolumeRow row = mRows.get(i);
             initRow(row, row.stream, row.iconRes, row.iconMuteRes, row.important);
             mDialogRowsView.addView(row.view);
+            updateVolumeRowH(row);
         }
     }
 
@@ -341,7 +283,6 @@
         writer.print("  mDynamic: "); writer.println(mDynamic);
         writer.print("  mAutomute: "); writer.println(mAutomute);
         writer.print("  mSilentMode: "); writer.println(mSilentMode);
-        writer.print("  mCollapseTime: "); writer.println(mCollapseTime);
         writer.print("  mAccessibility.mFeedbackEnabled: ");
         writer.println(mAccessibility.mFeedbackEnabled);
     }
@@ -364,9 +305,9 @@
         row.view = mDialog.getLayoutInflater().inflate(R.layout.volume_dialog_row, null);
         row.view.setId(row.stream);
         row.view.setTag(row);
-        row.header = (TextView) row.view.findViewById(R.id.volume_row_header);
+        row.header = row.view.findViewById(R.id.volume_row_header);
         row.header.setId(20 * row.stream);
-        row.slider = (SeekBar) row.view.findViewById(R.id.volume_row_slider);
+        row.slider =  row.view.findViewById(R.id.volume_row_slider);
         row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
         row.anim = null;
 
@@ -447,11 +388,27 @@
         rescheduleTimeoutH();
         if (mShowing) return;
         mShowing = true;
-        mMotion.startShow();
+        mHardwareLayout.setTranslationX(getAnimTranslation());
+        mHardwareLayout.setAlpha(0);
+        mHardwareLayout.animate()
+                .alpha(1)
+                .translationX(0)
+                .setDuration(300)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .withEndAction(() -> {
+                    mDialog.show();
+                    mWindow.getDecorView().requestAccessibilityFocus();
+                })
+                .start();
         Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
         mController.notifyVisible(true);
     }
 
+    private float getAnimTranslation() {
+        return mContext.getResources().getDimension(
+                R.dimen.volume_dialog_panel_width) / 2;
+    }
+
     protected void rescheduleTimeoutH() {
         mHandler.removeMessages(H.DISMISS);
         final int timeout = computeTimeoutH();
@@ -470,14 +427,19 @@
     }
 
     protected void dismissH(int reason) {
-        if (mMotion.isAnimating()) {
-            return;
-        }
         mHandler.removeMessages(H.DISMISS);
         mHandler.removeMessages(H.SHOW);
         if (!mShowing) return;
         mShowing = false;
-        mMotion.startDismiss();
+        mHardwareLayout.setTranslationX(0);
+        mHardwareLayout.setAlpha(1);
+        mHardwareLayout.animate()
+                .alpha(0)
+                .translationX(getAnimTranslation())
+                .setDuration(300)
+                .withEndAction(() -> mDialog.dismiss())
+                .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
+                .start();
         if (mAccessibilityMgr.isEnabled()) {
             AccessibilityEvent event =
                     AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
@@ -497,30 +459,6 @@
         }
     }
 
-    private void updateDialogBottomMarginH() {
-        final long diff = System.currentTimeMillis() - mCollapseTime;
-        final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
-        final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
-        final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
-                mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
-        if (bottomMargin != mlp.bottomMargin) {
-            if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
-            mlp.bottomMargin = bottomMargin;
-            mDialogView.setLayoutParams(mlp);
-        }
-    }
-
-    private long getConservativeCollapseDuration() {
-        return mExpandButtonAnimationDuration * 3;
-    }
-
-    private void prepareForCollapse() {
-        mHandler.removeMessages(H.UPDATE_BOTTOM_MARGIN);
-        mCollapseTime = System.currentTimeMillis();
-        updateDialogBottomMarginH();
-        mHandler.sendEmptyMessageDelayed(H.UPDATE_BOTTOM_MARGIN, getConservativeCollapseDuration());
-    }
-
     private boolean shouldBeVisibleH(VolumeRow row, VolumeRow activeRow) {
         boolean isActive = row == activeRow;
         if (row.stream == AudioSystem.STREAM_ACCESSIBILITY) {
@@ -567,13 +505,7 @@
     }
 
     private void onStateChangedH(State state) {
-        final boolean animating = mMotion.isAnimating();
-        if (D.BUG) Log.d(TAG, "onStateChangedH animating=" + animating);
         mState = state;
-        if (animating) {
-            mPendingStateChanged = true;
-            return;
-        }
         mDynamic.clear();
         // add any new dynamic rows
         for (int i = 0; i < state.states.size(); i++) {
@@ -642,19 +574,13 @@
         row.icon.setAlpha(iconEnabled ? 1 : 0.5f);
         final int iconRes =
                 isRingVibrate ? R.drawable.ic_volume_ringer_vibrate
-                : isRingSilent || zenMuted ? row.cachedIconRes
+                : isRingSilent || zenMuted ? row.iconMuteRes
                 : ss.routedToBluetooth ?
                         (ss.muted ? R.drawable.ic_volume_media_bt_mute
                                 : R.drawable.ic_volume_media_bt)
                 : mAutomute && ss.level == 0 ? row.iconMuteRes
                 : (ss.muted ? row.iconMuteRes : row.iconRes);
-        if (iconRes != row.cachedIconRes) {
-            if (row.cachedIconRes != 0 && isRingVibrate) {
-                mController.vibrate();
-            }
-            row.cachedIconRes = iconRes;
-            row.icon.setImageResource(iconRes);
-        }
+        row.icon.setImageResource(iconRes);
         row.iconState =
                 iconRes == R.drawable.ic_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE
                 : (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes)
@@ -864,14 +790,8 @@
 
         @Override
         public void onConfigurationChanged() {
-            Configuration newConfig = mContext.getResources().getConfiguration();
-            final int density = newConfig.densityDpi;
-            if (density != mDensity) {
-                mDialog.dismiss();
-                initDialog();
-                mDensity = density;
-            }
-            updateWindowWidthH();
+            mDialog.dismiss();
+            initDialog();
             mConfigurableTexts.update();
         }
 
@@ -908,23 +828,6 @@
         }
     };
 
-    private final ZenModePanel.Callback mZenPanelCallback = new ZenModePanel.Callback() {
-        @Override
-        public void onPrioritySettings() {
-            mCallback.onZenPrioritySettingsClicked();
-        }
-
-        @Override
-        public void onInteraction() {
-            mHandler.sendEmptyMessage(H.RESCHEDULE_TIMEOUT);
-        }
-
-        @Override
-        public void onExpanded(boolean expanded) {
-            // noop.
-        }
-    };
-
     private final class H extends Handler {
         private static final int SHOW = 1;
         private static final int DISMISS = 2;
@@ -933,7 +836,6 @@
         private static final int SET_STREAM_IMPORTANT = 5;
         private static final int RESCHEDULE_TIMEOUT = 6;
         private static final int STATE_CHANGED = 7;
-        private static final int UPDATE_BOTTOM_MARGIN = 8;
 
         public H() {
             super(Looper.getMainLooper());
@@ -949,14 +851,13 @@
                 case SET_STREAM_IMPORTANT: setStreamImportantH(msg.arg1, msg.arg2 != 0); break;
                 case RESCHEDULE_TIMEOUT: rescheduleTimeoutH(); break;
                 case STATE_CHANGED: onStateChangedH(mState); break;
-                case UPDATE_BOTTOM_MARGIN: updateDialogBottomMarginH(); break;
             }
         }
     }
 
-    private final class CustomDialog extends Dialog {
+    private final class CustomDialog extends Dialog implements DialogInterface {
         public CustomDialog(Context context) {
-            super(context);
+            super(context, com.android.systemui.R.style.qs_theme);
         }
 
         @Override
@@ -966,26 +867,15 @@
         }
 
         @Override
-        protected void onStop() {
-            super.onStop();
-            final boolean animating = mMotion.isAnimating();
-            if (D.BUG) Log.d(TAG, "onStop animating=" + animating);
-            if (animating) {
-                mPendingRecheckAll = true;
-                return;
-            }
-            mHandler.sendEmptyMessage(H.RECHECK_ALL);
+        protected void onStart() {
+            super.setCanceledOnTouchOutside(true);
+            super.onStart();
         }
 
         @Override
-        public boolean onTouchEvent(MotionEvent event) {
-            if (isShowing()) {
-                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-                    dismissH(Events.DISMISS_REASON_TOUCH_OUTSIDE);
-                    return true;
-                }
-            }
-            return false;
+        protected void onStop() {
+            super.onStop();
+            mHandler.sendEmptyMessage(H.RECHECK_ALL);
         }
 
         @Override
@@ -1128,7 +1018,6 @@
         private int iconRes;
         private int iconMuteRes;
         private boolean important;
-        private int cachedIconRes;
         private ColorStateList cachedSliderTint;
         private int iconState;  // from Events
         private ObjectAnimator anim;  // slider progress animation for non-touch-related updates
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
deleted file mode 100644
index 2b65fbd..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.DialogInterface.OnShowListener;
-import android.os.Handler;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.PathInterpolator;
-
-public class VolumeDialogMotion {
-    private static final String TAG = Util.logTag(VolumeDialogMotion.class);
-
-    private static final float ANIMATION_SCALE = 1.0f;
-    private static final int PRE_DISMISS_DELAY = 50;
-
-    private final Dialog mDialog;
-    private final View mDialogView;
-    private final ViewGroup mContents;  // volume rows + zen footer
-    private final Handler mHandler = new Handler();
-    private final Callback mCallback;
-
-    private boolean mAnimating;  // show or dismiss animation is running
-    private boolean mShowing;  // show animation is running
-    private boolean mDismissing;  // dismiss animation is running
-    private ValueAnimator mContentsPositionAnimator;
-
-    public VolumeDialogMotion(Dialog dialog, View dialogView, ViewGroup contents,
-            Callback callback) {
-        mDialog = dialog;
-        mDialogView = dialogView;
-        mContents = contents;
-        mCallback = callback;
-        mDialog.setOnDismissListener(new OnDismissListener() {
-            @Override
-            public void onDismiss(DialogInterface dialog) {
-                if (D.BUG) Log.d(TAG, "mDialog.onDismiss");
-            }
-        });
-        mDialog.setOnShowListener(new OnShowListener() {
-            @Override
-            public void onShow(DialogInterface dialog) {
-                if (D.BUG) Log.d(TAG, "mDialog.onShow");
-                final int h = mDialogView.getHeight();
-                mDialogView.setTranslationY(-h);
-                startShowAnimation();
-            }
-        });
-    }
-
-    public boolean isAnimating() {
-        return mAnimating;
-    }
-
-    private void setShowing(boolean showing) {
-        if (showing == mShowing) return;
-        mShowing = showing;
-        if (D.BUG) Log.d(TAG, "mShowing = " + mShowing);
-        updateAnimating();
-    }
-
-    private void setDismissing(boolean dismissing) {
-        if (dismissing == mDismissing) return;
-        mDismissing = dismissing;
-        if (D.BUG) Log.d(TAG, "mDismissing = " + mDismissing);
-        updateAnimating();
-    }
-
-    private void updateAnimating() {
-        final boolean animating = mShowing || mDismissing;
-        if (animating == mAnimating) return;
-        mAnimating = animating;
-        if (D.BUG) Log.d(TAG, "mAnimating = " + mAnimating);
-        if (mCallback != null) {
-            mCallback.onAnimatingChanged(mAnimating);
-        }
-    }
-
-    public void startShow() {
-        if (D.BUG) Log.d(TAG, "startShow");
-        if (mShowing) return;
-        setShowing(true);
-        if (mDismissing) {
-            mDialogView.animate().cancel();
-            setDismissing(false);
-            startShowAnimation();
-            return;
-        }
-        if (D.BUG) Log.d(TAG, "mDialog.show()");
-        mDialog.show();
-    }
-
-    private void startShowAnimation() {
-        if (D.BUG) Log.d(TAG, "startShowAnimation");
-        mDialogView.animate()
-                .translationY(0)
-                .setDuration(scaledDuration(300))
-                .setInterpolator(new LogDecelerateInterpolator())
-                .setListener(null)
-                .start();
-
-        mContentsPositionAnimator = ValueAnimator.ofFloat(0).setDuration(scaledDuration(400));
-        mContentsPositionAnimator.addListener(new AnimatorListenerAdapter() {
-            private boolean mCancelled;
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (mCancelled) return;
-                if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
-                setShowing(false);
-            }
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
-                mCancelled = true;
-            }
-        });
-        mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float v = (Float) animation.getAnimatedValue();
-                mContents.setTranslationY(v + -mDialogView.getTranslationY());
-            }
-        });
-        mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
-        mContentsPositionAnimator.start();
-
-        mContents.setAlpha(0);
-        mContents.animate()
-                .alpha(1)
-                .setDuration(scaledDuration(150))
-                .setInterpolator(new PathInterpolator(0f, 0f, .2f, 1f))
-                .start();
-    }
-
-    public void startDismiss() {
-        if (D.BUG) Log.d(TAG, "startDismiss");
-        if (mDismissing) return;
-        setDismissing(true);
-        if (mShowing) {
-            mDialogView.animate().cancel();
-            if (mContentsPositionAnimator != null) {
-                mContentsPositionAnimator.cancel();
-            }
-            mContents.animate().cancel();
-            setShowing(false);
-        }
-        mDialogView.animate()
-                .translationY(-mDialogView.getHeight())
-                .setDuration(scaledDuration(250))
-                .setInterpolator(new LogAccelerateInterpolator())
-                .setUpdateListener(new AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
-                        mContents.setTranslationY(-mDialogView.getTranslationY());
-                    }
-                })
-                .setListener(new AnimatorListenerAdapter() {
-                    private boolean mCancelled;
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        if (mCancelled) return;
-                        if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
-                        mHandler.postDelayed(new Runnable() {
-                            @Override
-                            public void run() {
-                                if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
-                                mDialog.dismiss();
-                                setDismissing(false);
-                            }
-                        }, PRE_DISMISS_DELAY);
-
-                    }
-                    @Override
-                    public void onAnimationCancel(Animator animation) {
-                        if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
-                        mCancelled = true;
-                    }
-                }).start();
-    }
-
-    private static int scaledDuration(int base) {
-        return (int) (base * ANIMATION_SCALE);
-    }
-
-    public static final class LogDecelerateInterpolator implements TimeInterpolator {
-        private final float mBase;
-        private final float mDrift;
-        private final float mTimeScale;
-        private final float mOutputScale;
-
-        public LogDecelerateInterpolator() {
-            this(400f, 1.4f, 0);
-        }
-
-        private LogDecelerateInterpolator(float base, float timeScale, float drift) {
-            mBase = base;
-            mDrift = drift;
-            mTimeScale = 1f / timeScale;
-
-            mOutputScale = 1f / computeLog(1f);
-        }
-
-        private float computeLog(float t) {
-            return 1f - (float) Math.pow(mBase, -t * mTimeScale) + (mDrift * t);
-        }
-
-        @Override
-        public float getInterpolation(float t) {
-            return computeLog(t) * mOutputScale;
-        }
-    }
-
-    public static final class LogAccelerateInterpolator implements TimeInterpolator {
-        private final int mBase;
-        private final int mDrift;
-        private final float mLogScale;
-
-        public LogAccelerateInterpolator() {
-            this(100, 0);
-        }
-
-        private LogAccelerateInterpolator(int base, int drift) {
-            mBase = base;
-            mDrift = drift;
-            mLogScale = 1f / computeLog(1, mBase, mDrift);
-        }
-
-        private static float computeLog(float t, int base, int drift) {
-            return (float) -Math.pow(base, -t) + 1 + (drift * t);
-        }
-
-        @Override
-        public float getInterpolation(float t) {
-            return 1 - computeLog(1 - t, mBase, mDrift) * mLogScale;
-        }
-    }
-
-    public interface Callback {
-        void onAnimatingChanged(boolean animating);
-    }
-}
diff --git a/proto/src/ipconnectivity.proto b/proto/src/ipconnectivity.proto
index 327f17d..0e39446 100644
--- a/proto/src/ipconnectivity.proto
+++ b/proto/src/ipconnectivity.proto
@@ -489,7 +489,7 @@
 
 // Represents statistics from NFLOG wakeup events due to ingress packets.
 // Since oc-mr1.
-// Next tag: 8.
+// Next tag: 13.
 message WakeupStats {
   // The time duration in seconds covered by these stats, for deriving
   // exact wakeup rates.
@@ -517,6 +517,24 @@
 
   // The total number of wakeup packets with no associated socket or uid.
   optional int64 no_uid_wakeups = 7;
+
+  // Counts of all different ethertype values from wakeup packets received.
+  repeated Pair ethertype_counts = 8;
+
+  // Counts of all different IP next header values from wakeup packets received.
+  repeated Pair ip_next_header_counts = 9;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a unicast address.
+  optional int64 l2_unicast_count = 10;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a multicast address.
+  optional int64 l2_multicast_count = 11;
+
+  // The total number of wakeup packets whose destination hardware address was
+  // a broadcast address.
+  optional int64 l2_broadcast_count = 12;
 }
 
 // Represents one of the IP connectivity event defined in this file.
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index e24aa3a..73a6d7c 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4733,6 +4733,31 @@
     // OS: P
     FIELD_TEXTCLASSIFIER_MODEL = 1256;
 
+    // OPEN: Settings > Sound & notification > Do Not Disturb > Behavior > Messages
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_MESSAGES = 1257;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > Behavior > Calls
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_CALLS = 1258;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > TURN ON -> Until you turn off
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_TOGGLE_ON_FOREVER = 1259;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > TURN ON -> Time countdown manual rule (ie: for one hour)
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_TOGGLE_ON_COUNTDOWN = 1260;
+
+    // OPEN: Settings > Sound & notification > Do Not Disturb > TURN ON -> Next Alarm (ie: Until Tue 7:20 AM)
+    // CATEGORY: SETTINGS
+    // OS: P
+    NOTIFICATION_ZEN_MODE_TOGGLE_ON_ALARM = 1261;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 9d25055..f5349df 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -364,6 +364,15 @@
   // (one value added per unique ESS - potentially multiple counts per single
   // scan!)
   repeated NumConnectableNetworksBucket observed_hotspot_r2_aps_per_ess_in_scan_histogram = 88;
+
+  // SoftAP event list tracking sessions and client counts in tethered mode
+  repeated SoftApConnectedClientsEvent soft_ap_connected_clients_events_tethered = 89;
+
+  // SoftAP event list tracking sessions and client counts in local only mode
+  repeated SoftApConnectedClientsEvent soft_ap_connected_clients_events_local_only = 90;
+
+  // Wps connection metrics
+  optional WpsMetrics wps_metrics = 91;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -1071,3 +1080,57 @@
   // Occurrences of this action.
   optional int32 count = 4;
 }
+
+// SoftAP event tracking sessions and client counts
+message SoftApConnectedClientsEvent {
+
+  // Soft AP event Types
+  enum SoftApEventType {
+
+    // Soft AP is Up and ready for use
+    SOFT_AP_UP = 0;
+
+    // Soft AP is Down
+    SOFT_AP_DOWN = 1;
+
+    // Number of connected soft AP clients has changed
+    NUM_CLIENTS_CHANGED = 2;
+  }
+
+  // Type of event being recorded
+  optional SoftApEventType event_type = 1;
+
+  // Absolute time when event happened
+  optional int64 time_stamp_millis = 2;
+
+  // Number of connected clients if event_type is NUM_CLIENTS_CHANGED, otherwise zero.
+  optional int32 num_connected_clients = 3;
+}
+
+// Wps connection metrics
+// Keeps track of Wi-Fi Protected Setup usage
+message WpsMetrics {
+  // Total number of wps connection attempts
+  optional int32 num_wps_attempts = 1;
+
+  // Total number of wps connection successes
+  optional int32 num_wps_success = 2;
+
+  // Total number of wps failures on start
+  optional int32 num_wps_start_failure = 3;
+
+  // Total number of wps overlap failure
+  optional int32 num_wps_overlap_failure = 4;
+
+  // Total number of wps timeout failure
+  optional int32 num_wps_timeout_failure = 5;
+
+  // Total number of other wps failure during connection
+  optional int32 num_wps_other_connection_failure = 6;
+
+  // Total number of supplicant failure after wps
+  optional int32 num_wps_supplicant_failure = 7;
+
+  // Total number of wps cancellation
+  optional int32 num_wps_cancellation = 8;
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 86ef857..5bef8cb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3840,6 +3840,10 @@
                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
+
+                // Replace any invalid GIDs
+                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
+                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
             }
             checkTime(startTime, "startProcess: building args");
             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
@@ -7075,10 +7079,12 @@
             }
 
             // We deprecated Build.SERIAL and it is not accessible to
-            // apps that target the v2 security sandbox. Since access to
-            // the serial is now behind a permission we push down the value.
-            String buildSerial = appInfo.targetSandboxVersion < 2
-                    ? sTheRealBuildSerial : Build.UNKNOWN;
+            // apps that target the v2 security sandbox and to apps that
+            // target APIs higher than O MR1. Since access to the serial
+            // is now behind a permission we push down the value.
+            final String buildSerial = (appInfo.targetSandboxVersion < 2
+                    && appInfo.targetSdkVersion <= Build.VERSION_CODES.O_MR1)
+                            ? sTheRealBuildSerial : Build.UNKNOWN;
 
             // Check if this is a secondary process that should be incorporated into some
             // currently active instrumentation.  (Note we do this AFTER all of the profiling
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3f23737..15a418dc 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1345,8 +1345,9 @@
         } else {
             final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
             final boolean activeForReal;
-            if (maybeActiveStreamType == AudioSystem.STREAM_MUSIC) {
-                activeForReal = isAfMusicActiveRecently(0);
+            if (maybeActiveStreamType == AudioSystem.STREAM_RING
+                    || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
+                activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
             } else {
                 activeForReal = AudioSystem.isStreamActive(maybeActiveStreamType, 0);
             }
@@ -3883,13 +3884,13 @@
 
     /**
      * For code clarity for getActiveStreamType(int)
-     * @param delay_ms max time since last STREAM_MUSIC activity to consider
-     * @return true if STREAM_MUSIC is active in streams handled by AudioFlinger now or
+     * @param delay_ms max time since last stream activity to consider
+     * @return true if stream is active in streams handled by AudioFlinger now or
      *     in the last "delay_ms" ms.
      */
-    private boolean isAfMusicActiveRecently(int delay_ms) {
-        return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, delay_ms)
-                || AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, delay_ms);
+    private boolean wasStreamActiveRecently(int stream, int delay_ms) {
+        return AudioSystem.isStreamActive(stream, delay_ms)
+                || AudioSystem.isStreamActiveRemotely(stream, delay_ms);
     }
 
     private int getActiveStreamType(int suggestedStreamType) {
@@ -3910,21 +3911,30 @@
                     return AudioSystem.STREAM_VOICE_CALL;
                 }
             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
-                if (isAfMusicActiveRecently(sStreamOverrideDelayMs)) {
+                if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
                     if (DEBUG_VOL)
-                        Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active");
+                        Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
+                    return AudioSystem.STREAM_RING;
+                } else if (wasStreamActiveRecently(
+                        AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
+                    if (DEBUG_VOL)
+                        Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
+                    return AudioSystem.STREAM_NOTIFICATION;
+                } else {
+                    if (DEBUG_VOL)
+                        Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC b/c default");
                     return AudioSystem.STREAM_MUSIC;
-                    } else {
-                        if (DEBUG_VOL)
-                            Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING b/c default");
-                        return AudioSystem.STREAM_RING;
                 }
-            } else if (isAfMusicActiveRecently(0)) {
+            } else if (
+                    wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
                 if (DEBUG_VOL)
-                    Log.v(TAG, "getActiveStreamType: Forcing STREAM_MUSIC stream active");
-                return AudioSystem.STREAM_MUSIC;
+                    Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
+                return AudioSystem.STREAM_NOTIFICATION;
+            } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
+                if (DEBUG_VOL)
+                    Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
+                return AudioSystem.STREAM_RING;
             }
-            break;
         default:
             if (isInCommunication()) {
                 if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
@@ -3935,20 +3945,26 @@
                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
                     return AudioSystem.STREAM_VOICE_CALL;
                 }
-            } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_NOTIFICATION,
-                    sStreamOverrideDelayMs) ||
-                    AudioSystem.isStreamActive(AudioSystem.STREAM_RING,
-                            sStreamOverrideDelayMs)) {
+            } else if (AudioSystem.isStreamActive(
+                    AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
                 return AudioSystem.STREAM_NOTIFICATION;
+            } else if (AudioSystem.isStreamActive(
+                    AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
+                if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
+                return AudioSystem.STREAM_RING;
             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
-                if (isAfMusicActiveRecently(sStreamOverrideDelayMs)) {
-                    if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: forcing STREAM_MUSIC");
-                    return AudioSystem.STREAM_MUSIC;
-                } else {
-                    if (DEBUG_VOL) Log.v(TAG,
-                            "getActiveStreamType: using STREAM_NOTIFICATION as default");
+                if (AudioSystem.isStreamActive(
+                        AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
+                    if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
                     return AudioSystem.STREAM_NOTIFICATION;
+                } else if (AudioSystem.isStreamActive(
+                        AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
+                    if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
+                    return AudioSystem.STREAM_RING;
+                } else {
+                    if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: using STREAM_MUSIC as default");
+                    return AudioSystem.STREAM_MUSIC;
                 }
             }
             break;
@@ -6349,10 +6365,10 @@
     //   stream override timeout when adjusting volume
     //---------------------------------------------------------------------------------
 
-    // AudioService.getActiveStreamType() will return:
     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
-    // - STREAM_MUSIC on phones during this period after music or talkback/voice search prompt
-    // stopped
+    // - STREAM_RING on phones during this period after a notification stopped
+    // - STREAM_MUSIC otherwise
+
     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
 
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index a011692b..397af7b 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -46,7 +46,6 @@
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.NetworkId;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.Pair;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -128,6 +127,11 @@
         wakeupStats.nonApplicationWakeups = in.nonApplicationWakeups;
         wakeupStats.applicationWakeups = in.applicationWakeups;
         wakeupStats.noUidWakeups = in.noUidWakeups;
+        wakeupStats.l2UnicastCount = in.l2UnicastCount;
+        wakeupStats.l2MulticastCount = in.l2MulticastCount;
+        wakeupStats.l2BroadcastCount = in.l2BroadcastCount;
+        wakeupStats.ethertypeCounts = toPairArray(in.ethertypes);
+        wakeupStats.ipNextHeaderCounts = toPairArray(in.ipNextHeaders);
         final IpConnectivityEvent out = buildEvent(0, 0, in.iface);
         out.setWakeupStats(wakeupStats);
         return out;
@@ -242,7 +246,6 @@
     private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) {
         IpConnectivityLogClass.NetworkEvent networkEvent =
                 new IpConnectivityLogClass.NetworkEvent();
-        networkEvent.networkId = netIdOf(in.netId);
         networkEvent.eventType = in.eventType;
         networkEvent.latencyMs = (int) in.durationMs;
         out.setNetworkEvent(networkEvent);
@@ -321,12 +324,6 @@
         return pairs;
     }
 
-    private static NetworkId netIdOf(int netid) {
-        final NetworkId ni = new NetworkId();
-        ni.networkId = netid;
-        return ni;
-    }
-
     private static int ipSupportOf(DefaultNetworkEvent in) {
         if (in.ipv4 && in.ipv6) {
             return IpConnectivityLogClass.DefaultNetworkEvent.DUAL;
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index af138b93..4bdbbe3 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -58,7 +58,6 @@
 
     private static final String TAG = NetdEventListenerService.class.getSimpleName();
     private static final boolean DBG = false;
-    private static final boolean VDBG = false;
 
     // Rate limit connect latency logging to 1 measurement per 15 seconds (5760 / day) with maximum
     // bursts of 5000 measurements.
@@ -198,8 +197,6 @@
     public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
             String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
             throws RemoteException {
-        maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
-
         long timestamp = System.currentTimeMillis();
         getMetricsForNetwork(timestamp, netId).addDnsResult(eventType, returnCode, latencyMs);
 
@@ -215,8 +212,6 @@
     // This method must not block or perform long-running operations.
     public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr,
             int port, int uid) throws RemoteException {
-        maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
-
         long timestamp = System.currentTimeMillis();
         getMetricsForNetwork(timestamp, netId).addConnectResult(error, latencyMs, ipAddr);
 
@@ -232,11 +227,8 @@
     }
 
     @Override
-    public synchronized void onWakeupEvent(String prefix, int uid, int gid, long timestampNs) {
-        maybeVerboseLog("onWakeupEvent(%s, %d, %d, %sns)", prefix, uid, gid, timestampNs);
-
-        // TODO: add ip protocol and port
-
+    public synchronized void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader,
+            byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs) {
         String iface = prefix.replaceFirst(WAKEUP_EVENT_IFACE_PREFIX, "");
         final long timestampMs;
         if (timestampNs > 0) {
@@ -245,15 +237,22 @@
             timestampMs = System.currentTimeMillis();
         }
 
-        addWakeupEvent(iface, timestampMs, uid);
-    }
-
-    @GuardedBy("this")
-    private void addWakeupEvent(String iface, long timestampMs, int uid) {
         WakeupEvent event = new WakeupEvent();
         event.iface = iface;
         event.timestampMs = timestampMs;
         event.uid = uid;
+        event.ethertype = ethertype;
+        event.dstHwAddr = dstHw;
+        event.srcIp = srcIp;
+        event.dstIp = dstIp;
+        event.ipNextHeader = ipNextHeader;
+        event.srcPort = srcPort;
+        event.dstPort = dstPort;
+        addWakeupEvent(event);
+    }
+
+    private void addWakeupEvent(WakeupEvent event) {
+        String iface = event.iface;
         mWakeupEvents.append(event);
         WakeupStats stats = mWakeupStats.get(iface);
         if (stats == null) {
@@ -333,10 +332,6 @@
         if (DBG) Log.d(TAG, String.format(s, args));
     }
 
-    private static void maybeVerboseLog(String s, Object... args) {
-        if (VDBG) Log.d(TAG, String.format(s, args));
-    }
-
     /** Helper class for buffering summaries of NetworkMetrics at regular time intervals */
     static class NetworkMetricsSnapshot {
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 8b886d6..7684030 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -1129,7 +1129,8 @@
     }
 
     private void logNetworkEvent(int evtype) {
-        mMetricsLog.log(new NetworkEvent(mNetId, evtype));
+        int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
+        mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype));
     }
 
     private int networkEventType(ValidationStage s, EvaluationResult r) {
@@ -1150,7 +1151,8 @@
 
     private void maybeLogEvaluationResult(int evtype) {
         if (mEvaluationTimer.isRunning()) {
-            mMetricsLog.log(new NetworkEvent(mNetId, evtype, mEvaluationTimer.stop()));
+            int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
+            mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype, mEvaluationTimer.stop()));
             mEvaluationTimer.reset();
         }
     }
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
new file mode 100644
index 0000000..361d928
--- /dev/null
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -0,0 +1,639 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ParceledListSlice;
+import android.database.ContentObserver;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.display.BrightnessChangeEvent;
+import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.RingBuffer;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+
+import java.util.Deque;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Class that tracks recent brightness settings changes and stores
+ * associated information such as light sensor readings.
+ */
+public class BrightnessTracker {
+
+    private static final String TAG = "BrightnessTracker";
+    private static final boolean DEBUG = false;
+
+    private static final String EVENTS_FILE = "brightness_events.xml";
+    private static final int MAX_EVENTS = 100;
+    // Discard events when reading or writing that are older than this.
+    private static final long MAX_EVENT_AGE = TimeUnit.DAYS.toMillis(30);
+    // Time over which we keep lux sensor readings.
+    private static final long LUX_EVENT_HORIZON = TimeUnit.SECONDS.toNanos(10);
+
+    private static final String TAG_EVENTS = "events";
+    private static final String TAG_EVENT = "event";
+    private static final String ATTR_BRIGHTNESS = "brightness";
+    private static final String ATTR_TIMESTAMP = "timestamp";
+    private static final String ATTR_PACKAGE_NAME = "packageName";
+    private static final String ATTR_USER = "user";
+    private static final String ATTR_LUX = "lux";
+    private static final String ATTR_LUX_TIMESTAMPS = "luxTimestamps";
+    private static final String ATTR_BATTERY_LEVEL = "batteryLevel";
+    private static final String ATTR_NIGHT_MODE = "nightMode";
+    private static final String ATTR_COLOR_TEMPERATURE = "colorTemperature";
+    private static final String ATTR_LAST_BRIGHTNESS = "lastBrightness";
+
+    // Lock held while accessing mEvents, is held while writing events to flash.
+    private final Object mEventsLock = new Object();
+    @GuardedBy("mEventsLock")
+    private RingBuffer<BrightnessChangeEvent> mEvents
+            = new RingBuffer<>(BrightnessChangeEvent.class, MAX_EVENTS);
+    private final Runnable mEventsWriter = () -> writeEvents();
+    private volatile boolean mWriteEventsScheduled;
+
+    private UserManager mUserManager;
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private Handler mBgHandler;
+    // mSettingsObserver, mBroadcastReceiver and mSensorListener should only be used on
+    // the mBgHandler thread.
+    private SettingsObserver mSettingsObserver;
+    private BroadcastReceiver mBroadcastReceiver;
+    private SensorListener mSensorListener;
+
+    // Lock held while collecting data related to brightness changes.
+    private final Object mDataCollectionLock = new Object();
+    @GuardedBy("mDataCollectionLock")
+    private Deque<LightData> mLastSensorReadings = new ArrayDeque<>();
+    @GuardedBy("mDataCollectionLock")
+    private float mLastBatteryLevel = Float.NaN;
+    @GuardedBy("mDataCollectionLock")
+    private int mIgnoreBrightness = -1;
+    @GuardedBy("mDataCollectionLock")
+    private int mLastBrightness = -1;
+
+    private final Injector mInjector;
+
+    public BrightnessTracker(Context context, @Nullable Injector injector) {
+        // Note this will be called very early in boot, other system
+        // services may not be present.
+        mContext = context;
+        mContentResolver = context.getContentResolver();
+        if (injector != null) {
+            mInjector = injector;
+        } else {
+            mInjector = new Injector();
+        }
+    }
+
+    /** Start listening for brightness slider events */
+    public void start() {
+        if (DEBUG) {
+            Slog.d(TAG, "Start");
+        }
+        mBgHandler = mInjector.getBackgroundHandler();
+        mUserManager = mContext.getSystemService(UserManager.class);
+
+        mBgHandler.post(() -> backgroundStart());
+    }
+
+    private void backgroundStart() {
+        readEvents();
+
+        mLastBrightness = mInjector.getSystemIntForUser(mContentResolver,
+                Settings.System.SCREEN_BRIGHTNESS, -1,
+                UserHandle.USER_CURRENT);
+
+        mSensorListener = new SensorListener();
+        mInjector.registerSensorListener(mContext, mSensorListener);
+
+        mSettingsObserver = new SettingsObserver(mBgHandler);
+        mInjector.registerBrightnessObserver(mContentResolver, mSettingsObserver);
+
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_SHUTDOWN);
+        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        mBroadcastReceiver = new Receiver();
+        mInjector.registerReceiver(mContext, mBroadcastReceiver, intentFilter);
+    }
+
+    /** Stop listening for events */
+    @VisibleForTesting
+    void stop() {
+        if (DEBUG) {
+            Slog.d(TAG, "Stop");
+        }
+        mInjector.unregisterSensorListener(mContext, mSensorListener);
+        mInjector.unregisterReceiver(mContext, mBroadcastReceiver);
+        mInjector.unregisterBrightnessObserver(mContext, mSettingsObserver);
+    }
+
+    /**
+     * @param userId userId to fetch data for.
+     * @return List of recent {@link BrightnessChangeEvent}s
+     */
+    public ParceledListSlice<BrightnessChangeEvent> getEvents(int userId) {
+        // TODO include apps from any managed profiles in the brightness information.
+        BrightnessChangeEvent[] events;
+        synchronized (mEventsLock) {
+            events = mEvents.toArray();
+        }
+        ArrayList<BrightnessChangeEvent> out = new ArrayList<>(events.length);
+        for (int i = 0; i < events.length; ++i) {
+            if (events[i].userId == userId) {
+                out.add(events[i]);
+            }
+        }
+        return new ParceledListSlice<>(out);
+    }
+
+    /** Sets brightness without logging the brightness change event */
+    public void setBrightness(int brightness, int userId) {
+        synchronized (mDataCollectionLock) {
+            mIgnoreBrightness = brightness;
+        }
+        mInjector.putSystemIntForUser(mContentResolver, Settings.System.SCREEN_BRIGHTNESS,
+                brightness, userId);
+    }
+
+    private void handleBrightnessChanged() {
+        if (DEBUG) {
+            Slog.d(TAG, "Brightness change");
+        }
+        final BrightnessChangeEvent event = new BrightnessChangeEvent();
+        event.timeStamp = mInjector.currentTimeMillis();
+
+        int brightness = mInjector.getSystemIntForUser(mContentResolver,
+                Settings.System.SCREEN_BRIGHTNESS, -1,
+                UserHandle.USER_CURRENT);
+
+        synchronized (mDataCollectionLock) {
+            int previousBrightness = mLastBrightness;
+            mLastBrightness = brightness;
+
+            if (brightness == -1 || brightness == mIgnoreBrightness) {
+                // Notified of brightness change but no setting or self change so ignore.
+                mIgnoreBrightness = -1;
+                return;
+            }
+
+            final int readingCount = mLastSensorReadings.size();
+            if (readingCount == 0) {
+                // No sensor data so ignore this.
+                return;
+            }
+
+            event.luxValues = new float[readingCount];
+            event.luxTimestamps = new long[readingCount];
+
+            int pos = 0;
+
+            // Convert sensor timestamp in elapsed time nanos to current time millis.
+            long currentTimeMillis = mInjector.currentTimeMillis();
+            long elapsedTimeNanos = mInjector.elapsedRealtimeNanos();
+            for (LightData reading : mLastSensorReadings) {
+                event.luxValues[pos] = reading.lux;
+                event.luxTimestamps[pos] = currentTimeMillis -
+                        TimeUnit.NANOSECONDS.toMillis(elapsedTimeNanos - reading.timestamp);
+                ++pos;
+            }
+
+            event.batteryLevel = mLastBatteryLevel;
+            event.lastBrightness = previousBrightness;
+        }
+
+        event.brightness = brightness;
+
+        try {
+            final ActivityManager.StackInfo focusedStack = mInjector.getFocusedStack();
+            event.userId = focusedStack.userId;
+            event.packageName = focusedStack.topActivity.getPackageName();
+        } catch (RemoteException e) {
+            // Really shouldn't be possible.
+        }
+
+        event.nightMode = mInjector.getSecureIntForUser(mContentResolver,
+                Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 0, UserHandle.USER_CURRENT)
+                == 1;
+        event.colorTemperature = mInjector.getSecureIntForUser(mContentResolver,
+                Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
+                0, UserHandle.USER_CURRENT);
+
+        if (DEBUG) {
+            Slog.d(TAG, "Event " + event.brightness + " " + event.packageName);
+        }
+        synchronized (mEventsLock) {
+            mEvents.append(event);
+        }
+    }
+
+    private void scheduleWriteEvents() {
+        if (!mWriteEventsScheduled) {
+            mBgHandler.post(mEventsWriter);
+            mWriteEventsScheduled = true;
+        }
+    }
+
+    private void writeEvents() {
+        mWriteEventsScheduled = false;
+        // TODO kick off write on handler thread e.g. every 24 hours.
+        synchronized (mEventsLock) {
+            final AtomicFile writeTo = mInjector.getFile();
+            if (writeTo == null) {
+                return;
+            }
+            if (mEvents.isEmpty()) {
+                if (writeTo.exists()) {
+                    writeTo.delete();
+                }
+            } else {
+                FileOutputStream output = null;
+                try {
+                    output = writeTo.startWrite();
+                    writeEventsLocked(output);
+                    writeTo.finishWrite(output);
+                } catch (IOException e) {
+                    writeTo.failWrite(output);
+                    Slog.e(TAG, "Failed to write change mEvents.", e);
+                }
+            }
+        }
+    }
+
+    private void readEvents() {
+        synchronized (mEventsLock) {
+            mEvents.clear();
+            final AtomicFile readFrom = mInjector.getFile();
+            if (readFrom != null && readFrom.exists()) {
+                FileInputStream input = null;
+                try {
+                    input = readFrom.openRead();
+                    readEventsLocked(input);
+                } catch (IOException e) {
+                    readFrom.delete();
+                    Slog.e(TAG, "Failed to read change mEvents.", e);
+                } finally {
+                    IoUtils.closeQuietly(input);
+                }
+            }
+        }
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mEventsLock")
+    void writeEventsLocked(OutputStream stream) throws IOException {
+        XmlSerializer out = new FastXmlSerializer();
+        out.setOutput(stream, StandardCharsets.UTF_8.name());
+        out.startDocument(null, true);
+        out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+        out.startTag(null, TAG_EVENTS);
+        BrightnessChangeEvent[] toWrite = mEvents.toArray();
+        if (DEBUG) {
+            Slog.d(TAG, "Writing events " + toWrite.length);
+        }
+        final long timeCutOff = System.currentTimeMillis() - MAX_EVENT_AGE;
+        for (int i = 0; i < toWrite.length; ++i) {
+            int userSerialNo = mInjector.getUserSerialNumber(mUserManager, toWrite[i].userId);
+            if (userSerialNo != -1 && toWrite[i].timeStamp > timeCutOff) {
+                out.startTag(null, TAG_EVENT);
+                out.attribute(null, ATTR_BRIGHTNESS, Integer.toString(toWrite[i].brightness));
+                out.attribute(null, ATTR_TIMESTAMP, Long.toString(toWrite[i].timeStamp));
+                out.attribute(null, ATTR_PACKAGE_NAME, toWrite[i].packageName);
+                out.attribute(null, ATTR_USER, Integer.toString(userSerialNo));
+                out.attribute(null, ATTR_BATTERY_LEVEL, Float.toString(toWrite[i].batteryLevel));
+                out.attribute(null, ATTR_NIGHT_MODE, Boolean.toString(toWrite[i].nightMode));
+                out.attribute(null, ATTR_COLOR_TEMPERATURE, Integer.toString(
+                        toWrite[i].colorTemperature));
+                out.attribute(null, ATTR_LAST_BRIGHTNESS,
+                        Integer.toString(toWrite[i].lastBrightness));
+                StringBuilder luxValues = new StringBuilder();
+                StringBuilder luxTimestamps = new StringBuilder();
+                for (int j = 0; j < toWrite[i].luxValues.length; ++j) {
+                    if (j > 0) {
+                        luxValues.append(',');
+                        luxTimestamps.append(',');
+                    }
+                    luxValues.append(Float.toString(toWrite[i].luxValues[j]));
+                    luxTimestamps.append(Long.toString(toWrite[i].luxTimestamps[j]));
+                }
+                out.attribute(null, ATTR_LUX, luxValues.toString());
+                out.attribute(null, ATTR_LUX_TIMESTAMPS, luxTimestamps.toString());
+                out.endTag(null, TAG_EVENT);
+            }
+        }
+        out.endTag(null, TAG_EVENTS);
+        out.endDocument();
+        stream.flush();
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mEventsLock")
+    void readEventsLocked(InputStream stream) throws IOException {
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(stream, StandardCharsets.UTF_8.name());
+
+            int type;
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && type != XmlPullParser.START_TAG) {
+            }
+            String tag = parser.getName();
+            if (!TAG_EVENTS.equals(tag)) {
+                throw new XmlPullParserException(
+                        "Events not found in brightness tracker file " + tag);
+            }
+
+            final long timeCutOff = mInjector.currentTimeMillis() - MAX_EVENT_AGE;
+
+            parser.next();
+            int outerDepth = parser.getDepth();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+                tag = parser.getName();
+                if (TAG_EVENT.equals(tag)) {
+                    BrightnessChangeEvent event = new BrightnessChangeEvent();
+
+                    String brightness = parser.getAttributeValue(null, ATTR_BRIGHTNESS);
+                    event.brightness = Integer.parseInt(brightness);
+                    String timestamp = parser.getAttributeValue(null, ATTR_TIMESTAMP);
+                    event.timeStamp = Long.parseLong(timestamp);
+                    event.packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+                    String user = parser.getAttributeValue(null, ATTR_USER);
+                    event.userId = mInjector.getUserId(mUserManager, Integer.parseInt(user));
+                    String batteryLevel = parser.getAttributeValue(null, ATTR_BATTERY_LEVEL);
+                    event.batteryLevel = Float.parseFloat(batteryLevel);
+                    String nightMode = parser.getAttributeValue(null, ATTR_NIGHT_MODE);
+                    event.nightMode = Boolean.parseBoolean(nightMode);
+                    String colorTemperature =
+                            parser.getAttributeValue(null, ATTR_COLOR_TEMPERATURE);
+                    event.colorTemperature = Integer.parseInt(colorTemperature);
+                    String lastBrightness = parser.getAttributeValue(null, ATTR_LAST_BRIGHTNESS);
+                    event.lastBrightness = Integer.parseInt(lastBrightness);
+
+                    String luxValue = parser.getAttributeValue(null, ATTR_LUX);
+                    String luxTimestamp = parser.getAttributeValue(null, ATTR_LUX_TIMESTAMPS);
+
+                    String[] luxValues = luxValue.split(",");
+                    String[] luxTimestamps = luxTimestamp.split(",");
+                    if (luxValues.length != luxTimestamps.length) {
+                        continue;
+                    }
+                    event.luxValues = new float[luxValues.length];
+                    event.luxTimestamps = new long[luxValues.length];
+                    for (int i = 0; i < luxValues.length; ++i) {
+                        event.luxValues[i] = Float.parseFloat(luxValues[i]);
+                        event.luxTimestamps[i] = Long.parseLong(luxTimestamps[i]);
+                    }
+
+                    if (DEBUG) {
+                        Slog.i(TAG, "Read event " + event.brightness
+                                + " " + event.packageName);
+                    }
+
+                    if (event.userId != -1 && event.timeStamp > timeCutOff
+                            && event.luxValues.length > 0) {
+                        mEvents.append(event);
+                    }
+                }
+            }
+        } catch (NullPointerException | NumberFormatException | XmlPullParserException
+                | IOException e) {
+            // Failed to parse something, just start with an empty event log.
+            mEvents = new RingBuffer<>(BrightnessChangeEvent.class, MAX_EVENTS);
+            Slog.e(TAG, "Failed to parse brightness event", e);
+            // Re-throw so we will delete the bad file.
+            throw new IOException("failed to parse file", e);
+        }
+    }
+
+    // Not allowed to keep the SensorEvent so used to copy the data we care about.
+    private static class LightData {
+        public float lux;
+        // Time in elapsedRealtimeNanos
+        public long timestamp;
+    }
+
+    private void recordSensorEvent(SensorEvent event) {
+        long horizon = mInjector.elapsedRealtimeNanos() - LUX_EVENT_HORIZON;
+        synchronized (mDataCollectionLock) {
+            if (DEBUG) {
+                Slog.v(TAG, "Sensor event " + event);
+            }
+            if (!mLastSensorReadings.isEmpty()
+                    && event.timestamp < mLastSensorReadings.getLast().timestamp) {
+                // Ignore event that came out of order.
+                return;
+            }
+            LightData data = null;
+            while (!mLastSensorReadings.isEmpty()
+                    && mLastSensorReadings.getFirst().timestamp < horizon) {
+                // Remove data that has fallen out of the window.
+                data = mLastSensorReadings.removeFirst();
+            }
+            // We put back the last one we removed so we know how long
+            // the first sensor reading was valid for.
+            if (data != null) {
+                mLastSensorReadings.addFirst(data);
+            }
+
+            data = new LightData();
+            data.timestamp = event.timestamp;
+            data.lux = event.values[0];
+            mLastSensorReadings.addLast(data);
+        }
+    }
+
+    private void batteryLevelChanged(int level, int scale) {
+        synchronized (mDataCollectionLock) {
+            mLastBatteryLevel = (float) level / (float) scale;
+        }
+    }
+
+    private final class SensorListener implements SensorEventListener {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            recordSensorEvent(event);
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+        }
+    }
+
+    private final class SettingsObserver extends ContentObserver {
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (DEBUG) {
+                Slog.v(TAG, "settings change " + uri);
+            }
+            // Self change is based on observer passed to notifyObserver, SettingsProvider
+            // passes null so no changes are self changes.
+            handleBrightnessChanged();
+        }
+    }
+
+    private final class Receiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Received " + intent.getAction());
+            }
+            String action = intent.getAction();
+            if (Intent.ACTION_SHUTDOWN.equals(action)) {
+                stop();
+                scheduleWriteEvents();
+            } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+                int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+                int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
+                if (level != -1 && scale != 0) {
+                    batteryLevelChanged(level, scale);
+                }
+            }
+        }
+    }
+
+    @VisibleForTesting
+    static class Injector {
+        public void registerSensorListener(Context context,
+                SensorEventListener sensorListener) {
+            SensorManager sensorManager = context.getSystemService(SensorManager.class);
+            Sensor lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+            sensorManager.registerListener(sensorListener,
+                    lightSensor, SensorManager.SENSOR_DELAY_NORMAL);
+        }
+
+        public void unregisterSensorListener(Context context, SensorEventListener sensorListener) {
+            SensorManager sensorManager = context.getSystemService(SensorManager.class);
+            sensorManager.unregisterListener(sensorListener);
+        }
+
+        public void registerBrightnessObserver(ContentResolver resolver,
+                ContentObserver settingsObserver) {
+            resolver.registerContentObserver(Settings.System.getUriFor(
+                    Settings.System.SCREEN_BRIGHTNESS),
+                    false, settingsObserver, UserHandle.USER_ALL);
+        }
+
+        public void unregisterBrightnessObserver(Context context,
+                ContentObserver settingsObserver) {
+            context.getContentResolver().unregisterContentObserver(settingsObserver);
+        }
+
+        public void registerReceiver(Context context,
+                BroadcastReceiver receiver, IntentFilter filter) {
+            context.registerReceiver(receiver, filter);
+        }
+
+        public void unregisterReceiver(Context context,
+                BroadcastReceiver receiver) {
+            context.unregisterReceiver(receiver);
+        }
+
+        public Handler getBackgroundHandler() {
+            return BackgroundThread.getHandler();
+        }
+
+        public int getSystemIntForUser(ContentResolver resolver, String setting, int defaultValue,
+                int userId) {
+            return Settings.System.getIntForUser(resolver, setting, defaultValue, userId);
+        }
+
+        public void putSystemIntForUser(ContentResolver resolver, String setting, int value,
+                int userId) {
+            Settings.System.putIntForUser(resolver, setting, value, userId);
+        }
+
+        public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue,
+                int userId) {
+            return Settings.Secure.getIntForUser(resolver, setting, defaultValue, userId);
+        }
+
+        public AtomicFile getFile() {
+            return new AtomicFile(new File(Environment.getDataSystemDeDirectory(), EVENTS_FILE));
+        }
+
+        public long currentTimeMillis() {
+            return System.currentTimeMillis();
+        }
+
+        public long elapsedRealtimeNanos() {
+            return SystemClock.elapsedRealtimeNanos();
+        }
+
+        public int getUserSerialNumber(UserManager userManager, int userId) {
+            return userManager.getUserSerialNumber(userId);
+        }
+
+        public int getUserId(UserManager userManager, int userSerialNumber) {
+            return userManager.getUserHandle(userSerialNumber);
+        }
+
+        public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
+            return ActivityManager.getService().getFocusedStackInfo();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d0a1d9e..f1e2011 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -31,9 +31,11 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.Point;
 import android.hardware.SensorManager;
+import android.hardware.display.BrightnessChangeEvent;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayViewport;
@@ -58,6 +60,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.IntArray;
 import android.util.Slog;
@@ -139,6 +142,7 @@
     private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
     private static final int MSG_REQUEST_TRAVERSAL = 4;
     private static final int MSG_UPDATE_VIEWPORT = 5;
+    private static final int MSG_REGISTER_BRIGHTNESS_TRACKER = 6;
 
     private final Context mContext;
     private final DisplayManagerHandler mHandler;
@@ -256,6 +260,8 @@
 
     private final Injector mInjector;
 
+    private final BrightnessTracker mBrightnessTracker;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -274,6 +280,7 @@
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
+        mBrightnessTracker = new BrightnessTracker(context, null);
     }
 
     public void setupSchedulerPolicies() {
@@ -350,6 +357,7 @@
         }
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
+        mHandler.sendEmptyMessage(MSG_REGISTER_BRIGHTNESS_TRACKER);
     }
 
     @VisibleForTesting
@@ -1352,6 +1360,10 @@
                             mTempExternalTouchViewport, mTempVirtualTouchViewports);
                     break;
                 }
+
+                case MSG_REGISTER_BRIGHTNESS_TRACKER:
+                    mBrightnessTracker.start();
+                    break;
             }
         }
     }
@@ -1736,6 +1748,35 @@
             }
         }
 
+        @Override // Binder call
+        public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents() {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
+                    "Permission to read brightness events.");
+            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mBrightnessTracker.getEvents(userId);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
+        public void setBrightness(int brightness) {
+            // STOPSHIP - remove when adaptive brightness controller accepts curves.
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
+                    "Permission to set brightness.");
+            int userId = UserHandle.getUserId(Binder.getCallingUid());
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mBrightnessTracker.setBrightness(brightness, userId);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         private boolean validatePackageName(int uid, String packageName) {
             if (packageName != null) {
                 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index beb7486..0b511f2 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1361,24 +1361,26 @@
     public boolean sendExtraCommand(String command, Bundle extras) {
 
         long identity = Binder.clearCallingIdentity();
-        boolean result = false;
+        try {
+            boolean result = false;
 
-        if ("delete_aiding_data".equals(command)) {
-            result = deleteAidingData(extras);
-        } else if ("force_time_injection".equals(command)) {
-            requestUtcTime();
-            result = true;
-        } else if ("force_xtra_injection".equals(command)) {
-            if (mSupportsXtra) {
-                xtraDownloadRequest();
+            if ("delete_aiding_data".equals(command)) {
+                result = deleteAidingData(extras);
+            } else if ("force_time_injection".equals(command)) {
+                requestUtcTime();
                 result = true;
+            } else if ("force_xtra_injection".equals(command)) {
+                if (mSupportsXtra) {
+                    xtraDownloadRequest();
+                    result = true;
+                }
+            } else {
+                Log.w(TAG, "sendExtraCommand: unknown command " + command);
             }
-        } else {
-            Log.w(TAG, "sendExtraCommand: unknown command " + command);
+            return result;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
-
-        Binder.restoreCallingIdentity(identity);
-        return result;
     }
 
     private IGpsGeofenceHardware mGpsGeofenceBinder = new IGpsGeofenceHardware.Stub() {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 09f9cb8..be9b2f3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -32,6 +32,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.IntentSender.SendIntentException;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageInstallerCallback;
 import android.content.pm.IPackageInstallerSession;
@@ -45,6 +46,7 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -724,6 +726,12 @@
                 Binder.restoreCallingIdentity(ident);
             }
         } else {
+            ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId);
+            if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
+                        null);
+            }
+
             // Take a short detour to confirm with user
             final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
             intent.setData(Uri.fromParts("package", versionedPackage.getPackageName(), null));
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index a3585bc..ba97c42 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -615,10 +615,16 @@
 
             // Fix up isPinned for the caller.  Note we need to do it before the "test" callback,
             // since it may check isPinned.
-            if (!isPinnedByCaller) {
-                clone.clearFlags(ShortcutInfo.FLAG_PINNED);
+            // However, if getPinnedByAnyLauncher is set, we do it after the test.
+            if (!getPinnedByAnyLauncher) {
+                if (!isPinnedByCaller) {
+                    clone.clearFlags(ShortcutInfo.FLAG_PINNED);
+                }
             }
             if (query == null || query.test(clone)) {
+                if (!isPinnedByCaller) {
+                    clone.clearFlags(ShortcutInfo.FLAG_PINNED);
+                }
                 result.add(clone);
             }
         }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 25e9239..0907dd7 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -2234,7 +2234,7 @@
     // We override this method in unit tests to do a simpler check.
     boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId,
             int callingPid, int callingUid) {
-        if (injectCheckAccessShortcutsPermission(callingPid, callingUid)) {
+        if (canSeeAnyPinnedShortcut(callingPackage, userId, callingPid, callingUid)) {
             return true;
         }
         final long start = injectElapsedRealtime();
@@ -2245,10 +2245,21 @@
         }
     }
 
+    boolean canSeeAnyPinnedShortcut(@NonNull String callingPackage, int userId,
+            int callingPid, int callingUid) {
+        if (injectHasAccessShortcutsPermission(callingPid, callingUid)) {
+            return true;
+        }
+        synchronized (mLock) {
+            return getUserShortcutsLocked(userId).hasHostPackage(callingPackage);
+        }
+    }
+
     /**
      * Returns true if the caller has the "ACCESS_SHORTCUTS" permission.
      */
-    boolean injectCheckAccessShortcutsPermission(int callingPid, int callingUid) {
+    @VisibleForTesting
+    boolean injectHasAccessShortcutsPermission(int callingPid, int callingUid) {
         return mContext.checkPermission(android.Manifest.permission.ACCESS_SHORTCUTS,
                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
     }
@@ -2262,10 +2273,6 @@
 
             final ShortcutUser user = getUserShortcutsLocked(userId);
 
-            if (user.hasHostPackage(packageName)) {
-                return true;
-            }
-
             // Always trust the cached component.
             final ComponentName cached = user.getCachedLauncher();
             if (cached != null) {
@@ -2491,8 +2498,8 @@
             final ArraySet<String> ids = shortcutIds == null ? null
                     : new ArraySet<>(shortcutIds);
 
-            final ShortcutPackage p = getUserShortcutsLocked(userId)
-                    .getPackageShortcutsIfExists(packageName);
+            final ShortcutUser user = getUserShortcutsLocked(userId);
+            final ShortcutPackage p = user.getPackageShortcutsIfExists(packageName);
             if (p == null) {
                 return; // No need to instantiate ShortcutPackage.
             }
@@ -2500,9 +2507,12 @@
             final boolean matchPinned = (queryFlags & ShortcutQuery.FLAG_MATCH_PINNED) != 0;
             final boolean matchManifest = (queryFlags & ShortcutQuery.FLAG_MATCH_MANIFEST) != 0;
 
+            final boolean canAccessAllShortcuts =
+                    canSeeAnyPinnedShortcut(callingPackage, launcherUserId, callingPid, callingUid);
+
             final boolean getPinnedByAnyLauncher =
-                    ((queryFlags & ShortcutQuery.FLAG_MATCH_ALL_PINNED) != 0)
-                    && injectCheckAccessShortcutsPermission(callingPid, callingUid);
+                    canAccessAllShortcuts &&
+                    ((queryFlags & ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER) != 0);
 
             p.findAll(ret,
                     (ShortcutInfo si) -> {
@@ -2521,7 +2531,7 @@
                         if (matchDynamic && si.isDynamic()) {
                             return true;
                         }
-                        if ((matchPinned && si.isPinned()) || getPinnedByAnyLauncher) {
+                        if ((matchPinned || getPinnedByAnyLauncher) && si.isPinned()) {
                             return true;
                         }
                         if (matchManifest && si.isDeclaredInManifest()) {
@@ -2614,14 +2624,15 @@
                         .attemptToRestoreIfNeededAndSave();
 
                 final boolean getPinnedByAnyLauncher =
-                        injectCheckAccessShortcutsPermission(callingPid, callingUid);
+                        canSeeAnyPinnedShortcut(callingPackage, launcherUserId,
+                                callingPid, callingUid);
 
                 // Make sure the shortcut is actually visible to the launcher.
                 final ShortcutInfo si = getShortcutInfoLocked(
                         launcherUserId, callingPackage, packageName, shortcutId, userId,
                         getPinnedByAnyLauncher);
                 // "si == null" should suffice here, but check the flags too just to make sure.
-                if (si == null || !si.isEnabled() || !si.isAlive()) {
+                if (si == null || !si.isEnabled() || !(si.isAlive() || getPinnedByAnyLauncher)) {
                     Log.e(TAG, "Shortcut " + shortcutId + " does not exist or disabled");
                     return null;
                 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1e5245c..1152310 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1010,6 +1010,23 @@
         }
     }
 
+    @Override
+    public boolean hasRestrictedProfiles() {
+        checkManageUsersPermission("hasRestrictedProfiles");
+        final int callingUserId = UserHandle.getCallingUserId();
+        synchronized (mUsersLock) {
+            final int userSize = mUsers.size();
+            for (int i = 0; i < userSize; i++) {
+                UserInfo profile = mUsers.valueAt(i).info;
+                if (callingUserId != profile.id
+                        && profile.restrictedProfileParentId == callingUserId) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
     /*
      * Should be locked on mUsers before calling this.
      */
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a11d282..9162a97 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4613,7 +4613,7 @@
         } else if (mNavigationBarPosition == NAV_BAR_LEFT) {
             // Seascape screen; nav bar goes to the left.
             final int right = displayFrames.mUnrestricted.left
-                    - getNavigationBarWidth(rotation, uiMode);
+                    + getNavigationBarWidth(rotation, uiMode);
             mTmpNavigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight);
             displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
             if (transientNavBarShowing) {
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index f41ff2c..e1edf11 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -62,6 +62,8 @@
 public class StatsCompanionService extends IStatsCompanionService.Stub {
     static final String TAG = "StatsCompanionService";
     static final boolean DEBUG = true;
+    public static final String ACTION_TRIGGER_COLLECTION =
+        "com.android.server.stats.action.TRIGGER_COLLECTION";
 
     private final Context mContext;
     private final AlarmManager mAlarmManager;
@@ -120,6 +122,12 @@
         }
     }
 
+    @Override
+    public void sendBroadcast(String pkg, String cls) {
+        mContext.sendBroadcastAsUser(new Intent(ACTION_TRIGGER_COLLECTION).setClassName(pkg, cls),
+                UserHandle.SYSTEM);
+    }
+
     private final static int[] toIntArray(List<Integer> list) {
         int[] ret = new int[list.size()];
         for (int i = 0; i < ret.length; i++) {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 1f1324a..daf3f2f 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1207,6 +1207,13 @@
         ALOGE("Unable to initialize GNSS NI interface\n");
     }
 
+    sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
+    if (agnssRilIface != nullptr) {
+        agnssRilIface->setCallback(aGnssRilCbIface);
+    } else {
+        ALOGI("Unable to Initialize AGnss Ril interface\n");
+    }
+
     return JNI_TRUE;
 }
 
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 58833be..e8ae020 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -597,6 +597,7 @@
                 PrintJobStateChangeListenerRecord record =
                         mPrintJobStateChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintJobStateChangeListenerRecords.remove(i);
                     break;
                 }
@@ -639,6 +640,7 @@
                 ListenerRecord<IPrintServicesChangeListener> record =
                         mPrintServicesChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintServicesChangeListenerRecords.remove(i);
                     break;
                 }
@@ -686,6 +688,7 @@
                 ListenerRecord<IRecommendationsChangeListener> record =
                         mPrintServiceRecommendationsChangeListenerRecords.get(i);
                 if (record.listener.asBinder().equals(listener.asBinder())) {
+                    record.destroy();
                     mPrintServiceRecommendationsChangeListenerRecords.remove(i);
                     break;
                 }
@@ -1285,6 +1288,10 @@
             listener.asBinder().linkToDeath(this, 0);
         }
 
+        public void destroy() {
+            listener.asBinder().unlinkToDeath(this, 0);
+        }
+
         @Override
         public void binderDied() {
             listener.asBinder().unlinkToDeath(this, 0);
@@ -1302,6 +1309,10 @@
             listener.asBinder().linkToDeath(this, 0);
         }
 
+        public void destroy() {
+            listener.asBinder().unlinkToDeath(this, 0);
+        }
+
         @Override
         public void binderDied() {
             listener.asBinder().unlinkToDeath(this, 0);
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 59d2a24..f63d1e7 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -45,6 +45,7 @@
     platform-test-annotations \
     truth-prebuilt
 
+# TODO(b/69254249): Migrate to Robolectric 3.4.2
 LOCAL_JAVA_LIBRARIES := \
     junit \
     platform-robolectric-prebuilt
@@ -72,4 +73,5 @@
 
 LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java
 
-include prebuilts/misc/common/robolectric/run_robotests.mk
+# TODO(b/69254249): Migrate to Robolectric 3.4.2
+include prebuilts/misc/common/robolectric/3.1.1/run_robotests.mk
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
new file mode 100644
index 0000000..d9fac87
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -0,0 +1,640 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.display;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.display.BrightnessChangeEvent;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.MessageQueue;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.AtomicFile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BrightnessTrackerTest {
+
+    private BrightnessTracker mTracker;
+    private TestInjector mInjector;
+
+    private static Object sHandlerLock = new Object();
+    private static Handler sHandler;
+    private static HandlerThread sThread =
+            new HandlerThread("brightness.test", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+
+    private static Handler ensureHandler() {
+        synchronized (sHandlerLock) {
+            if (sHandler == null) {
+                sThread.start();
+                sHandler = new Handler(sThread.getLooper());
+            }
+            return sHandler;
+        }
+    }
+
+
+    @Before
+    public void setUp() throws Exception {
+        mInjector = new TestInjector(ensureHandler());
+
+        mTracker = new BrightnessTracker(InstrumentationRegistry.getContext(), mInjector);
+    }
+
+    @Test
+    public void testStartStopTracker() {
+        startTracker(mTracker);
+        assertNotNull(mInjector.mSensorListener);
+        assertNotNull(mInjector.mSettingsObserver);
+        assertNotNull(mInjector.mBroadcastReceiver);
+        mTracker.stop();
+        assertNull(mInjector.mSensorListener);
+        assertNull(mInjector.mSettingsObserver);
+        assertNull(mInjector.mBroadcastReceiver);
+    }
+
+    @Test
+    public void testBrightnessEvent() {
+        final int brightness = 20;
+
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
+        startTracker(mTracker);
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0).getList();
+        mTracker.stop();
+
+        assertEquals(1, events.size());
+        BrightnessChangeEvent event = events.get(0);
+        assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
+        assertEquals(1, event.luxValues.length);
+        assertEquals(1.0f, event.luxValues[0], 0.1f);
+        assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2),
+                event.luxTimestamps[0]);
+        assertEquals(brightness, event.brightness);
+
+        // System had no data so these should all be at defaults.
+        assertEquals(Float.NaN, event.batteryLevel, 0.0);
+        assertFalse(event.nightMode);
+        assertEquals(0, event.colorTemperature);
+    }
+
+    @Test
+    public void testBrightnessFullPopulatedEvent() {
+        final int lastBrightness = 230;
+        final int brightness = 130;
+
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, lastBrightness);
+        mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
+        mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
+
+        startTracker(mTracker);
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
+        mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
+                batteryChangeEvent(30, 60));
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
+        final long sensorTime = mInjector.currentTimeMillis();
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0).getList();
+        mTracker.stop();
+
+        assertEquals(1, events.size());
+        BrightnessChangeEvent event = events.get(0);
+        assertEquals(event.timeStamp, mInjector.currentTimeMillis());
+        assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f);
+        assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps);
+        assertEquals(brightness, event.brightness);
+        assertEquals(lastBrightness, event.lastBrightness);
+        assertEquals(0.5, event.batteryLevel, 0.01);
+        assertTrue(event.nightMode);
+        assertEquals(3333, event.colorTemperature);
+        assertEquals("a.package", event.packageName);
+        assertEquals(0, event.userId);
+    }
+
+    @Test
+    public void testIgnoreSelfChange() {
+        final int initialBrightness = 30;
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, initialBrightness);
+        startTracker(mTracker);
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
+
+        final int systemUpdatedBrightness = 20;
+        mTracker.setBrightness(systemUpdatedBrightness, 0);
+        assertEquals(systemUpdatedBrightness,
+                (int) mInjector.mSystemIntSettings.get(Settings.System.SCREEN_BRIGHTNESS));
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0).getList();
+        // No events because we filtered out our change.
+        assertEquals(0, events.size());
+
+        final int firstUserUpdateBrightness = 20;
+        // Then change comes from somewhere else so we shouldn't filter.
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
+                firstUserUpdateBrightness);
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+
+        // and with a different brightness value.
+        final int secondUserUpdateBrightness = 34;
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
+                secondUserUpdateBrightness);
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        events = mTracker.getEvents(0).getList();
+
+        assertEquals(2, events.size());
+        // First event is change from system update (20) to first user update (20)
+        assertEquals(systemUpdatedBrightness, events.get(0).lastBrightness);
+        assertEquals(firstUserUpdateBrightness, events.get(0).brightness);
+        // Second event is from first to second user update.
+        assertEquals(firstUserUpdateBrightness, events.get(1).lastBrightness);
+        assertEquals(secondUserUpdateBrightness, events.get(1).brightness);
+
+        mTracker.stop();
+    }
+
+    @Test
+    public void testLimitedBufferSize() {
+        startTracker(mTracker);
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
+
+        for (int brightness = 0; brightness <= 255; ++brightness) {
+            mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
+            mInjector.incrementTime(TimeUnit.SECONDS.toNanos(1));
+            mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
+            mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                    Settings.System.SCREEN_BRIGHTNESS));
+        }
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0).getList();
+        mTracker.stop();
+
+        // Should be capped at 100 events, and they should be the most recent 100.
+        assertEquals(100, events.size());
+        for (int i = 0; i < events.size(); i++) {
+            BrightnessChangeEvent event = events.get(i);
+            assertEquals(156 + i, event.brightness);
+        }
+    }
+
+    @Test
+    public void testLimitedSensorEvents() {
+        final int brightness = 20;
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
+
+        startTracker(mTracker);
+        // 20 Sensor events 1 second apart.
+        for (int i = 0; i < 20; ++i) {
+            mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
+            mInjector.mSensorListener.onSensorChanged(createSensorEvent(i + 1.0f));
+        }
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        List<BrightnessChangeEvent> events = mTracker.getEvents(0).getList();
+        mTracker.stop();
+
+        assertEquals(1, events.size());
+        BrightnessChangeEvent event = events.get(0);
+        assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
+
+        // 12 sensor events, 11 for 0->10 seconds + 1 previous event.
+        assertEquals(12, event.luxValues.length);
+        for (int i = 0; i < 12; ++i) {
+            assertEquals(event.luxTimestamps[11 - i],
+                    mInjector.currentTimeMillis() - i * TimeUnit.SECONDS.toMillis(1));
+        }
+        assertEquals(brightness, event.brightness);
+    }
+
+    @Test
+    public void testReadEvents() throws Exception {
+        BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
+                mInjector);
+        mInjector.mCurrentTimeMillis = System.currentTimeMillis();
+        long someTimeAgo = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12);
+        long twoMonthsAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
+        // 3 Events in the file but one too old to read.
+        String eventFile =
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<events>\n"
+                + "<event brightness=\"194\" timestamp=\""
+                + Long.toString(someTimeAgo) + "\" packageName=\""
+                + "com.example.app\" user=\"10\" "
+                + "lastBrightness=\"32\" "
+                + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+                + "lux=\"32.2,31.1\" luxTimestamps=\""
+                + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
+                + "<event brightness=\"71\" timestamp=\""
+                + Long.toString(someTimeAgo) + "\" packageName=\""
+                + "com.android.anapp\" user=\"11\" "
+                + "lastBrightness=\"32\" "
+                + "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\"\n"
+                + "lux=\"132.2,131.1\" luxTimestamps=\""
+                + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
+                // Event that is too old so shouldn't show up.
+                + "<event brightness=\"142\" timestamp=\""
+                + Long.toString(twoMonthsAgo) + "\" packageName=\""
+                + "com.example.app\" user=\"10\" "
+                + "lastBrightness=\"32\" "
+                + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
+                + "lux=\"32.2,31.1\" luxTimestamps=\""
+                + Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>"
+                + "</events>";
+        tracker.readEventsLocked(getInputStream(eventFile));
+        List<BrightnessChangeEvent> events = tracker.getEvents(0).getList();
+        assertEquals(1, events.size());
+        BrightnessChangeEvent event = events.get(0);
+        assertEquals(someTimeAgo, event.timeStamp);
+        assertEquals(194, event.brightness);
+        assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, 0.01f);
+        assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
+        assertEquals(32, event.lastBrightness);
+        assertEquals(0, event.userId);
+        assertFalse(event.nightMode);
+        assertEquals(1.0f, event.batteryLevel, 0.01);
+        assertEquals("com.example.app", event.packageName);
+
+        events = tracker.getEvents(1).getList();
+        assertEquals(1, events.size());
+        event = events.get(0);
+        assertEquals(someTimeAgo, event.timeStamp);
+        assertEquals(71, event.brightness);
+        assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, 0.01f);
+        assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
+        assertEquals(32, event.lastBrightness);
+        assertEquals(1, event.userId);
+        assertTrue(event.nightMode);
+        assertEquals(3235, event.colorTemperature);
+        assertEquals(0.5f, event.batteryLevel, 0.01);
+        assertEquals("com.android.anapp", event.packageName);
+    }
+
+    @Test
+    public void testFailedRead() {
+        String someTimeAgo =
+                Long.toString(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12));
+        mInjector.mCurrentTimeMillis = System.currentTimeMillis();
+
+        BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
+                mInjector);
+        String eventFile = "junk in the file";
+        try {
+            tracker.readEventsLocked(getInputStream(eventFile));
+        } catch (IOException e) {
+            // Expected;
+        }
+        assertEquals(0, tracker.getEvents(0).getList().size());
+
+        // Missing lux value.
+        eventFile =
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                        + "<events>\n"
+                        + "<event brightness=\"194\" timestamp=\"" + someTimeAgo + "\" packageName=\""
+                        + "com.example.app\" user=\"10\" "
+                        + "batteryLevel=\"0.7\" nightMode=\"false\" colorTemperature=\"0\" />\n"
+                        + "</events>";
+        try {
+            tracker.readEventsLocked(getInputStream(eventFile));
+        } catch (IOException e) {
+            // Expected;
+        }
+        assertEquals(0, tracker.getEvents(0).getList().size());
+    }
+
+    @Test
+    public void testWriteThenRead() throws Exception {
+        final int brightness = 20;
+
+        mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
+        mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
+        mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
+
+        startTracker(mTracker);
+        mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
+                batteryChangeEvent(30, 100));
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
+        final long firstSensorTime = mInjector.currentTimeMillis();
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
+        mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
+        final long secondSensorTime = mInjector.currentTimeMillis();
+        mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
+        mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
+                Settings.System.SCREEN_BRIGHTNESS));
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        mTracker.writeEventsLocked(baos);
+        mTracker.stop();
+
+        baos.flush();
+        ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
+        BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
+                mInjector);
+        tracker.readEventsLocked(input);
+        List<BrightnessChangeEvent> events = tracker.getEvents(0).getList();
+
+        assertEquals(1, events.size());
+        BrightnessChangeEvent event = events.get(0);
+        assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, 0.01f);
+        assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps);
+        assertEquals(brightness, event.brightness);
+        assertEquals(0.3, event.batteryLevel, 0.01f);
+        assertTrue(event.nightMode);
+        assertEquals(3339, event.colorTemperature);
+    }
+
+    @Test
+    public void testParcelUnParcel() {
+        Parcel parcel = Parcel.obtain();
+        BrightnessChangeEvent event = new BrightnessChangeEvent();
+        event.brightness = 23;
+        event.timeStamp = 345L;
+        event.packageName = "com.example";
+        event.userId = 12;
+        event.luxValues = new float[2];
+        event.luxValues[0] = 3000.0f;
+        event.luxValues[1] = 4000.0f;
+        event.luxTimestamps = new long[2];
+        event.luxTimestamps[0] = 325L;
+        event.luxTimestamps[1] = 315L;
+        event.batteryLevel = 0.7f;
+        event.nightMode = false;
+        event.colorTemperature = 345;
+        event.lastBrightness = 50;
+
+        event.writeToParcel(parcel, 0);
+        byte[] parceled = parcel.marshall();
+        parcel.recycle();
+
+        parcel = Parcel.obtain();
+        parcel.unmarshall(parceled, 0, parceled.length);
+        parcel.setDataPosition(0);
+
+        BrightnessChangeEvent event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        assertEquals(event.brightness, event2.brightness);
+        assertEquals(event.timeStamp, event2.timeStamp);
+        assertEquals(event.packageName, event2.packageName);
+        assertEquals(event.userId, event2.userId);
+        assertArrayEquals(event.luxValues, event2.luxValues, 0.01f);
+        assertArrayEquals(event.luxTimestamps, event2.luxTimestamps);
+        assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
+        assertEquals(event.nightMode, event2.nightMode);
+        assertEquals(event.colorTemperature, event2.colorTemperature);
+        assertEquals(event.lastBrightness, event2.lastBrightness);
+
+        parcel = Parcel.obtain();
+        event.batteryLevel = Float.NaN;
+        event.writeToParcel(parcel, 0);
+        parceled = parcel.marshall();
+        parcel.recycle();
+
+        parcel = Parcel.obtain();
+        parcel.unmarshall(parceled, 0, parceled.length);
+        parcel.setDataPosition(0);
+        event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
+        assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
+    }
+
+    private InputStream getInputStream(String data) {
+        return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+    }
+
+    private Intent batteryChangeEvent(int level, int scale) {
+        Intent intent = new Intent();
+        intent.setAction(Intent.ACTION_BATTERY_CHANGED);
+        intent.putExtra(BatteryManager.EXTRA_LEVEL, level);
+        intent.putExtra(BatteryManager.EXTRA_SCALE, scale);
+        return intent;
+    }
+
+    private SensorEvent createSensorEvent(float lux) {
+        SensorEvent event;
+        try {
+            Constructor<SensorEvent> constr =
+                    SensorEvent.class.getDeclaredConstructor(Integer.TYPE);
+            constr.setAccessible(true);
+            event = constr.newInstance(1);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        event.values[0] = lux;
+        event.timestamp = mInjector.mElapsedRealtimeNanos;
+
+        return event;
+    }
+
+    private void startTracker(BrightnessTracker tracker) {
+        tracker.start();
+        mInjector.waitForHandler();
+    }
+
+
+    private static final class Idle implements MessageQueue.IdleHandler {
+        private boolean mIdle;
+
+        @Override
+        public boolean queueIdle() {
+            synchronized (this) {
+                mIdle = true;
+                notifyAll();
+            }
+            return false;
+        }
+
+        public synchronized void waitForIdle() {
+            while (!mIdle) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    private class TestInjector extends BrightnessTracker.Injector {
+        SensorEventListener mSensorListener;
+        ContentObserver mSettingsObserver;
+        BroadcastReceiver mBroadcastReceiver;
+        Map<String, Integer> mSystemIntSettings = new HashMap<>();
+        Map<String, Integer> mSecureIntSettings = new HashMap<>();
+        long mCurrentTimeMillis = System.currentTimeMillis();
+        long mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
+        Handler mHandler;
+
+        public TestInjector(Handler handler) {
+            mHandler = handler;
+        }
+
+        public void incrementTime(long timeMillis) {
+            mCurrentTimeMillis += timeMillis;
+            mElapsedRealtimeNanos += TimeUnit.MILLISECONDS.toNanos(timeMillis);
+        }
+
+        @Override
+        public void registerSensorListener(Context context,
+                SensorEventListener sensorListener) {
+            mSensorListener = sensorListener;
+        }
+
+        @Override
+        public void unregisterSensorListener(Context context,
+                SensorEventListener sensorListener) {
+            mSensorListener = null;
+        }
+
+        @Override
+        public void registerBrightnessObserver(ContentResolver resolver,
+                ContentObserver settingsObserver) {
+            mSettingsObserver = settingsObserver;
+        }
+
+        @Override
+        public void unregisterBrightnessObserver(Context context,
+                ContentObserver settingsObserver) {
+            mSettingsObserver = null;
+        }
+
+        @Override
+        public void registerReceiver(Context context,
+                BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter) {
+            mBroadcastReceiver = shutdownReceiver;
+        }
+
+        @Override
+        public void unregisterReceiver(Context context,
+                BroadcastReceiver broadcastReceiver) {
+            assertEquals(mBroadcastReceiver, broadcastReceiver);
+            mBroadcastReceiver = null;
+        }
+
+        @Override
+        public Handler getBackgroundHandler() {
+            return mHandler;
+        }
+
+        public void waitForHandler() {
+            Idle idle = new Idle();
+            mHandler.getLooper().getQueue().addIdleHandler(idle);
+            mHandler.post(() -> {});
+            idle.waitForIdle();
+        }
+
+        @Override
+        public int getSystemIntForUser(ContentResolver resolver, String setting, int defaultValue,
+                int userId) {
+            Integer value = mSystemIntSettings.get(setting);
+            if (value == null) {
+                return defaultValue;
+            } else {
+                return value;
+            }
+        }
+
+        @Override
+        public void putSystemIntForUser(ContentResolver resolver, String setting, int value,
+                int userId) {
+            mSystemIntSettings.put(setting, value);
+        }
+
+        @Override
+        public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue,
+                int userId) {
+            Integer value = mSecureIntSettings.get(setting);
+            if (value == null) {
+                return defaultValue;
+            } else {
+                return value;
+            }
+        }
+
+        @Override
+        public AtomicFile getFile() {
+            // Don't have the test write / read from anywhere.
+            return null;
+        }
+
+        @Override
+        public long currentTimeMillis() {
+            return mCurrentTimeMillis;
+        }
+
+        @Override
+        public long elapsedRealtimeNanos() {
+            return mElapsedRealtimeNanos;
+        }
+
+        @Override
+        public int getUserSerialNumber(UserManager userManager, int userId) {
+            return userId + 10;
+        }
+
+        @Override
+        public int getUserId(UserManager userManager, int userSerialNumber) {
+            return userSerialNumber - 10;
+        }
+
+        @Override
+        public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
+            ActivityManager.StackInfo focusedStack = new ActivityManager.StackInfo();
+            focusedStack.userId = 0;
+            focusedStack.topActivity = new ComponentName("a.package", "a.class");
+            return focusedStack;
+        }
+    }
+}
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 6bb5bc6..025ebc3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -453,7 +453,7 @@
         }
 
         @Override
-        boolean injectCheckAccessShortcutsPermission(int callingPid, int callingUid) {
+        boolean injectHasAccessShortcutsPermission(int callingPid, int callingUid) {
             return mInjectCheckAccessShortcutsPermission;
         }
 
@@ -1648,7 +1648,6 @@
     protected void assertShortcutLaunchable(@NonNull String packageName, @NonNull String shortcutId,
             int userId) {
         assertNotNull(launchShortcutAndGetIntent(packageName, shortcutId, userId));
-        assertNotNull(launchShortcutAndGetIntent_withShortcutInfo(packageName, shortcutId, userId));
     }
 
     protected void assertShortcutNotLaunched(@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 b5e8e1c..f92b575 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -1918,7 +1918,7 @@
             // Make sure FLAG_MATCH_ALL_PINNED will be ignored.
             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
-                            | ShortcutQuery.FLAG_MATCH_ALL_PINNED), getCallingUser()))
+                            | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER), getCallingUser()))
                     .isEmpty();
 
             // Make sure the special permission works.
@@ -1928,14 +1928,18 @@
 
             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED
-                            | ShortcutQuery.FLAG_MATCH_ALL_PINNED), getCallingUser()))
+                            | ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER), getCallingUser()))
                     .haveIds("s1", "s2");
             assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
                     /* activity =*/ null, ShortcutQuery.FLAG_MATCH_PINNED), getCallingUser()))
                     .isEmpty();
 
+            assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", getCallingUser().getIdentifier());
+
             mInjectCheckAccessShortcutsPermission = false;
 
+            assertShortcutNotLaunched(CALLING_PACKAGE_2, "s1", getCallingUser().getIdentifier());
+
             assertShortcutIds(assertAllDynamic(
                     mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
                     /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
@@ -2106,6 +2110,62 @@
         });
     }
 
+    public void testPinShortcutAndGetPinnedShortcuts_assistant() {
+        // Create some shortcuts.
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertTrue(mManager.setDynamicShortcuts(list(
+                    makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+        });
+
+        // Pin some.
+        runWithCaller(LAUNCHER_1, USER_0, () -> {
+            mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+                    list("s3", "s4"), getCallingUser());
+        });
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertTrue(mManager.setDynamicShortcuts(list(
+                    makeShortcut("s1"))));
+        });
+
+        runWithCaller(LAUNCHER_2, USER_0, () -> {
+            final ShortcutQuery allPinned = new ShortcutQuery().setQueryFlags(
+                    ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER);
+
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .isEmpty();
+
+            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+            assertShortcutNotLaunched(CALLING_PACKAGE_1, "s3", USER_0);
+            assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
+
+            // Make it the assistant app.
+            mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .haveIds("s3");
+
+            assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
+            assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+            assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
+
+            mInternal.setShortcutHostPackage("another-type", LAUNCHER_3, USER_0);
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .haveIds("s3");
+
+            mInternal.setShortcutHostPackage("assistant", null, USER_0);
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .isEmpty();
+
+            mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .haveIds("s3");
+
+            mInternal.setShortcutHostPackage("assistant", LAUNCHER_1, USER_0);
+            assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+                    .isEmpty();
+        });
+    }
+
     public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
         // Create some shortcuts.
         runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index b656d5e..dd9a8ab 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -309,6 +309,8 @@
 
     @MediumTest
     public void testAddRestrictedProfile() throws Exception {
+        assertFalse("There should be no associated restricted profiles before the test",
+                mUserManager.hasRestrictedProfiles());
         UserInfo userInfo = createRestrictedProfile("Profile");
         assertNotNull(userInfo);
 
@@ -324,6 +326,9 @@
                 userInfo.id);
         assertEquals("Restricted profile should have setting LOCATION_MODE set to "
                 + "LOCATION_MODE_OFF by default", locationMode, Settings.Secure.LOCATION_MODE_OFF);
+
+        assertTrue("Newly created profile should be associated with the current user",
+                mUserManager.hasRestrictedProfiles());
     }
 
     @MediumTest
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 99f2685..96fbc14 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -32,7 +32,6 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.util.ArraySet;
 
-import com.android.internal.util.Predicate;
 import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
 
 import org.junit.Test;
@@ -200,4 +199,16 @@
                 new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
         assertTrueForFiles(existsFiles, File::exists, " must exist");
     }
+
+    /**
+     * Private predicate definition.
+     *
+     * This is needed because com.android.internal.util.Predicate is deprecated
+     * and can only be used with classes fron android.test.runner. This cannot
+     * use java.util.function.Predicate because that is not present on all API
+     * versions that this test must run on.
+     */
+    private interface Predicate<T> {
+        boolean apply(T t);
+    }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0030ab6..1db6ef7 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -855,6 +855,14 @@
     public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
 
     /**
+     * Default Enhanced 4G LTE mode enabled. When this is {@code true}, Enhanced 4G LTE mode by
+     * default is on, otherwise if {@code false}, Enhanced 4G LTE mode by default is off.
+     * @hide
+     */
+    public static final String KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL =
+            "enhanced_4g_lte_on_by_default_bool";
+
+    /**
      * Determine whether IMS apn can be shown.
      */
     public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
@@ -1812,6 +1820,7 @@
         sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
         sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
         sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
+        sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL, true);
         sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false);
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 6276626..4d7c71f 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -115,10 +115,11 @@
         // for inbound parcels
         mBsic = (bsic == 0xFF) ? Integer.MAX_VALUE : bsic;
 
+        // Only allow INT_MAX if unknown string mcc/mnc
         if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
             mMccStr = mccStr;
-        } else if (mccStr.isEmpty()) {
-            // If the mccStr parsed from Parcel is empty, set it as null.
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
             mMccStr = null;
         } else {
             throw new IllegalArgumentException("invalid MCC format");
@@ -126,8 +127,8 @@
 
         if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
             mMncStr = mncStr;
-        } else if (mncStr.isEmpty()) {
-            // If the mncStr parsed from Parcel is empty, set it as null.
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
             mMncStr = null;
         } else {
             throw new IllegalArgumentException("invalid MNC format");
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 74d2966..fd837fc 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -114,10 +114,11 @@
         mTac = tac;
         mEarfcn = earfcn;
 
+        // Only allow INT_MAX if unknown string mcc/mnc
         if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
             mMccStr = mccStr;
-        } else if (mccStr.isEmpty()) {
-            // If the mccStr parsed from Parcel is empty, set it as null.
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
             mMccStr = null;
         } else {
             throw new IllegalArgumentException("invalid MCC format");
@@ -125,8 +126,8 @@
 
         if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
             mMncStr = mncStr;
-        } else if (mncStr.isEmpty()) {
-            // If the mncStr parsed from Parcel is empty, set it as null.
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
             mMncStr = null;
         } else {
             throw new IllegalArgumentException("invalid MNC format");
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 51b11aa..1597245 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -114,10 +114,11 @@
         mPsc = psc;
         mUarfcn = uarfcn;
 
+        // Only allow INT_MAX if unknown string mcc/mnc
         if (mccStr == null || mccStr.matches("^[0-9]{3}$")) {
             mMccStr = mccStr;
-        } else if (mccStr.isEmpty()) {
-            // If the mccStr parsed from Parcel is empty, set it as null.
+        } else if (mccStr.isEmpty() || mccStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mccStr is empty or unknown, set it as null.
             mMccStr = null;
         } else {
             throw new IllegalArgumentException("invalid MCC format");
@@ -125,8 +126,8 @@
 
         if (mncStr == null || mncStr.matches("^[0-9]{2,3}$")) {
             mMncStr = mncStr;
-        } else if (mncStr.isEmpty()) {
-            // If the mncStr parsed from Parcel is empty, set it as null.
+        } else if (mncStr.isEmpty() || mncStr.equals(String.valueOf(Integer.MAX_VALUE))) {
+            // If the mncStr is empty or unknown, set it as null.
             mMncStr = null;
         } else {
             throw new IllegalArgumentException("invalid MNC format");
@@ -135,7 +136,7 @@
         mAlphaLong = alphal;
         mAlphaShort = alphas;
     }
-
+    
     private CellIdentityWcdma(CellIdentityWcdma cid) {
         this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 88f4880..2f39ddb 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -360,6 +360,42 @@
     public static final String CB_OPT_OUT_DIALOG = "show_cmas_opt_out_dialog";
 
     /**
+     * TelephonyProvider column name for enable Volte.
+     *@hide
+     */
+    public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled";
+
+    /**
+     * TelephonyProvider column name for enable VT (Video Telephony over IMS)
+     *@hide
+     */
+    public static final String VT_IMS_ENABLED = "vt_ims_enabled";
+
+    /**
+     * TelephonyProvider column name for enable Wifi calling
+     *@hide
+     */
+    public static final String WFC_IMS_ENABLED = "wfc_ims_enabled";
+
+    /**
+     * TelephonyProvider column name for Wifi calling mode
+     *@hide
+     */
+    public static final String WFC_IMS_MODE = "wfc_ims_mode";
+
+    /**
+     * TelephonyProvider column name for Wifi calling mode in roaming
+     *@hide
+     */
+    public static final String WFC_IMS_ROAMING_MODE = "wfc_ims_roaming_mode";
+
+    /**
+     * TelephonyProvider column name for enable Wifi calling in roaming
+     *@hide
+     */
+    public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
+
+    /**
      * Broadcast Action: The user has changed one of the default subs related to
      * data, phone calls, or sms</p>
      *
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 92a21b6..7bcdcdc 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -73,8 +73,8 @@
         /**
          * Informs the user that there is some error about the scan.
          *
-         * This callback will be called whenever there is any error about the scan, but the scan
-         * won't stop unless the onComplete() callback is called.
+         * This callback will be called whenever there is any error about the scan, and the scan
+         * will be terminated. onComplete() will NOT be called.
          */
         public void onError(int error) {}
     }
diff --git a/telephony/java/android/telephony/mbms/DownloadStateCallback.java b/telephony/java/android/telephony/mbms/DownloadStateCallback.java
index 892fbf0..9f60cc3 100644
--- a/telephony/java/android/telephony/mbms/DownloadStateCallback.java
+++ b/telephony/java/android/telephony/mbms/DownloadStateCallback.java
@@ -38,7 +38,7 @@
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ALL_UPDATES, PROGRESS_UPDATES, STATE_UPDATES})
+    @IntDef(flag = true, value = {ALL_UPDATES, PROGRESS_UPDATES, STATE_UPDATES})
     public @interface FilterFlag {}
 
     /**
diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java
index 0d737b5..e064adb 100644
--- a/telephony/java/android/telephony/mbms/FileInfo.java
+++ b/telephony/java/android/telephony/mbms/FileInfo.java
@@ -17,10 +17,13 @@
 package android.telephony.mbms;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Objects;
+
 /**
  * Describes a single file that is available over MBMS.
  */
@@ -47,6 +50,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public FileInfo(Uri uri, String mimeType) {
         this.uri = uri;
         this.mimeType = mimeType;
@@ -82,4 +86,23 @@
     public String getMimeType() {
         return mimeType;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        FileInfo fileInfo = (FileInfo) o;
+        return Objects.equals(uri, fileInfo.uri) &&
+                Objects.equals(mimeType, fileInfo.mimeType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(uri, mimeType);
+    }
 }
diff --git a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
index 9af1eb9..9ef188c 100644
--- a/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
+++ b/telephony/java/android/telephony/mbms/MbmsDownloadReceiver.java
@@ -165,16 +165,16 @@
                 Log.w(LOG_TAG, "Download result did not include a result code. Ignoring.");
                 return false;
             }
+            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)) {
+                Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring.");
+                return false;
+            }
             // We do not need to verify below extras if the result is not success.
             if (MbmsDownloadSession.RESULT_SUCCESSFUL !=
                     intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
                     MbmsDownloadSession.RESULT_CANCELLED)) {
                 return true;
             }
-            if (!intent.hasExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST)) {
-                Log.w(LOG_TAG, "Download result did not include the associated request. Ignoring.");
-                return false;
-            }
             if (!intent.hasExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT)) {
                 Log.w(LOG_TAG, "Download result did not include the temp file root. Ignoring.");
                 return false;
@@ -242,10 +242,12 @@
         int result = intent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
                 MbmsDownloadSession.RESULT_CANCELLED);
         intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
+        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
 
         if (result != MbmsDownloadSession.RESULT_SUCCESSFUL) {
             Log.i(LOG_TAG, "Download request indicated a failed download. Aborting.");
             context.sendBroadcast(intentForApp);
+            setResultCode(RESULT_OK);
             return;
         }
 
@@ -273,7 +275,6 @@
         intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI,
                 stagedFileLocation);
         intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO, completedFileInfo);
-        intentForApp.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
 
         context.sendBroadcast(intentForApp);
         setResultCode(RESULT_OK);
diff --git a/telephony/java/android/telephony/mbms/UriPathPair.java b/telephony/java/android/telephony/mbms/UriPathPair.java
index 187e9ee..dd20a69 100644
--- a/telephony/java/android/telephony/mbms/UriPathPair.java
+++ b/telephony/java/android/telephony/mbms/UriPathPair.java
@@ -17,6 +17,7 @@
 package android.telephony.mbms;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.os.Parcel;
@@ -29,6 +30,7 @@
  * @hide
  */
 @SystemApi
+@TestApi
 public final class UriPathPair implements Parcelable {
     private final Uri mFilePathUri;
     private final Uri mContentUri;
diff --git a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
index a43f122..f1cac8c 100644
--- a/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
+++ b/telephony/java/android/telephony/mbms/vendor/VendorUtils.java
@@ -17,6 +17,7 @@
 package android.telephony.mbms.vendor;
 
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +35,7 @@
  * @hide
  */
 @SystemApi
+@TestApi
 public class VendorUtils {
 
     /**
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index a65bb24..0656c5f 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -337,7 +337,6 @@
     public void testNetworkEventSerialization() {
         ConnectivityMetricsEvent ev = describeIpEvent(
                 aType(NetworkEvent.class),
-                anInt(100),
                 anInt(5),
                 aLong(20410));
 
@@ -352,9 +351,6 @@
                 "  network_event <",
                 "    event_type: 5",
                 "    latency_ms: 20410",
-                "    network_id <",
-                "      network_id: 100",
-                "    >",
                 "  >",
                 ">",
                 "version: 2\n");
@@ -508,6 +504,13 @@
         stats.rootWakeups = 2;
         stats.systemWakeups = 3;
         stats.noUidWakeups = 3;
+        stats.l2UnicastCount = 5;
+        stats.l2MulticastCount = 1;
+        stats.l2BroadcastCount = 2;
+        stats.ethertypes.put(0x800, 3);
+        stats.ethertypes.put(0x86dd, 3);
+        stats.ipNextHeaders.put(6, 5);
+
 
         IpConnectivityEvent got = IpConnectivityEventBuilder.toProto(stats);
         String want = String.join("\n",
@@ -521,6 +524,21 @@
                 "  wakeup_stats <",
                 "    application_wakeups: 5",
                 "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 3",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 5",
+                "    >",
+                "    l2_broadcast_count: 2",
+                "    l2_multicast_count: 1",
+                "    l2_unicast_count: 5",
                 "    no_uid_wakeups: 3",
                 "    non_application_wakeups: 1",
                 "    root_wakeups: 2",
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index b48ff8d..10d6deb 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -78,6 +78,9 @@
     private static final String EXAMPLE_IPV4 = "192.0.2.1";
     private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
 
+    private static final byte[] MAC_ADDR =
+            {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b};
+
     @Mock Context mCtx;
     @Mock IIpConnectivityMetrics mMockService;
     @Mock ConnectivityManager mCm;
@@ -351,13 +354,21 @@
         dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
 
         // iface, uid
-        wakeupEvent("wlan0", 1000);
-        wakeupEvent("rmnet0", 10123);
-        wakeupEvent("wlan0", 1000);
-        wakeupEvent("rmnet0", 10008);
-        wakeupEvent("wlan0", -1);
-        wakeupEvent("wlan0", 10008);
-        wakeupEvent("rmnet0", 1000);
+        final byte[] mac = {0x48, 0x7c, 0x2b, 0x6a, 0x3e, 0x4b};
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final int sport = 2356;
+        final int dport = 13489;
+        final long now = 1001L;
+        final int v4 = 0x800;
+        final int tcp = 6;
+        final int udp = 17;
+        wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10008, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", -1, v4, udp, mac, srcIp, dstIp, sport, dport, 1001L);
+        wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, 1001L);
 
         long timeMs = mService.mDefaultNetworkMetrics.creationTimeMs;
         final long cell = BitUtils.packBits(new int[]{NetworkCapabilities.TRANSPORT_CELLULAR});
@@ -560,34 +571,33 @@
                 ">",
                 "events <",
                 "  if_name: \"\"",
-                "  link_layer: 2",
-                "  network_id: 0",
-                "  time_ms: 0",
-                "  transports: 0",
-                "  wakeup_stats <",
-                "    application_wakeups: 2",
-                "    duration_sec: 0",
-                "    no_uid_wakeups: 0",
-                "    non_application_wakeups: 0",
-                "    root_wakeups: 0",
-                "    system_wakeups: 1",
-                "    total_wakeups: 3",
-                "  >",
-                ">",
-                "events <",
-                "  if_name: \"\"",
                 "  link_layer: 4",
                 "  network_id: 0",
                 "  time_ms: 0",
                 "  transports: 0",
                 "  wakeup_stats <",
-                "    application_wakeups: 1",
+                "    application_wakeups: 3",
                 "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 6",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 17",
+                "      value: 3",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 6",
                 "    no_uid_wakeups: 1",
                 "    non_application_wakeups: 0",
                 "    root_wakeups: 0",
                 "    system_wakeups: 2",
-                "    total_wakeups: 4",
+                "    total_wakeups: 6",
                 "  >",
                 ">",
                 "version: 2\n");
@@ -610,9 +620,10 @@
         mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
     }
 
-    void wakeupEvent(String iface, int uid) throws Exception {
+    void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp,
+            String dstIp, int sport, int dport, long now) throws Exception {
         String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
-        mNetdListener.onWakeupEvent(prefix, uid, uid, 0);
+        mNetdListener.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now);
     }
 
     NetworkAgentInfo makeNai(int netId, int score, boolean ipv4, boolean ipv6, long transports) {
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 83194d9..67805c9 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -61,7 +61,10 @@
     private static final String EXAMPLE_IPV4 = "192.0.2.1";
     private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
 
-    NetdEventListenerService mNetdEventListenerService;
+    private static final byte[] MAC_ADDR =
+            {(byte)0x84, (byte)0xc9, (byte)0xb2, (byte)0x6a, (byte)0xed, (byte)0x4b};
+
+    NetdEventListenerService mService;
     ConnectivityManager mCm;
 
     @Before
@@ -75,28 +78,49 @@
         when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
         when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
 
-        mNetdEventListenerService = new NetdEventListenerService(mCm);
+        mService = new NetdEventListenerService(mCm);
     }
 
     @Test
     public void testWakeupEventLogging() throws Exception {
         final int BUFFER_LENGTH = NetdEventListenerService.WAKEUP_EVENT_BUFFER_LENGTH;
+        final long now = System.currentTimeMillis();
+        final String iface = "wlan0";
+        final byte[] mac = MAC_ADDR;
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final String srcIp6 = "2001:db8:4:fd00:a585:13d1:6a23:4fb4";
+        final String dstIp6 = "2001:db8:4006:807::200a";
+        final int sport = 2356;
+        final int dport = 13489;
+
+        final int v4 = 0x800;
+        final int v6 = 0x86dd;
+        final int tcp = 6;
+        final int udp = 17;
+        final int icmp6 = 58;
 
         // Baseline without any event
         String[] baseline = listNetdEvent();
 
-        long now = System.currentTimeMillis();
-        String prefix = "iface:wlan0";
-        int[] uids = { 10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004 };
-        for (int uid : uids) {
-            mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
-        }
+        int[] uids = {10001, 10002, 10004, 1000, 10052, 10023, 10002, 10123, 10004};
+        wakeupEvent(iface, uids[0], v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[1], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[2], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[3], v4, icmp6, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[4], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[5], v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent(iface, uids[6], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[7], v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent(iface, uids[8], v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
 
         String[] events2 = remove(listNetdEvent(), baseline);
         int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
         assertEquals(expectedLength2, events2.length);
         assertContains(events2[0], "WakeupStats");
         assertContains(events2[0], "wlan0");
+        assertContains(events2[0], "0x800");
+        assertContains(events2[0], "0x86dd");
         for (int i = 0; i < uids.length; i++) {
             String got = events2[i+1];
             assertContains(got, "WakeupEvent");
@@ -107,7 +131,7 @@
         int uid = 20000;
         for (int i = 0; i < BUFFER_LENGTH * 2; i++) {
             long ts = now + 10;
-            mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, ts);
+            wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, ts);
         }
 
         String[] events3 = remove(listNetdEvent(), baseline);
@@ -123,7 +147,7 @@
         }
 
         uid = 45678;
-        mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, now);
+        wakeupEvent(iface, uid, 0x800, 6, mac, srcIp, dstIp, 23, 24, now);
 
         String[] events4 = remove(listNetdEvent(), baseline);
         String lastEvent = events4[events4.length - 1];
@@ -134,21 +158,36 @@
 
     @Test
     public void testWakeupStatsLogging() throws Exception {
-        wakeupEvent("wlan0", 1000);
-        wakeupEvent("rmnet0", 10123);
-        wakeupEvent("wlan0", 1000);
-        wakeupEvent("rmnet0", 10008);
-        wakeupEvent("wlan0", -1);
-        wakeupEvent("wlan0", 10008);
-        wakeupEvent("rmnet0", 1000);
-        wakeupEvent("wlan0", 10004);
-        wakeupEvent("wlan0", 1000);
-        wakeupEvent("wlan0", 0);
-        wakeupEvent("wlan0", -1);
-        wakeupEvent("rmnet0", 10052);
-        wakeupEvent("wlan0", 0);
-        wakeupEvent("rmnet0", 1000);
-        wakeupEvent("wlan0", 1010);
+        final byte[] mac = MAC_ADDR;
+        final String srcIp = "192.168.2.1";
+        final String dstIp = "192.168.2.23";
+        final String srcIp6 = "2401:fa00:4:fd00:a585:13d1:6a23:4fb4";
+        final String dstIp6 = "2404:6800:4006:807::200a";
+        final int sport = 2356;
+        final int dport = 13489;
+        final long now = 1001L;
+
+        final int v4 = 0x800;
+        final int v6 = 0x86dd;
+        final int tcp = 6;
+        final int udp = 17;
+        final int icmp6 = 58;
+
+        wakeupEvent("wlan0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 10123, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 1000, v4, udp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 10008, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("rmnet0", 1000, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 10004, v4, udp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", -1, v6, icmp6, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("rmnet0", 10052, v4, tcp, mac, srcIp, dstIp, sport, dport, now);
+        wakeupEvent("wlan0", 0, v6, udp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("rmnet0", 1000, v6, tcp, mac, srcIp6, dstIp6, sport, dport, now);
+        wakeupEvent("wlan0", 1010, v4, udp, mac, srcIp, dstIp, sport, dport, now);
 
         String got = flushStatistics();
         String want = String.join("\n",
@@ -162,6 +201,21 @@
                 "  wakeup_stats <",
                 "    application_wakeups: 3",
                 "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 4",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 1",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 5",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 5",
                 "    no_uid_wakeups: 0",
                 "    non_application_wakeups: 0",
                 "    root_wakeups: 0",
@@ -178,6 +232,29 @@
                 "  wakeup_stats <",
                 "    application_wakeups: 2",
                 "    duration_sec: 0",
+                "    ethertype_counts <",
+                "      key: 2048",
+                "      value: 5",
+                "    >",
+                "    ethertype_counts <",
+                "      key: 34525",
+                "      value: 5",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 6",
+                "      value: 3",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 17",
+                "      value: 5",
+                "    >",
+                "    ip_next_header_counts <",
+                "      key: 58",
+                "      value: 2",
+                "    >",
+                "    l2_broadcast_count: 0",
+                "    l2_multicast_count: 0",
+                "    l2_unicast_count: 10",
                 "    no_uid_wakeups: 2",
                 "    non_application_wakeups: 1",
                 "    root_wakeups: 2",
@@ -401,7 +478,7 @@
     Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
         return new Thread(() -> {
             try {
-                mNetdEventListenerService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
+                mService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
             } catch (Exception e) {
                 fail(e.toString());
             }
@@ -409,12 +486,13 @@
     }
 
     void dnsEvent(int netId, int type, int result, int latency) throws Exception {
-        mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
+        mService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
     }
 
-    void wakeupEvent(String iface, int uid) throws Exception {
+    void wakeupEvent(String iface, int uid, int ether, int ip, byte[] mac, String srcIp,
+            String dstIp, int sport, int dport, long now) throws Exception {
         String prefix = NetdEventListenerService.WAKEUP_EVENT_IFACE_PREFIX + iface;
-        mNetdEventListenerService.onWakeupEvent(prefix, uid, uid, 0);
+        mService.onWakeupEvent(prefix, uid, ether, ip, mac, srcIp, dstIp, sport, dport, now);
     }
 
     void asyncDump(long durationMs) throws Exception {
@@ -422,7 +500,7 @@
         final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
         new Thread(() -> {
             while (System.currentTimeMillis() < stop) {
-                mNetdEventListenerService.list(pw);
+                mService.list(pw);
             }
         }).start();
     }
@@ -431,7 +509,7 @@
     String flushStatistics() throws Exception {
         IpConnectivityMetrics metricsService =
                 new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
-        metricsService.mNetdListener = mNetdEventListenerService;
+        metricsService.mNetdListener = mService;
 
         StringWriter buffer = new StringWriter();
         PrintWriter writer = new PrintWriter(buffer);
@@ -453,7 +531,7 @@
     String[] listNetdEvent() throws Exception {
         StringWriter buffer = new StringWriter();
         PrintWriter writer = new PrintWriter(buffer);
-        mNetdEventListenerService.list(writer);
+        mService.list(writer);
         return buffer.toString().split("\\n");
     }
 
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index 921d853..5981401 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -235,8 +235,7 @@
         return false;
       }
     } else {
-      uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
-      if (!io::CopyFileToArchive(context, file, path, compression_flags, writer)) {
+      if (!io::CopyFileToArchivePreserveCompression(context, file, path, writer)) {
         return false;
       }
     }
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index a34d51b..2bd2405 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -26,58 +26,52 @@
 #include "format/binary/TableFlattener.h"
 #include "format/binary/XmlFlattener.h"
 #include "format/proto/ProtoDeserialize.h"
+#include "format/proto/ProtoSerialize.h"
 #include "io/BigBufferStream.h"
 #include "io/Util.h"
 #include "process/IResourceTableConsumer.h"
 #include "process/SymbolTable.h"
+#include "util/Util.h"
 
 using ::android::StringPiece;
+using ::android::base::StringPrintf;
 using ::std::unique_ptr;
 using ::std::vector;
 
 namespace aapt {
 
-class ISerializer {
+class IApkSerializer {
  public:
-  ISerializer(IAaptContext* context, const Source& source) : context_(context), source_(source) {}
+  IApkSerializer(IAaptContext* context, const Source& source) : context_(context), source_(source) {}
 
   virtual bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
                             IArchiveWriter* writer) = 0;
   virtual bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) = 0;
   virtual bool SerializeFile(const FileReference* file, IArchiveWriter* writer) = 0;
 
-  bool CopyFileToArchive(const FileReference* file, IArchiveWriter* writer) {
-    uint32_t compression_flags = file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
-    if (!io::CopyFileToArchive(context_, file->file, *file->path, compression_flags, writer)) {
-      context_->GetDiagnostics()->Error(DiagMessage(source_)
-                                        << "failed to copy file " << *file->path);
-      return false;
-    }
-
-    return true;
-  }
-
-  virtual ~ISerializer() = default;
+  virtual ~IApkSerializer() = default;
 
  protected:
   IAaptContext* context_;
   Source source_;
 };
 
-bool ConvertProtoApkToBinaryApk(IAaptContext* context, unique_ptr<LoadedApk> apk,
-                                ISerializer* serializer, IArchiveWriter* writer) {
+bool ConvertApk(IAaptContext* context, unique_ptr<LoadedApk> apk, IApkSerializer* serializer,
+                IArchiveWriter* writer) {
   if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/, writer)) {
     context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
                                      << "failed to serialize AndroidManifest.xml");
     return false;
   }
 
+  // Resource table
   if (!serializer->SerializeTable(apk->GetResourceTable(), writer)) {
     context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
                                      << "failed to serialize the resource table");
     return false;
   }
 
+  // Resources
   for (const auto& package : apk->GetResourceTable()->packages) {
     for (const auto& type : package->types) {
       for (const auto& entry : type->entries) {
@@ -86,7 +80,7 @@
           if (file != nullptr) {
             if (file->file == nullptr) {
               context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
-                                              << "no file associated with " << *file);
+                                               << "no file associated with " << *file);
               return false;
             }
 
@@ -100,18 +94,43 @@
       } // entry
     } // type
   } // package
+
+  // Other files
+  std::unique_ptr<io::IFileCollectionIterator> iterator = apk->GetFileCollection()->Iterator();
+  while (iterator->HasNext()) {
+    io::IFile* file = iterator->Next();
+
+    std::string path = file->GetSource().path;
+    // The name of the path has the format "<zip-file-name>@<path-to-file>".
+    path = path.substr(path.find('@') + 1);
+
+    // Manifest, resource table and resources have already been taken care of.
+    if (path == kAndroidManifestPath ||
+        path == kApkResourceTablePath ||
+        path == kProtoResourceTablePath ||
+        path.find("res/") == 0) {
+      continue;
+    }
+
+    if (!io::CopyFileToArchivePreserveCompression(context, file, path, writer)) {
+      context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
+                                       << "failed to copy file " << path);
+      return false;
+    }
+  }
+
   return true;
 }
 
 
-class BinarySerializer : public ISerializer {
+class BinaryApkSerializer : public IApkSerializer {
  public:
-  BinarySerializer(IAaptContext* context, const Source& source,
+  BinaryApkSerializer(IAaptContext* context, const Source& source,
                    const TableFlattenerOptions& options)
-      : ISerializer(context, source), tableFlattenerOptions_(options) {}
+      : IApkSerializer(context, source), tableFlattenerOptions_(options) {}
 
   bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
-                    IArchiveWriter* writer) {
+                    IArchiveWriter* writer) override {
     BigBuffer buffer(4096);
     XmlFlattenerOptions options = {};
     options.use_utf16 = utf16;
@@ -125,7 +144,7 @@
                                         writer);
   }
 
-  bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) {
+  bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
     BigBuffer buffer(4096);
     TableFlattener table_flattener(tableFlattenerOptions_, &buffer);
     if (!table_flattener.Consume(context_, table)) {
@@ -137,7 +156,7 @@
                                         ArchiveEntry::kAlign, writer);
   }
 
-  bool SerializeFile(const FileReference* file, IArchiveWriter* writer) {
+  bool SerializeFile(const FileReference* file, IArchiveWriter* writer) override {
     if (file->type == ResourceFile::Type::kProtoXml) {
       unique_ptr<io::InputStream> in = file->file->OpenInputStream();
       if (in == nullptr) {
@@ -165,11 +184,15 @@
 
       if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) {
         context_->GetDiagnostics()->Error(DiagMessage(source_)
-                                          << "failed to serialize proto XML " << *file->path);
+                                          << "failed to serialize to binary XML: " << *file->path);
         return false;
       }
     } else {
-      return CopyFileToArchive(file, writer);
+      if (!io::CopyFileToArchivePreserveCompression(context_, file->file, *file->path, writer)) {
+        context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                          << "failed to copy file " << *file->path);
+        return false;
+      }
     }
 
     return true;
@@ -178,7 +201,63 @@
  private:
   TableFlattenerOptions tableFlattenerOptions_;
 
-  DISALLOW_COPY_AND_ASSIGN(BinarySerializer);
+  DISALLOW_COPY_AND_ASSIGN(BinaryApkSerializer);
+};
+
+class ProtoApkSerializer : public IApkSerializer {
+ public:
+  ProtoApkSerializer(IAaptContext* context, const Source& source)
+      : IApkSerializer(context, source) {}
+
+  bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
+                    IArchiveWriter* writer) override {
+    pb::XmlNode pb_node;
+    SerializeXmlResourceToPb(*xml, &pb_node);
+    return io::CopyProtoToArchive(context_, &pb_node, path, ArchiveEntry::kCompress, writer);
+  }
+
+  bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
+    pb::ResourceTable pb_table;
+    SerializeTableToPb(*table, &pb_table);
+    return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath,
+                                  ArchiveEntry::kCompress, writer);
+  }
+
+  bool SerializeFile(const FileReference* file, IArchiveWriter* writer) override {
+    if (file->type == ResourceFile::Type::kBinaryXml) {
+      std::unique_ptr<io::IData> data = file->file->OpenAsData();
+      if (!data) {
+        context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                         << "failed to open file " << *file->path);
+        return false;
+      }
+
+      std::string error;
+      std::unique_ptr<xml::XmlResource> xml = xml::Inflate(data->data(), data->size(), &error);
+      if (xml == nullptr) {
+        context_->GetDiagnostics()->Error(DiagMessage(source_) << "failed to parse binary XML: "
+                                          << error);
+        return false;
+      }
+
+      if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) {
+        context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                          << "failed to serialize to proto XML: " << *file->path);
+        return false;
+      }
+    } else {
+      if (!io::CopyFileToArchivePreserveCompression(context_, file->file, *file->path, writer)) {
+        context_->GetDiagnostics()->Error(DiagMessage(source_)
+                                          << "failed to copy file " << *file->path);
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProtoApkSerializer);
 };
 
 class Context : public IAaptContext {
@@ -233,12 +312,20 @@
 };
 
 int Convert(const vector<StringPiece>& args) {
+
+  static const char* kOutputFormatProto = "proto";
+  static const char* kOutputFormatBinary = "binary";
+
   Context context;
   std::string output_path;
+  Maybe<std::string> output_format;
   TableFlattenerOptions options;
   Flags flags =
       Flags()
           .RequiredFlag("-o", "Output path", &output_path)
+          .OptionalFlag("--output-format", StringPrintf("Format of the output. Accepted values are "
+                        "'%s' and '%s'. When not set, defaults to '%s'.", kOutputFormatProto,
+                        kOutputFormatBinary, kOutputFormatBinary), &output_format)
           .OptionalSwitch("--enable-sparse-encoding",
                           "Enables encoding sparse entries using a binary search tree.\n"
                           "This decreases APK size at the cost of resource retrieval performance.",
@@ -274,8 +361,21 @@
   if (writer == nullptr) {
     return 1;
   }
-  BinarySerializer serializer(&context, apk->GetSource(), options);
-  return ConvertProtoApkToBinaryApk(&context, std::move(apk), &serializer, writer.get()) ? 0 : 1;
+
+  unique_ptr<IApkSerializer> serializer;
+  if (!output_format || output_format.value() == kOutputFormatBinary) {
+    serializer.reset(new BinaryApkSerializer(&context, apk->GetSource(), options));
+  } else if (output_format.value() == kOutputFormatProto) {
+    serializer.reset(new ProtoApkSerializer(&context, apk->GetSource()));
+  } else {
+    context.GetDiagnostics()->Error(DiagMessage(path)
+                                    << "Invalid value for flag --output-format: "
+                                    << output_format.value());
+    return 1;
+  }
+
+
+  return ConvertApk(&context, std::move(apk), serializer.get(), writer.get()) ? 0 : 1;
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 688b6a7..2bf91a5 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -256,10 +256,8 @@
 
         for (auto& entry : config_sorted_files) {
           FileReference* file_ref = entry.second;
-          uint32_t compression_flags =
-              file_ref->file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
-          if (!io::CopyFileToArchive(context_, file_ref->file, *file_ref->path, compression_flags,
-                                     writer)) {
+          if (!io::CopyFileToArchivePreserveCompression(context_, file_ref->file, *file_ref->path,
+                                                        writer)) {
             return false;
           }
         }
diff --git a/tools/aapt2/io/Util.cpp b/tools/aapt2/io/Util.cpp
index 7ee1016..9751632 100644
--- a/tools/aapt2/io/Util.cpp
+++ b/tools/aapt2/io/Util.cpp
@@ -48,6 +48,12 @@
   return CopyInputStreamToArchive(context, data.get(), out_path, compression_flags, writer);
 }
 
+bool CopyFileToArchivePreserveCompression(IAaptContext* context, io::IFile* file,
+                                          const std::string& out_path, IArchiveWriter* writer) {
+  uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
+  return CopyFileToArchive(context, file, out_path, compression_flags, writer);
+}
+
 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
                         const std::string& out_path, uint32_t compression_flags,
                         IArchiveWriter* writer) {
diff --git a/tools/aapt2/io/Util.h b/tools/aapt2/io/Util.h
index de2ab39..b07fb53 100644
--- a/tools/aapt2/io/Util.h
+++ b/tools/aapt2/io/Util.h
@@ -35,6 +35,9 @@
 bool CopyFileToArchive(IAaptContext* context, IFile* file, const std::string& out_path,
                        uint32_t compression_flags, IArchiveWriter* writer);
 
+bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file,
+                                          const std::string& out_path, IArchiveWriter* writer);
+
 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
                         const std::string& out_path, uint32_t compression_flags,
                         IArchiveWriter* writer);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 6350b72..eb29150 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -2,7 +2,7 @@
 
 #include "Collation.h"
 
-#include "frameworks/base/cmds/statsd/src/stats_events.pb.h"
+#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
 
 #include <set>
 #include <vector>
@@ -18,7 +18,7 @@
 namespace android {
 namespace stats_log_api_gen {
 
-using android::os::statsd::StatsEvent;
+using android::os::statsd::Atom;
 
 // TODO: Support WorkSources
 
@@ -582,7 +582,7 @@
 
     // Collate the parameters
     Atoms atoms;
-    int errorCount = collate_atoms(StatsEvent::descriptor(), &atoms);
+    int errorCount = collate_atoms(Atom::descriptor(), &atoms);
     if (errorCount != 0) {
         return 1;
     }
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 2311a11..6686158 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto2";
 
-import "frameworks/base/cmds/statsd/src/stats_events.proto";
+import "frameworks/base/cmds/statsd/src/atoms.proto";
 
 package android.stats_log_api_gen;
 
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 551e4df..26a2bdd 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -66,11 +66,11 @@
 
     List<OsuProvider> getMatchingOsuProviders(in ScanResult scanResult);
 
-    int addOrUpdateNetwork(in WifiConfiguration config);
+    int addOrUpdateNetwork(in WifiConfiguration config, String packageName);
 
-    boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config);
+    boolean addOrUpdatePasspointConfiguration(in PasspointConfiguration config, String packageName);
 
-    boolean removePasspointConfiguration(in String fqdn);
+    boolean removePasspointConfiguration(in String fqdn, String packageName);
 
     List<PasspointConfiguration> getPasspointConfigurations();
 
@@ -80,21 +80,21 @@
 
     void deauthenticateNetwork(long holdoff, boolean ess);
 
-    boolean removeNetwork(int netId);
+    boolean removeNetwork(int netId, String packageName);
 
-    boolean enableNetwork(int netId, boolean disableOthers);
+    boolean enableNetwork(int netId, boolean disableOthers, String packageName);
 
-    boolean disableNetwork(int netId);
+    boolean disableNetwork(int netId, String packageName);
 
-    void startScan(in ScanSettings requested, in WorkSource ws, in String packageName);
+    void startScan(in ScanSettings requested, in WorkSource ws, String packageName);
 
     List<ScanResult> getScanResults(String callingPackage);
 
-    void disconnect();
+    void disconnect(String packageName);
 
-    void reconnect();
+    void reconnect(String packageName);
 
-    void reassociate();
+    void reassociate(String packageName);
 
     WifiInfo getConnectionInfo(String callingPackage);
 
@@ -108,7 +108,7 @@
 
     boolean isDualBandSupported();
 
-    boolean saveConfiguration();
+    boolean saveConfiguration(String packageName);
 
     DhcpInfo getDhcpInfo();
 
@@ -134,9 +134,9 @@
 
     boolean stopSoftAp();
 
-    int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, in String packageName);
+    int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, String packageName);
 
-    void stopLocalOnlyHotspot();
+    void stopLocalOnlyHotspot(String packageName);
 
     void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
 
@@ -146,9 +146,9 @@
 
     WifiConfiguration getWifiApConfiguration();
 
-    void setWifiApConfiguration(in WifiConfiguration wifiConfig);
+    void setWifiApConfiguration(in WifiConfiguration wifiConfig, String packageName);
 
-    Messenger getWifiServiceMessenger();
+    Messenger getWifiServiceMessenger(String packageName);
 
     void enableTdls(String remoteIPAddress, boolean enable);
 
@@ -166,16 +166,16 @@
     void setAllowScansWithTraffic(int enabled);
     int getAllowScansWithTraffic();
 
-    boolean setEnableAutoJoinWhenAssociated(boolean enabled);
+    boolean setEnableAutoJoinWhenAssociated(boolean enabled, String packageName);
     boolean getEnableAutoJoinWhenAssociated();
 
     void enableWifiConnectivityManager(boolean enabled);
 
     WifiConnectionStatistics getConnectionStatistics();
 
-    void disableEphemeralNetwork(String SSID);
+    void disableEphemeralNetwork(String SSID, String packageName);
 
-    void factoryReset();
+    void factoryReset(String packageName);
 
     Network getCurrentNetwork();
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 04efd56..68e6203 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1127,7 +1127,7 @@
      */
     private int addOrUpdateNetwork(WifiConfiguration config) {
         try {
-            return mService.addOrUpdateNetwork(config);
+            return mService.addOrUpdateNetwork(config, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1148,7 +1148,7 @@
      */
     public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
         try {
-            if (!mService.addOrUpdatePasspointConfiguration(config)) {
+            if (!mService.addOrUpdatePasspointConfiguration(config, mContext.getOpPackageName())) {
                 throw new IllegalArgumentException();
             }
         } catch (RemoteException e) {
@@ -1165,7 +1165,7 @@
      */
     public void removePasspointConfiguration(String fqdn) {
         try {
-            if (!mService.removePasspointConfiguration(fqdn)) {
+            if (!mService.removePasspointConfiguration(fqdn, mContext.getOpPackageName())) {
                 throw new IllegalArgumentException();
             }
         } catch (RemoteException e) {
@@ -1251,7 +1251,7 @@
      */
     public boolean removeNetwork(int netId) {
         try {
-            return mService.removeNetwork(netId);
+            return mService.removeNetwork(netId, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1297,7 +1297,7 @@
 
         boolean success;
         try {
-            success = mService.enableNetwork(netId, attemptConnect);
+            success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1323,7 +1323,7 @@
      */
     public boolean disableNetwork(int netId) {
         try {
-            return mService.disableNetwork(netId);
+            return mService.disableNetwork(netId, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1336,7 +1336,7 @@
      */
     public boolean disconnect() {
         try {
-            mService.disconnect();
+            mService.disconnect(mContext.getOpPackageName());
             return true;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1351,7 +1351,7 @@
      */
     public boolean reconnect() {
         try {
-            mService.reconnect();
+            mService.reconnect(mContext.getOpPackageName());
             return true;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1366,7 +1366,7 @@
      */
     public boolean reassociate() {
         try {
-            mService.reassociate();
+            mService.reassociate(mContext.getOpPackageName());
             return true;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1739,7 +1739,7 @@
     @Deprecated
     public boolean saveConfiguration() {
         try {
-            return mService.saveConfiguration();
+            return mService.saveConfiguration(mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2056,7 +2056,7 @@
             }
             mLOHSCallbackProxy = null;
             try {
-                mService.stopLocalOnlyHotspot();
+                mService.stopLocalOnlyHotspot(mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -2175,7 +2175,7 @@
     @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
     public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
         try {
-            mService.setWifiApConfiguration(wifiConfig);
+            mService.setWifiApConfiguration(wifiConfig, mContext.getOpPackageName());
             return true;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2947,7 +2947,7 @@
     public void disableEphemeralNetwork(String SSID) {
         if (SSID == null) throw new IllegalArgumentException("SSID cannot be null");
         try {
-            mService.disableEphemeralNetwork(SSID);
+            mService.disableEphemeralNetwork(SSID, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2986,7 +2986,7 @@
      */
     public Messenger getWifiServiceMessenger() {
         try {
-            return mService.getWifiServiceMessenger();
+            return mService.getWifiServiceMessenger(mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3516,7 +3516,7 @@
      */
     public void factoryReset() {
         try {
-            mService.factoryReset();
+            mService.factoryReset(mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3543,7 +3543,7 @@
      */
     public boolean setEnableAutoJoinWhenAssociated(boolean enabled) {
         try {
-            return mService.setEnableAutoJoinWhenAssociated(enabled);
+            return mService.setEnableAutoJoinWhenAssociated(enabled, mContext.getOpPackageName());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
index e1ad783..3e37af0 100644
--- a/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
+++ b/wifi/java/android/net/wifi/rtt/IWifiRttManager.aidl
@@ -16,6 +16,8 @@
 
 package android.net.wifi.rtt;
 
+import android.os.WorkSource;
+
 import android.net.wifi.rtt.IRttCallback;
 import android.net.wifi.rtt.RangingRequest;
 
@@ -25,6 +27,7 @@
 interface IWifiRttManager
 {
     boolean isAvailable();
-    void startRanging(in IBinder binder, in String callingPackage, in RangingRequest request,
-            in IRttCallback callback);
+    void startRanging(in IBinder binder, in String callingPackage, in WorkSource workSource,
+            in RangingRequest request, in IRttCallback callback);
+    void cancelRanging(in WorkSource workSource);
 }
diff --git a/wifi/java/android/net/wifi/rtt/WifiRttManager.java b/wifi/java/android/net/wifi/rtt/WifiRttManager.java
index c7c0923..128d6c9 100644
--- a/wifi/java/android/net/wifi/rtt/WifiRttManager.java
+++ b/wifi/java/android/net/wifi/rtt/WifiRttManager.java
@@ -3,16 +3,19 @@
 import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
 import static android.Manifest.permission.ACCESS_WIFI_STATE;
 import static android.Manifest.permission.CHANGE_WIFI_STATE;
+import static android.Manifest.permission.LOCATION_HARDWARE;
 
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.WorkSource;
 import android.util.Log;
 
 import java.util.List;
@@ -94,21 +97,63 @@
     @RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, CHANGE_WIFI_STATE, ACCESS_WIFI_STATE})
     public void startRanging(RangingRequest request, RangingResultCallback callback,
             @Nullable Handler handler) {
+        startRanging(null, request, callback, handler);
+    }
+
+    /**
+     * Initiate a request to range to a set of devices specified in the {@link RangingRequest}.
+     * Results will be returned in the {@link RangingResultCallback} set of callbacks.
+     *
+     * @param workSource A mechanism to specify an alternative work-source for the request.
+     * @param request  A request specifying a set of devices whose distance measurements are
+     *                 requested.
+     * @param callback A callback for the result of the ranging request.
+     * @param handler  The Handler on whose thread to execute the callbacks of the {@code
+     *                 callback} object. If a null is provided then the application's main thread
+     *                 will be used.
+     *
+     * @hide (@SystemApi)
+     */
+    @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_COARSE_LOCATION, CHANGE_WIFI_STATE,
+            ACCESS_WIFI_STATE})
+    public void startRanging(@Nullable WorkSource workSource, RangingRequest request,
+            RangingResultCallback callback, @Nullable Handler handler) {
         if (VDBG) {
-            Log.v(TAG, "startRanging: request=" + request + ", callback=" + callback + ", handler="
-                    + handler);
+            Log.v(TAG, "startRanging: workSource=" + workSource + ", request=" + request
+                    + ", callback=" + callback + ", handler=" + handler);
         }
 
         Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper();
         Binder binder = new Binder();
         try {
-            mService.startRanging(binder, mContext.getOpPackageName(), request,
+            mService.startRanging(binder, mContext.getOpPackageName(), workSource, request,
                     new RttCallbackProxy(looper, callback));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /**
+     * Cancel all ranging requests for the specified work sources. The requests have been requested
+     * using {@link #startRanging(WorkSource, RangingRequest, RangingResultCallback, Handler)}.
+     *
+     * @param workSource The work-sources of the requesters.
+     *
+     * @hide (@SystemApi)
+     */
+    @RequiresPermission(allOf = {LOCATION_HARDWARE})
+    public void cancelRanging(WorkSource workSource) {
+        if (VDBG) {
+            Log.v(TAG, "cancelRanging: workSource=" + workSource);
+        }
+
+        try {
+            mService.cancelRanging(workSource);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private static class RttCallbackProxy extends IRttCallback.Stub {
         private final Handler mHandler;
         private final RangingResultCallback mCallback;
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index ee6f12b..1364224 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -136,7 +136,7 @@
 
         assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
         callback.mRes.close();
-        verify(mWifiService).stopLocalOnlyHotspot();
+        verify(mWifiService).stopLocalOnlyHotspot(TEST_PACKAGE_NAME);
     }
 
     /**
@@ -156,7 +156,7 @@
             assertEquals(mApConfig, res.getWifiConfiguration());
         }
 
-        verify(mWifiService).stopLocalOnlyHotspot();
+        verify(mWifiService).stopLocalOnlyHotspot(TEST_PACKAGE_NAME);
     }
 
     /**
@@ -547,7 +547,7 @@
                 anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
+        verify(mWifiService).stopLocalOnlyHotspot(TEST_PACKAGE_NAME);
     }
 
     /**
@@ -569,7 +569,7 @@
                 anyString())).thenReturn(REQUEST_REGISTERED);
         mWifiManager.startLocalOnlyHotspot(callback, mHandler);
         mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService).stopLocalOnlyHotspot();
+        verify(mWifiService).stopLocalOnlyHotspot(TEST_PACKAGE_NAME);
         mLooper.dispatchAll();
         assertEquals(ERROR_NOT_SET, callback.mFailureReason);
         assertFalse(callback.mOnStartedCalled);
@@ -593,7 +593,7 @@
         assertFalse(callback.mOnStoppedCalled);
         assertEquals(null, callback.mRes);
         mWifiManager.cancelLocalOnlyHotspotRequest();
-        verify(mWifiService, never()).stopLocalOnlyHotspot();
+        verify(mWifiService, never()).stopLocalOnlyHotspot(anyString());
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
index 33bd982..300d425 100644
--- a/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
@@ -85,8 +85,8 @@
 
         // verify ranging request passed to service
         mDut.startRanging(request, callbackMock, mMockLooperHandler);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(request),
-                callbackCaptor.capture());
+        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null),
+                eq(request), callbackCaptor.capture());
 
         // service calls back with success
         callbackCaptor.getValue().onRangingResults(results);
@@ -109,8 +109,8 @@
 
         // verify ranging request passed to service
         mDut.startRanging(request, callbackMock, mMockLooperHandler);
-        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(request),
-                callbackCaptor.capture());
+        verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(null),
+                eq(request), callbackCaptor.capture());
 
         // service calls back with failure code
         callbackCaptor.getValue().onRangingFailure(failureCode);