Merge "Unhide the new AndroidKeyStore API."
diff --git a/Android.mk b/Android.mk
index 3e049f7..f4b9551 100644
--- a/Android.mk
+++ b/Android.mk
@@ -195,7 +195,6 @@
 	core/java/android/os/IBatteryPropertiesListener.aidl \
 	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
 	core/java/android/os/ICancellationSignal.aidl \
-	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/INetworkActivityListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
diff --git a/core/java/android/app/IUserSwitchObserver.aidl b/core/java/android/app/IUserSwitchObserver.aidl
index 845897b..caee14f 100644
--- a/core/java/android/app/IUserSwitchObserver.aidl
+++ b/core/java/android/app/IUserSwitchObserver.aidl
@@ -22,4 +22,5 @@
 oneway interface IUserSwitchObserver {
     void onUserSwitching(int newUserId, IRemoteCallback reply);
     void onUserSwitchComplete(int newUserId);
+    void onForegroundProfileSwitch(int newProfileId);
 }
diff --git a/core/java/android/os/IHardwareService.aidl b/core/java/android/os/IHardwareService.aidl
deleted file mode 100644
index 38abfc00..0000000
--- a/core/java/android/os/IHardwareService.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-/** {@hide} */
-interface IHardwareService
-{
-    // obsolete flashlight support
-    boolean getFlashlightEnabled();
-    void setFlashlightEnabled(boolean on);
-}
-
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index a157087..06a5bd2 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -534,22 +534,23 @@
 
     @Override
     public void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
+        final SavedState ss = (SavedState) state;
 
         // TODO: Move instance state into DayPickerView, YearPickerView.
         mCurrentDate.set(ss.getSelectedYear(), ss.getSelectedMonth(), ss.getSelectedDay());
-        mCurrentView = ss.getCurrentView();
         mMinDate.setTimeInMillis(ss.getMinDate());
         mMaxDate.setTimeInMillis(ss.getMaxDate());
 
         onCurrentDateChanged(false);
-        setCurrentView(mCurrentView);
+
+        final int currentView = ss.getCurrentView();
+        setCurrentView(currentView);
 
         final int listPosition = ss.getListPosition();
         if (listPosition != -1) {
-            if (mCurrentView == VIEW_MONTH_DAY) {
+            if (currentView == VIEW_MONTH_DAY) {
                 mDayPickerView.setCurrentItem(listPosition);
-            } else if (mCurrentView == VIEW_YEAR) {
+            } else if (currentView == VIEW_YEAR) {
                 final int listPositionOffset = ss.getListPositionOffset();
                 mYearPickerView.setSelectionFromTop(listPosition, listPositionOffset);
             }
@@ -601,7 +602,6 @@
      * Class for managing state storing/restoring.
      */
     private static class SavedState extends View.BaseSavedState {
-
         private final int mSelectedYear;
         private final int mSelectedMonth;
         private final int mSelectedDay;
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index ec2528f..0e0b2d3 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -22,9 +22,12 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.MathUtils;
+import android.view.View;
 
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Locale;
 
@@ -41,6 +44,8 @@
     private final Calendar mMinDate = Calendar.getInstance();
     private final Calendar mMaxDate = Calendar.getInstance();
 
+    private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
     private final DayPickerAdapter mAdapter;
 
     /** Temporary calendar used for date calculations. */
@@ -140,6 +145,93 @@
         });
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        populate();
+
+        // Everything below is mostly copied from FrameLayout.
+        int count = getChildCount();
+
+        final boolean measureMatchParentChildren =
+                MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+                        MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+        int maxHeight = 0;
+        int maxWidth = 0;
+        int childState = 0;
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                measureChild(child, widthMeasureSpec, heightMeasureSpec);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
+                maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
+                childState = combineMeasuredStates(childState, child.getMeasuredState());
+                if (measureMatchParentChildren) {
+                    if (lp.width == LayoutParams.MATCH_PARENT ||
+                            lp.height == LayoutParams.MATCH_PARENT) {
+                        mMatchParentChildren.add(child);
+                    }
+                }
+            }
+        }
+
+        // Account for padding too
+        maxWidth += getPaddingLeft() + getPaddingRight();
+        maxHeight += getPaddingTop() + getPaddingBottom();
+
+        // Check against our minimum height and width
+        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+        // Check against our foreground's minimum height and width
+        final Drawable drawable = getForeground();
+        if (drawable != null) {
+            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+        }
+
+        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+                resolveSizeAndState(maxHeight, heightMeasureSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+        count = mMatchParentChildren.size();
+        if (count > 1) {
+            for (int i = 0; i < count; i++) {
+                final View child = mMatchParentChildren.get(i);
+
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                final int childWidthMeasureSpec;
+                final int childHeightMeasureSpec;
+
+                if (lp.width == LayoutParams.MATCH_PARENT) {
+                    childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
+                            MeasureSpec.EXACTLY);
+                } else {
+                    childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+                            getPaddingLeft() + getPaddingRight(),
+                            lp.width);
+                }
+
+                if (lp.height == LayoutParams.MATCH_PARENT) {
+                    childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
+                            MeasureSpec.EXACTLY);
+                } else {
+                    childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                            getPaddingTop() + getPaddingBottom(),
+                            lp.height);
+                }
+
+                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+            }
+        }
+
+        mMatchParentChildren.clear();
+    }
+
     public void setDayOfWeekTextAppearance(int resId) {
         mAdapter.setDayOfWeekTextAppearance(resId);
     }
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index d9f1f0e..aa7f0b6 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -585,7 +585,6 @@
                 mToday = day;
             }
         }
-        mNumWeeks = calculateNumRows();
 
         // Invalidate the old title.
         mTitle = null;
@@ -616,18 +615,6 @@
         }
     }
 
-    public void reuse() {
-        mNumWeeks = MAX_WEEKS_IN_MONTH;
-        requestLayout();
-    }
-
-    private int calculateNumRows() {
-        final int offset = findDayOffset();
-        final int dividend = (offset + mDaysInMonth) / DAYS_IN_WEEK;
-        final int remainder = (offset + mDaysInMonth) % DAYS_IN_WEEK;
-        return dividend + (remainder > 0 ? 1 : 0);
-    }
-
     private boolean sameDay(int day, Calendar today) {
         return mYear == today.get(Calendar.YEAR) && mMonth == today.get(Calendar.MONTH)
                 && day == today.get(Calendar.DAY_OF_MONTH);
@@ -635,8 +622,9 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int preferredHeight = mDesiredDayHeight * mNumWeeks + mDesiredDayOfWeekHeight
-                + mDesiredMonthHeight + getPaddingTop() + getPaddingBottom();
+        final int preferredHeight = mDesiredDayHeight * MAX_WEEKS_IN_MONTH
+                + mDesiredDayOfWeekHeight + mDesiredMonthHeight
+                + getPaddingTop() + getPaddingBottom();
         final int preferredWidth = mDesiredCellWidth * DAYS_IN_WEEK
                 + getPaddingStart() + getPaddingEnd();
         final int resolvedWidth = resolveSize(preferredWidth, widthMeasureSpec);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5d60f99..9bbf375 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -540,6 +540,7 @@
     private Layout mLayout;
     private boolean mLocaleChanged = false;
 
+    @ViewDebug.ExportedProperty(category = "text")
     private int mGravity = Gravity.TOP | Gravity.START;
     private boolean mHorizontallyScrolling;
 
diff --git a/core/java/android/widget/YearPickerView.java b/core/java/android/widget/YearPickerView.java
index 7182414..89e59f9 100644
--- a/core/java/android/widget/YearPickerView.java
+++ b/core/java/android/widget/YearPickerView.java
@@ -178,24 +178,29 @@
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(ITEM_LAYOUT, parent, false);
+            final TextView v;
+            final boolean hasNewView = convertView == null;
+            if (hasNewView) {
+                v = (TextView) mInflater.inflate(ITEM_LAYOUT, parent, false);
+            } else {
+                v = (TextView) convertView;
             }
 
             final int year = getYearForPosition(position);
             final boolean activated = mActivatedYear == year;
 
-            final int textAppearanceResId;
-            if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
-                textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
-            } else {
-                textAppearanceResId = ITEM_TEXT_APPEARANCE;
+            if (hasNewView || v.isActivated() != activated) {
+                final int textAppearanceResId;
+                if (activated && ITEM_TEXT_ACTIVATED_APPEARANCE != 0) {
+                    textAppearanceResId = ITEM_TEXT_ACTIVATED_APPEARANCE;
+                } else {
+                    textAppearanceResId = ITEM_TEXT_APPEARANCE;
+                }
+                v.setTextAppearance(textAppearanceResId);
+                v.setActivated(activated);
             }
 
-            final TextView v = (TextView) convertView;
-            v.setText("" + year);
-            v.setTextAppearance(v.getContext(), textAppearanceResId);
-            v.setActivated(activated);
+            v.setText(Integer.toString(year));
             return v;
         }
 
diff --git a/core/java/com/android/internal/widget/DialogViewAnimator.java b/core/java/com/android/internal/widget/DialogViewAnimator.java
new file mode 100644
index 0000000..bdfc1af
--- /dev/null
+++ b/core/java/com/android/internal/widget/DialogViewAnimator.java
@@ -0,0 +1,141 @@
+/*
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ViewAnimator;
+
+import java.util.ArrayList;
+
+/**
+ * ViewAnimator with a more reasonable handling of MATCH_PARENT.
+ */
+public class DialogViewAnimator extends ViewAnimator {
+    private final ArrayList<View> mMatchParentChildren = new ArrayList<>(1);
+
+    public DialogViewAnimator(Context context) {
+        super(context);
+    }
+
+    public DialogViewAnimator(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final boolean measureMatchParentChildren =
+                MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
+                        MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
+
+        int maxHeight = 0;
+        int maxWidth = 0;
+        int childState = 0;
+
+        // First measure all children and record maximum dimensions where the
+        // spec isn't MATCH_PARENT.
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (getMeasureAllChildren() || child.getVisibility() != GONE) {
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                final boolean matchWidth = lp.width == LayoutParams.MATCH_PARENT;
+                final boolean matchHeight = lp.height == LayoutParams.MATCH_PARENT;
+                if (measureMatchParentChildren && (matchWidth || matchHeight)) {
+                    mMatchParentChildren.add(child);
+                }
+
+                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+
+                // Measured dimensions only count against the maximum
+                // dimensions if they're not MATCH_PARENT.
+                int state = 0;
+
+                if (measureMatchParentChildren && !matchWidth) {
+                    maxWidth = Math.max(maxWidth, child.getMeasuredWidth()
+                            + lp.leftMargin + lp.rightMargin);
+                    state |= child.getMeasuredWidthAndState() & MEASURED_STATE_MASK;
+                }
+
+                if (measureMatchParentChildren && !matchHeight) {
+                    maxHeight = Math.max(maxHeight, child.getMeasuredHeight()
+                            + lp.topMargin + lp.bottomMargin);
+                    state |= (child.getMeasuredHeightAndState() >> MEASURED_HEIGHT_STATE_SHIFT)
+                            & (MEASURED_STATE_MASK >> MEASURED_HEIGHT_STATE_SHIFT);
+                }
+
+                childState = combineMeasuredStates(childState, state);
+            }
+        }
+
+        // Account for padding too.
+        maxWidth += getPaddingLeft() + getPaddingRight();
+        maxHeight += getPaddingTop() + getPaddingBottom();
+
+        // Check against our minimum height and width.
+        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+        // Check against our foreground's minimum height and width.
+        final Drawable drawable = getForeground();
+        if (drawable != null) {
+            maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
+            maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
+        }
+
+        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+                resolveSizeAndState(maxHeight, heightMeasureSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+
+        // Measure remaining MATCH_PARENT children again using real dimensions.
+        final int matchCount = mMatchParentChildren.size();
+        for (int i = 0; i < matchCount; i++) {
+            final View child = mMatchParentChildren.get(i);
+            final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+            final int childWidthMeasureSpec;
+            if (lp.width == LayoutParams.MATCH_PARENT) {
+                childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        getMeasuredWidth() - getPaddingLeft() - getPaddingRight()
+                                - lp.leftMargin - lp.rightMargin,
+                        MeasureSpec.EXACTLY);
+            } else {
+                childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
+                        getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin,
+                        lp.width);
+            }
+
+            final int childHeightMeasureSpec;
+            if (lp.height == LayoutParams.MATCH_PARENT) {
+                childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        getMeasuredHeight() - getPaddingTop() - getPaddingBottom()
+                                - lp.topMargin - lp.bottomMargin,
+                        MeasureSpec.EXACTLY);
+            } else {
+                childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+                        getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin,
+                        lp.height);
+            }
+
+            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+        }
+
+        mMatchParentChildren.clear();
+    }
+}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 8d66191..5c08daf 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -889,7 +889,7 @@
         }
     }
 
-    void populate() {
+    public void populate() {
         populate(mCurItem);
     }
 
diff --git a/core/res/res/anim/date_picker_fade_in_material.xml b/core/res/res/anim/date_picker_fade_in_material.xml
new file mode 100644
index 0000000..12e7ce3
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_in_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+       android:interpolator="@interpolator/accelerate_quad"
+       android:fromAlpha="0.0"
+       android:toAlpha="1.0"
+       android:duration="250"  />
diff --git a/core/res/res/anim/date_picker_fade_out_material.xml b/core/res/res/anim/date_picker_fade_out_material.xml
new file mode 100644
index 0000000..4084605
--- /dev/null
+++ b/core/res/res/anim/date_picker_fade_out_material.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+       android:interpolator="@interpolator/decelerate_quad"
+       android:fromAlpha="1.0"
+       android:toAlpha="0.0"
+       android:duration="250" />
diff --git a/core/res/res/layout/date_picker_material.xml b/core/res/res/layout/date_picker_material.xml
index a1c97ff..763f2a4 100644
--- a/core/res/res/layout/date_picker_material.xml
+++ b/core/res/res/layout/date_picker_material.xml
@@ -16,8 +16,8 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
               android:orientation="vertical">
 
     <include
diff --git a/core/res/res/layout/date_picker_view_animator_material.xml b/core/res/res/layout/date_picker_view_animator_material.xml
index 620ddfa..e863b28 100644
--- a/core/res/res/layout/date_picker_view_animator_material.xml
+++ b/core/res/res/layout/date_picker_view_animator_material.xml
@@ -15,23 +15,23 @@
      limitations under the License.
 -->
 
-<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.internal.widget.DialogViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/animator"
     android:layout_width="match_parent"
-    android:layout_height="0dp"
-    android:layout_weight="1"
-    android:gravity="center">
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:inAnimation="@anim/date_picker_fade_in_material"
+    android:outAnimation="@anim/date_picker_fade_out_material"
+    android:measureAllChildren="true">
 
     <android.widget.DayPickerView
         android:id="@+id/date_picker_day_picker"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:inAnimation="@anim/fade_in"
-        android:outAnimation="@anim/fade_out" />
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
 
     <android.widget.YearPickerView
         android:id="@+id/date_picker_year_picker"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
-</ViewAnimator>
+</com.android.internal.widget.DialogViewAnimator>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 18615d9..147ac19 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -763,6 +763,10 @@
                             mSwitchingUser = false;
                             startListeningForFingerprint();
                         }
+                        @Override
+                        public void onForegroundProfileSwitch(int newProfileId) {
+                            // Ignore.
+                        }
                     });
         } catch (RemoteException e) {
             // TODO Auto-generated catch block
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d92a89f..0f9090d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -797,6 +797,11 @@
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
                         }
+
+                        @Override
+                        public void onForegroundProfileSwitch(int newProfileId) {
+                            // Ignore.
+                        }
                     });
             userId = ActivityManagerNative.getDefault().getCurrentUser().id;
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 5add88e..9a6f696 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -116,6 +116,11 @@
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
                         }
+
+                        @Override
+                        public void onForegroundProfileSwitch(int newProfileId) {
+                            // Ignore.
+                        }
                     });
             userId = ActivityManagerNative.getDefault().getCurrentUser().id;
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2af765..6341807 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1284,6 +1284,7 @@
     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
     static final int DELETE_DUMPHEAP_MSG = 52;
+    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1922,6 +1923,9 @@
                     mMemWatchDumpUid = -1;
                 }
             } break;
+            case FOREGROUND_PROFILE_CHANGED_MSG: {
+                dispatchForegroundProfileChanged(msg.arg1);
+            } break;
             }
         }
     };
@@ -2523,6 +2527,11 @@
                 mWindowManager.setFocusedApp(r.appToken, true);
             }
             applyUpdateLockStateLocked(r);
+            if (last != null && last.userId != mFocusedActivity.userId) {
+                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
+                mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
+                                mFocusedActivity.userId, 0));
+            }
         }
         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
@@ -19072,6 +19081,18 @@
         return true;
     }
 
+    void dispatchForegroundProfileChanged(int userId) {
+        final int N = mUserSwitchObservers.beginBroadcast();
+        for (int i = 0; i < N; i++) {
+            try {
+                mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        }
+        mUserSwitchObservers.finishBroadcast();
+    }
+
     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
         long ident = Binder.clearCallingIdentity();
         try {
diff --git a/services/core/java/com/android/server/display/DisplayBlanker.java b/services/core/java/com/android/server/display/DisplayBlanker.java
index eb0ae6a..816dc13 100644
--- a/services/core/java/com/android/server/display/DisplayBlanker.java
+++ b/services/core/java/com/android/server/display/DisplayBlanker.java
@@ -20,5 +20,5 @@
  * Interface used to update the actual display state.
  */
 public interface DisplayBlanker {
-    void requestDisplayState(int state);
+    void requestDisplayState(int state, int brightness);
 }
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 61631d4..e16be71 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -118,10 +118,12 @@
     /**
      * Sets the display state, if supported.
      *
+     * @param state The new display state.
+     * @param brightness The new display brightness.
      * @return A runnable containing work to be deferred until after we have
      * exited the critical section, or null if none.
      */
-    public Runnable requestDisplayStateLocked(int state) {
+    public Runnable requestDisplayStateLocked(int state, int brightness) {
         return null;
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5f0ad9f..9ea0444 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -40,11 +40,13 @@
 import android.os.IBinder.DeathRecipient;
 import android.os.Looper;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -179,7 +181,11 @@
 
     // The overall display state, independent of changes that might influence one
     // display or another in particular.
-    private int mGlobalDisplayState = Display.STATE_UNKNOWN;
+    private int mGlobalDisplayState = Display.STATE_ON;
+
+    // The overall display brightness.
+    // For now, this only applies to the built-in display but we may split it up eventually.
+    private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
 
     // Set to true when there are pending display changes that have yet to be applied
     // to the surface flinger state.
@@ -226,6 +232,9 @@
         mUiHandler = UiThread.getHandler();
         mDisplayAdapterListener = new DisplayAdapterListener();
         mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
+
+        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
     }
 
     @Override
@@ -322,16 +331,34 @@
         }
     }
 
-    private void requestGlobalDisplayStateInternal(int state) {
+    private void requestGlobalDisplayStateInternal(int state, int brightness) {
+        if (state == Display.STATE_UNKNOWN) {
+            state = Display.STATE_ON;
+        }
+        if (state == Display.STATE_OFF) {
+            brightness = PowerManager.BRIGHTNESS_OFF;
+        } else if (brightness < 0) {
+            brightness = PowerManager.BRIGHTNESS_DEFAULT;
+        } else if (brightness > PowerManager.BRIGHTNESS_ON) {
+            brightness = PowerManager.BRIGHTNESS_ON;
+        }
+
         synchronized (mTempDisplayStateWorkQueue) {
             try {
                 // Update the display state within the lock.
                 synchronized (mSyncRoot) {
-                    if (mGlobalDisplayState != state) {
-                        mGlobalDisplayState = state;
-                        updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
-                        scheduleTraversalLocked(false);
+                    if (mGlobalDisplayState == state
+                            && mGlobalDisplayBrightness == brightness) {
+                        return; // no change
                     }
+
+                    Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
+                            + Display.stateToString(state)
+                            + ", brightness=" + brightness + ")");
+                    mGlobalDisplayState = state;
+                    mGlobalDisplayBrightness = brightness;
+                    updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
+                    scheduleTraversalLocked(false);
                 }
 
                 // Setting the display power state can take hundreds of milliseconds
@@ -341,6 +368,7 @@
                 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
                     mTempDisplayStateWorkQueue.get(i).run();
                 }
+                Trace.traceEnd(Trace.TRACE_TAG_POWER);
             } finally {
                 mTempDisplayStateWorkQueue.clear();
             }
@@ -708,7 +736,7 @@
         // by the display power controller (if known).
         DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
-            return device.requestDisplayStateLocked(mGlobalDisplayState);
+            return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
         }
         return null;
     }
@@ -1462,16 +1490,16 @@
             synchronized (mSyncRoot) {
                 DisplayBlanker blanker = new DisplayBlanker() {
                     @Override
-                    public void requestDisplayState(int state) {
+                    public void requestDisplayState(int state, int brightness) {
                         // The order of operations is important for legacy reasons.
                         if (state == Display.STATE_OFF) {
-                            requestGlobalDisplayStateInternal(state);
+                            requestGlobalDisplayStateInternal(state, brightness);
                         }
 
                         callbacks.onDisplayStateChange(state);
 
                         if (state != Display.STATE_OFF) {
-                            requestGlobalDisplayStateInternal(state);
+                            requestGlobalDisplayStateInternal(state, brightness);
                         }
                     }
                 };
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index cf1f4b0..f74601e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -19,7 +19,6 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.server.LocalServices;
 import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.LightsManager;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
@@ -122,9 +121,6 @@
     // Battery stats.
     private final IBatteryStats mBatteryStats;
 
-    // The lights service.
-    private final LightsManager mLights;
-
     // The sensor manager.
     private final SensorManager mSensorManager;
 
@@ -260,7 +256,6 @@
         mCallbacks = callbacks;
 
         mBatteryStats = BatteryStatsService.getService();
-        mLights = LocalServices.getService(LightsManager.class);
         mSensorManager = sensorManager;
         mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
         mBlanker = blanker;
@@ -443,7 +438,6 @@
         // Initialize the power state object for the default display.
         // In the future, we might manage multiple displays independently.
         mPowerState = new DisplayPowerState(mBlanker,
-                mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
                 new ColorFade(Display.DEFAULT_DISPLAY));
 
         mColorFadeOnAnimator = ObjectAnimator.ofFloat(
diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java
index a3c9738..f53ccc9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerState.java
+++ b/services/core/java/com/android/server/display/DisplayPowerState.java
@@ -16,13 +16,10 @@
 
 package com.android.server.display;
 
-import com.android.server.lights.Light;
-
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
-import android.os.Trace;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Slog;
@@ -56,7 +53,6 @@
     private final Handler mHandler;
     private final Choreographer mChoreographer;
     private final DisplayBlanker mBlanker;
-    private final Light mBacklight;
     private final ColorFade mColorFade;
     private final PhotonicModulator mPhotonicModulator;
 
@@ -72,12 +68,11 @@
 
     private Runnable mCleanListener;
 
-    public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
+    public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
         mHandler = new Handler(true /*async*/);
         mChoreographer = Choreographer.getInstance();
         mBlanker = blanker;
-        mBacklight = backlight;
-        mColorFade = electronBeam;
+        mColorFade = colorFade;
         mPhotonicModulator = new PhotonicModulator();
         mPhotonicModulator.start();
 
@@ -415,35 +410,7 @@
                     Slog.d(TAG, "Updating screen state: state="
                             + Display.stateToString(state) + ", backlight=" + backlight);
                 }
-                boolean suspending = Display.isSuspendedState(state);
-                if (stateChanged && !suspending) {
-                    requestDisplayState(state);
-                }
-                if (backlightChanged) {
-                    setBrightness(backlight);
-                }
-                if (stateChanged && suspending) {
-                    requestDisplayState(state);
-                }
-            }
-        }
-
-        private void requestDisplayState(int state) {
-            Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
-                    + Display.stateToString(state) + ")");
-            try {
-                mBlanker.requestDisplayState(state);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_POWER);
-            }
-        }
-
-        private void setBrightness(int backlight) {
-            Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
-            try {
-                mBacklight.setBrightness(backlight);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_POWER);
+                mBlanker.requestDisplayState(state, backlight);
             }
         }
     }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 5ebe64d..e87f265 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,10 +16,15 @@
 
 package com.android.server.display;
 
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
 import android.content.Context;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.PowerManager;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.Slog;
@@ -40,6 +45,7 @@
  */
 final class LocalDisplayAdapter extends DisplayAdapter {
     private static final String TAG = "LocalDisplayAdapter";
+    private static final boolean DEBUG = false;
 
     private static final String UNIQUE_ID_PREFIX = "local:";
 
@@ -132,14 +138,17 @@
         private final int mBuiltInDisplayId;
         private final SurfaceControl.PhysicalDisplayInfo mPhys;
         private final int mDefaultPhysicalDisplayInfo;
+        private final Light mBacklight;
 
         private DisplayDeviceInfo mInfo;
         private boolean mHavePendingChanges;
         private int mState = Display.STATE_UNKNOWN;
+        private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
         private float[] mSupportedRefreshRates;
         private int[] mRefreshRateConfigIndices;
         private float mLastRequestedRefreshRate;
 
+
         public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
                 SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
             super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
@@ -148,6 +157,13 @@
                     physicalDisplayInfos[activeDisplayInfo]);
             mDefaultPhysicalDisplayInfo = activeDisplayInfo;
             updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
+
+            if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+                LightsManager lights = LocalServices.getService(LightsManager.class);
+                mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
+            } else {
+                mBacklight = null;
+            }
         }
 
         public boolean updatePhysicalDisplayInfoLocked(
@@ -225,28 +241,91 @@
         }
 
         @Override
-        public Runnable requestDisplayStateLocked(final int state) {
-            if (mState != state) {
+        public Runnable requestDisplayStateLocked(final int state, final int brightness) {
+            // Assume that the brightness is off if the display is being turned off.
+            assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
+
+            final boolean stateChanged = (mState != state);
+            final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
+            if (stateChanged || brightnessChanged) {
                 final int displayId = mBuiltInDisplayId;
                 final IBinder token = getDisplayTokenLocked();
-                final int mode = getPowerModeForState(state);
-                mState = state;
-                updateDeviceInfoLocked();
+                final int oldState = mState;
 
-                // Defer actually setting the display power mode until we have exited
+                if (stateChanged) {
+                    mState = state;
+                    updateDeviceInfoLocked();
+                }
+
+                if (brightnessChanged) {
+                    mBrightness = brightness;
+                }
+
+                // Defer actually setting the display state until after we have exited
                 // the critical section since it can take hundreds of milliseconds
                 // to complete.
                 return new Runnable() {
                     @Override
                     public void run() {
-                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
-                                + Display.stateToString(state) + ", id=" + displayId + ")");
+                        // Exit a suspended state before making any changes.
+                        int currentState = oldState;
+                        if (Display.isSuspendedState(oldState)
+                                || oldState == Display.STATE_UNKNOWN) {
+                            if (!Display.isSuspendedState(state)) {
+                                setDisplayState(state);
+                                currentState = state;
+                            } else if (state == Display.STATE_DOZE_SUSPEND
+                                    || oldState == Display.STATE_DOZE_SUSPEND) {
+                                setDisplayState(Display.STATE_DOZE);
+                                currentState = Display.STATE_DOZE;
+                            } else {
+                                return; // old state and new state is off
+                            }
+                        }
+
+                        // Apply brightness changes given that we are in a non-suspended state.
+                        if (brightnessChanged) {
+                            setDisplayBrightness(brightness);
+                        }
+
+                        // Enter the final desired state, possibly suspended.
+                        if (state != currentState) {
+                            setDisplayState(state);
+                        }
+                    }
+
+                    private void setDisplayState(int state) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "setDisplayState("
+                                    + "id=" + displayId
+                                    + ", state=" + Display.stateToString(state) + ")");
+                        }
+
+                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
+                                + "id=" + displayId
+                                + ", state=" + Display.stateToString(state) + ")");
                         try {
+                            final int mode = getPowerModeForState(state);
                             SurfaceControl.setDisplayPowerMode(token, mode);
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
                     }
+
+                    private void setDisplayBrightness(int brightness) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "setDisplayBrightness("
+                                    + "id=" + displayId + ", brightness=" + brightness + ")");
+                        }
+
+                        Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
+                                + "id=" + displayId + ", brightness=" + brightness + ")");
+                        try {
+                            mBacklight.setBrightness(brightness);
+                        } finally {
+                            Trace.traceEnd(Trace.TRACE_TAG_POWER);
+                        }
+                    }
                 };
             }
             return null;
@@ -278,6 +357,8 @@
             pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
             pw.println("mPhys=" + mPhys);
             pw.println("mState=" + Display.stateToString(mState));
+            pw.println("mBrightness=" + mBrightness);
+            pw.println("mBacklight=" + mBacklight);
         }
 
         private void updateDeviceInfoLocked() {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f181cd5..6f59b54 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -221,7 +221,7 @@
         }
 
         @Override
-        public Runnable requestDisplayStateLocked(int state) {
+        public Runnable requestDisplayStateLocked(int state, int brightness) {
             if (state != mDisplayState) {
                 mDisplayState = state;
                 if (state == Display.STATE_OFF) {
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 2da9d8e..ed884ef 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -19,16 +19,11 @@
 import com.android.server.SystemService;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.Handler;
-import android.os.IHardwareService;
 import android.os.Message;
 import android.os.Trace;
 import android.util.Slog;
 
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-
 public class LightsService extends SystemService {
     static final String TAG = "LightsService";
     static final boolean DEBUG = false;
@@ -124,46 +119,6 @@
         private boolean mFlashing;
     }
 
-    /* This class implements an obsolete API that was removed after eclair and re-added during the
-     * final moments of the froyo release to support flashlight apps that had been using the private
-     * IHardwareService API. This is expected to go away in the next release.
-     */
-    private final IHardwareService.Stub mLegacyFlashlightHack = new IHardwareService.Stub() {
-
-        private static final String FLASHLIGHT_FILE = "/sys/class/leds/spotlight/brightness";
-
-        public boolean getFlashlightEnabled() {
-            try {
-                FileInputStream fis = new FileInputStream(FLASHLIGHT_FILE);
-                int result = fis.read();
-                fis.close();
-                return (result != '0');
-            } catch (Exception e) {
-                return false;
-            }
-        }
-
-        public void setFlashlightEnabled(boolean on) {
-            final Context context = getContext();
-            if (context.checkCallingOrSelfPermission(android.Manifest.permission.FLASHLIGHT)
-                    != PackageManager.PERMISSION_GRANTED &&
-                    context.checkCallingOrSelfPermission(android.Manifest.permission.HARDWARE_TEST)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("Requires FLASHLIGHT or HARDWARE_TEST permission");
-            }
-            try {
-                FileOutputStream fos = new FileOutputStream(FLASHLIGHT_FILE);
-                byte[] bytes = new byte[2];
-                bytes[0] = (byte)(on ? '1' : '0');
-                bytes[1] = '\n';
-                fos.write(bytes);
-                fos.close();
-            } catch (Exception e) {
-                // fail silently
-            }
-        }
-    };
-
     public LightsService(Context context) {
         super(context);
 
@@ -176,13 +131,12 @@
 
     @Override
     public void onStart() {
-        publishBinderService("hardware", mLegacyFlashlightHack);
         publishLocalService(LightsManager.class, mService);
     }
 
     private final LightsManager mService = new LightsManager() {
         @Override
-        public com.android.server.lights.Light getLight(int id) {
+        public Light getLight(int id) {
             if (id < LIGHT_ID_COUNT) {
                 return mLights[id];
             } else {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 99cf8df..54be380 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -538,6 +538,11 @@
                         @Override
                         public void onUserSwitchComplete(int newUserId) throws RemoteException {
                         }
+
+                        @Override
+                        public void onForegroundProfileSwitch(int newProfileId) {
+                            // Ignore.
+                        }
                     });
         } catch (RemoteException e) {
             // TODO Auto-generated catch block
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 53da75b..593853c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -325,6 +325,9 @@
         // initialize power management features.
         mActivityManagerService.initPowerManagement();
 
+        // Manages LEDs and display backlight so we need it to bring up the display.
+        mSystemServiceManager.startService(LightsService.class);
+
         // Display manager is needed to provide display metrics before package manager
         // starts up.
         mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
@@ -363,9 +366,6 @@
      * Starts some essential services that are not tangled up in the bootstrap process.
      */
     private void startCoreServices() {
-        // Manages LEDs and display backlight.
-        mSystemServiceManager.startService(LightsService.class);
-
         // Tracks the battery level.  Requires LightService.
         mSystemServiceManager.startService(BatteryService.class);