Merge "Quick settings user display and switching" into jb-mr1-dev
diff --git a/api/17.txt b/api/17.txt
index 91dc71f..f236a74 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -20347,7 +20347,6 @@
     method public android.view.WindowManager getWindowManager();
     method public boolean isFullscreen();
     method public boolean isInteractive();
-    method public boolean isLowProfile();
     method public boolean isScreenBright();
     method public void onActionModeFinished(android.view.ActionMode);
     method public void onActionModeStarted(android.view.ActionMode);
@@ -20372,7 +20371,6 @@
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void setFullscreen(boolean);
     method public void setInteractive(boolean);
-    method public void setLowProfile(boolean);
     method public void setScreenBright(boolean);
     field public static final java.lang.String DREAM_META_DATA = "android.service.dream";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService";
diff --git a/api/current.txt b/api/current.txt
index 91dc71f..f236a74 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20347,7 +20347,6 @@
     method public android.view.WindowManager getWindowManager();
     method public boolean isFullscreen();
     method public boolean isInteractive();
-    method public boolean isLowProfile();
     method public boolean isScreenBright();
     method public void onActionModeFinished(android.view.ActionMode);
     method public void onActionModeStarted(android.view.ActionMode);
@@ -20372,7 +20371,6 @@
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void setFullscreen(boolean);
     method public void setInteractive(boolean);
-    method public void setLowProfile(boolean);
     method public void setScreenBright(boolean);
     field public static final java.lang.String DREAM_META_DATA = "android.service.dream";
     field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.DreamService";
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index dd51764..cb78763a 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -22,6 +22,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Service;
 import android.content.Intent;
+import android.graphics.PixelFormat;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Handler;
 import android.os.IBinder;
@@ -401,6 +402,9 @@
      * Sets View.SYSTEM_UI_FLAG_LOW_PROFILE on the content view.
      *
      * @param lowProfile True to set View.SYSTEM_UI_FLAG_LOW_PROFILE
+     * @hide There is no reason to have this -- dreams can set this flag
+     * on their own content view, and from there can actually do the
+     * correct interactions with it (seeing when it is cleared etc).
      */
     public void setLowProfile(boolean lowProfile) {
         mLowProfile = lowProfile;
@@ -412,20 +416,23 @@
      * Returns whether or not this dream is in low profile mode. Defaults to true.
      *
      * @see #setLowProfile(boolean)
+     * @hide
      */
     public boolean isLowProfile() {
         return getSystemUiVisibilityFlagValue(View.SYSTEM_UI_FLAG_LOW_PROFILE, mLowProfile);
     }
 
     /**
-     * Sets View.SYSTEM_UI_FLAG_FULLSCREEN on the content view.
+     * Controls {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN}
+     * on the dream's window.
      *
-     * @param fullscreen True to set View.SYSTEM_UI_FLAG_FULLSCREEN
+     * @param fullscreen If true, the fullscreen flag will be set; else it
+     * will be cleared.
      */
     public void setFullscreen(boolean fullscreen) {
         mFullscreen = fullscreen;
-        int flag = View.SYSTEM_UI_FLAG_FULLSCREEN;
-        applySystemUiVisibilityFlags(mFullscreen ? flag : 0, flag);
+        int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
+        applyWindowFlags(mFullscreen ? flag : 0, flag);
     }
 
     /**
@@ -434,7 +441,7 @@
      * @see #setFullscreen(boolean)
      */
     public boolean isFullscreen() {
-        return getSystemUiVisibilityFlagValue(View.SYSTEM_UI_FLAG_FULLSCREEN, mFullscreen);
+        return mFullscreen;
     }
 
     /**
@@ -565,6 +572,7 @@
         mWindow.setCallback(this);
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
         mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
+        mWindow.setFormat(PixelFormat.OPAQUE);
 
         if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",
                 windowToken, WindowManager.LayoutParams.TYPE_DREAM));
@@ -573,9 +581,12 @@
         lp.type = WindowManager.LayoutParams.TYPE_DREAM;
         lp.token = windowToken;
         lp.windowAnimations = com.android.internal.R.style.Animation_Dream;
-        lp.flags |= ( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+        lp.flags |= ( WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                     | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                     | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
+                    | (mFullscreen ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0)
                     | (mScreenBright ? WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON : 0)
                     );
         mWindow.setAttributes(lp);
@@ -588,9 +599,8 @@
         if (mDebug) Slog.v(TAG, "Window added on thread " + Thread.currentThread().getId());
         try {
             applySystemUiVisibilityFlags(
-                    (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0)
-                  | (mFullscreen ? View.SYSTEM_UI_FLAG_FULLSCREEN : 0),
-                    View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN);
+                    (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0),
+                    View.SYSTEM_UI_FLAG_LOW_PROFILE);
             getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
         } catch (Throwable t) {
             Slog.w("Crashed adding window view", t);
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring.png
deleted file mode 100644
index 5912301..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring_notconnected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring_notconnected.png
deleted file mode 100644
index 49ee056..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_mirroring_notconnected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png
new file mode 100644
index 0000000..a7bc3c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png
new file mode 100644
index 0000000..012a4e8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring.png
deleted file mode 100644
index a5f16e8..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring_notconnected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring_notconnected.png
deleted file mode 100644
index a4e0420..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_mirroring_notconnected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png
new file mode 100644
index 0000000..1ff9cbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png
new file mode 100644
index 0000000..0ec78c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring.png
deleted file mode 100644
index eb6d5a6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring_notconnected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring_notconnected.png
deleted file mode 100644
index 98d7b09..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_mirroring_notconnected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png
new file mode 100644
index 0000000..88ea017
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png
new file mode 100644
index 0000000..7573636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_wifi_display.xml b/packages/SystemUI/res/layout/quick_settings_tile_wifi_display.xml
index 454d54a..2d7e441 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_wifi_display.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_wifi_display.xml
@@ -21,6 +21,6 @@
     android:layout_height="wrap_content"
     android:layout_gravity="center"
     android:gravity="center"
-    android:drawableTop="@drawable/ic_qs_mirroring"
+    android:drawableTop="@drawable/ic_qs_remote_display"
     android:text="@string/quick_settings_wifi_display_label"
     />
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2b74f56..61299c4 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -449,7 +449,7 @@
     <!-- QuickSettings: Wifi display [CHAR LIMIT=NONE] -->
     <string name="quick_settings_wifi_display_label">Wi-Fi Display</string>
     <!-- QuickSettings: Wifi display [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_wifi_display_no_connection_label">No Wi-Fi Display Connection</string>
+    <string name="quick_settings_wifi_display_no_connection_label">Wireless Display</string>
     <!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_title">Brightness</string>
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 90ba820..f981eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -595,6 +595,7 @@
             public void refreshView(QuickSettingsTileView view, State state) {
                 TextView tv = (TextView) view.findViewById(R.id.wifi_display_textview);
                 tv.setText(state.label);
+                tv.setCompoundDrawablesWithIntrinsicBounds(0, state.iconId, 0, 0);
                 view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 0e53617..95cb922 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.ActivityManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
 import android.content.BroadcastReceiver;
@@ -42,6 +43,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 import com.android.systemui.statusbar.policy.BrightnessController.BrightnessStateChangeCallback;
+import com.android.systemui.statusbar.policy.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 
@@ -98,16 +100,6 @@
         }
     };
 
-    /** Broadcast receiver to act on user switches to update visuals of per-user state */
-    private BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
-                onUserSwitched(intent);
-            }
-        }
-    };
-
     /** ContentObserver to determine the next alarm */
     private class NextAlarmObserver extends ContentObserver {
         public NextAlarmObserver(Handler handler) {
@@ -141,10 +133,36 @@
                     Settings.Secure.getUriFor(Settings.Secure.BUGREPORT_IN_POWER_MENU), false, this);
         }
     }
-    private Context mContext;
-    private Handler mHandler;
-    private NextAlarmObserver mNextAlarmObserver;
-    private BugreportObserver mBugreportObserver;
+
+    /** ContentObserver to watch brightness **/
+    private class BrightnessObserver extends ContentObserver {
+        public BrightnessObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onBrightnessLevelChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(
+                    Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(
+                    Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    private final Context mContext;
+    private final Handler mHandler;
+    private final CurrentUserTracker mUserTracker;
+    private final NextAlarmObserver mNextAlarmObserver;
+    private final BugreportObserver mBugreportObserver;
+    private final BrightnessObserver mBrightnessObserver;
 
     private QuickSettingsTileView mUserTile;
     private RefreshCallback mUserCallback;
@@ -209,17 +227,24 @@
     public QuickSettingsModel(Context context) {
         mContext = context;
         mHandler = new Handler();
+        mUserTracker = new CurrentUserTracker(mContext) {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                super.onReceive(context, intent);
+                onUserSwitched();
+            }
+        };
+
         mNextAlarmObserver = new NextAlarmObserver(mHandler);
         mNextAlarmObserver.startObserving();
         mBugreportObserver = new BugreportObserver(mHandler);
         mBugreportObserver.startObserving();
+        mBrightnessObserver = new BrightnessObserver(mHandler);
+        mBrightnessObserver.startObserving();
 
         IntentFilter alarmIntentFilter = new IntentFilter();
         alarmIntentFilter.addAction(Intent.ACTION_ALARM_CHANGED);
         context.registerReceiver(mAlarmIntentReceiver, alarmIntentFilter);
-
-        IntentFilter userSwitchedFilter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        context.registerReceiver(mUserSwitchedReceiver, userSwitchedFilter);
     }
 
     void updateResources() {
@@ -499,9 +524,11 @@
                 (status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON);
         if (status.getActiveDisplay() != null) {
             mWifiDisplayState.label = status.getActiveDisplay().getFriendlyDisplayName();
+            mWifiDisplayState.iconId = R.drawable.ic_qs_remote_display_connected;
         } else {
             mWifiDisplayState.label = mContext.getString(
                     R.string.quick_settings_wifi_display_no_connection_label);
+            mWifiDisplayState.iconId = R.drawable.ic_qs_remote_display;
         }
         mWifiDisplayCallback.refreshView(mWifiDisplayTile, mWifiDisplayState);
 
@@ -625,9 +652,10 @@
     @Override
     public void onBrightnessLevelChanged() {
         Resources r = mContext.getResources();
-        int mode = Settings.System.getInt(mContext.getContentResolver(),
+        int mode = Settings.System.getIntForUser(mContext.getContentResolver(),
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
-                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
+                mUserTracker.getCurrentUserId());
         mBrightnessState.autoBrightness =
                 (mode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
         mBrightnessState.iconId = mBrightnessState.autoBrightness
@@ -641,7 +669,8 @@
     }
 
     // User switch: need to update visuals of all tiles known to have per-user state
-    void onUserSwitched(Intent intent) {
+    void onUserSwitched() {
+        mBrightnessObserver.startObserving();
         onRotationLockChanged();
         onBrightnessLevelChanged();
         onNextAlarmChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
index bb59420..0009503 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
@@ -39,9 +39,11 @@
     private final int mMinimumBacklight;
     private final int mMaximumBacklight;
 
-    private Context mContext;
-    private ToggleSlider mControl;
-    private IPowerManager mPower;
+    private final Context mContext;
+    private final ToggleSlider mControl;
+    private final boolean mAutomaticAvailable;
+    private final IPowerManager mPower;
+    private final CurrentUserTracker mUserTracker;
 
     private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks =
             new ArrayList<BrightnessStateChangeCallback>();
@@ -53,20 +55,31 @@
     public BrightnessController(Context context, ToggleSlider control) {
         mContext = context;
         mControl = control;
+        mUserTracker = new CurrentUserTracker(mContext);
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mMinimumBacklight = pm.getMinimumScreenBrightnessSetting();
         mMaximumBacklight = pm.getMaximumScreenBrightnessSetting();
 
-        boolean automaticAvailable = context.getResources().getBoolean(
+        mAutomaticAvailable = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
         mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
 
-        if (automaticAvailable) {
+        control.setOnChangedListener(this);
+    }
+
+    public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
+        mChangeCallbacks.add(cb);
+    }
+
+    @Override
+    public void onInit(ToggleSlider control) {
+        if (mAutomaticAvailable) {
             int automatic;
             try {
-                automatic = Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.SCREEN_BRIGHTNESS_MODE);
+                automatic = Settings.System.getIntForUser(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_MODE,
+                        mUserTracker.getCurrentUserId());
             } catch (SettingNotFoundException snfe) {
                 automatic = 0;
             }
@@ -78,20 +91,15 @@
         
         int value;
         try {
-            value = Settings.System.getInt(mContext.getContentResolver(), 
-                    Settings.System.SCREEN_BRIGHTNESS);
+            value = Settings.System.getIntForUser(mContext.getContentResolver(),
+                    Settings.System.SCREEN_BRIGHTNESS,
+                    mUserTracker.getCurrentUserId());
         } catch (SettingNotFoundException ex) {
             value = mMaximumBacklight;
         }
 
         control.setMax(mMaximumBacklight - mMinimumBacklight);
         control.setValue(value - mMinimumBacklight);
-
-        control.setOnChangedListener(this);
-    }
-
-    public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
-        mChangeCallbacks.add(cb);
     }
 
     public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
@@ -103,8 +111,9 @@
             if (!tracking) {
                 AsyncTask.execute(new Runnable() {
                         public void run() {
-                            Settings.System.putInt(mContext.getContentResolver(), 
-                                    Settings.System.SCREEN_BRIGHTNESS, val);
+                            Settings.System.putIntForUser(mContext.getContentResolver(),
+                                    Settings.System.SCREEN_BRIGHTNESS, val,
+                                    mUserTracker.getCurrentUserId());
                         }
                     });
             }
@@ -116,8 +125,9 @@
     }
 
     private void setMode(int mode) {
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_MODE, mode);
+        Settings.System.putIntForUser(mContext.getContentResolver(),
+                Settings.System.SCREEN_BRIGHTNESS_MODE, mode,
+                mUserTracker.getCurrentUserId());
     }
     
     private void setBrightness(int brightness) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java
new file mode 100644
index 0000000..7a2f25a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java
@@ -0,0 +1,29 @@
+package com.android.systemui.statusbar.policy;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public class CurrentUserTracker extends BroadcastReceiver {
+
+    private int mCurrentUserId;
+
+    public CurrentUserTracker(Context context) {
+        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
+        context.registerReceiver(this, filter);
+        mCurrentUserId = ActivityManager.getCurrentUser();
+    }
+
+    public int getCurrentUserId() {
+        return mCurrentUserId;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
+            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
index fe2ec69..39f8fcc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ToggleSlider.java
@@ -36,6 +36,7 @@
     private static final String TAG = "StatusBar.ToggleSlider";
 
     public interface Listener {
+        public void onInit(ToggleSlider v);
         public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value);
     }
 
@@ -75,6 +76,14 @@
         a.recycle();
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (mListener != null) {
+            mListener.onInit(this);
+        }
+    }
+
     public void onCheckedChanged(CompoundButton toggle, boolean checked) {
         Drawable thumb;
         Drawable slider;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
index 43cb85e..6fee432 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -51,11 +51,15 @@
 
         mMute = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
         mVolume = mAudioManager.getStreamVolume(STREAM);
+
+        control.setOnChangedListener(this);
+    }
+
+    @Override
+    public void onInit(ToggleSlider control) {
         control.setMax(mAudioManager.getStreamMaxVolume(STREAM));
         control.setValue(mVolume);
         control.setChecked(mMute);
-
-        control.setOnChangedListener(this);
     }
 
     public void onChanged(ToggleSlider view, boolean tracking, boolean mute, int level) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3074370..e4ca8d8 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -182,56 +182,6 @@
     static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
     static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
 
-    // wallpaper is at the bottom, though the window manager may move it.
-    static final int UNIVERSE_BACKGROUND_LAYER = 1;
-    static final int WALLPAPER_LAYER = 2;
-    static final int APPLICATION_LAYER = 2;
-    static final int PHONE_LAYER = 3;
-    static final int SEARCH_BAR_LAYER = 4;
-    static final int SYSTEM_DIALOG_LAYER = 5;
-    // toasts and the plugged-in battery thing
-    static final int TOAST_LAYER = 6;
-    // SIM errors and unlock.  Not sure if this really should be in a high layer.
-    static final int PRIORITY_PHONE_LAYER = 7;
-    // like the ANR / app crashed dialogs
-    static final int SYSTEM_ALERT_LAYER = 8;
-    // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_LAYER = 9;
-    // on-screen keyboards and other such input method user interfaces go here.
-    static final int INPUT_METHOD_DIALOG_LAYER = 10;
-    // the keyguard; nothing on top of these can take focus, since they are
-    // responsible for power management when displayed.
-    static final int KEYGUARD_LAYER = 11;
-    static final int KEYGUARD_DIALOG_LAYER = 12;
-    // used for Dreams (screensavers with TYPE_DREAM windows)
-    static final int SCREENSAVER_LAYER = 13;
-    static final int STATUS_BAR_SUB_PANEL_LAYER = 14;
-    static final int STATUS_BAR_LAYER = 15;
-    static final int STATUS_BAR_PANEL_LAYER = 16;
-    // the on-screen volume indicator and controller shown when the user
-    // changes the device volume
-    static final int VOLUME_OVERLAY_LAYER = 17;
-    // things in here CAN NOT take focus, but are shown on top of everything else.
-    static final int SYSTEM_OVERLAY_LAYER = 18;
-    // the navigation bar, if available, shows atop most things
-    static final int NAVIGATION_BAR_LAYER = 19;
-    // some panels (e.g. search) need to show on top of the navigation bar
-    static final int NAVIGATION_BAR_PANEL_LAYER = 20;
-    // system-level error dialogs
-    static final int SYSTEM_ERROR_LAYER = 21;
-    // used to highlight the magnified portion of a display
-    static final int MAGNIFICATION_OVERLAY_LAYER = 22;
-    // used to simulate secondary display devices
-    static final int DISPLAY_OVERLAY_LAYER = 23;
-    // the drag layer: input for drag-and-drop is associated with this window,
-    // which sits above all other focusable windows
-    static final int DRAG_LAYER = 24;
-    static final int SECURE_SYSTEM_OVERLAY_LAYER = 25;
-    static final int BOOT_PROGRESS_LAYER = 26;
-    // the (mouse) pointer layer
-    static final int POINTER_LAYER = 27;
-    static final int HIDDEN_NAV_CONSUMER_LAYER = 28;
-
     static final int APPLICATION_MEDIA_SUBLAYER = -2;
     static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
     static final int APPLICATION_PANEL_SUBLAYER = 1;
@@ -459,8 +409,10 @@
     WindowState mTopFullscreenOpaqueWindowState;
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
+    boolean mForceStatusBarFromKeyguard;
     boolean mHideLockScreen;
     boolean mDismissKeyguard;
+    boolean mNoDreamEnterAnim;
     boolean mHomePressed;
     boolean mHomeLongPressed;
     Intent mHomeIntent;
@@ -1353,70 +1305,90 @@
     /** {@inheritDoc} */
     public int windowTypeToLayerLw(int type) {
         if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return APPLICATION_LAYER;
+            return 2;
         }
         switch (type) {
-        case TYPE_STATUS_BAR:
-            return STATUS_BAR_LAYER;
-        case TYPE_STATUS_BAR_PANEL:
-            return STATUS_BAR_PANEL_LAYER;
-        case TYPE_STATUS_BAR_SUB_PANEL:
-            return STATUS_BAR_SUB_PANEL_LAYER;
-        case TYPE_SYSTEM_DIALOG:
-            return SYSTEM_DIALOG_LAYER;
-        case TYPE_SEARCH_BAR:
-            return SEARCH_BAR_LAYER;
-        case TYPE_PHONE:
-            return PHONE_LAYER;
-        case TYPE_KEYGUARD:
-            return KEYGUARD_LAYER;
-        case TYPE_KEYGUARD_DIALOG:
-            return KEYGUARD_DIALOG_LAYER;
-        case TYPE_SYSTEM_ALERT:
-            return SYSTEM_ALERT_LAYER;
-        case TYPE_SYSTEM_ERROR:
-            return SYSTEM_ERROR_LAYER;
-        case TYPE_INPUT_METHOD:
-            return INPUT_METHOD_LAYER;
-        case TYPE_INPUT_METHOD_DIALOG:
-            return INPUT_METHOD_DIALOG_LAYER;
-        case TYPE_VOLUME_OVERLAY:
-            return VOLUME_OVERLAY_LAYER;
-        case TYPE_SYSTEM_OVERLAY:
-            return SYSTEM_OVERLAY_LAYER;
-        case TYPE_SECURE_SYSTEM_OVERLAY:
-            return SECURE_SYSTEM_OVERLAY_LAYER;
-        case TYPE_PRIORITY_PHONE:
-            return PRIORITY_PHONE_LAYER;
-        case TYPE_TOAST:
-            return TOAST_LAYER;
-        case TYPE_WALLPAPER:
-            return WALLPAPER_LAYER;
-        case TYPE_DRAG:
-            return DRAG_LAYER;
-        case TYPE_POINTER:
-            return POINTER_LAYER;
-        case TYPE_NAVIGATION_BAR:
-            return NAVIGATION_BAR_LAYER;
-        case TYPE_NAVIGATION_BAR_PANEL:
-            return NAVIGATION_BAR_PANEL_LAYER;
-        case TYPE_BOOT_PROGRESS:
-            return BOOT_PROGRESS_LAYER;
-        case TYPE_HIDDEN_NAV_CONSUMER:
-            return HIDDEN_NAV_CONSUMER_LAYER;
-        case TYPE_DREAM:
-            return SCREENSAVER_LAYER;
         case TYPE_UNIVERSE_BACKGROUND:
-            return UNIVERSE_BACKGROUND_LAYER;
-        case TYPE_DISPLAY_OVERLAY:
-            return DISPLAY_OVERLAY_LAYER;
-        case TYPE_MAGNIFICATION_OVERLAY:
-            return MAGNIFICATION_OVERLAY_LAYER;
+            return 1;
+        case TYPE_WALLPAPER:
+            // wallpaper is at the bottom, though the window manager may move it.
+            return 2;
+        case TYPE_PHONE:
+            return 3;
+        case TYPE_SEARCH_BAR:
+            return 4;
         case TYPE_RECENTS_OVERLAY:
-            return SYSTEM_DIALOG_LAYER;
+        case TYPE_SYSTEM_DIALOG:
+            return 5;
+        case TYPE_TOAST:
+            // toasts and the plugged-in battery thing
+            return 6;
+        case TYPE_PRIORITY_PHONE:
+            // SIM errors and unlock.  Not sure if this really should be in a high layer.
+            return 7;
+        case TYPE_DREAM:
+            // used for Dreams (screensavers with TYPE_DREAM windows)
+            return 8;
+        case TYPE_SYSTEM_ALERT:
+            // like the ANR / app crashed dialogs
+            return 9;
+        case TYPE_INPUT_METHOD:
+            // on-screen keyboards and other such input method user interfaces go here.
+            return 10;
+        case TYPE_INPUT_METHOD_DIALOG:
+            // on-screen keyboards and other such input method user interfaces go here.
+            return 11;
+        case TYPE_KEYGUARD:
+            // the keyguard; nothing on top of these can take focus, since they are
+            // responsible for power management when displayed.
+            return 12;
+        case TYPE_KEYGUARD_DIALOG:
+            return 13;
+        case TYPE_STATUS_BAR_SUB_PANEL:
+            return 14;
+        case TYPE_STATUS_BAR:
+            return 15;
+        case TYPE_STATUS_BAR_PANEL:
+            return 16;
+        case TYPE_VOLUME_OVERLAY:
+            // the on-screen volume indicator and controller shown when the user
+            // changes the device volume
+            return 17;
+        case TYPE_SYSTEM_OVERLAY:
+            // the on-screen volume indicator and controller shown when the user
+            // changes the device volume
+            return 18;
+        case TYPE_NAVIGATION_BAR:
+            // the navigation bar, if available, shows atop most things
+            return 19;
+        case TYPE_NAVIGATION_BAR_PANEL:
+            // some panels (e.g. search) need to show on top of the navigation bar
+            return 20;
+        case TYPE_SYSTEM_ERROR:
+            // system-level error dialogs
+            return 21;
+        case TYPE_MAGNIFICATION_OVERLAY:
+            // used to highlight the magnified portion of a display
+            return 22;
+        case TYPE_DISPLAY_OVERLAY:
+            // used to simulate secondary display devices
+            return 23;
+        case TYPE_DRAG:
+            // the drag layer: input for drag-and-drop is associated with this window,
+            // which sits above all other focusable windows
+            return 24;
+        case TYPE_SECURE_SYSTEM_OVERLAY:
+            return 25;
+        case TYPE_BOOT_PROGRESS:
+            return 26;
+        case TYPE_POINTER:
+            // the (mouse) pointer layer
+            return 27;
+        case TYPE_HIDDEN_NAV_CONSUMER:
+            return 28;
         }
         Log.e(TAG, "Unknown window type: " + type);
-        return APPLICATION_LAYER;
+        return 2;
     }
 
     /** {@inheritDoc} */
@@ -1437,11 +1409,11 @@
     }
 
     public int getMaxWallpaperLayer() {
-        return STATUS_BAR_LAYER;
+        return windowTypeToLayerLw(TYPE_STATUS_BAR);
     }
 
     public int getAboveUniverseLayer() {
-        return SYSTEM_ERROR_LAYER;
+        return windowTypeToLayerLw(TYPE_SYSTEM_ERROR);
     }
 
     public boolean hasSystemNavBar() {
@@ -1493,11 +1465,12 @@
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
         return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
     }
-    
+
     public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
         return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
                 && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                 && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER
+                && attrs.type != WindowManager.LayoutParams.TYPE_DREAM
                 && attrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
     }
 
@@ -1730,6 +1703,13 @@
                 if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT");
                 return com.android.internal.R.anim.app_starting_exit;
             }
+        } else if (win.getAttrs().type == TYPE_DREAM && mNoDreamEnterAnim
+                && transit == TRANSIT_ENTER) {
+            // Special case: we are animating in a dream, while the keyguard
+            // is shown.  We don't want an animation on the dream, because
+            // we need it shown immediately with the keyguard animating away
+            // to reveal it.
+            return -1;
         }
 
         return 0;
@@ -2919,10 +2899,12 @@
     public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
         mTopFullscreenOpaqueWindowState = null;
         mForceStatusBar = false;
+        mForceStatusBarFromKeyguard = false;
         
         mHideLockScreen = false;
         mAllowLockscreenWhenOn = false;
         mDismissKeyguard = false;
+        mNoDreamEnterAnim = false;
     }
 
     /** {@inheritDoc} */
@@ -2933,7 +2915,14 @@
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
             if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
-                mForceStatusBar = true;
+                if (attrs.type == TYPE_KEYGUARD) {
+                    mForceStatusBarFromKeyguard = true;
+                } else {
+                    mForceStatusBar = true;
+                }
+            }
+            if (attrs.type == TYPE_KEYGUARD) {
+                mNoDreamEnterAnim = true;
             }
             if (((attrs.type >= FIRST_APPLICATION_WINDOW && attrs.type <= LAST_APPLICATION_WINDOW)
                         || attrs.type == TYPE_DREAM)
@@ -2942,13 +2931,18 @@
                     && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
                 if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win);
                 mTopFullscreenOpaqueWindowState = win;
+                if (attrs.type == TYPE_DREAM) {
+                    mNoDreamEnterAnim = true;
+                }
                 if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
-                    if (localLOGV) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
+                    if (DEBUG_LAYOUT) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
                     mHideLockScreen = true;
+                    mForceStatusBarFromKeyguard = false;
                 }
                 if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
-                    if (localLOGV) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win);
+                    if (DEBUG_LAYOUT) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win);
                     mDismissKeyguard = true;
+                    mForceStatusBarFromKeyguard = false;
                 }
                 if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                     mAllowLockscreenWhenOn = true;
@@ -2968,8 +2962,9 @@
 
         if (mStatusBar != null) {
             if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar
+                    + " forcefkg=" + mForceStatusBarFromKeyguard
                     + " top=" + mTopFullscreenOpaqueWindowState);
-            if (mForceStatusBar) {
+            if (mForceStatusBar || mForceStatusBarFromKeyguard) {
                 if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced");
                 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
             } else if (mTopFullscreenOpaqueWindowState != null) {
@@ -4349,6 +4344,15 @@
         if (mFocusedWindow == null) {
             return 0;
         }
+        if (mFocusedWindow.getAttrs().type == TYPE_KEYGUARD && mHideLockScreen == true) {
+            // We are updating at a point where the keyguard has gotten
+            // focus, but we were last in a state where the top window is
+            // hiding it.  This is probably because the keyguard as been
+            // shown while the top window was displayed, so we want to ignore
+            // it here because this is just a very transient change and it
+            // will quickly lose focus once it correctly gets hidden.
+            return 0;
+        }
         final int visibility = mFocusedWindow.getSystemUiVisibility()
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
@@ -4495,9 +4499,11 @@
                 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
         pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
                 pw.println(mTopFullscreenOpaqueWindowState);
-        pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
-                pw.print(" mForceStatusBar="); pw.print(mForceStatusBar);
+            pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
                 pw.print(" mHideLockScreen="); pw.println(mHideLockScreen);
+        pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
+                pw.print(" mForceStatusBarFromKeyguard=");
+                pw.println(mForceStatusBarFromKeyguard);
         pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
                 pw.print(" mHomePressed="); pw.println(mHomePressed);
         pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index f907697..8e9362e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -65,6 +65,7 @@
     private static final String KEYGUARD_WIDGET_PREFS = "keyguard_widget_prefs";
 
     private AppWidgetHost mAppWidgetHost;
+    private KeyguardWidgetRegion mAppWidgetRegion;
     private KeyguardWidgetPager mAppWidgetContainer;
     private ViewFlipper mSecurityViewContainer;
     private KeyguardSelectorView mKeyguardSelectorView;
@@ -142,9 +143,11 @@
 
     @Override
     protected void onFinishInflate() {
+        mAppWidgetRegion = (KeyguardWidgetRegion) findViewById(R.id.kg_widget_region);
+        mAppWidgetRegion.setVisibility(VISIBLE);
+        mAppWidgetRegion.setCallbacks(mWidgetCallbacks);
+
         mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
-        KeyguardWidgetRegion kgwr = (KeyguardWidgetRegion) findViewById(R.id.kg_widget_region);
-        kgwr.setVisibility(VISIBLE);
         mSecurityViewContainer = (ViewFlipper) findViewById(R.id.view_flipper);
         mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
 
@@ -209,6 +212,33 @@
         mAppWidgetContainer.addWidget(view);
     }
 
+    private KeyguardWidgetRegion.Callbacks mWidgetCallbacks
+            = new KeyguardWidgetRegion.Callbacks() {
+        @Override
+        public void userActivity() {
+            if (mViewMediatorCallback != null) {
+                mViewMediatorCallback.userActivity();
+            }
+        }
+
+        @Override
+        public void onUserActivityTimeoutChanged() {
+            if (mViewMediatorCallback != null) {
+                mViewMediatorCallback.onUserActivityTimeoutChanged();
+            }
+        }
+    };
+
+    @Override
+    public long getUserActivityTimeout() {
+        // Currently only considering user activity timeouts needed by widgets.
+        // Could also take into account longer timeouts for certain security views.
+        if (mAppWidgetRegion != null) {
+            return mAppWidgetRegion.getUserActivityTimeout();
+        }
+        return -1;
+    }
+
     private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
 
         public void userActivity(long timeout) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
index ad5de0e..3191f4a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
@@ -137,6 +137,12 @@
      */
     abstract public void cleanUp();
 
+    /**
+     * Gets the desired user activity timeout in milliseconds, or -1 if the
+     * default should be used.
+     */
+    abstract public long getUserActivityTimeout();
+
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (interceptMediaKey(event)) {
@@ -250,5 +256,4 @@
             KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
         mViewMediatorCallback = viewMediatorCallback;
     }
-
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index b0f5596..33ff71e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -184,12 +184,13 @@
                 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
             }
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-            lp.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
             lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard");
             mWindowLayoutParams = lp;
             mViewManager.addView(mKeyguardHost, lp);
         }
+
         inflateKeyguardView(options);
+        updateUserActivityTimeoutInWindowLayoutParams();
         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
 
         mKeyguardHost.restoreHierarchyState(mStateContainer);
@@ -224,6 +225,25 @@
         }
     }
 
+    public void updateUserActivityTimeout() {
+        updateUserActivityTimeoutInWindowLayoutParams();
+        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+    }
+
+    private void updateUserActivityTimeoutInWindowLayoutParams() {
+        // Use the user activity timeout requested by the keyguard view, if any.
+        if (mKeyguardView != null) {
+            long timeout = mKeyguardView.getUserActivityTimeout();
+            if (timeout >= 0) {
+                mWindowLayoutParams.userActivityTimeout = timeout;
+                return;
+            }
+        }
+
+        // Otherwise, use the default timeout.
+        mWindowLayoutParams.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
+    }
+
     private void maybeEnableScreenRotation(boolean enableScreenRotation) {
         // TODO: move this outside
         if (enableScreenRotation) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 1ca85b4..3ed952c 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -259,9 +259,14 @@
         void wakeUp();
 
         /**
-         * Reports user activity and requests that the screen stay on for the specified
-         * amount of time.
-         * @param millis The amount of time in millis.
+         * Reports user activity and requests that the screen stay on.
+         */
+        void userActivity();
+
+        /**
+         * Reports user activity and requests that the screen stay on for at least
+         * the specified amount of time.
+         * @param millis The amount of time in millis.  This value is currently ignored.
          */
         void userActivity(long millis);
 
@@ -284,6 +289,12 @@
          * @param needsInput
          */
         void setNeedsInput(boolean needsInput);
+
+        /**
+         * Tell view mediator that the keyguard view's desired user activity timeout
+         * has changed and needs to be reapplied to the window.
+         */
+        void onUserActivityTimeoutChanged();
     }
 
     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@@ -400,6 +411,10 @@
             KeyguardViewMediator.this.wakeUp();
         }
 
+        public void userActivity() {
+            KeyguardViewMediator.this.userActivity();
+        }
+
         public void userActivity(long holdMs) {
             KeyguardViewMediator.this.userActivity(holdMs);
         }
@@ -416,6 +431,11 @@
         public void setNeedsInput(boolean needsInput) {
             mKeyguardViewManager.setNeedsInput(needsInput);
         }
+
+        @Override
+        public void onUserActivityTimeoutChanged() {
+            mKeyguardViewManager.updateUserActivityTimeout();
+        }
     };
 
     public void wakeUp() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
index e9ea2c3..47bf85b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
@@ -16,8 +16,6 @@
 package com.android.internal.policy.impl.keyguard;
 
 import android.content.Context;
-import android.os.PowerManager;
-import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
@@ -31,7 +29,9 @@
     KeyguardGlowStripView mRightStrip;
     KeyguardWidgetPager mPager;
     private int mPage = 0;
-    private PowerManager mPowerManager;
+    private Callbacks mCallbacks;
+
+    private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
 
     public KeyguardWidgetRegion(Context context) {
         this(context, null, 0);
@@ -43,7 +43,6 @@
 
     public KeyguardWidgetRegion(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
     }
 
     @Override
@@ -75,9 +74,10 @@
     @Override
     public void onPageSwitch(View newPage, int newPageIndex) {
         boolean showingStatusWidget = false;
-        if ((newPage instanceof ViewGroup)) {
+        if (newPage instanceof ViewGroup) {
             ViewGroup vg = (ViewGroup) newPage;
-            if (vg.getChildAt(0) instanceof KeyguardStatusView) {
+            View view = vg.getChildAt(0);
+            if (view instanceof KeyguardStatusView) {
                 showingStatusWidget = true;
             }
         }
@@ -91,8 +91,33 @@
 
         // Extend the display timeout if the user switches pages
         if (mPage != newPageIndex) {
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
             mPage = newPageIndex;
+            if (mCallbacks != null) {
+                mCallbacks.onUserActivityTimeoutChanged();
+                mCallbacks.userActivity();
+            }
         }
     }
+
+    public long getUserActivityTimeout() {
+        View page = mPager.getPageAt(mPage);
+        if (page instanceof ViewGroup) {
+            ViewGroup vg = (ViewGroup) page;
+            View view = vg.getChildAt(0);
+            if (!(view instanceof KeyguardStatusView)
+                    && !(view instanceof KeyguardMultiUserSelectorView)) {
+                return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT;
+            }
+        }
+        return -1;
+    }
+
+    public void setCallbacks(Callbacks callbacks) {
+        mCallbacks = callbacks;
+    }
+
+    public interface Callbacks {
+        public void userActivity();
+        public void onUserActivityTimeoutChanged();
+    }
 }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 5e9e223..6782f5e 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -643,6 +643,10 @@
         return mSecurityPolicy.mActiveWindowId;
     }
 
+    void onTouchInteractionEnd() {
+        mSecurityPolicy.onTouchInteractionEnd();
+    }
+
     private void switchUser(int userId) {
         synchronized (mLock) {
             // The user switched so we do not need to restore the current user
@@ -2178,16 +2182,24 @@
                         mActiveWindowId = windowId;
                     }
                 } break;
-                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
-                case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: {
+                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
                     mActiveWindowId = windowId;
                 } break;
-                case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END: {
-                    mActiveWindowId = getFocusedWindowId();
-                } break;
             }
         }
 
+        public void onTouchInteractionEnd() {
+            // We want to set the active window to be current immediately
+            // after the user has stopped touching the screen since if the
+            // user types with the IME he should get a feedback for the
+            // letter typed in the text view which is in the input focused
+            // window. Note that we always deliver hover accessibility events
+            // (they are a result of user touching the screen) so change of
+            // the active window before all hover accessibility events from
+            // the touched window are delivered is fine.
+            mActiveWindowId = getFocusedWindowId();
+        }
+
         public int getRetrievalAllowingWindowLocked() {
             return mActiveWindowId;
         }
diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java
index ec3c88c..51ccd47 100644
--- a/services/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -846,7 +846,6 @@
     private static final class DisplayContentObserver {
 
         private static final int MESSAGE_SHOW_VIEWPORT_FRAME = 1;
-        private static final int MESSAGE_RECOMPUTE_VIEWPORT_BOUNDS = 2;
         private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 3;
         private static final int MESSAGE_ON_WINDOW_TRANSITION = 4;
         private static final int MESSAGE_ON_ROTATION_CHANGED = 5;
@@ -892,7 +891,9 @@
                                 || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
                             && (transition == WindowManagerPolicy.TRANSIT_EXIT
                                 || transition == WindowManagerPolicy.TRANSIT_HIDE)) {
-                        mHandler.sendMessageDelayed(message, mLongAnimationDuration);
+                        final long delay = (long) (2 * mLongAnimationDuration
+                                * mWindowAnimationScale);
+                        mHandler.sendMessageDelayed(message, delay);
                     } else {
                         message.sendToTarget();
                     }
@@ -1170,10 +1171,6 @@
                     case MESSAGE_SHOW_VIEWPORT_FRAME: {
                         mViewport.setFrameShown(true, true);
                     } break;
-                    case MESSAGE_RECOMPUTE_VIEWPORT_BOUNDS: {
-                        final boolean animate = message.arg1 == 1;
-                        mViewport.recomputeBounds(animate);
-                    } break;
                     case MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
                         SomeArgs args = (SomeArgs) message.obj;
                         try {
@@ -1526,8 +1523,10 @@
             Rect magnifiedFrame = mTempRect1;
             magnifiedFrame.set(0, 0, 0, 0);
 
-            Rect notMagnifiedFrame = mTempRect2;
-            notMagnifiedFrame.set(0, 0, 0, 0);
+            DisplayInfo displayInfo = mDisplayProvider.getDisplayInfo();
+
+            Rect availableFrame = mTempRect2;
+            availableFrame.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
 
             ArrayList<WindowInfo> infos = mTempWindowInfoList;
             infos.clear();
@@ -1542,18 +1541,16 @@
                     if (info.type == WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
                         continue;
                     }
+                    Rect windowFrame = mTempRect3;
+                    windowFrame.set(info.touchableRegion);
                     if (isWindowMagnified(info.type)) {
-                        Rect clippedFrame = mTempRect3;
-                        clippedFrame.set(info.touchableRegion);
-                        subtract(clippedFrame, notMagnifiedFrame);
-                        magnifiedFrame.union(clippedFrame);
+                        magnifiedFrame.union(windowFrame);
+                        magnifiedFrame.intersect(availableFrame);
                     } else {
-                        Rect clippedFrame = mTempRect3;
-                        clippedFrame.set(info.touchableRegion);
-                        subtract(clippedFrame, magnifiedFrame);
-                        notMagnifiedFrame.union(clippedFrame);
+                        subtract(windowFrame, magnifiedFrame);
+                        subtract(availableFrame, windowFrame);
                     }
-                    if (magnifiedFrame.bottom >= notMagnifiedFrame.top) {
+                    if (availableFrame.equals(magnifiedFrame)) {
                         break;
                     }
                 }
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index b3bf6fe..2688776 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -304,6 +304,7 @@
             mNext.clear();
         }
         mTouchExplorationInProgress = false;
+        mAms.onTouchInteractionEnd();
     }
 
     @Override
@@ -615,6 +616,7 @@
                 }
             } break;
             case MotionEvent.ACTION_UP:
+                mAms.onTouchInteractionEnd();
                 // We know that we do not need the pre-fed gesture points are not
                 // needed anymore since the last pointer just went up.
                 mStrokeBuffer.clear();
@@ -737,6 +739,7 @@
                  }
             } break;
             case MotionEvent.ACTION_UP: {
+                mAms.onTouchInteractionEnd();
                 // Announce the end of a new touch interaction.
                 sendAccessibilityEvent(
                         AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
@@ -782,6 +785,7 @@
                         AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
                 //$FALL-THROUGH$
             case MotionEvent.ACTION_POINTER_UP: {
+                mAms.onTouchInteractionEnd();
                 mLongPressingPointerId = -1;
                 mLongPressingPointerDeltaX = 0;
                 mLongPressingPointerDeltaY = 0;
@@ -819,6 +823,7 @@
                 }
             } break;
             case MotionEvent.ACTION_UP: {
+                mAms.onTouchInteractionEnd();
                 // Announce the end of gesture recognition.
                 sendAccessibilityEvent(
                         AccessibilityEvent.TYPE_GESTURE_DETECTION_END);
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 23df701..a1c1fa6 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -89,6 +89,9 @@
     // auto-brightness adjustment setting.
     private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
 
+    // The minimum reduction in brightness when dimmed.
+    private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
+
     // If true, enables the use of the current time as an auto-brightness adjustment.
     // The basic idea here is to expand the dynamic range of auto-brightness
     // when it is especially dark outside.  The light sensor tends to perform
@@ -185,6 +188,12 @@
     // The dim screen brightness.
     private final int mScreenBrightnessDimConfig;
 
+    // The minimum allowed brightness.
+    private final int mScreenBrightnessRangeMinimum;
+
+    // The maximum allowed brightness.
+    private final int mScreenBrightnessRangeMaximum;
+
     // True if auto-brightness should be used.
     private boolean mUseSoftwareAutoBrightnessConfig;
 
@@ -343,8 +352,14 @@
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
 
         final Resources resources = context.getResources();
-        mScreenBrightnessDimConfig = resources.getInteger(
-                com.android.internal.R.integer.config_screenBrightnessDim);
+
+        mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
+                com.android.internal.R.integer.config_screenBrightnessDim));
+
+        int screenBrightnessMinimum = Math.min(resources.getInteger(
+                com.android.internal.R.integer.config_screenBrightnessSettingMinimum),
+                mScreenBrightnessDimConfig);
+
         mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
         if (mUseSoftwareAutoBrightnessConfig) {
@@ -362,12 +377,19 @@
                         + "which must be strictly increasing.  "
                         + "Auto-brightness will be disabled.");
                 mUseSoftwareAutoBrightnessConfig = false;
+            } else {
+                if (screenBrightness[0] < screenBrightnessMinimum) {
+                    screenBrightnessMinimum = screenBrightness[0];
+                }
             }
 
             mLightSensorWarmUpTimeConfig = resources.getInteger(
                     com.android.internal.R.integer.config_lightSensorWarmupTime);
         }
 
+        mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum);
+        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
+
         mElectronBeamAnimatesBacklightConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_animateScreenLights);
 
@@ -394,14 +416,14 @@
             final int n = brightness.length;
             float[] x = new float[n];
             float[] y = new float[n];
-            y[0] = (float)brightness[0] / PowerManager.BRIGHTNESS_ON;
+            y[0] = normalizeAbsoluteBrightness(brightness[0]);
             for (int i = 1; i < n; i++) {
                 x[i] = lux[i - 1];
-                y[i] = (float)brightness[i] / PowerManager.BRIGHTNESS_ON;
+                y[i] = normalizeAbsoluteBrightness(brightness[i]);
             }
 
             Spline spline = Spline.createMonotoneCubicSpline(x, y);
-            if (false) {
+            if (DEBUG) {
                 Slog.d(TAG, "Auto-brightness spline: " + spline);
                 for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
                     Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
@@ -602,30 +624,31 @@
         }
 
         // Set the screen brightness.
-        if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
-            // Screen is dimmed.  Overrides everything else.
-            animateScreenBrightness(
-                    clampScreenBrightness(mScreenBrightnessDimConfig),
-                    BRIGHTNESS_RAMP_RATE_FAST);
-            mUsingScreenAutoBrightness = false;
-        } else if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_BRIGHT) {
+        if (wantScreenOn(mPowerRequest.screenState)) {
+            int target;
+            boolean slow;
             if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
                 // Use current auto-brightness value.
-                animateScreenBrightness(
-                        clampScreenBrightness(mScreenAutoBrightness),
-                        mUsingScreenAutoBrightness ? BRIGHTNESS_RAMP_RATE_SLOW :
-                                BRIGHTNESS_RAMP_RATE_FAST);
+                target = mScreenAutoBrightness;
+                slow = mUsingScreenAutoBrightness;
                 mUsingScreenAutoBrightness = true;
             } else {
                 // Light sensor is disabled or not ready yet.
                 // Use the current brightness setting from the request, which is expected
                 // provide a nominal default value for the case where auto-brightness
                 // is not ready yet.
-                animateScreenBrightness(
-                        clampScreenBrightness(mPowerRequest.screenBrightness),
-                        BRIGHTNESS_RAMP_RATE_FAST);
+                target = mPowerRequest.screenBrightness;
+                slow = false;
                 mUsingScreenAutoBrightness = false;
             }
+            if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM) {
+                // Screen is dimmed.  Sets an upper bound on everything else.
+                target = Math.min(target - SCREEN_DIM_MINIMUM_REDUCTION,
+                        mScreenBrightnessDimConfig);
+                slow = false;
+            }
+            animateScreenBrightness(clampScreenBrightness(target),
+                    slow ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
         } else {
             // Screen is off.  Don't bother changing the brightness.
             mUsingScreenAutoBrightness = false;
@@ -729,7 +752,25 @@
     }
 
     private int clampScreenBrightness(int value) {
-        return Math.min(Math.max(Math.max(value, mScreenBrightnessDimConfig), 0), 255);
+        return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
+    }
+
+    private static int clampAbsoluteBrightness(int value) {
+        return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
+    }
+
+    private static int clamp(int value, int min, int max) {
+        if (value <= min) {
+            return min;
+        }
+        if (value >= max) {
+            return max;
+        }
+        return value;
+    }
+
+    private static float normalizeAbsoluteBrightness(int value) {
+        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
     }
 
     private void animateScreenBrightness(int target, int rate) {
@@ -1055,6 +1096,8 @@
         pw.println();
         pw.println("Display Controller Configuration:");
         pw.println("  mScreenBrightnessDimConfig=" + mScreenBrightnessDimConfig);
+        pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
+        pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
         pw.println("  mUseSoftwareAutoBrightnessConfig="
                 + mUseSoftwareAutoBrightnessConfig);
         pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0089046..545d1a9 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8237,7 +8237,9 @@
         int seq = mLayoutSeq+1;
         if (seq < 0) seq = 0;
         mLayoutSeq = seq;
-        
+
+        boolean behindDream = false;
+
         // First perform layout of any root windows (not attached
         // to another window).
         int topAttached = -1;
@@ -8247,7 +8249,8 @@
             // Don't do layout of a window if it is not visible, or
             // soon won't be visible, to avoid wasting time and funky
             // changes while a window is animating away.
-            final boolean gone = win.isGoneForLayoutLw();
+            final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
+                    || win.isGoneForLayoutLw();
 
             if (DEBUG_LAYOUT && !win.mLayoutAttached) {
                 Slog.v(TAG, "1ST PASS " + win
@@ -8282,6 +8285,12 @@
                         //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
                         win.mContentChanged = false;
                     }
+                    if (win.mAttrs.type == TYPE_DREAM) {
+                        // Don't layout windows behind a dream, so that if it
+                        // does stuff like hide the status bar we won't get a
+                        // bad transition when it goes away.
+                        behindDream = true;
+                    }
                     win.mLayoutNeeded = false;
                     win.prelayout();
                     mPolicy.layoutWindowLw(win, win.mAttrs, null);
@@ -8306,6 +8315,8 @@
             mAnimator.mUniverseBackground = universeBackground;
         }
 
+        boolean attachedBehindDream = false;
+
         // Now perform layout of attached windows, which usually
         // depend on the position of the window they are attached to.
         // XXX does not deal with windows that are attached to windows
@@ -8323,6 +8334,9 @@
                 // if they want.  (We do the normal layout for INVISIBLE
                 // windows, since that means "perform layout as normal,
                 // just don't display").
+                if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
+                    continue;
+                }
                 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
                         || !win.mHaveFrame || win.mLayoutNeeded) {
                     if (initial) {
@@ -8338,6 +8352,11 @@
                             + win.mContainingFrame + " mDisplayFrame="
                             + win.mDisplayFrame);
                 }
+            } else if (win.mAttrs.type == TYPE_DREAM) {
+                // Don't layout windows behind a dream, so that if it
+                // does stuff like hide the status bar we won't get a
+                // bad transition when it goes away.
+                attachedBehindDream = behindDream;
             }
         }
         
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 817a234..43f7a08 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -1500,7 +1500,7 @@
             int attr = -1;
             Animation a = null;
             if (anim != 0) {
-                a = AnimationUtils.loadAnimation(mContext, anim);
+                a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
             } else {
                 switch (transit) {
                     case WindowManagerPolicy.TRANSIT_ENTER: