Merge "Handle error result returned from MTP API correctly." into nyc-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d1f5143..631a129 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
@@ -1305,6 +1306,12 @@
          */
         public boolean isDockable;
 
+        /**
+         * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
+         * @hide
+         */
+        public int resizeMode;
+
         public RecentTaskInfo() {
         }
 
@@ -1349,6 +1356,7 @@
                 dest.writeInt(0);
             }
             dest.writeInt(isDockable ? 1 : 0);
+            dest.writeInt(resizeMode);
         }
 
         public void readFromParcel(Parcel source) {
@@ -1372,6 +1380,7 @@
             bounds = source.readInt() > 0 ?
                     Rect.CREATOR.createFromParcel(source) : null;
             isDockable = source.readInt() == 1;
+            resizeMode = source.readInt();
         }
 
         public static final Creator<RecentTaskInfo> CREATOR
@@ -1560,6 +1569,12 @@
          */
         public boolean isDockable;
 
+        /**
+         * The resize mode of the task. See {@link ActivityInfo#resizeMode}.
+         * @hide
+         */
+        public int resizeMode;
+
         public RunningTaskInfo() {
         }
 
@@ -1583,6 +1598,7 @@
             dest.writeInt(numActivities);
             dest.writeInt(numRunning);
             dest.writeInt(isDockable ? 1 : 0);
+            dest.writeInt(resizeMode);
         }
 
         public void readFromParcel(Parcel source) {
@@ -1599,6 +1615,7 @@
             numActivities = source.readInt();
             numRunning = source.readInt();
             isDockable = source.readInt() != 0;
+            resizeMode = source.readInt();
         }
 
         public static final Creator<RunningTaskInfo> CREATOR = new Creator<RunningTaskInfo>() {
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 3564e11..e93e58d 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -48,6 +48,9 @@
         implements KeyListener {
     /* package */ static final Object OLD_SEL_START = new NoCopySpan.Concrete();
 
+    private static final int LINE_FEED = 0x0A;
+    private static final int CARRIAGE_RETURN = 0x0D;
+
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
@@ -110,34 +113,37 @@
         // Initial state
         final int STATE_START = 0;
 
+        // The offset is immediately before line feed.
+        final int STATE_LF = 1;
+
         // The offset is immediately before a KEYCAP.
-        final int STATE_BEFORE_KEYCAP = 1;
+        final int STATE_BEFORE_KEYCAP = 2;
         // The offset is immediately before a variation selector and a KEYCAP.
-        final int STATE_BEFORE_VS_AND_KEYCAP = 2;
+        final int STATE_BEFORE_VS_AND_KEYCAP = 3;
 
         // The offset is immediately before an emoji modifier.
-        final int STATE_BEFORE_EMOJI_MODIFIER = 3;
+        final int STATE_BEFORE_EMOJI_MODIFIER = 4;
         // The offset is immediately before a variation selector and an emoji modifier.
-        final int STATE_BEFORE_VS_AND_EMOJI_MODIFIER = 4;
+        final int STATE_BEFORE_VS_AND_EMOJI_MODIFIER = 5;
 
         // The offset is immediately before a variation selector.
-        final int STATE_BEFORE_VS = 5;
+        final int STATE_BEFORE_VS = 6;
 
         // The offset is immediately before a ZWJ emoji.
-        final int STATE_BEFORE_ZWJ_EMOJI = 6;
+        final int STATE_BEFORE_ZWJ_EMOJI = 7;
         // The offset is immediately before a ZWJ that were seen before a ZWJ emoji.
-        final int STATE_BEFORE_ZWJ = 7;
+        final int STATE_BEFORE_ZWJ = 8;
         // The offset is immediately before a variation selector and a ZWJ that were seen before a
         // ZWJ emoji.
-        final int STATE_BEFORE_VS_AND_ZWJ = 8;
+        final int STATE_BEFORE_VS_AND_ZWJ = 9;
 
         // The number of following RIS code points is odd.
-        final int STATE_ODD_NUMBERED_RIS = 9;
+        final int STATE_ODD_NUMBERED_RIS = 10;
         // The number of following RIS code points is even.
-        final int STATE_EVEN_NUMBERED_RIS = 10;
+        final int STATE_EVEN_NUMBERED_RIS = 11;
 
         // The state machine has been stopped.
-        final int STATE_FINISHED = 11;
+        final int STATE_FINISHED = 12;
 
         int deleteCharCount = 0;  // Char count to be deleted by backspace.
         int lastSeenVSCharCount = 0;  // Char count of previous variation selector.
@@ -152,7 +158,9 @@
             switch (state) {
                 case STATE_START:
                     deleteCharCount = Character.charCount(codePoint);
-                    if (isVariationSelector(codePoint)) {
+                    if (codePoint == LINE_FEED) {
+                        state = STATE_LF;
+                    } else if (isVariationSelector(codePoint)) {
                         state = STATE_BEFORE_VS;
                     } else if (Emoji.isZwjEmoji(codePoint)) {
                         state = STATE_BEFORE_ZWJ_EMOJI;
@@ -166,6 +174,11 @@
                         state = STATE_FINISHED;
                     }
                     break;
+                case STATE_LF:
+                    if (codePoint == CARRIAGE_RETURN) {
+                        ++deleteCharCount;
+                    }
+                    state = STATE_FINISHED;
                 case STATE_ODD_NUMBERED_RIS:
                     if (Emoji.isRegionalIndicatorSymbol(codePoint)) {
                         deleteCharCount += 2; /* Char count of RIS */
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 001d1f2..73b9d02 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -32,7 +32,8 @@
     /**
      * Docks the top-most task and opens recents.
      */
-    boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds);
+    boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds,
+            int metricsDockAction);
 
     /**
      * Called during a drag-from-navbar-in gesture.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 82daaa6..b2d7b48 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -36,10 +37,13 @@
 import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.MutableBoolean;
 import android.view.Display;
 import android.view.View;
 import android.widget.Toast;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
@@ -78,6 +82,10 @@
     private final static String ACTION_HIDE_RECENTS = "com.android.systemui.recents.ACTION_HIDE";
     private final static String ACTION_TOGGLE_RECENTS = "com.android.systemui.recents.ACTION_TOGGLE";
 
+    private static final String COUNTER_WINDOW_SUPPORTED = "window_enter_supported";
+    private static final String COUNTER_WINDOW_UNSUPPORTED = "window_enter_unsupported";
+    private static final String COUNTER_WINDOW_INCOMPATIBLE = "window_enter_incompatible";
+
     private static SystemServicesProxy sSystemServicesProxy;
     private static RecentsDebugFlags sDebugFlags;
     private static RecentsTaskLoader sTaskLoader;
@@ -393,7 +401,8 @@
     }
 
     @Override
-    public boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds) {
+    public boolean dockTopTask(int dragMode, int stackCreateMode, Rect initialBounds,
+            int metricsDockAction) {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
@@ -413,7 +422,12 @@
         boolean screenPinningActive = ssp.isScreenPinningActive();
         boolean isTopTaskHome = topTask != null && SystemServicesProxy.isHomeStack(topTask.stackId);
         if (topTask != null && !isTopTaskHome && !screenPinningActive) {
+            logDockAttempt(mContext, topTask.topActivity, topTask.resizeMode);
             if (topTask.isDockable) {
+                if (metricsDockAction != -1) {
+                    MetricsLogger.action(mContext, metricsDockAction,
+                            topTask.topActivity.flattenToShortString());
+                }
                 if (sSystemServicesProxy.isSystemUser(currentUser)) {
                     mImpl.dockTopTask(topTask.id, dragMode, stackCreateMode, initialBounds);
                 } else {
@@ -444,6 +458,26 @@
         }
     }
 
+    public static void logDockAttempt(Context ctx, ComponentName activity, int resizeMode) {
+        if (resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE) {
+            MetricsLogger.action(ctx, MetricsEvent.ACTION_WINDOW_DOCK_UNRESIZABLE,
+                    activity.flattenToShortString());
+        }
+        MetricsLogger.count(ctx, getMetricsCounterForResizeMode(resizeMode), 1);
+    }
+
+    private static String getMetricsCounterForResizeMode(int resizeMode) {
+        switch (resizeMode) {
+            case ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE:
+                return COUNTER_WINDOW_UNSUPPORTED;
+            case ActivityInfo.RESIZE_MODE_RESIZEABLE:
+            case ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE:
+                return COUNTER_WINDOW_SUPPORTED;
+            default:
+                return COUNTER_WINDOW_INCOMPATIBLE;
+        }
+    }
+
     @Override
     public void onDraggingInRecents(float distanceFromTop) {
         if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 7aeff1f..af1628b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -206,7 +206,7 @@
             Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
                     thumbnail, title, titleDescription, dismissDescription, appInfoDescription,
                     activityColor, backgroundColor, isLaunchTarget, isStackTask, isSystemApp,
-                    t.isDockable, t.bounds, t.taskDescription);
+                    t.isDockable, t.bounds, t.taskDescription, t.resizeMode, t.topActivity);
 
             allTasks.add(task);
             affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 24eeaf2..9f9c48f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.Rect;
@@ -174,6 +175,15 @@
     @ViewDebug.ExportedProperty(category="recents")
     public boolean isDockable;
 
+    /**
+     * Resize mode. See {@link ActivityInfo#resizeMode}.
+     */
+    @ViewDebug.ExportedProperty(category="recents")
+    public int resizeMode;
+
+    @ViewDebug.ExportedProperty(category="recents")
+    public ComponentName topActivity;
+
     private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>();
 
     public Task() {
@@ -184,7 +194,8 @@
                 Bitmap thumbnail, String title, String titleDescription, String dismissDescription,
                 String appInfoDescription, int colorPrimary, int colorBackground,
                 boolean isLaunchTarget, boolean isStackTask, boolean isSystemApp,
-                boolean isDockable, Rect bounds, ActivityManager.TaskDescription taskDescription) {
+                boolean isDockable, Rect bounds, ActivityManager.TaskDescription taskDescription,
+                int resizeMode, ComponentName topActivity) {
         boolean isInAffiliationGroup = (affiliationTaskId != key.id);
         boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
         this.key = key;
@@ -206,6 +217,8 @@
         this.isStackTask = isStackTask;
         this.isSystemApp = isSystemApp;
         this.isDockable = isDockable;
+        this.resizeMode = resizeMode;
+        this.topActivity = topActivity;
     }
 
     /**
@@ -231,6 +244,8 @@
         this.isStackTask = o.isStackTask;
         this.isSystemApp = o.isSystemApp;
         this.isDockable = o.isDockable;
+        this.resizeMode = o.resizeMode;
+        this.topActivity = o.topActivity;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 21a43d5..59b7560 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -540,7 +540,8 @@
                     mTransitionHelper.wrapStartedListener(startedListener),
                     true /* scaleUp */);
 
-            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP);
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_DRAG_DROP,
+                    event.task.topActivity.flattenToShortString());
         } else {
             // Animate the overlay alpha back to 0
             updateVisibleDockRegions(null, true /* isDefaultDockState */, -1,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 22acb88..5fbc037 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -41,7 +41,6 @@
 
 import java.util.ArrayList;
 
-
 /**
  * Represents the dock regions for each orientation.
  */
@@ -163,6 +162,7 @@
         mVisibleDockStates.clear();
         if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask()
                 && mDividerSnapAlgorithm.isSplitScreenFeasible()) {
+            Recents.logDockAttempt(mRv.getContext(), event.task.topActivity, event.task.resizeMode);
             if (!event.task.isDockable) {
                 EventBus.getDefault().send(new ShowIncompatibleAppOverlayEvent());
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 69dcabe..0aeb7b4 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -102,8 +102,8 @@
                 int dockMode = (shortcutCode == SC_DOCK_LEFT)
                         ? ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT
                         : ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
-                recents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, dockMode, null);
-                MetricsLogger.action(mContext, MetricsEvent.WINDOW_DOCK_SHORTCUTS);
+                recents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, dockMode, null,
+                        MetricsEvent.WINDOW_DOCK_SHORTCUTS);
             } else {
                 // If there is already a docked window, we respond by resizing the docking pane.
                 DividerView dividerView = getComponent(Divider.class).getView();
@@ -115,7 +115,8 @@
                 DividerSnapAlgorithm.SnapTarget target = snapAlgorithm.cycleNonDismissTarget(
                         currentTarget, increment);
                 dividerView.startDragging(true /* animate */, false /* touching */);
-                dividerView.stopDragging(target.position, 0f, true /* avoidDismissStart */);
+                dividerView.stopDragging(target.position, 0f, true /* avoidDismissStart */,
+                        true /* logMetrics */);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "handleDockKey() failed.");
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 141f60b..a6c75e8 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -54,11 +54,14 @@
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
 import com.android.internal.policy.DockedDividerUtils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.recents.Constants.Metrics;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
@@ -80,7 +83,13 @@
     static final long TOUCH_ANIMATION_DURATION = 150;
     static final long TOUCH_RELEASE_ANIMATION_DURATION = 200;
 
-    private static final String TAG = "DividerView";
+    private static final int LOG_VALUE_RESIZE_50_50 = 0;
+    private static final int LOG_VALUE_RESIZE_DOCKED_SMALLER = 1;
+    private static final int LOG_VALUE_RESIZE_DOCKED_LARGER = 2;
+
+    private static final int LOG_VALUE_UNDOCK_MAX_DOCKED = 0;
+    private static final int LOG_VALUE_UNDOCK_MAX_OTHER = 1;
+
 
     private static final int TASK_POSITION_SAME = Integer.MAX_VALUE;
     private static final boolean SWAPPING_ENABLED = false;
@@ -313,9 +322,10 @@
         return mDockSide != WindowManager.DOCKED_INVALID;
     }
 
-    public void stopDragging(int position, float velocity, boolean avoidDismissStart) {
+    public void stopDragging(int position, float velocity, boolean avoidDismissStart,
+            boolean logMetrics) {
         mHandle.setTouching(false, true /* animate */);
-        fling(position, velocity, avoidDismissStart);
+        fling(position, velocity, avoidDismissStart, logMetrics);
         mWindowManager.setSlippery(true);
         releaseBackground();
     }
@@ -413,22 +423,54 @@
                 mVelocityTracker.computeCurrentVelocity(1000);
                 int position = calculatePosition(x, y);
                 stopDragging(position, isHorizontalDivision() ? mVelocityTracker.getYVelocity()
-                        : mVelocityTracker.getXVelocity(), false /* avoidDismissStart */);
+                        : mVelocityTracker.getXVelocity(), false /* avoidDismissStart */,
+                        true /* log */);
                 mMoving = false;
                 break;
         }
         return true;
     }
 
+    private void logResizeEvent(SnapTarget snapTarget) {
+        if (snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
+            MetricsLogger.action(
+                    mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideTopLeft(mDockSide)
+                            ? LOG_VALUE_UNDOCK_MAX_OTHER
+                            : LOG_VALUE_UNDOCK_MAX_DOCKED);
+        } else if (snapTarget == mSnapAlgorithm.getDismissEndTarget()) {
+            MetricsLogger.action(
+                    mContext, MetricsEvent.ACTION_WINDOW_UNDOCK_MAX, dockSideBottomRight(mDockSide)
+                            ? LOG_VALUE_UNDOCK_MAX_OTHER
+                            : LOG_VALUE_UNDOCK_MAX_DOCKED);
+        } else if (snapTarget == mSnapAlgorithm.getMiddleTarget()) {
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
+                    LOG_VALUE_RESIZE_50_50);
+        } else if (snapTarget == mSnapAlgorithm.getFirstSplitTarget()) {
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
+                    dockSideTopLeft(mDockSide)
+                            ? LOG_VALUE_RESIZE_DOCKED_SMALLER
+                            : LOG_VALUE_RESIZE_DOCKED_LARGER);
+        } else if (snapTarget == mSnapAlgorithm.getLastSplitTarget()) {
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_RESIZE,
+                    dockSideTopLeft(mDockSide)
+                            ? LOG_VALUE_RESIZE_DOCKED_LARGER
+                            : LOG_VALUE_RESIZE_DOCKED_SMALLER);
+        }
+    }
+
     private void convertToScreenCoordinates(MotionEvent event) {
         event.setLocation(event.getRawX(), event.getRawY());
     }
 
-    private void fling(int position, float velocity, boolean avoidDismissStart) {
+    private void fling(int position, float velocity, boolean avoidDismissStart,
+            boolean logMetrics) {
         SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(position, velocity);
         if (avoidDismissStart && snapTarget == mSnapAlgorithm.getDismissStartTarget()) {
             snapTarget = mSnapAlgorithm.getFirstSplitTarget();
         }
+        if (logMetrics) {
+            logResizeEvent(snapTarget);
+        }
         ValueAnimator anim = getFlingAnimator(position, snapTarget);
         mFlingAnimationUtils.apply(anim, position, snapTarget.position, velocity);
         anim.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3ac7b26..11a7048 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1230,7 +1230,7 @@
 
     @Override
     public void toggleSplitScreen() {
-        toggleSplitScreenMode();
+        toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
     }
 
     @Override
@@ -1306,9 +1306,12 @@
     /**
      * Toggle docking the app window
      *
-     * @return {@code true} if the app window is docked after the toggle, {@code false} otherwise.
+     * @param metricsDockAction the action to log when docking is successful, or -1 to not log
+     *                          anything on successful docking
+     * @param metricsUndockAction the action to log when undocking, or -1 to not log anything when
+     *                            undocking
      */
-    protected abstract boolean toggleSplitScreenMode();
+    protected abstract void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction);
 
     /** Proxy for RecentsComponent */
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index bb03454..583a63e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -214,15 +214,14 @@
                         < mContext.getResources().getDisplayMetrics().widthPixels / 2) {
                     createMode = ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
                 }
-                boolean docked = mRecentsComponent.dockTopTask(dragMode, createMode, initialBounds);
+                boolean docked = mRecentsComponent.dockTopTask(dragMode, createMode, initialBounds,
+                        MetricsEvent.ACTION_WINDOW_DOCK_SWIPE);
                 if (docked) {
                     mDragMode = dragMode;
                     if (mDragMode == DRAG_MODE_DIVIDER) {
                         mDivider.getView().startDragging(false /* animate */, true /* touching*/);
                     }
                     mDockWindowTouchSlopExceeded = true;
-                    MetricsLogger.action(mContext, MetricsEvent.ACTION_WINDOW_DOCK_SWIPE);
-
                     return true;
                 }
             }
@@ -250,7 +249,7 @@
                         mIsVertical
                                 ? mVelocityTracker.getXVelocity()
                                 : mVelocityTracker.getYVelocity(),
-                        true /* avoidDismissStart */);
+                        true /* avoidDismissStart */, false /* logMetrics */);
             } else if (mDragMode == DRAG_MODE_RECENTS) {
                 mRecentsComponent.onDraggingInRecentsEnded(mVelocityTracker.getYVelocity());
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f68b24b..5423f9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1177,31 +1177,26 @@
                 return false;
             }
 
-            boolean initiallyDocked = WindowManagerProxy.getInstance().getDockSide()
-                    == WindowManager.DOCKED_INVALID;
-            boolean dockedAtEnd = toggleSplitScreenMode();
-            if (dockedAtEnd != initiallyDocked) {
-                int logAction = dockedAtEnd ? MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS
-                        : MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS;
-                MetricsLogger.action(mContext, logAction);
-                return true;
-            }
-            return false;
+            toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
+                    MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
+            return true;
         }
     };
 
     @Override
-    protected boolean toggleSplitScreenMode() {
+    protected void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
         if (mRecents == null) {
-            return false;
+            return;
         }
         int dockSide = WindowManagerProxy.getInstance().getDockSide();
         if (dockSide == WindowManager.DOCKED_INVALID) {
-            return mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
-                    ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null);
+            mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE,
+                    ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
         } else {
             EventBus.getDefault().send(new UndockingTaskEvent());
-            return false;
+            if (metricsUndockAction != -1) {
+                MetricsLogger.action(mContext, metricsUndockAction);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 450001f..acef81b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -127,8 +127,7 @@
     }
 
     @Override
-    protected boolean toggleSplitScreenMode() {
-        return false;
+    protected void toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
     }
 
     @Override
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index ea3cffe..afea7f3 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2138,6 +2138,20 @@
     // Settings > Apps > Gear > Special Access > Premium SMS access
     PREMIUM_SMS_ACCESS = 388;
 
+    // Logged when the user resizes the docked stack. Arguments:
+    // 0: Split 50:50
+    // 1: Docked smaller
+    // 2: Docked larger
+    ACTION_WINDOW_DOCK_RESIZE = 389;
+
+    // User exits split-screen by dragging the divider to the side of the screen. Arguments
+    // 0: Docked gets maximized
+    // 1: Fullscreen gets maximized
+    ACTION_WINDOW_UNDOCK_MAX = 390;
+
+    // User tried to dock an unresizable app.
+    ACTION_WINDOW_DOCK_UNRESIZABLE = 391;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 05e4245..4791818 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -91,6 +91,8 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
+
 import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
 
@@ -127,9 +129,34 @@
 public class AccountManagerService
         extends IAccountManager.Stub
         implements RegisteredServicesCacheListener<AuthenticatorDescription> {
-
     private static final String TAG = "AccountManagerService";
 
+    public static class Lifecycle extends SystemService {
+        private AccountManagerService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mService = new AccountManagerService(getContext());
+            publishBinderService(Context.ACCOUNT_SERVICE, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mService.systemReady();
+            }
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+    }
+
     private static final String DATABASE_NAME = "accounts.db";
     private static final int PRE_N_DATABASE_VERSION = 9;
     private static final int CE_DATABASE_VERSION = 10;
@@ -340,15 +367,12 @@
 
         IntentFilter userFilter = new IntentFilter();
         userFilter.addAction(Intent.ACTION_USER_REMOVED);
-        userFilter.addAction(Intent.ACTION_USER_UNLOCKED);
         mContext.registerReceiverAsUser(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
                 String action = intent.getAction();
                 if (Intent.ACTION_USER_REMOVED.equals(action)) {
                     onUserRemoved(intent);
-                } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
-                    onUserUnlocked(intent);
                 }
             }
         }, UserHandle.ALL, userFilter, null, null);
@@ -654,7 +678,10 @@
 
     @VisibleForTesting
     void onUserUnlocked(Intent intent) {
-        int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+        onUnlockUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1));
+    }
+
+    void onUnlockUser(int userId) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "onUserUnlocked " + userId);
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3ec51e3..c01b4f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8792,6 +8792,7 @@
             rti.bounds = new Rect(tr.mBounds);
         }
         rti.isDockable = tr.canGoInDockedStack();
+        rti.resizeMode = tr.mResizeMode;
 
         ActivityRecord base = null;
         ActivityRecord top = null;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2e9947a..837a1c1 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4776,6 +4776,7 @@
             ci.numActivities = numActivities;
             ci.numRunning = numRunning;
             ci.isDockable = task.canGoInDockedStack();
+            ci.resizeMode = task.mResizeMode;
             list.add(ci);
         }
     }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 6e7ea99..03eb019 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -77,7 +77,7 @@
     static final boolean DEBUG = false;
 
     public static class Lifecycle extends SystemService {
-        private ContentService mContentService;
+        private ContentService mService;
 
         public Lifecycle(Context context) {
             super(context);
@@ -87,14 +87,21 @@
         public void onStart() {
             final boolean factoryTest = (FactoryTest
                     .getMode() == FactoryTest.FACTORY_TEST_LOW_LEVEL);
-            mContentService = new ContentService(getContext(), factoryTest);
-            publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mContentService);
+            mService = new ContentService(getContext(), factoryTest);
+            publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mService.systemReady();
+            }
         }
 
         @Override
         public void onCleanupUser(int userHandle) {
-            synchronized (mContentService.mCache) {
-                mContentService.mCache.remove(userHandle);
+            synchronized (mService.mCache) {
+                mService.mCache.remove(userHandle);
             }
         }
     }
@@ -265,7 +272,7 @@
                 localeFilter, null, null);
     }
 
-    public void systemReady() {
+    void systemReady() {
         getSyncManager();
     }
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index fe32104..ca1a7ac 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -16,9 +16,12 @@
 
 package com.android.server.wallpaper;
 
-import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.app.WallpaperManager.FLAG_LOCK;
-import static android.os.ParcelFileDescriptor.*;
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -41,27 +44,26 @@
 import android.content.ServiceConnection;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
-import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.FileObserver;
 import android.os.FileUtils;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
-import android.os.RemoteException;
-import android.os.FileObserver;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteCallbackList;
+import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -79,35 +81,62 @@
 import android.view.IWindowManager;
 import android.view.WindowManager;
 
-import java.io.BufferedOutputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
+import com.android.internal.R;
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.JournaledFile;
+import com.android.server.EventLogTags;
+import com.android.server.SystemService;
+
+import libcore.io.IoUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.JournaledFile;
-import com.android.internal.R;
-import com.android.server.EventLogTags;
-
-import libcore.io.IoUtils;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
 
 public class WallpaperManagerService extends IWallpaperManager.Stub {
     static final String TAG = "WallpaperManagerService";
     static final boolean DEBUG = false;
 
+    public static class Lifecycle extends SystemService {
+        private WallpaperManagerService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mService = new WallpaperManagerService(getContext());
+            publishBinderService(Context.WALLPAPER_SERVICE, mService);
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+                mService.systemReady();
+            }
+        }
+
+        @Override
+        public void onUnlockUser(int userHandle) {
+            mService.onUnlockUser(userHandle);
+        }
+    }
+
     final Object mLock = new Object();
 
     /**
@@ -417,6 +446,7 @@
     final AppOpsManager mAppOpsManager;
     WallpaperData mLastWallpaper;
     IWallpaperManagerCallback mKeyguardListener;
+    boolean mWaitingForUnlock;
 
     /**
      * ID of the current wallpaper, changed every time anything sets a wallpaper.
@@ -744,8 +774,9 @@
             if (wallpaper.wallpaperComponent != null
                     && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
                 try {
-                    mContext.getPackageManager().getServiceInfo(
-                            wallpaper.wallpaperComponent, 0);
+                    mContext.getPackageManager().getServiceInfo(wallpaper.wallpaperComponent,
+                            PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
                 } catch (NameNotFoundException e) {
                     Slog.w(TAG, "Wallpaper component gone, removing: "
                             + wallpaper.wallpaperComponent);
@@ -755,8 +786,9 @@
             if (wallpaper.nextWallpaperComponent != null
                     && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
                 try {
-                    mContext.getPackageManager().getServiceInfo(
-                            wallpaper.nextWallpaperComponent, 0);
+                    mContext.getPackageManager().getServiceInfo(wallpaper.nextWallpaperComponent,
+                            PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
                 } catch (NameNotFoundException e) {
                     wallpaper.nextWallpaperComponent = null;
                 }
@@ -793,7 +825,7 @@
         }
     }
 
-    public void systemRunning() {
+    void systemReady() {
         if (DEBUG) Slog.v(TAG, "systemReady");
         WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
         // If we think we're going to be using the system image wallpaper imagery, make
@@ -828,7 +860,7 @@
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
+                final String action = intent.getAction();
                 if (Intent.ACTION_USER_REMOVED.equals(action)) {
                     onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                             UserHandle.USER_NULL));
@@ -892,6 +924,14 @@
         mLockWallpaperMap.remove(userId);
     }
 
+    void onUnlockUser(int userId) {
+        synchronized (mLock) {
+            if (mCurrentUserId == userId && mWaitingForUnlock) {
+                switchUser(userId, null);
+            }
+        }
+    }
+
     void onRemoveUser(int userId) {
         if (userId < 1) return;
 
@@ -919,18 +959,34 @@
 
     void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
         synchronized (mLock) {
-            RuntimeException e = null;
-            try {
-                ComponentName cname = wallpaper.wallpaperComponent != null ?
-                        wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
-                if (bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
-                    return;
+            mWaitingForUnlock = false;
+            final ComponentName cname = wallpaper.wallpaperComponent != null ?
+                    wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
+            if (!bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
+                // We failed to bind the desired wallpaper, but that might
+                // happen if the wallpaper isn't direct-boot aware
+                ServiceInfo si = null;
+                try {
+                    si = mIPackageManager.getServiceInfo(cname,
+                            PackageManager.MATCH_DIRECT_BOOT_UNAWARE, wallpaper.userId);
+                } catch (RemoteException ignored) {
                 }
-            } catch (RuntimeException e1) {
-                e = e1;
+
+                if (si == null) {
+                    Slog.w(TAG, "Failure starting previous wallpaper; clearing");
+                    clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
+                } else {
+                    Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
+                    // We might end up persisting the current wallpaper data
+                    // while locked, so pretend like the component was actually
+                    // bound into place
+                    wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
+                    final WallpaperData fallback = new WallpaperData(wallpaper.userId,
+                            WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
+                    bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
+                    mWaitingForUnlock = true;
+                }
             }
-            Slog.w(TAG, "Failure starting previous wallpaper", e);
-            clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
         }
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6f45508..8c2f559 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -18,7 +18,6 @@
 
 import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
-import android.app.IAlarmManager;
 import android.app.INotificationManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.ComponentName;
@@ -55,13 +54,11 @@
 import com.android.internal.os.ZygoteInit;
 import com.android.internal.widget.ILockSettings;
 import com.android.server.accessibility.AccessibilityManagerService;
-import com.android.server.accounts.AccountManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.audio.AudioService;
 import com.android.server.camera.CameraService;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.connectivity.MetricsLoggerService;
-import com.android.server.content.ContentService;
 import com.android.server.devicepolicy.DevicePolicyManagerService;
 import com.android.server.display.DisplayManagerService;
 import com.android.server.dreams.DreamManagerService;
@@ -97,7 +94,6 @@
 import com.android.server.twilight.TwilightService;
 import com.android.server.usage.UsageStatsService;
 import com.android.server.vr.VrManagerService;
-import com.android.server.wallpaper.WallpaperManagerService;
 import com.android.server.webkit.WebViewUpdateService;
 import com.android.server.wm.WindowManagerService;
 
@@ -157,8 +153,12 @@
             "com.google.android.clockwork.ThermalObserver";
     private static final String WEAR_BLUETOOTH_SERVICE_CLASS =
             "com.google.android.clockwork.bluetooth.WearBluetoothService";
+    private static final String ACCOUNT_SERVICE_CLASS =
+            "com.android.server.accounts.AccountManagerService$Lifecycle";
     private static final String CONTENT_SERVICE_CLASS =
             "com.android.server.content.ContentService$Lifecycle";
+    private static final String WALLPAPER_SERVICE_CLASS =
+            "com.android.server.wallpaper.WallpaperManagerService$Lifecycle";
 
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
@@ -187,6 +187,7 @@
     private PackageManagerService mPackageManagerService;
     private PackageManager mPackageManager;
     private ContentResolver mContentResolver;
+    private EntropyMixer mEntropyMixer;
 
     private boolean mOnlyCore;
     private boolean mFirstBoot;
@@ -497,10 +498,7 @@
      */
     private void startOtherServices() {
         final Context context = mSystemContext;
-        AccountManagerService accountManager = null;
-        ContentService contentService = null;
         VibratorService vibrator = null;
-        IAlarmManager alarm = null;
         IMountService mountService = null;
         NetworkManagementService networkManagement = null;
         NetworkStatsService networkStats = null;
@@ -516,8 +514,6 @@
         TelephonyRegistry telephonyRegistry = null;
         ConsumerIrService consumerIr = null;
         MmsServiceBroker mmsService = null;
-        EntropyMixer entropyMixer = null;
-        VrManagerService vrManagerService = null;
         HardwarePropertiesManagerService hardwarePropertiesService = null;
 
         boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
@@ -556,7 +552,7 @@
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             traceBeginAndSlog("StartEntropyMixer");
-            entropyMixer = new EntropyMixer(context);
+            mEntropyMixer = new EntropyMixer(context);
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             mContentResolver = context.getContentResolver();
@@ -566,13 +562,7 @@
 
             // The AccountManager must come before the ContentService
             traceBeginAndSlog("StartAccountManagerService");
-            try {
-                // TODO: seems like this should be disable-able, but req'd by ContentService
-                accountManager = new AccountManagerService(context);
-                ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting Account Manager", e);
-            }
+            mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             traceBeginAndSlog("StartContentService");
@@ -593,9 +583,9 @@
             ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
             Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+            traceBeginAndSlog("StartAlarmManagerService");
             mSystemServiceManager.startService(AlarmManagerService.class);
-            alarm = IAlarmManager.Stub.asInterface(
-                    ServiceManager.getService(Context.ALARM_SERVICE));
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
             traceBeginAndSlog("InitWatchdog");
             final Watchdog watchdog = Watchdog.getInstance();
@@ -652,7 +642,6 @@
 
         StatusBarManagerService statusBar = null;
         INotificationManager notification = null;
-        WallpaperManagerService wallpaper = null;
         LocationManagerService location = null;
         CountryDetectorService countryDetector = null;
         ILockSettings lockSettings = null;
@@ -886,24 +875,6 @@
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeAccountManagerServiceReady");
-            try {
-                if (accountManager != null)
-                    accountManager.systemReady();
-            } catch (Throwable e) {
-                reportWtf("making Account Manager Service ready", e);
-            }
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeContentServiceReady");
-            try {
-                if (contentService != null)
-                    contentService.systemReady();
-            } catch (Throwable e) {
-                reportWtf("making Content Service ready", e);
-            }
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
-
             mSystemServiceManager.startService(NotificationManagerService.class);
             notification = INotificationManager.Stub.asInterface(
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
@@ -946,12 +917,7 @@
             if (!disableNonCoreServices && context.getResources().getBoolean(
                         R.bool.config_enableWallpaperService)) {
                 traceBeginAndSlog("StartWallpaperManagerService");
-                try {
-                    wallpaper = new WallpaperManagerService(context);
-                    ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
-                } catch (Throwable e) {
-                    reportWtf("starting Wallpaper Service", e);
-                }
+                mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
                 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
             }
 
@@ -1278,12 +1244,10 @@
         final NetworkPolicyManagerService networkPolicyF = networkPolicy;
         final ConnectivityService connectivityF = connectivity;
         final NetworkScoreService networkScoreF = networkScore;
-        final WallpaperManagerService wallpaperF = wallpaper;
         final LocationManagerService locationF = location;
         final CountryDetectorService countryDetectorF = countryDetector;
         final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
         final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
-        final StatusBarManagerService statusBarF = statusBar;
         final AssetAtlasService atlasF = atlas;
         final InputManagerService inputManagerF = inputManager;
         final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
@@ -1371,11 +1335,6 @@
                         SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
 
                 try {
-                    if (wallpaperF != null) wallpaperF.systemRunning();
-                } catch (Throwable e) {
-                    reportWtf("Notifying WallpaperService running", e);
-                }
-                try {
                     if (locationF != null) locationF.systemRunning();
                 } catch (Throwable e) {
                     reportWtf("Notifying Location Service running", e);