Merge "Fix camera disambiguation in secure keyguard" into jb-mr1-dev
diff --git a/api/17.txt b/api/17.txt
index 5406157..1a6657c 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -5827,6 +5827,7 @@
     field public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED";
     field public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY";
     field public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED";
+    field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -18809,11 +18810,14 @@
     field public static final java.lang.String ADB_ENABLED = "adb_enabled";
     field public static final java.lang.String AIRPLANE_MODE_ON = "airplane_mode_on";
     field public static final java.lang.String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
+    field public static final java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
+    field public static final java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
     field public static final java.lang.String AUTO_TIME = "auto_time";
     field public static final java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
     field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DATA_ROAMING = "data_roaming";
+    field public static final java.lang.String DEBUG_APP = "debug_app";
     field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
     field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
     field public static final java.lang.String HTTP_PROXY = "http_proxy";
@@ -18824,10 +18828,13 @@
     field public static final java.lang.String RADIO_CELL = "cell";
     field public static final java.lang.String RADIO_NFC = "nfc";
     field public static final java.lang.String RADIO_WIFI = "wifi";
+    field public static final java.lang.String SHOW_PROCESSES = "show_processes";
     field public static final java.lang.String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
     field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_global_version";
+    field public static final java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
     field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
     field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
+    field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
     field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
     field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
     field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -18839,6 +18846,7 @@
     field public static final int WIFI_SLEEP_POLICY_NEVER = 2; // 0x2
     field public static final int WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED = 1; // 0x1
     field public static final java.lang.String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
+    field public static final java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
   }
 
   public static class Settings.NameValueTable implements android.provider.BaseColumns {
@@ -18953,9 +18961,9 @@
     field public static final deprecated java.lang.String AIRPLANE_MODE_ON = "airplane_mode_on";
     field public static final deprecated java.lang.String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
     field public static final java.lang.String ALARM_ALERT = "alarm_alert";
-    field public static final java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
+    field public static final deprecated java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
     field public static final deprecated java.lang.String ANDROID_ID = "android_id";
-    field public static final java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
+    field public static final deprecated java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
     field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
     field public static final deprecated java.lang.String AUTO_TIME = "auto_time";
     field public static final deprecated java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
@@ -18965,7 +18973,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final deprecated java.lang.String DATA_ROAMING = "data_roaming";
     field public static final java.lang.String DATE_FORMAT = "date_format";
-    field public static final java.lang.String DEBUG_APP = "debug_app";
+    field public static final deprecated java.lang.String DEBUG_APP = "debug_app";
     field public static final android.net.Uri DEFAULT_ALARM_ALERT_URI;
     field public static final android.net.Uri DEFAULT_NOTIFICATION_URI;
     field public static final android.net.Uri DEFAULT_RINGTONE_URI;
@@ -19004,7 +19012,7 @@
     field public static final deprecated java.lang.String SETTINGS_CLASSNAME = "settings_classname";
     field public static final java.lang.String SETUP_WIZARD_HAS_RUN = "setup_wizard_has_run";
     field public static final java.lang.String SHOW_GTALK_SERVICE_STATUS = "SHOW_GTALK_SERVICE_STATUS";
-    field public static final java.lang.String SHOW_PROCESSES = "show_processes";
+    field public static final deprecated java.lang.String SHOW_PROCESSES = "show_processes";
     field public static final deprecated java.lang.String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
     field public static final java.lang.String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
     field public static final deprecated java.lang.String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
@@ -19014,7 +19022,7 @@
     field public static final java.lang.String TEXT_AUTO_REPLACE = "auto_replace";
     field public static final java.lang.String TEXT_SHOW_PASSWORD = "show_password";
     field public static final java.lang.String TIME_12_24 = "time_12_24";
-    field public static final java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
+    field public static final deprecated java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
     field public static final deprecated java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
     field public static final java.lang.String USER_ROTATION = "user_rotation";
     field public static final deprecated java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
@@ -19027,8 +19035,8 @@
     field public static final java.lang.String[] VOLUME_SETTINGS;
     field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
     field public static final java.lang.String VOLUME_VOICE = "volume_voice";
-    field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
-    field public static final java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
+    field public static final deprecated java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+    field public static final deprecated java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
     field public static final deprecated java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
     field public static final deprecated java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
     field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -19056,7 +19064,7 @@
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
-    field public static final java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
+    field public static final deprecated java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
   }
 
   public class SyncStateContract {
diff --git a/api/current.txt b/api/current.txt
index 5205856..4e7d012 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5832,6 +5832,7 @@
     field public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED";
     field public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY";
     field public static final java.lang.String ACTION_PROVIDER_CHANGED = "android.intent.action.PROVIDER_CHANGED";
+    field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -18814,11 +18815,14 @@
     field public static final java.lang.String ADB_ENABLED = "adb_enabled";
     field public static final java.lang.String AIRPLANE_MODE_ON = "airplane_mode_on";
     field public static final java.lang.String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
+    field public static final java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
+    field public static final java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
     field public static final java.lang.String AUTO_TIME = "auto_time";
     field public static final java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
     field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DATA_ROAMING = "data_roaming";
+    field public static final java.lang.String DEBUG_APP = "debug_app";
     field public static final java.lang.String DEVELOPMENT_SETTINGS_ENABLED = "development_settings_enabled";
     field public static final java.lang.String DEVICE_PROVISIONED = "device_provisioned";
     field public static final java.lang.String HTTP_PROXY = "http_proxy";
@@ -18829,10 +18833,13 @@
     field public static final java.lang.String RADIO_CELL = "cell";
     field public static final java.lang.String RADIO_NFC = "nfc";
     field public static final java.lang.String RADIO_WIFI = "wifi";
+    field public static final java.lang.String SHOW_PROCESSES = "show_processes";
     field public static final java.lang.String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
     field public static final java.lang.String SYS_PROP_SETTING_VERSION = "sys.settings_global_version";
+    field public static final java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
     field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
     field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
+    field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
     field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
     field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
     field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -18844,6 +18851,7 @@
     field public static final int WIFI_SLEEP_POLICY_NEVER = 2; // 0x2
     field public static final int WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED = 1; // 0x1
     field public static final java.lang.String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
+    field public static final java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
   }
 
   public static class Settings.NameValueTable implements android.provider.BaseColumns {
@@ -18958,9 +18966,9 @@
     field public static final deprecated java.lang.String AIRPLANE_MODE_ON = "airplane_mode_on";
     field public static final deprecated java.lang.String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
     field public static final java.lang.String ALARM_ALERT = "alarm_alert";
-    field public static final java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
+    field public static final deprecated java.lang.String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
     field public static final deprecated java.lang.String ANDROID_ID = "android_id";
-    field public static final java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
+    field public static final deprecated java.lang.String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
     field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible";
     field public static final deprecated java.lang.String AUTO_TIME = "auto_time";
     field public static final deprecated java.lang.String AUTO_TIME_ZONE = "auto_time_zone";
@@ -18970,7 +18978,7 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final deprecated java.lang.String DATA_ROAMING = "data_roaming";
     field public static final java.lang.String DATE_FORMAT = "date_format";
-    field public static final java.lang.String DEBUG_APP = "debug_app";
+    field public static final deprecated java.lang.String DEBUG_APP = "debug_app";
     field public static final android.net.Uri DEFAULT_ALARM_ALERT_URI;
     field public static final android.net.Uri DEFAULT_NOTIFICATION_URI;
     field public static final android.net.Uri DEFAULT_RINGTONE_URI;
@@ -19009,7 +19017,7 @@
     field public static final deprecated java.lang.String SETTINGS_CLASSNAME = "settings_classname";
     field public static final java.lang.String SETUP_WIZARD_HAS_RUN = "setup_wizard_has_run";
     field public static final java.lang.String SHOW_GTALK_SERVICE_STATUS = "SHOW_GTALK_SERVICE_STATUS";
-    field public static final java.lang.String SHOW_PROCESSES = "show_processes";
+    field public static final deprecated java.lang.String SHOW_PROCESSES = "show_processes";
     field public static final deprecated java.lang.String SHOW_WEB_SUGGESTIONS = "show_web_suggestions";
     field public static final java.lang.String SOUND_EFFECTS_ENABLED = "sound_effects_enabled";
     field public static final deprecated java.lang.String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
@@ -19019,7 +19027,7 @@
     field public static final java.lang.String TEXT_AUTO_REPLACE = "auto_replace";
     field public static final java.lang.String TEXT_SHOW_PASSWORD = "show_password";
     field public static final java.lang.String TIME_12_24 = "time_12_24";
-    field public static final java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
+    field public static final deprecated java.lang.String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
     field public static final deprecated java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled";
     field public static final java.lang.String USER_ROTATION = "user_rotation";
     field public static final deprecated java.lang.String USE_GOOGLE_MAIL = "use_google_mail";
@@ -19032,8 +19040,8 @@
     field public static final java.lang.String[] VOLUME_SETTINGS;
     field public static final java.lang.String VOLUME_SYSTEM = "volume_system";
     field public static final java.lang.String VOLUME_VOICE = "volume_voice";
-    field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
-    field public static final java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
+    field public static final deprecated java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+    field public static final deprecated java.lang.String WALLPAPER_ACTIVITY = "wallpaper_activity";
     field public static final deprecated java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count";
     field public static final deprecated java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms";
     field public static final deprecated java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on";
@@ -19061,7 +19069,7 @@
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
     field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
-    field public static final java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
+    field public static final deprecated java.lang.String WINDOW_ANIMATION_SCALE = "window_animation_scale";
   }
 
   public class SyncStateContract {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6ef3651..ef9f6d4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2700,6 +2700,7 @@
                 r.activity.mStartedActivity = false;
             }
             try {
+                r.activity.mFragments.noteStateNotSaved();
                 if (r.pendingIntents != null) {
                     deliverNewIntents(r, r.pendingIntents);
                     r.pendingIntents = null;
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a9ccef0..3ecafc3 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -50,6 +50,7 @@
     private boolean mRemoteActive;
     private boolean mToggleMode;
     private boolean mCheatSheetEnabled;
+    private boolean mIsConnecting;
 
     private int mMinWidth;
     private int mMinHeight;
@@ -57,6 +58,10 @@
     private OnClickListener mExtendedSettingsClickListener;
     private MediaRouteChooserDialogFragment mDialogFragment;
 
+    private static final int[] CHECKED_STATE_SET = {
+        R.attr.state_checked
+    };
+
     private static final int[] ACTIVATED_STATE_SET = {
         R.attr.state_activated
     };
@@ -210,10 +215,21 @@
     }
 
     void updateRemoteIndicator() {
-        final boolean isRemote =
-                mRouter.getSelectedRoute(mRouteTypes) != mRouter.getSystemAudioRoute();
+        final RouteInfo selected = mRouter.getSelectedRoute(mRouteTypes);
+        final boolean isRemote = selected != mRouter.getSystemAudioRoute();
+        final boolean isConnecting = selected.getStatusCode() == RouteInfo.STATUS_CONNECTING;
+
+        boolean needsRefresh = false;
         if (mRemoteActive != isRemote) {
             mRemoteActive = isRemote;
+            needsRefresh = true;
+        }
+        if (mIsConnecting != isConnecting) {
+            mIsConnecting = isConnecting;
+            needsRefresh = true;
+        }
+
+        if (needsRefresh) {
             refreshDrawableState();
         }
     }
@@ -248,7 +264,14 @@
     @Override
     protected int[] onCreateDrawableState(int extraSpace) {
         final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-        if (mRemoteActive) {
+
+        // Technically we should be handling this more completely, but these
+        // are implementation details here. Checked is used to express the connecting
+        // drawable state and it's mutually exclusive with activated for the purposes
+        // of state selection here.
+        if (mIsConnecting) {
+            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
+        } else if (mRemoteActive) {
             mergeDrawableStates(drawableState, ACTIVATED_STATE_SET);
         }
         return drawableState;
@@ -426,6 +449,11 @@
         }
 
         @Override
+        public void onRouteChanged(MediaRouter router, RouteInfo info) {
+            updateRemoteIndicator();
+        }
+
+        @Override
         public void onRouteAdded(MediaRouter router, RouteInfo info) {
             updateRouteCount();
         }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d4f6c06..c14a703 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2414,6 +2414,12 @@
     public static final String ACTION_USER_INFO_CHANGED =
             "android.intent.action.USER_INFO_CHANGED";
 
+    /**
+     * Sent when the user taps on the clock widget in the system's "quick settings" area.
+     */
+    public static final String ACTION_QUICK_CLOCK =
+            "android.intent.action.QUICK_CLOCK";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index cf3b802..f07002e 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -683,8 +683,8 @@
                 com.android.internal.R.layout.input_method, null);
         mWindow.setContentView(mRootView);
         mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
-        if (Settings.System.getInt(getContentResolver(),
-                Settings.System.FANCY_IME_ANIMATIONS, 0) != 0) {
+        if (Settings.Global.getInt(getContentResolver(),
+                Settings.Global.FANCY_IME_ANIMATIONS, 0) != 0) {
             mWindow.getWindow().setWindowAnimations(
                     com.android.internal.R.style.Animation_InputMethodFancy);
         }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 5345a6d..557d3f3 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -40,7 +40,6 @@
     void reboot(String reason);
     void crash(String message);
 
-    void setPokeLock(int pokey, IBinder lock, String tag);
     void setStayOnSetting(int val);
     void setMaximumScreenOffTimeoutFromDeviceAdmin(int timeMs);
 
diff --git a/core/java/android/os/LocalPowerManager.java b/core/java/android/os/LocalPowerManager.java
deleted file mode 100644
index 519315c..0000000
--- a/core/java/android/os/LocalPowerManager.java
+++ /dev/null
@@ -1,28 +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 */
-public interface LocalPowerManager {
-    // FIXME: Replace poke locks with something else.
-
-    public static final int POKE_LOCK_IGNORE_TOUCH_EVENTS = 0x1;
-
-    public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2;
-    public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4;
-    public static final int POKE_LOCK_TIMEOUT_MASK = 0x6;
-}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 58372f4..ae50ddb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -340,6 +340,15 @@
     }
 
     /**
+     * Returns true if the twilight service should be used to adjust screen brightness
+     * policy.  This setting is experimental and disabled by default.
+     * @hide
+     */
+    public static boolean useTwilightAdjustmentFeature() {
+        return SystemProperties.getBoolean("persist.power.usetwilightadj", false);
+    }
+
+    /**
      * Creates a new wake lock with the specified level and flags.
      * <p>
      * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8f1210b..2a8cf21 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -19,6 +19,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.SearchManager;
+import android.app.WallpaperManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -940,6 +941,17 @@
             MOVED_TO_GLOBAL.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_SLEEP_POLICY);
             MOVED_TO_GLOBAL.add(Settings.Global.MODE_RINGER);
+            MOVED_TO_GLOBAL.add(Settings.Global.WINDOW_ANIMATION_SCALE);
+            MOVED_TO_GLOBAL.add(Settings.Global.TRANSITION_ANIMATION_SCALE);
+            MOVED_TO_GLOBAL.add(Settings.Global.ANIMATOR_DURATION_SCALE);
+            MOVED_TO_GLOBAL.add(Settings.Global.FANCY_IME_ANIMATIONS);
+            MOVED_TO_GLOBAL.add(Settings.Global.COMPATIBILITY_MODE);
+            MOVED_TO_GLOBAL.add(Settings.Global.EMERGENCY_TONE);
+            MOVED_TO_GLOBAL.add(Settings.Global.CALL_AUTO_RETRY);
+            MOVED_TO_GLOBAL.add(Settings.Global.DEBUG_APP);
+            MOVED_TO_GLOBAL.add(Settings.Global.WAIT_FOR_DEBUGGER);
+            MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
+            MOVED_TO_GLOBAL.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES);
         }
 
         /**
@@ -1608,14 +1620,20 @@
 
         /**
          * Name of an application package to be debugged.
+         *
+         * @deprecated Use {@link Global#DEBUG_APP} instead
          */
-        public static final String DEBUG_APP = "debug_app";
+        @Deprecated
+        public static final String DEBUG_APP = Global.DEBUG_APP;
 
         /**
          * If 1, when launching DEBUG_APP it will wait for the debugger before
          * starting user code.  If 0, it will run normally.
+         *
+         * @deprecated Use {@link Global#WAIT_FOR_DEBUGGER} instead
          */
-        public static final String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+        @Deprecated
+        public static final String WAIT_FOR_DEBUGGER = Global.WAIT_FOR_DEBUGGER;
 
         /**
          * Whether or not to dim the screen. 0=no  1=yes
@@ -1630,14 +1648,6 @@
         public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
 
         /**
-         * If 0, the compatibility mode is off for all applications.
-         * If 1, older applications run under compatibility mode.
-         * TODO: remove this settings before code freeze (bug/1907571)
-         * @hide
-         */
-        public static final String COMPATIBILITY_MODE = "compatibility_mode";
-
-        /**
          * The screen backlight brightness between 0 and 255.
          */
         public static final String SCREEN_BRIGHTNESS = "screen_brightness";
@@ -1666,16 +1676,21 @@
 
         /**
          * Control whether the process CPU usage meter should be shown.
+         *
+         * @deprecated Use {@link Global#SHOW_PROCESSES} instead
          */
-        public static final String SHOW_PROCESSES = "show_processes";
+        @Deprecated
+        public static final String SHOW_PROCESSES = Global.SHOW_PROCESSES;
 
         /**
          * If 1, the activity manager will aggressively finish activities and
          * processes as soon as they are no longer needed.  If 0, the normal
          * extended lifetime is used.
+         *
+         * @deprecated Use {@link Global#ALWAYS_FINISH_ACTIVITIES} instead
          */
-        public static final String ALWAYS_FINISH_ACTIVITIES =
-                "always_finish_activities";
+        @Deprecated
+        public static final String ALWAYS_FINISH_ACTIVITIES = Global.ALWAYS_FINISH_ACTIVITIES;
 
         /**
          * Determines which streams are affected by ringer mode changes. The
@@ -1899,7 +1914,10 @@
 
         /**
          * Name of activity to use for wallpaper on the home screen.
+         *
+         * @deprecated Use {@link WallpaperManager} instead.
          */
+        @Deprecated
         public static final String WALLPAPER_ACTIVITY = "wallpaper_activity";
 
         /**
@@ -1943,28 +1961,30 @@
         /**
          * Scaling factor for normal window animations. Setting to 0 will disable window
          * animations.
+         *
+         * @deprecated Use {@link Global#WINDOW_ANIMATION_SCALE} instead
          */
-        public static final String WINDOW_ANIMATION_SCALE = "window_animation_scale";
+        @Deprecated
+        public static final String WINDOW_ANIMATION_SCALE = Global.WINDOW_ANIMATION_SCALE;
 
         /**
          * Scaling factor for activity transition animations. Setting to 0 will disable window
          * animations.
+         *
+         * @deprecated Use {@link Global#TRANSITION_ANIMATION_SCALE} instead
          */
-        public static final String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
+        @Deprecated
+        public static final String TRANSITION_ANIMATION_SCALE = Global.TRANSITION_ANIMATION_SCALE;
 
         /**
          * Scaling factor for Animator-based animations. This affects both the start delay and
          * duration of all such animations. Setting to 0 will cause animations to end immediately.
          * The default value is 1.
+         *
+         * @deprecated Use {@link Global#ANIMATOR_DURATION_SCALE} instead
          */
-        public static final String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
-
-        /**
-         * Scaling factor for normal window animations. Setting to 0 will disable window
-         * animations.
-         * @hide
-         */
-        public static final String FANCY_IME_ANIMATIONS = "fancy_ime_animations";
+        @Deprecated
+        public static final String ANIMATOR_DURATION_SCALE = Global.ANIMATOR_DURATION_SCALE;
 
         /**
          * Control whether the accelerometer will be used to change screen
@@ -2028,23 +2048,6 @@
         public static final String DTMF_TONE_TYPE_WHEN_DIALING = "dtmf_tone_type";
 
         /**
-         * CDMA only settings
-         * Emergency Tone  0 = Off
-         *                 1 = Alert
-         *                 2 = Vibrate
-         * @hide
-         */
-        public static final String EMERGENCY_TONE = "emergency_tone";
-
-        /**
-         * CDMA only settings
-         * Whether the auto retry is enabled. The value is
-         * boolean (1 or 0).
-         * @hide
-         */
-        public static final String CALL_AUTO_RETRY = "call_auto_retry";
-
-        /**
          * Whether the hearing aid is enabled. The value is
          * boolean (1 or 0).
          * @hide
@@ -2296,8 +2299,8 @@
             DATE_FORMAT,
             DTMF_TONE_WHEN_DIALING,
             DTMF_TONE_TYPE_WHEN_DIALING,
-            EMERGENCY_TONE,
-            CALL_AUTO_RETRY,
+            Global.EMERGENCY_TONE,
+            Global.CALL_AUTO_RETRY,
             HEARING_AID,
             TTY_MODE,
             SOUND_EFFECTS_ENABLED,
@@ -2695,6 +2698,8 @@
             MOVED_TO_GLOBAL.add(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
             MOVED_TO_GLOBAL.add(Settings.Global.SET_GLOBAL_HTTP_PROXY);
             MOVED_TO_GLOBAL.add(Settings.Global.DEFAULT_DNS_SERVER);
+            MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_NETWORK_MODE);
+            MOVED_TO_GLOBAL.add(Settings.Global.PREFERRED_CDMA_SUBSCRIPTION);
         }
 
         /**
@@ -3653,20 +3658,6 @@
                 = "allowed_geolocation_origins";
 
         /**
-         * The preferred network mode   7 = Global
-         *                              6 = EvDo only
-         *                              5 = CDMA w/o EvDo
-         *                              4 = CDMA / EvDo auto
-         *                              3 = GSM / WCDMA auto
-         *                              2 = WCDMA only
-         *                              1 = GSM only
-         *                              0 = GSM / WCDMA preferred
-         * @hide
-         */
-        public static final String PREFERRED_NETWORK_MODE =
-                "preferred_network_mode";
-
-        /**
          * The preferred TTY mode     0 = TTy Off, CDMA default
          *                            1 = TTY Full
          *                            2 = TTY HCO
@@ -3677,14 +3668,6 @@
                 "preferred_tty_mode";
 
         /**
-         * The cdma subscription 0 = Subscription from RUIM, when available
-         *                       1 = Subscription from NV
-         * @hide
-         */
-        public static final String PREFERRED_CDMA_SUBSCRIPTION =
-                "preferred_cdma_subscription";
-
-        /**
          * Whether the enhanced voice privacy mode is enabled.
          * 0 = normal voice privacy
          * 1 = enhanced voice privacy
@@ -5170,6 +5153,104 @@
             return BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX + address.toUpperCase();
         }
 
+        /**
+         * Scaling factor for normal window animations. Setting to 0 will
+         * disable window animations.
+         */
+        public static final String WINDOW_ANIMATION_SCALE = "window_animation_scale";
+
+        /**
+         * Scaling factor for activity transition animations. Setting to 0 will
+         * disable window animations.
+         */
+        public static final String TRANSITION_ANIMATION_SCALE = "transition_animation_scale";
+
+        /**
+         * Scaling factor for Animator-based animations. This affects both the
+         * start delay and duration of all such animations. Setting to 0 will
+         * cause animations to end immediately. The default value is 1.
+         */
+        public static final String ANIMATOR_DURATION_SCALE = "animator_duration_scale";
+
+        /**
+         * Scaling factor for normal window animations. Setting to 0 will
+         * disable window animations.
+         *
+         * @hide
+         */
+        public static final String FANCY_IME_ANIMATIONS = "fancy_ime_animations";
+
+        /**
+         * If 0, the compatibility mode is off for all applications.
+         * If 1, older applications run under compatibility mode.
+         * TODO: remove this settings before code freeze (bug/1907571)
+         * @hide
+         */
+        public static final String COMPATIBILITY_MODE = "compatibility_mode";
+
+        /**
+         * CDMA only settings
+         * Emergency Tone  0 = Off
+         *                 1 = Alert
+         *                 2 = Vibrate
+         * @hide
+         */
+        public static final String EMERGENCY_TONE = "emergency_tone";
+
+        /**
+         * CDMA only settings
+         * Whether the auto retry is enabled. The value is
+         * boolean (1 or 0).
+         * @hide
+         */
+        public static final String CALL_AUTO_RETRY = "call_auto_retry";
+
+        /**
+         * The preferred network mode   7 = Global
+         *                              6 = EvDo only
+         *                              5 = CDMA w/o EvDo
+         *                              4 = CDMA / EvDo auto
+         *                              3 = GSM / WCDMA auto
+         *                              2 = WCDMA only
+         *                              1 = GSM only
+         *                              0 = GSM / WCDMA preferred
+         * @hide
+         */
+        public static final String PREFERRED_NETWORK_MODE =
+                "preferred_network_mode";
+
+        /**
+         * The cdma subscription 0 = Subscription from RUIM, when available
+         *                       1 = Subscription from NV
+         * @hide
+         */
+        public static final String PREFERRED_CDMA_SUBSCRIPTION =
+                "preferred_cdma_subscription";
+
+        /**
+         * Name of an application package to be debugged.
+         */
+        public static final String DEBUG_APP = "debug_app";
+
+        /**
+         * If 1, when launching DEBUG_APP it will wait for the debugger before
+         * starting user code.  If 0, it will run normally.
+         */
+        public static final String WAIT_FOR_DEBUGGER = "wait_for_debugger";
+
+        /**
+         * Control whether the process CPU usage meter should be shown.
+         */
+        public static final String SHOW_PROCESSES = "show_processes";
+
+        /**
+         * If 1, the activity manager will aggressively finish activities and
+         * processes as soon as they are no longer needed.  If 0, the normal
+         * extended lifetime is used.
+         */
+        public static final String ALWAYS_FINISH_ACTIVITIES =
+                "always_finish_activities";
+
         // Populated lazily, guarded by class object:
         private static NameValueCache sNameValueCache = new NameValueCache(
                     SYS_PROP_SETTING_VERSION,
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index f97354f..03b685b 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -47,24 +47,30 @@
  *
  * <p>Dreams should be declared in the manifest as follows:</p>
  * <pre>
- * {@code
- * <service
+ * &lt;service
  *     android:name=".MyDream"
  *     android:exported="true"
  *     android:icon="@drawable/my_icon"
  *     android:label="@string/my_dream_label" >
  *
- *     <intent-filter>
- *         <action android:name="android.intent.action.MAIN" />
- *         <category android:name="android.intent.category.DREAM" />
- *     </intent-filter>
+ *     &lt;intent-filter>
+ *         &lt;action android:name="android.service.dreams.DreamService" />
+ *         &lt;category android:name="android.intent.category.DEFAULT" />
+ *     &lt;/intent-filter>
  *
- *     <!-- Point to additional information for this dream (optional) -->
- *     <meta-data
+ *     &lt;!-- Point to additional information for this dream (optional) -->
+ *     &lt;meta-data
  *         android:name="android.service.dream"
  *         android:resource="@xml/my_dream" />
- * </service>
- * }
+ * &lt;/service>
+ * </pre>
+ * <p>If specified, additional information for the dream is defined using the
+ * <code>&lt;{@link android.R.styleable#Dream dream}&gt;</code> element.  For example:</p>
+ * <pre>
+ * (in res/xml/my_dream.xml)
+ *
+ * &lt;dream xmlns:android="http://schemas.android.com/apk/res/android"
+ *     android:settingsActivity="com.example.app/.MyDreamSettingsActivity" />
  * </pre>
  */
 public class DreamService extends Service implements Window.Callback {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4b6f4ea..3ed47ea 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2881,14 +2881,14 @@
      *
      * @hide
      */
-    int mUserPaddingLeftInitial = UNDEFINED_PADDING;
+    int mUserPaddingLeftInitial = 0;
 
     /**
      * Cache initial right padding.
      *
      * @hide
      */
-    int mUserPaddingRightInitial = UNDEFINED_PADDING;
+    int mUserPaddingRightInitial = 0;
 
     /**
      * Default undefined padding
@@ -3643,26 +3643,41 @@
             mUserPaddingRightInitial = padding;
         }
 
-        // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
-        // left / right padding are used if defined (meaning here nothing to do). If they are not
-        // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
-        // start / end and resolve them as left / right (layout direction is not taken into account).
         if (isRtlCompatibilityMode()) {
+            // RTL compatibility mode: pre Jelly Bean MR1 case OR no RTL support case.
+            // left / right padding are used if defined (meaning here nothing to do). If they are not
+            // defined and start / end padding are defined (e.g. in Frameworks resources), then we use
+            // start / end and resolve them as left / right (layout direction is not taken into account).
+            // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
+            // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
+            // defined.
             if (!leftPaddingDefined && startPaddingDefined) {
                 leftPadding = startPadding;
             }
+            mUserPaddingLeftInitial = (leftPadding >= 0) ? leftPadding : mUserPaddingLeftInitial;
             if (!rightPaddingDefined && endPaddingDefined) {
                 rightPadding = endPadding;
             }
+            mUserPaddingRightInitial = (rightPadding >= 0) ? rightPadding : mUserPaddingRightInitial;
+        } else {
+            // Jelly Bean MR1 and after case: if start/end defined, they will override any left/right
+            // values defined. Otherwise, left /right values are used.
+            // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
+            // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
+            // defined.
+            if (startPaddingDefined) {
+                mUserPaddingLeftInitial = startPadding;
+            } else if (leftPaddingDefined) {
+                mUserPaddingLeftInitial = leftPadding;
+            }
+            if (endPaddingDefined) {
+                mUserPaddingRightInitial = endPadding;
+            }
+            else if (rightPaddingDefined) {
+                mUserPaddingRightInitial = rightPadding;
+            }
         }
 
-        // If the user specified the padding (either with android:padding or
-        // android:paddingLeft/Top/Right/Bottom), use this padding, otherwise
-        // use the default padding or the padding from the background drawable
-        // (stored at this point in mPadding*). Padding resolution will happen later if
-        // RTL is supported.
-        mUserPaddingLeftInitial = leftPadding >= 0 ? leftPadding : mPaddingLeft;
-        mUserPaddingRightInitial = rightPadding >= 0 ? rightPadding : mPaddingRight;
         internalSetPadding(
                 mUserPaddingLeftInitial,
                 topPadding >= 0 ? topPadding : mPaddingTop,
@@ -6451,11 +6466,6 @@
             if (viewRootImpl != null) {
                 viewRootImpl.setAccessibilityFocus(this, null);
             }
-            if (mAttachInfo != null) {
-                Rect rectangle = mAttachInfo.mTmpInvalRect;
-                getDrawingRect(rectangle);
-                requestRectangleOnScreen(rectangle);
-            }
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
             notifyAccessibilityStateChanged();
@@ -11745,10 +11755,8 @@
             // If start / end padding are not defined, use the left / right ones.
             int resolvedLayoutDirection = getLayoutDirection();
             // Set user padding to initial values ...
-            mUserPaddingLeft = (mUserPaddingLeftInitial == UNDEFINED_PADDING) ?
-                    0 : mUserPaddingLeftInitial;
-            mUserPaddingRight = (mUserPaddingRightInitial == UNDEFINED_PADDING) ?
-                    0 : mUserPaddingRightInitial;
+            mUserPaddingLeft = mUserPaddingLeftInitial;
+            mUserPaddingRight = mUserPaddingRightInitial;
             // ... then resolve it.
             switch (resolvedLayoutDirection) {
                 case LAYOUT_DIRECTION_RTL:
@@ -14782,8 +14790,18 @@
      * @hide
      */
     public void resetPaddingToInitialValues() {
-        mPaddingLeft = mUserPaddingLeftInitial;
-        mPaddingRight = mUserPaddingRightInitial;
+        if (isRtlCompatibilityMode()) {
+            mPaddingLeft = mUserPaddingLeftInitial;
+            mPaddingRight = mUserPaddingRightInitial;
+        } else {
+            if (isLayoutRtl()) {
+                mPaddingLeft = mUserPaddingRightInitial;
+                mPaddingRight = mUserPaddingLeftInitial;
+            } else {
+                mPaddingLeft = mUserPaddingLeftInitial;
+                mPaddingRight = mUserPaddingRightInitial;
+            }
+        }
     }
 
     /**
@@ -17211,7 +17229,7 @@
          * @return the measure specification based on size and mode
          */
         public static int makeMeasureSpec(int size, int mode) {
-            return (size & ~MODE_MASK) | (mode & MODE_MASK);
+            return size + mode;
         }
 
         /**
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fa2d4e8..6e51270 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1176,14 +1176,42 @@
         public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002;
 
         /**
+         * When this window has focus, does not call user activity for all input events so
+         * the application will have to do it itself.  Should only be used by
+         * the keyguard and phone app.
+         * <p>
+         * Should only be used by the keyguard and phone app.
+         * </p>
+         *
+         * @hide
+         */
+        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004;
+
+        /**
          * Control special features of the input subsystem.
          *
          * @see #INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES
          * @see #INPUT_FEATURE_NO_INPUT_CHANNEL
+         * @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
          * @hide
          */
         public int inputFeatures;
 
+        /**
+         * Sets the number of milliseconds before the user activity timeout occurs
+         * when this window has focus.  A value of -1 uses the standard timeout.
+         * A value of 0 uses the minimum support display timeout.
+         * <p>
+         * This property can only be used to reduce the user specified display timeout;
+         * it can never make the timeout longer than it normally would be.
+         * </p><p>
+         * Should only be used by the keyguard and phone app.
+         * </p>
+         *
+         * @hide
+         */
+        public long userActivityTimeout = -1;
+
         public LayoutParams() {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = TYPE_APPLICATION;
@@ -1268,6 +1296,7 @@
             out.writeInt(subtreeSystemUiVisibility);
             out.writeInt(hasSystemUiListeners ? 1 : 0);
             out.writeInt(inputFeatures);
+            out.writeLong(userActivityTimeout);
         }
         
         public static final Parcelable.Creator<LayoutParams> CREATOR
@@ -1308,6 +1337,7 @@
             subtreeSystemUiVisibility = in.readInt();
             hasSystemUiListeners = in.readInt() != 0;
             inputFeatures = in.readInt();
+            userActivityTimeout = in.readLong();
         }
     
         @SuppressWarnings({"PointlessBitwiseExpression"})
@@ -1334,6 +1364,8 @@
         /** {@hide} */
         public static final int PRIVATE_FLAGS_CHANGED = 1<<16;
         /** {@hide} */
+        public static final int USER_ACTIVITY_TIMEOUT_CHANGED = 1<<17;
+        /** {@hide} */
         public static final int EVERYTHING_CHANGED = 0xffffffff;
 
         // internal buffer to backup/restore parameters under compatibility mode.
@@ -1455,6 +1487,11 @@
                 changes |= INPUT_FEATURES_CHANGED;
             }
 
+            if (userActivityTimeout != o.userActivityTimeout) {
+                userActivityTimeout = o.userActivityTimeout;
+                changes |= USER_ACTIVITY_TIMEOUT_CHANGED;
+            }
+
             return changes;
         }
     
@@ -1547,6 +1584,9 @@
             if (inputFeatures != 0) {
                 sb.append(" if=0x").append(Integer.toHexString(inputFeatures));
             }
+            if (userActivityTimeout >= 0) {
+                sb.append(" userActivityTimeout=").append(userActivityTimeout);
+            }
             sb.append('}');
             return sb.toString();
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 1d465ce..87396fb 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -789,12 +789,6 @@
                     if (resizeWidth) {
                         int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
                                 pleft + pright;
-
-                        // Allow the width to outgrow its original estimate if height is fixed.
-                        if (!resizeHeight) {
-                            widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec);
-                        }
-
                         if (newWidth <= widthSize) {
                             widthSize = newWidth;
                             done = true;
@@ -805,13 +799,6 @@
                     if (!done && resizeHeight) {
                         int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
                                 ptop + pbottom;
-
-                        // Allow the height to outgrow its original estimate if width is fixed.
-                        if (!resizeWidth) {
-                            heightSize = resolveAdjustedSize(newHeight, mMaxHeight,
-                                    heightMeasureSpec);
-                        }
-
                         if (newHeight <= heightSize) {
                             heightSize = newHeight;
                         }
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 5f46d89..455355f 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -369,10 +369,10 @@
         int width = 0;
         int height = 0;
 
-        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
 
         // Record our dimensions if they are known;
         if (widthMode != MeasureSpec.UNSPECIFIED) {
@@ -637,12 +637,7 @@
                 mPaddingLeft, mPaddingRight,
                 myWidth);
         int childHeightMeasureSpec;
-        if (myHeight < 0) {
-            // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
-            // is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
-            // Carry it forward.
-            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        } else if (params.width == LayoutParams.MATCH_PARENT) {
+        if (params.width == LayoutParams.MATCH_PARENT) {
             childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.EXACTLY);
         } else {
             childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.AT_MOST);
@@ -669,13 +664,6 @@
     private int getChildMeasureSpec(int childStart, int childEnd,
             int childSize, int startMargin, int endMargin, int startPadding,
             int endPadding, int mySize) {
-        if (mySize < 0) {
-            // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
-            // is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
-            // Carry it forward.
-            return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        }
-
         int childSpecMode = 0;
         int childSpecSize = 0;
 
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 4715750..991c699 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -556,12 +556,16 @@
         // Make sure the home button has an accurate content description for accessibility.
         if (!enable) {
             mHomeLayout.setContentDescription(null);
-        } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-            mHomeLayout.setContentDescription(mContext.getResources().getText(
-                    R.string.action_bar_up_description));
+            mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
         } else {
-            mHomeLayout.setContentDescription(mContext.getResources().getText(
-                    R.string.action_bar_home_description));
+            mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+            if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+                mHomeLayout.setContentDescription(mContext.getResources().getText(
+                        R.string.action_bar_up_description));
+            } else {
+                mHomeLayout.setContentDescription(mContext.getResources().getText(
+                        R.string.action_bar_home_description));
+            }
         }
     }
 
@@ -624,12 +628,16 @@
         // Make sure the home button has an accurate content description for accessibility.
         if (!mHomeLayout.isEnabled()) {
             mHomeLayout.setContentDescription(null);
-        } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
-            mHomeLayout.setContentDescription(mContext.getResources().getText(
-                    R.string.action_bar_up_description));
+            mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
         } else {
-            mHomeLayout.setContentDescription(mContext.getResources().getText(
-                    R.string.action_bar_home_description));
+            mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+            if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+                mHomeLayout.setContentDescription(mContext.getResources().getText(
+                        R.string.action_bar_up_description));
+            } else {
+                mHomeLayout.setContentDescription(mContext.getResources().getText(
+                        R.string.action_bar_home_description));
+            }
         }
     }
 
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 48fe7fa..9820e60 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -574,7 +574,7 @@
 
     strcpy(heaptargetutilizationOptsBuf, "-XX:HeapTargetUtilization=");
     property_get("dalvik.vm.heaptargetutilization", heaptargetutilizationOptsBuf+26, "");
-    if (heapmaxfreeOptsBuf[26] != '\0') {
+    if (heaptargetutilizationOptsBuf[26] != '\0') {
         opt.optionString = heaptargetutilizationOptsBuf;
         mOptions.add(opt);
     }
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index ba8cea4..4669c37 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -111,7 +111,7 @@
 
         // Compute advances and store them
         mShaper->computeValues(value.get(), paint,
-                reinterpret_cast<const UChar*>(text), start, count,
+                reinterpret_cast<const UChar*>(key.getText()), start, count,
                 size_t(contextCount), int(dirFlags));
 
         if (mDebugEnabled) {
@@ -139,15 +139,12 @@
             // Update current cache size
             mSize += size;
 
-            // Copy the text when we insert the new entry
-            key.internalTextCopy();
-
             bool putOne = mCache.put(key, value);
             LOG_ALWAYS_FATAL_IF(!putOne, "Failed to put an entry into the cache.  "
                     "This indicates that the cache already has an entry with the "
                     "same key but it should not since we checked earlier!"
                     " - start = %d, count = %d, contextCount = %d - Text = '%s'",
-                    start, count, contextCount, String8(text + start, count).string());
+                    start, count, contextCount, String8(key.getText() + start, count).string());
 
             if (mDebugEnabled) {
                 nsecs_t totalTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
@@ -158,7 +155,7 @@
                         value.get(), start, count, contextCount, size, mMaxSize - mSize,
                         value->getElapsedTime() * 0.000001f,
                         (totalTime - value->getElapsedTime()) * 0.000001f,
-                        String8(text + start, count).string());
+                        String8(key.getText() + start, count).string());
             }
         } else {
             if (mDebugEnabled) {
@@ -168,7 +165,7 @@
                         " - Compute time %0.6f ms - Text = '%s'",
                         start, count, contextCount, size, mMaxSize - mSize,
                         value->getElapsedTime() * 0.000001f,
-                        String8(text + start, count).string());
+                        String8(key.getText() + start, count).string());
             }
         }
     } else {
@@ -188,7 +185,7 @@
                         value->getElapsedTime() * 0.000001f,
                         elapsedTimeThruCacheGet * 0.000001f,
                         deltaPercent,
-                        String8(text + start, count).string());
+                        String8(key.getText() + start, count).string());
             }
             if (mCacheHitCount % DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL == 0) {
                 dumpCacheStats();
@@ -225,15 +222,16 @@
 /**
  * TextLayoutCacheKey
  */
-TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0),
+TextLayoutCacheKey::TextLayoutCacheKey(): start(0), count(0), contextCount(0),
         dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
         hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language()  {
 }
 
 TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
         size_t start, size_t count, size_t contextCount, int dirFlags) :
-            text(text), start(start), count(count), contextCount(contextCount),
+            start(start), count(count), contextCount(contextCount),
             dirFlags(dirFlags) {
+    textCopy.setTo(text, contextCount);
     typeface = paint->getTypeface();
     textSize = paint->getTextSize();
     textSkewX = paint->getTextSkewX();
@@ -245,7 +243,6 @@
 }
 
 TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
-        text(NULL),
         textCopy(other.textCopy),
         start(other.start),
         count(other.count),
@@ -259,9 +256,6 @@
         hinting(other.hinting),
         variant(other.variant),
         language(other.language) {
-    if (other.text) {
-        textCopy.setTo(other.text, other.contextCount);
-    }
 }
 
 int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
@@ -304,11 +298,6 @@
     return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
 }
 
-void TextLayoutCacheKey::internalTextCopy() {
-    textCopy.setTo(text, contextCount);
-    text = NULL;
-}
-
 size_t TextLayoutCacheKey::getSize() const {
     return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
 }
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 1f4e22c..9994393 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -77,20 +77,15 @@
     TextLayoutCacheKey(const TextLayoutCacheKey& other);
 
     /**
-     * We need to copy the text when we insert the key into the cache itself.
-     * We don't need to copy the text when we are only comparing keys.
-     */
-    void internalTextCopy();
-
-    /**
      * Get the size of the Cache key.
      */
     size_t getSize() const;
 
     static int compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs);
 
+    inline const UChar* getText() const { return textCopy.string(); }
+
 private:
-    const UChar* text; // if text is NULL, use textCopy
     String16 textCopy;
     size_t start;
     size_t count;
@@ -105,8 +100,6 @@
     SkPaint::FontVariant variant;
     SkLanguage language;
 
-    inline const UChar* getText() const { return text ? text : textCopy.string(); }
-
 }; // TextLayoutCacheKey
 
 inline int strictly_order_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
@@ -316,6 +309,12 @@
     TextLayoutEngine();
     virtual ~TextLayoutEngine();
 
+    /**
+     * Note: this method currently does a defensive copy of the text argument, in case
+     * there is concurrent mutation of it. The contract may change, and may in the
+     * future require the caller to guarantee that the contents will not change during
+     * the call. Be careful of this when doing optimization.
+     **/
     sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
             jint count, jint contextCount, jint dirFlags);
 
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
new file mode 100644
index 0000000..10fc8da
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
new file mode 100644
index 0000000..a0e5060
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
new file mode 100644
index 0000000..8364a36
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
new file mode 100644
index 0000000..44b89e1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
new file mode 100644
index 0000000..770bf78
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
new file mode 100644
index 0000000..2a2467b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png
new file mode 100644
index 0000000..9beeb0f
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png
new file mode 100644
index 0000000..844e38b
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png
new file mode 100644
index 0000000..c22dc90
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png
new file mode 100644
index 0000000..f49b715
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png
new file mode 100644
index 0000000..8dfb7d8
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png
new file mode 100644
index 0000000..29852ad
--- /dev/null
+++ b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
new file mode 100644
index 0000000..fb2ac25
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
new file mode 100644
index 0000000..0c20091
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
new file mode 100644
index 0000000..2f70cee
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
new file mode 100644
index 0000000..0b76d8e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
new file mode 100644
index 0000000..ae7b105
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
new file mode 100644
index 0000000..8d37b99
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
new file mode 100644
index 0000000..483b612
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
new file mode 100644
index 0000000..c3507dc
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
new file mode 100644
index 0000000..24c6519
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
new file mode 100644
index 0000000..2be0380
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
new file mode 100644
index 0000000..4fd69bd
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
new file mode 100644
index 0000000..51588564
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml b/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml
new file mode 100644
index 0000000..36e01f6
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_connecting_holo_dark.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2012, 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.
+ */
+-->
+<animation-list
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:oneshot="false">
+    <item android:drawable="@drawable/ic_media_route_on_0_holo_dark" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_1_holo_dark" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_2_holo_dark" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_holo_dark" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_2_holo_dark" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_1_holo_dark" android:duration="500" />
+</animation-list>
diff --git a/core/res/res/drawable/ic_media_route_connecting_holo_light.xml b/core/res/res/drawable/ic_media_route_connecting_holo_light.xml
new file mode 100644
index 0000000..6683db8
--- /dev/null
+++ b/core/res/res/drawable/ic_media_route_connecting_holo_light.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2012, 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.
+ */
+-->
+<animation-list
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:oneshot="false">
+    <item android:drawable="@drawable/ic_media_route_on_0_holo_light" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_1_holo_light" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_2_holo_light" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_holo_light" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_2_holo_light" android:duration="500" />
+    <item android:drawable="@drawable/ic_media_route_on_1_holo_light" android:duration="500" />
+</animation-list>
diff --git a/core/res/res/drawable/ic_media_route_holo_dark.xml b/core/res/res/drawable/ic_media_route_holo_dark.xml
index 0b267d7..b4c1fac 100644
--- a/core/res/res/drawable/ic_media_route_holo_dark.xml
+++ b/core/res/res/drawable/ic_media_route_holo_dark.xml
@@ -15,6 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_connecting_holo_dark" />
     <item android:state_activated="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_on_holo_dark" />
     <item android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_off_holo_dark" />
     <item android:drawable="@android:drawable/ic_media_route_disabled_holo_dark" />
diff --git a/core/res/res/drawable/ic_media_route_holo_light.xml b/core/res/res/drawable/ic_media_route_holo_light.xml
index 377253a..553721d6 100644
--- a/core/res/res/drawable/ic_media_route_holo_light.xml
+++ b/core/res/res/drawable/ic_media_route_holo_light.xml
@@ -15,6 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_connecting_holo_light" />
     <item android:state_activated="true" android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_on_holo_light" />
     <item android:state_enabled="true" android:drawable="@android:drawable/ic_media_route_off_holo_light" />
     <item android:drawable="@android:drawable/ic_media_route_disabled_holo_light" />
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
index 18e23f0..ac943cb 100644
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ b/core/res/res/layout-land/keyguard_host_view.xml
@@ -28,17 +28,16 @@
     android:orientation="horizontal">
 
     <include layout="@layout/keyguard_widget_region"
-        android:layout_width="0dip"
-        android:layout_height="230dip"
-        android:layout_weight=".45"/>
+        android:layout_width="0dp"
+        android:layout_weight=".45" />
 
     <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
         android:id="@+id/view_flipper"
-        android:layout_width="0dip"
+        android:layout_width="0dp"
         android:layout_height="match_parent"
         android:layout_weight="0.55"
-        android:layout_marginLeft="8dip"
-        android:layout_marginRight="8dip"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
         android:gravity="center">
 
         <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
diff --git a/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml
index a3621c0..df3ee00 100644
--- a/core/res/res/layout/keyguard_multi_user_avatar.xml
+++ b/core/res/res/layout/keyguard_multi_user_avatar.xml
@@ -37,4 +37,4 @@
         android:textSize="12sp"
         android:background="#99FFFFFF"
         android:textColor="#ff000000"/>
-</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>
\ No newline at end of file
+</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
index 710a78e..8ef3b75 100644
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ b/core/res/res/layout/keyguard_selector_view.xml
@@ -29,10 +29,7 @@
     <include layout="@layout/keyguard_widget_region"
         android:layout_width="match_parent"
         android:layout_height="0dip"
-        android:layout_weight="0.45"
-        android:layout_marginTop="35dip"
-        android:layout_marginLeft="33dip"
-        android:layout_marginRight="33dip"/>
+        android:layout_weight="0.45" />
 
     <RelativeLayout
         android:layout_width="wrap_content"
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
index d8adc93..dc596f9 100644
--- a/core/res/res/layout/keyguard_status_view.xml
+++ b/core/res/res/layout/keyguard_status_view.xml
@@ -20,9 +20,9 @@
 <!-- This is a view that shows general status information in Keyguard. -->
 <com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_status_view"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:id="@+id/keyguard_status_view"
     android:gravity="center_horizontal">
 
     <com.android.internal.policy.impl.keyguard.KeyguardStatusView
diff --git a/core/res/res/layout/keyguard_widget_region.xml b/core/res/res/layout/keyguard_widget_region.xml
index 123d105..42bf42b 100644
--- a/core/res/res/layout/keyguard_widget_region.xml
+++ b/core/res/res/layout/keyguard_widget_region.xml
@@ -25,43 +25,47 @@
         android:visibility="gone"
         android:gravity="center"
         android:orientation="vertical">
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1" />
     <com.android.internal.policy.impl.keyguard.KeyguardWidgetPager
         android:id="@+id/app_widget_container"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/kg_widget_container_height">
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:clipChildren="false"
+        android:clipToPadding="false">
             <!-- TODO: Remove this when supported as a widget -->
             <include layout="@layout/keyguard_status_view"/>
             <include layout="@layout/keyguard_transport_control_view"/>
     </com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1"
-        android:orientation="horizontal">
+        android:layout_height="10dp"
+        android:orientation="horizontal"
+        android:paddingLeft="@dimen/kg_widget_pager_horizontal_padding"
+        android:paddingRight="@dimen/kg_widget_pager_horizontal_padding">
         <com.android.internal.policy.impl.keyguard.KeyguardGlowStripView
             android:id="@+id/left_strip"
-            android:layout_width="0dip"
+            android:paddingTop="@dimen/kg_runway_lights_vertical_padding"
+            android:paddingBottom="@dimen/kg_runway_lights_vertical_padding"
+            android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1"
             prvandroid:numDots="5"
-            prvandroid:dotSize="7dip"
+            prvandroid:dotSize="@dimen/kg_runway_lights_height"
             prvandroid:leftToRight="false"
             prvandroid:glowDot="@*android:drawable/ic_lockscreen_glowdot" />
         <Space
-            android:layout_width="0dip"
+            android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1.6"/>
         <com.android.internal.policy.impl.keyguard.KeyguardGlowStripView
             android:id="@+id/right_strip"
-            android:layout_width="0dip"
+            android:paddingTop="@dimen/kg_runway_lights_vertical_padding"
+            android:paddingBottom="@dimen/kg_runway_lights_vertical_padding"
+            android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="1"
             prvandroid:numDots="5"
-            prvandroid:dotSize="7dip"
+            prvandroid:dotSize="@dimen/kg_runway_lights_height"
             prvandroid:leftToRight="true"
             prvandroid:glowDot="@*android:drawable/ic_lockscreen_glowdot" />
     </LinearLayout>
diff --git a/core/res/res/values-mcc310/config.xml b/core/res/res/values-mcc310/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc310/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc311/config.xml b/core/res/res/values-mcc311/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc311/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc312/config.xml b/core/res/res/values-mcc312/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc312/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc313/config.xml b/core/res/res/values-mcc313/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc313/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc314/config.xml b/core/res/res/values-mcc314/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc314/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc315/config.xml b/core/res/res/values-mcc315/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc315/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc316/config.xml b/core/res/res/values-mcc316/config.xml
new file mode 100644
index 0000000..df398f9
--- /dev/null
+++ b/core/res/res/values-mcc316/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">false</bool>
+
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ab183a3..d3d994f 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -960,4 +960,11 @@
     -->
     <bool name="config_enableWifiDisplay">false</bool>
 
+    <!-- When true use the linux /dev/input/event subsystem to detect the switch changes
+         on the headphone/microphone jack. When false use the older uevent framework. -->
+    <bool name="config_useDevInputEventForAudioJack">false</bool>
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 01a35b0..289adf4 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -254,9 +254,6 @@
     <!-- Height of widget view in keyguard. -->
     <dimen name="kg_widget_view_height">0dp</dimen>
 
-    <!-- Padding surrounding each widget page -->
-    <dimen name="kg_widget_page_padding">10dp</dimen>
-
     <!-- Size of the clock font in keyguard's status view -->
     <dimen name="kg_status_clock_font_size">94dp</dimen>
 
@@ -285,8 +282,20 @@
     <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
     <dimen name="kg_secure_padding_height">46dp</dimen>
 
-    <!-- The height of the widget container -->
-    <dimen name="kg_widget_container_height">200dp</dimen>
+    <!-- The height of the runway lights strip -->
+    <dimen name="kg_runway_lights_height">7dp</dimen>
+
+    <!-- The height of the runway lights strip -->
+    <dimen name="kg_runway_lights_vertical_padding">3dp</dimen>
+
+    <!-- Horizontal padding for the widget pager -->
+    <dimen name="kg_widget_pager_horizontal_padding">16dp</dimen>
+
+    <!-- Top padding for the widget pager -->
+    <dimen name="kg_widget_pager_top_padding">16dp</dimen>
+
+    <!-- Bottom padding for the widget pager -->
+    <dimen name="kg_widget_pager_bottom_padding">6dp</dimen>
 
     <!-- Touch slop for the global toggle accessibility gesture -->
     <dimen name="accessibility_touch_slop">80dip</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 51dc0d2..2f9ce0c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3926,14 +3926,13 @@
        "Raise volume above safe level?\nListening at high volume for long periods may damage your hearing."
     </string>
 
-
     <!-- Text spoken when the user is performing a gesture that will enable accessibility. [CHAR LIMIT=none] -->
-    <string name="continue_to_enable_accessibility">Continue touching the screen to enable accessibility.</string>
+    <string name="continue_to_enable_accessibility">Keep holding down your two fingers to enable accessibility.</string>
     <!-- Text spoken when the user enabled accessibility. [CHAR LIMIT=none] -->
     <string name="accessibility_enabled">Accessibility enabled.</string>
     <!-- Text spoken when the user stops preforming a gesture that would enable accessibility. [CHAR LIMIT=none] -->
-    <string name="enable_accessibility_canceled">Enable accessibility canceled.</string>
+    <string name="enable_accessibility_canceled">Accessibility canceled.</string>
     <!-- Text spoken when the current user is switched if accessibility is enabled. [CHAR LIMIT=none] -->
-    <string name="user_switched">Switched to user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string>
+    <string name="user_switched">Current user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string>
 
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 224a059..eb2b5a6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -271,6 +271,8 @@
   <java-symbol type="bool" name="config_enableScreenshotChord" />
   <java-symbol type="bool" name="config_bluetooth_default_profiles" />
   <java-symbol type="bool" name="config_enableWifiDisplay" />
+  <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
+  <java-symbol type="bool" name="config_safe_media_volume_enabled" />
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
@@ -1183,7 +1185,9 @@
   <java-symbol type="dimen" name="navigation_bar_height_landscape" />
   <java-symbol type="dimen" name="navigation_bar_width" />
   <java-symbol type="dimen" name="status_bar_height" />
-  <java-symbol type="dimen" name="kg_widget_page_padding" />
+  <java-symbol type="dimen" name="kg_widget_pager_horizontal_padding" />
+  <java-symbol type="dimen" name="kg_widget_pager_top_padding" />
+  <java-symbol type="dimen" name="kg_widget_pager_bottom_padding" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index c3da3bf..6555733 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -30,33 +30,31 @@
   <th>API</th>
   <th>Distribution</th>
 </tr>
-<tr><td><a href="/about/versions/android-1.5.html">1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.2%</td></tr>
+<tr><td><a href="/about/versions/android-1.5.html">1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.1%</td></tr>
 <tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.4%</td></tr>
-<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>3.7%</td></tr>
-<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>14%</td></tr>
+<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>3.4%</td></tr>
+<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>12.9%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.html">2.3 - 2.3.2</a>
                                    </td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.3%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.3.html">2.3.3 - 2.3.7
-        </a></td><!-- Gingerbread -->                                       <td>10</td><td>57.2%</td></tr>
+        </a></td><!-- Gingerbread -->                                       <td>10</td><td>55.5%</td></tr>
 <tr><td><a href="/about/versions/android-3.1.html">3.1</a></td>
-                                                   <td rowspan="2">Honeycomb</td>      <td>12</td><td>0.5%</td></tr>
-<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.6%</td></tr> 
-<tr><td><a href="/about/versions/android-4.0.html">4.0 - 4.0.2</a></td>
-                                                <td rowspan="2">Ice Cream Sandwich</td><td>14</td><td>0.1%</td></tr> 
+                                                   <td rowspan="2">Honeycomb</td>      <td>12</td><td>0.4%</td></tr>
+<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.5%</td></tr>
 <tr><td><a href="/about/versions/android-4.0.3.html">4.0.3 - 4.0.4</a></td>
-                                                                     <!-- ICS     -->  <td>15</td><td>20.8%</td></tr> 
-<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>1.2%</td></tr> 
+                                                            <td>Ice Cream Sandwich</td><td>15</td><td>23.7%</td></tr> 
+<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>1.8%</td></tr> 
 </table>
 
 </div>
 
 <div class="col-8" style="margin-right:0">
 <img alt=""
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x245&chd=t:4.3,14,57.5,2.1,20.9,1.2&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x245&chd=t:3.9,12.9,55.8,1.9,23.7,1.8&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
 
 </div><!-- end dashboard-panel -->
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on September 4, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 14-day period ending on October 1, 2012</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -81,9 +79,9 @@
 Google Play within a 14-day period ending on the date indicated on the x-axis.</p>
 
 <img alt="" height="250" width="660"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:97.6,97.8,97.8,97.9,98.1,98.1,98.3,98.5,98.6,98.7,98.9,98.9,99.0|90.8,91.4,91.8,92.1,92.5,92.7,93.1,93.5,93.9,94.2,94.7,94.9,95.3|65.2,66.8,68.6,69.9,71.5,72.6,74.0,75.2,76.5,77.8,79.2,80.1,81.1|4.3,4.6,5.5,6.5,7.6,8.2,9.4,11.0,12.8,15.6,18.9,21.2,23.7|3.2,3.5,4.5,5.5,6.6,7.4,8.7,10.4,12.3,15.1,18.4,20.7,23.2|1.1,1.3,2.3,3.3,4.4,5.3,6.7,8.4,10.4,13.2,16.6,19.0,21.5|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.9,1.1&chm=b,c3df9b,0,1,0|tAndroid%202.2,6c9729,1,0,15,,t::-5|b,b6dc7d,1,2,0|tAndroid%202.3.3,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|b,9ddb3d,3,4,0|b,91da1e,4,5,0|tAndroid%204.0.3,253a06,5,8,15,,t::-5|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3|Android%204.1&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:97.8,97.9,98.1,98.1,98.3,98.5,98.6,98.7,98.9,98.9,99.0,99.1,99.2|91.8,92.1,92.5,92.7,93.1,93.5,93.9,94.2,94.7,94.9,95.3,95.5,95.8|68.6,69.9,71.5,72.6,74.0,75.2,76.5,77.8,79.2,80.1,81.1,82.0,82.9|5.5,6.5,7.6,8.2,9.4,11.0,12.8,15.6,18.9,21.2,23.7,25.5,27.4|4.5,5.5,6.6,7.4,8.7,10.4,12.3,15.1,18.4,20.7,23.2,25.1,27.0|2.3,3.3,4.4,5.3,6.7,8.4,10.4,13.2,16.6,19.0,21.5,23.5,25.5|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.9,1.1,1.4,1.8&chm=b,c3df9b,0,1,0|tAndroid%202.2,6c9729,1,0,15,,t::-5|b,b6dc7d,1,2,0|tAndroid%202.3.3,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|b,9ddb3d,3,4,0|b,91da1e,4,5,0|tAndroid%204.0.3,253a06,5,6,15,,t::-5|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3|Android%204.1&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on September 1, 2012</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on October 1, 2012</em></p>
 
 
 
@@ -112,11 +110,11 @@
 
 
 <img alt="" style="float:right;"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.7,6.5,86,2.8" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.6,6.1,86.6,2.7" />
 
 
 <img alt="" style="float:right;clear:right"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=ldpi%7Cmdpi%7Chdpi%7Cxhdpi&chd=t%3A1.6,18.6,53.6,26.2" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chf=bg,s,00000000&chco=c4df9b,6fad0c&chl=ldpi%7Cmdpi%7Chdpi%7Cxhdpi&chd=t%3A2.2,18,51.1,28.7" />
 
 <p>This section provides data about the relative number of active devices that have a particular
 screen configuration, defined by a combination of screen size and density. To simplify the way that
@@ -148,32 +146,32 @@
 <th scope="col">xhdpi</th>
 </tr>
 <tr><th scope="row">small</th> 
-<td>1.1%</td>     <!-- small/ldpi -->
+<td>1.7%</td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>1.7%</td> <!-- small/hdpi -->
+<td>1.0%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
 <td>0.4%</td>  <!-- normal/ldpi -->
-<td>11.4%</td> <!-- normal/mdpi -->
-<td>51.9%</td> <!-- normal/hdpi -->
-<td>22.3%</td>      <!-- normal/xhdpi -->
+<td>11%</td> <!-- normal/mdpi -->
+<td>50.1%</td> <!-- normal/hdpi -->
+<td>25.1%</td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
 <td>0.1%</td>     <!-- large/ldpi -->
-<td>2.5%</td> <!-- large/mdpi -->
+<td>2.4%</td> <!-- large/mdpi -->
 <td></td>     <!-- large/hdpi -->
-<td>3.9%</td>     <!-- large/xhdpi -->
+<td>3.6%</td>     <!-- large/xhdpi -->
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
-<td>4.7%</td> <!-- xlarge/mdpi -->
+<td>4.6%</td> <!-- xlarge/mdpi -->
 <td></td>     <!-- xlarge/hdpi -->
 <td></td>     <!-- xlarge/xhdpi -->
 </tr> 
 </table>
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on October 1, 2012</em></p>
 
 
 
@@ -225,4 +223,4 @@
 
 
 
-<p style="clear:both"><em>Data collected during a 7-day period ending on September 4, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 7-day period ending on October 1, 2012</em></p>
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index c015077..c2e6ee3 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1265,7 +1265,7 @@
 }
 
 bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
-    if (mSnapshot->isIgnored()) {
+    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
         return true;
     }
 
@@ -1951,6 +1951,11 @@
     // TODO: try clipping large paths to viewport
     PathRenderer::convexPathVertices(path, paint, mSnapshot->transform, vertexBuffer);
 
+    if (!vertexBuffer.getSize()) {
+        // no vertices to draw
+        return;
+    }
+
     setupDraw();
     setupDrawNoTexture();
     if (isAA) setupDrawAA();
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
index 4a66c62..5b55c2b 100644
--- a/libs/hwui/PathRenderer.cpp
+++ b/libs/hwui/PathRenderer.cpp
@@ -323,6 +323,11 @@
     convexPathPerimeterVertices(path, threshInvScaleX * threshInvScaleX,
             threshInvScaleY * threshInvScaleY, tempVertices);
 
+    if (!tempVertices.size()) {
+        // path was empty, return without allocating vertex buffer
+        return;
+    }
+
 #if VERTEX_DEBUG
     for (unsigned int i = 0; i < tempVertices.size(); i++) {
         ALOGD("orig path: point at %f %f", tempVertices[i].position[0], tempVertices[i].position[1]);
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 0adba06..57e2786 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -26,6 +26,7 @@
 import android.location.LocationManager;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.R;
@@ -89,7 +90,6 @@
     
     // configuration of notificaiton behavior
     private boolean mPlaySounds = false;
-    private boolean visible = true;
     private boolean mPopupImmediately = true;
     
     // Set to true if string from HAL is encoded as Hex, e.g., "3F0039"    
@@ -213,11 +213,8 @@
         PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);                
         mNiNotification.setLatestEventInfo(mContext, title, message, pi);
 
-        if (visible) {
-            notificationManager.notify(notif.notificationId, mNiNotification);
-        } else {
-            notificationManager.cancel(notif.notificationId);
-        }
+        notificationManager.notifyAsUser(null, notif.notificationId, mNiNotification,
+                UserHandle.ALL);
     }
 
     // Opens the notification dialog and waits for user input
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a754ef3..fdb6818 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -63,6 +63,7 @@
 import android.provider.Settings.System;
 import android.speech.RecognizerIntent;
 import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -155,6 +156,8 @@
     private static final int MSG_SET_FORCE_RSX_USE = 24;        // force remote submix audio routing
     private static final int MSG_CHECK_MUSIC_ACTIVE = 25;
     private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 26;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 27;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 28;
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
     // persisted
@@ -429,6 +432,8 @@
             AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET |
             AudioSystem.DEVICE_OUT_ALL_USB;
 
+    private final boolean mMonitorOrientation;
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -439,8 +444,6 @@
         mContentResolver = context.getContentResolver();
         mVoiceCapable = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_capable);
-        mSafeMediaVolumeIndex = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_safe_media_volume_index) * 10;
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
@@ -465,13 +468,10 @@
         updateStreamVolumeAlias(false /*updateVolumes*/);
         createStreamStates();
 
-        mSafeMediaVolumeEnabled = new Boolean(true);
-        synchronized (mSafeMediaVolumeEnabled) {
-            enforceSafeMediaVolume();
-        }
-
         mMediaServerOk = true;
 
+        mSafeMediaVolumeState = new Integer(SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
+
         // Call setRingerModeInt() to apply correct mute
         // state on streams affected by ringer mode.
         mRingerModeMutedStreams = 0;
@@ -491,11 +491,12 @@
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
 
+        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         // Register a configuration change listener only if requested by system properties
         // to monitor orientation changes (off by default)
-        if (SystemProperties.getBoolean("ro.audio.monitorOrientation", false)) {
+        mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false);
+        if (mMonitorOrientation) {
             Log.v(TAG, "monitoring device orientation");
-            intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
             // initialize orientation in AudioSystem
             setOrientationForAudioSystem();
         }
@@ -1748,8 +1749,8 @@
 
         checkAllAliasStreamVolumes();
 
-        synchronized (mSafeMediaVolumeEnabled) {
-            if (mSafeMediaVolumeEnabled) {
+        synchronized (mSafeMediaVolumeState) {
+            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
                 enforceSafeMediaVolume();
             }
         }
@@ -2212,8 +2213,8 @@
     }
 
     private void onCheckMusicActive() {
-        synchronized (mSafeMediaVolumeEnabled) {
-            if (!mSafeMediaVolumeEnabled) {
+        synchronized (mSafeMediaVolumeState) {
+            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
                 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
 
                 if ((device & mSafeMediaVolumeDevices) != 0) {
@@ -2241,6 +2242,25 @@
         }
     }
 
+    private void onConfigureSafeVolume(boolean force) {
+        synchronized (mSafeMediaVolumeState) {
+            int mcc = mContext.getResources().getConfiguration().mcc;
+            if ((mMcc != mcc) || ((mMcc == 0) && force)) {
+                mSafeMediaVolumeIndex = mContext.getResources().getInteger(
+                        com.android.internal.R.integer.config_safe_media_volume_index) * 10;
+                boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean(
+                        com.android.internal.R.bool.config_safe_media_volume_enabled);
+                if (safeMediaVolumeEnabled) {
+                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
+                    enforceSafeMediaVolume();
+                } else {
+                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
+                }
+                mMcc = mcc;
+            }
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Internal methods
     ///////////////////////////////////////////////////////////////////////////
@@ -3185,7 +3205,7 @@
                     restoreMasterVolume();
 
                     // Reset device orientation (if monitored for this device)
-                    if (SystemProperties.getBoolean("ro.audio.monitorOrientation", false)) {
+                    if (mMonitorOrientation) {
                         setOrientationForAudioSystem();
                     }
 
@@ -3290,6 +3310,11 @@
                 case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
                     onSendBecomingNoisyIntent();
                     break;
+
+                case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:
+                case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
+                    onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED));
+                    break;
             }
         }
     }
@@ -3739,6 +3764,14 @@
                     adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
                                             BluetoothProfile.A2DP);
                 }
+
+                sendMsg(mAudioHandler,
+                        MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
+                        SENDMSG_REPLACE,
+                        0,
+                        0,
+                        null,
+                        SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
             } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                     // a package is being removed, not replaced
@@ -5512,11 +5545,21 @@
         try {
             // reading new orientation "safely" (i.e. under try catch) in case anything
             // goes wrong when obtaining resources and configuration
-            int newOrientation = context.getResources().getConfiguration().orientation;
-            if (newOrientation != mDeviceOrientation) {
-                mDeviceOrientation = newOrientation;
-                setOrientationForAudioSystem();
+            Configuration config = context.getResources().getConfiguration();
+            if (mMonitorOrientation) {
+                int newOrientation = config.orientation;
+                if (newOrientation != mDeviceOrientation) {
+                    mDeviceOrientation = newOrientation;
+                    setOrientationForAudioSystem();
+                }
             }
+            sendMsg(mAudioHandler,
+                    MSG_CONFIGURE_SAFE_MEDIA_VOLUME,
+                    SENDMSG_REPLACE,
+                    0,
+                    0,
+                    null,
+                    0);
         } catch (Exception e) {
             Log.e(TAG, "Error retrieving device orientation: " + e);
         }
@@ -5587,12 +5630,21 @@
     // overlay.
     //==========================================================================================
 
-    // mSafeMediaVolumeEnabled indicates whether the media volume is limited over headphones.
-    // It is true by default when headphones or a headset are inserted and can be overriden by
-    // calling AudioService.disableSafeMediaVolume() (when user opts out).
-    private Boolean mSafeMediaVolumeEnabled;
+    // mSafeMediaVolumeState indicates whether the media volume is limited over headphones.
+    // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected
+    // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or
+    // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
+    // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
+    // (when user opts out).
+    private final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
+    private final int SAFE_MEDIA_VOLUME_DISABLED = 1;
+    private final int SAFE_MEDIA_VOLUME_INACTIVE = 2;
+    private final int SAFE_MEDIA_VOLUME_ACTIVE = 3;
+    private Integer mSafeMediaVolumeState;
+
+    private int mMcc = 0;
     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
-    private final int mSafeMediaVolumeIndex;
+    private int mSafeMediaVolumeIndex;
     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
     private final int mSafeMediaVolumeDevices = AudioSystem.DEVICE_OUT_WIRED_HEADSET |
                                                 AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
@@ -5602,22 +5654,27 @@
     private int mMusicActiveMs;
     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
+    private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
 
     private void setSafeMediaVolumeEnabled(boolean on) {
-        synchronized (mSafeMediaVolumeEnabled) {
-            if (on && !mSafeMediaVolumeEnabled) {
-                enforceSafeMediaVolume();
-            } else if (!on && mSafeMediaVolumeEnabled) {
-                mMusicActiveMs = 0;
-                sendMsg(mAudioHandler,
-                        MSG_CHECK_MUSIC_ACTIVE,
-                        SENDMSG_REPLACE,
-                        0,
-                        0,
-                        null,
-                        MUSIC_ACTIVE_POLL_PERIOD_MS);
+        synchronized (mSafeMediaVolumeState) {
+            if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
+                    (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
+                if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
+                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
+                    enforceSafeMediaVolume();
+                } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {
+                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
+                    mMusicActiveMs = 0;
+                    sendMsg(mAudioHandler,
+                            MSG_CHECK_MUSIC_ACTIVE,
+                            SENDMSG_REPLACE,
+                            0,
+                            0,
+                            null,
+                            MUSIC_ACTIVE_POLL_PERIOD_MS);
+                }
             }
-            mSafeMediaVolumeEnabled = on;
         }
     }
 
@@ -5659,8 +5716,8 @@
     }
 
     private boolean checkSafeMediaVolume(int streamType, int index, int device) {
-        synchronized (mSafeMediaVolumeEnabled) {
-            if (mSafeMediaVolumeEnabled &&
+        synchronized (mSafeMediaVolumeState) {
+            if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) &&
                     (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
                     ((device & mSafeMediaVolumeDevices) != 0) &&
                     (index > mSafeMediaVolumeIndex)) {
@@ -5672,7 +5729,7 @@
     }
 
     public void disableSafeMediaVolume() {
-        synchronized (mSafeMediaVolumeEnabled) {
+        synchronized (mSafeMediaVolumeState) {
             setSafeMediaVolumeEnabled(false);
         }
     }
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 36c9c70..e5b9637 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -105,8 +105,13 @@
             mDefaultAudioVideo = new RouteInfo(mSystemCategory);
             mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name;
             mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
-            addRoute(mDefaultAudioVideo);
+            addRouteStatic(mDefaultAudioVideo);
 
+            // This will select the active wifi display route if there is one.
+            updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
+
+            appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
+                    new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
             appContext.registerReceiver(new VolumeChangeReceiver(),
                     new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
 
@@ -116,13 +121,17 @@
             } catch (RemoteException e) {
             }
             if (newAudioRoutes != null) {
+                // This will select the active BT route if there is one and the current
+                // selected route is the default system route, or if there is no selected
+                // route yet.
                 updateAudioRoutes(newAudioRoutes);
             }
 
-            updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
-
-            appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
-                    new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
+            // Select the default route if the above didn't sync us up
+            // appropriately with relevant system state.
+            if (mSelectedRoute == null) {
+                selectRouteStatic(mDefaultAudioVideo.getSupportedTypes(), mDefaultAudioVideo);
+            }
         }
 
         void updateAudioRoutes(AudioRoutesInfo newRoutes) {
@@ -159,7 +168,7 @@
                         info.mName = mCurAudioRoutesInfo.mBluetoothName;
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
                         sStatic.mBluetoothA2dpRoute = info;
-                        addRoute(sStatic.mBluetoothA2dpRoute);
+                        addRouteStatic(sStatic.mBluetoothA2dpRoute);
                     } else {
                         sStatic.mBluetoothA2dpRoute.mName = mCurAudioRoutesInfo.mBluetoothName;
                         dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
@@ -175,7 +184,8 @@
                         mSelectedRoute == mBluetoothA2dpRoute) {
                     selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
                 } else if (mCurAudioRoutesInfo.mMainType == AudioRoutesInfo.MAIN_SPEAKER &&
-                        mSelectedRoute == mDefaultAudioVideo && a2dpEnabled) {
+                        (mSelectedRoute == mDefaultAudioVideo || mSelectedRoute == null) &&
+                        a2dpEnabled) {
                     selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
                 }
             }
@@ -393,22 +403,21 @@
      * @see #removeUserRoute(UserRouteInfo)
      */
     public void addUserRoute(UserRouteInfo info) {
-        addRoute(info);
+        addRouteStatic(info);
     }
 
     /**
      * @hide Framework use only
      */
     public void addRouteInt(RouteInfo info) {
-        addRoute(info);
+        addRouteStatic(info);
     }
 
-    static void addRoute(RouteInfo info) {
+    static void addRouteStatic(RouteInfo info) {
         final RouteCategory cat = info.getCategory();
         if (!sStatic.mCategories.contains(cat)) {
             sStatic.mCategories.add(cat);
         }
-        final boolean onlyRoute = sStatic.mRoutes.isEmpty();
         if (cat.isGroupable() && !(info instanceof RouteGroup)) {
             // Enforce that any added route in a groupable category must be in a group.
             final RouteGroup group = new RouteGroup(info.getCategory());
@@ -422,10 +431,6 @@
             sStatic.mRoutes.add(info);
             dispatchRouteAdded(info);
         }
-
-        if (onlyRoute) {
-            selectRouteStatic(info.getSupportedTypes(), info);
-        }
     }
 
     /**
@@ -693,18 +698,25 @@
                 oldStatus.getRememberedDisplays() : new WifiDisplay[0];
         WifiDisplay[] newDisplays = newStatus.getRememberedDisplays();
         WifiDisplay[] availableDisplays = newStatus.getAvailableDisplays();
+        WifiDisplay activeDisplay = newStatus.getActiveDisplay();
 
         for (int i = 0; i < newDisplays.length; i++) {
             final WifiDisplay d = newDisplays[i];
             final WifiDisplay oldRemembered = findMatchingDisplay(d, oldDisplays);
             if (oldRemembered == null) {
-                addRoute(makeWifiDisplayRoute(d));
+                addRouteStatic(makeWifiDisplayRoute(d));
                 needScan = true;
             } else {
                 final boolean available = findMatchingDisplay(d, availableDisplays) != null;
                 final RouteInfo route = findWifiDisplayRoute(d);
                 updateWifiDisplayRoute(route, d, available, newStatus);
             }
+            if (d.equals(activeDisplay)) {
+                final RouteInfo activeRoute = findWifiDisplayRoute(d);
+                if (activeRoute != null) {
+                    selectRouteStatic(activeRoute.getSupportedTypes(), activeRoute);
+                }
+            }
         }
         for (int i = 0; i < oldDisplays.length; i++) {
             final WifiDisplay d = oldDisplays[i];
@@ -840,11 +852,11 @@
         // A predetermined connection status that can override mStatus
         private int mStatusCode;
 
-        static final int STATUS_NONE = 0;
-        static final int STATUS_SCANNING = 1;
-        static final int STATUS_CONNECTING = 2;
-        static final int STATUS_AVAILABLE = 3;
-        static final int STATUS_NOT_AVAILABLE = 4;
+        /** @hide */ public static final int STATUS_NONE = 0;
+        /** @hide */ public static final int STATUS_SCANNING = 1;
+        /** @hide */ public static final int STATUS_CONNECTING = 2;
+        /** @hide */ public static final int STATUS_AVAILABLE = 3;
+        /** @hide */ public static final int STATUS_NOT_AVAILABLE = 4;
 
         private Object mTag;
 
@@ -941,6 +953,13 @@
         }
 
         /**
+         * @hide
+         */
+        public int getStatusCode() {
+            return mStatusCode;
+        }
+
+        /**
          * @return A media type flag set describing which types this route supports.
          */
         public int getSupportedTypes() {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 06c8e11..2716b04 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -68,7 +68,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 90;
+    private static final int DATABASE_VERSION = 91;
 
     private Context mContext;
     private int mUserHandle;
@@ -1400,6 +1400,39 @@
             upgradeVersion = 90;
         }
 
+        if (upgradeVersion == 90) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                try {
+                    String[] systemToGlobal = {
+                            Settings.Global.WINDOW_ANIMATION_SCALE,
+                            Settings.Global.TRANSITION_ANIMATION_SCALE,
+                            Settings.Global.ANIMATOR_DURATION_SCALE,
+                            Settings.Global.FANCY_IME_ANIMATIONS,
+                            Settings.Global.COMPATIBILITY_MODE,
+                            Settings.Global.EMERGENCY_TONE,
+                            Settings.Global.CALL_AUTO_RETRY,
+                            Settings.Global.DEBUG_APP,
+                            Settings.Global.WAIT_FOR_DEBUGGER,
+                            Settings.Global.SHOW_PROCESSES,
+                            Settings.Global.ALWAYS_FINISH_ACTIVITIES,
+                    };
+                    String[] secureToGlobal = {
+                            Settings.Global.PREFERRED_NETWORK_MODE,
+                            Settings.Global.PREFERRED_CDMA_SUBSCRIPTION,
+                    };
+
+                    moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_GLOBAL, systemToGlobal, true);
+                    moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, secureToGlobal, true);
+
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+            upgradeVersion = 91;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1816,12 +1849,6 @@
             loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                     R.integer.def_screen_off_timeout);
 
-            // Set default cdma emergency tone
-            loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
-
-            // Set default cdma call auto retry
-            loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
-
             // Set default cdma DTMF type
             loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
 
@@ -1846,9 +1873,6 @@
 
             loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                     R.bool.def_notification_pulse);
-            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
-            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
-                    PackageHelper.APP_INSTALL_AUTO);
 
             loadUISoundEffectsSettings(stmt);
 
@@ -1884,10 +1908,6 @@
 
         loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
             R.integer.def_lockscreen_sounds_enabled);
-        loadStringSetting(stmt, Settings.System.LOCK_SOUND,
-            R.string.def_lock_sound);
-        loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,
-            R.string.def_unlock_sound);
     }
 
     private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
@@ -1916,16 +1936,6 @@
                 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
             }
 
-            // Set the preferred network mode to 0 = Global, CDMA default
-            int type;
-            if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
-                type = Phone.NT_MODE_GLOBAL;
-            } else {
-                type = SystemProperties.getInt("ro.telephony.default_network",
-                        RILConstants.PREFERRED_NETWORK_MODE);
-            }
-            loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
-
             // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
             // persistent system property instead.
             //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
@@ -2103,6 +2113,32 @@
             loadBooleanSetting(stmt, Settings.Global.WIFI_DISPLAY_ON,
                     R.bool.def_wifi_display_on);
 
+            loadStringSetting(stmt, Settings.Global.LOCK_SOUND,
+                    R.string.def_lock_sound);
+
+            loadStringSetting(stmt, Settings.Global.UNLOCK_SOUND,
+                    R.string.def_unlock_sound);
+
+            loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0);
+            loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION,
+                    PackageHelper.APP_INSTALL_AUTO);
+
+            // Set default cdma emergency tone
+            loadSetting(stmt, Settings.Global.EMERGENCY_TONE, 0);
+
+            // Set default cdma call auto retry
+            loadSetting(stmt, Settings.Global.CALL_AUTO_RETRY, 0);
+
+            // Set the preferred network mode to 0 = Global, CDMA default
+            int type;
+            if (TelephonyManager.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE) {
+                type = Phone.NT_MODE_GLOBAL;
+            } else {
+                type = SystemProperties.getInt("ro.telephony.default_network",
+                        RILConstants.PREFERRED_NETWORK_MODE);
+            }
+            loadSetting(stmt, Settings.Global.PREFERRED_NETWORK_MODE, type);
+
             // --- New global settings start here
         } finally {
             if (stmt != null) stmt.close();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 10f96cc..cc6656d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -227,6 +227,8 @@
         sSecureGlobalKeys.add(Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
         sSecureGlobalKeys.add(Settings.Global.SET_GLOBAL_HTTP_PROXY);
         sSecureGlobalKeys.add(Settings.Global.DEFAULT_DNS_SERVER);
+        sSecureGlobalKeys.add(Settings.Global.PREFERRED_NETWORK_MODE);
+        sSecureGlobalKeys.add(Settings.Global.PREFERRED_CDMA_SUBSCRIPTION);
 
         // Keys from the 'system' table now moved to 'global'
         // These must match Settings.System.MOVED_TO_GLOBAL
@@ -249,6 +251,17 @@
         sSystemGlobalKeys.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
         sSystemGlobalKeys.add(Settings.Global.WIFI_SLEEP_POLICY);
         sSystemGlobalKeys.add(Settings.Global.MODE_RINGER);
+        sSystemGlobalKeys.add(Settings.Global.WINDOW_ANIMATION_SCALE);
+        sSystemGlobalKeys.add(Settings.Global.TRANSITION_ANIMATION_SCALE);
+        sSystemGlobalKeys.add(Settings.Global.ANIMATOR_DURATION_SCALE);
+        sSystemGlobalKeys.add(Settings.Global.FANCY_IME_ANIMATIONS);
+        sSystemGlobalKeys.add(Settings.Global.COMPATIBILITY_MODE);
+        sSystemGlobalKeys.add(Settings.Global.EMERGENCY_TONE);
+        sSystemGlobalKeys.add(Settings.Global.CALL_AUTO_RETRY);
+        sSystemGlobalKeys.add(Settings.Global.DEBUG_APP);
+        sSystemGlobalKeys.add(Settings.Global.WAIT_FOR_DEBUGGER);
+        sSystemGlobalKeys.add(Settings.Global.SHOW_PROCESSES);
+        sSystemGlobalKeys.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES);
     }
 
     private boolean settingMovedToGlobal(final String name) {
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 715ccba..10e313e 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -23,13 +23,17 @@
     android:layout_height="match_parent"
     android:layout_width="wrap_content"
     android:paddingLeft="@dimen/status_bar_recents_item_padding"
-    android:paddingRight="@dimen/status_bar_recents_item_padding">
+    android:paddingRight="@dimen/status_bar_recents_item_padding"
+    android:importantForAccessibility="no"
+    android:clipChildren="false">
 
     <RelativeLayout android:id="@+id/recent_item"
         android:layout_gravity="center_vertical"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
-        android:paddingTop="@*android:dimen/status_bar_height">
+        android:paddingTop="@*android:dimen/status_bar_height"
+        android:clipChildren="false"
+        android:clipToPadding="false">
 
         <FrameLayout android:id="@+id/app_thumbnail"
             android:layout_width="wrap_content"
@@ -75,6 +79,7 @@
             android:singleLine="true"
             android:ellipsize="marquee"
             android:textColor="@color/status_bar_recents_app_label_color"
+            android:importantForAccessibility="no"
         />
 
         <TextView android:id="@+id/app_description"
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 8fdde92..e940c85 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -41,7 +41,8 @@
             android:fadingEdge="horizontal"
             android:scrollbars="none"
             android:layout_gravity="right"
-            android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length">
+            android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
+            android:importantForAccessibility="no">
 
             <LinearLayout android:id="@+id/recents_linear_layout"
                 android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_time.xml b/packages/SystemUI/res/layout/quick_settings_tile_time.xml
index 4ffbf52..910e1f6 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_time.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_time.xml
@@ -29,10 +29,11 @@
         android:hand_hour="@drawable/ic_qs_clock_hour"
         android:hand_minute="@drawable/ic_qs_clock_minute"
         />
-    <com.android.systemui.statusbar.policy.QuickSettingsDateView
+    <com.android.systemui.statusbar.policy.DateView
         android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal"
+        android:gravity="center"
         />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index ffcead0..7f6098a 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -29,6 +29,12 @@
     android:layout_marginLeft="@dimen/notification_panel_margin_left"
     >
 
+    <View
+        android:id="@+id/handle"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/close_handle_height"
+        />
+
     <include
         layout="@layout/carrier_label"
         android:layout_height="@dimen/carrier_label_height"
@@ -75,10 +81,4 @@
                 />
         </ScrollView>
     </LinearLayout>
-
-    <View
-        android:id="@+id/handle"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/close_handle_height"
-        />
 </com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/layout/status_bar_recent_item.xml b/packages/SystemUI/res/layout/status_bar_recent_item.xml
index 50643ab..e2b5723 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout/status_bar_recent_item.xml
@@ -23,12 +23,15 @@
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
     android:paddingTop="@dimen/status_bar_recents_item_padding"
-    android:paddingBottom="@dimen/status_bar_recents_item_padding">
+    android:paddingBottom="@dimen/status_bar_recents_item_padding"
+    android:clipChildren="false"
+    android:importantForAccessibility="no">
 
     <RelativeLayout android:id="@+id/recent_item"
         android:layout_gravity="center_horizontal"
         android:layout_height="wrap_content"
-        android:layout_width="wrap_content">
+        android:layout_width="wrap_content"
+        android:clipChildren="false">
 
         <TextView android:id="@+id/app_label"
             android:layout_width="@dimen/status_bar_recents_app_label_width"
@@ -44,6 +47,7 @@
             android:singleLine="true"
             android:ellipsize="marquee"
             android:textColor="@color/status_bar_recents_app_label_color"
+            android:importantForAccessibility="no"
         />
         <FrameLayout android:id="@+id/app_thumbnail"
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/status_bar_recent_panel.xml b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
index 7335f86..12599f8 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_recent_panel.xml
@@ -45,7 +45,8 @@
             android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
             android:layout_gravity="bottom|left"
             android:clipToPadding="false"
-            android:clipChildren="false">
+            android:clipChildren="false"
+            android:importantForAccessibility="no">
 
             <LinearLayout android:id="@+id/recents_linear_layout"
                 android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/system_bar_recent_item.xml b/packages/SystemUI/res/layout/system_bar_recent_item.xml
index 7d639ec..b5f7da7 100644
--- a/packages/SystemUI/res/layout/system_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout/system_bar_recent_item.xml
@@ -37,6 +37,7 @@
         android:singleLine="true"
         android:ellipsize="marquee"
         android:textColor="@color/status_bar_recents_app_label_color"
+        android:importantForAccessibility="no"
     />
 
     <FrameLayout android:id="@+id/app_thumbnail"
diff --git a/packages/SystemUI/res/layout/system_bar_recent_panel.xml b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
index 3951bba..8afed22 100644
--- a/packages/SystemUI/res/layout/system_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
@@ -49,7 +49,8 @@
             android:fadingEdgeLength="20dip"
             android:layout_gravity="bottom|left"
             android:clipToPadding="false"
-            android:clipChildren="false">
+            android:clipChildren="false"
+            android:importantForAccessibility="no">
 
             <LinearLayout android:id="@+id/recents_linear_layout"
                 android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 756f5e3..1bccbbc 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -154,8 +154,8 @@
     <string name="start_dreams" msgid="870400522982252717">"Iniciar Dreams"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modo de avión"</string>
-    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Cargando <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
-    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Cobrado"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Cargada"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> dispositivos)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth desactivado"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a117897..8da1e80c 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -173,9 +173,9 @@
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Нет соединения"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Нет сети"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Модуль Wi-Fi отключен"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Экран, подключенный через Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="7834964244709912066">"Экран не подключен через Wi-Fi"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi выкл."</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Проектор вкл."</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="7834964244709912066">"Проектор выкл."</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a743c9e..faa7ab7 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -173,7 +173,7 @@
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"未连接"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"无网络"</string>
-    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"已关闭 Wi-Fi"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 已关闭"</string>
     <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi 显示设备"</string>
     <string name="quick_settings_wifi_display_no_connection_label" msgid="7834964244709912066">"无 Wi-Fi 显示设备连接"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 64a3699..6dbdcc7 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -172,7 +172,7 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Akuxhunyiwe"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ayikho inethiwekhi"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"I-Wi-Fi icimile"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Ukusboniswa kwe-Wi-"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Ukuboniswa kwe-Wi-"</string>
     <string name="quick_settings_wifi_display_no_connection_label" msgid="7834964244709912066">"Alukho uxhumo lokubonisa le-Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ukugqama"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 62289fb..5023d23 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -50,6 +50,10 @@
     <dimen name="status_bar_recents_app_label_left_margin">0dip</dimen>
     <!-- Padding between recents items -->
     <dimen name="status_bar_recents_item_padding">0dip</dimen>
+    <!-- When recents first appears, how far the icon and label of the primary activity
+         travel -->
+    <dimen name="status_bar_recents_app_icon_translate_distance">100dp</dimen>
+
     <!-- Where to place the app icon over the thumbnail -->
     <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
     <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 58f749a..2b74f56 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -399,7 +399,7 @@
     <string name="jelly_bean_dream_name">BeanFlinger</string>
 
     <!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
-    <string name="start_dreams">Start dreams</string>
+    <string name="start_dreams">Sleep Now</string>
 
     <!-- Textual description of Ethernet connections -->
     <string name="ethernet_label">Ethernet</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index f97d4ff..c120690 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -19,9 +19,12 @@
 import android.app.Application;
 
 import com.android.systemui.recent.RecentTasksLoader;
+import com.android.systemui.recent.RecentsActivity;
 
 public class SystemUIApplication extends Application {
     private RecentTasksLoader mRecentTasksLoader;
+    private boolean mWaitingForWinAnimStart;
+    private RecentsActivity.WindowAnimationStartListener mWinAnimStartListener;
 
     public RecentTasksLoader getRecentTasksLoader() {
         if (mRecentTasksLoader == null) {
@@ -29,4 +32,28 @@
         }
         return mRecentTasksLoader;
     }
+
+    public void setWaitingForWinAnimStart(boolean waiting) {
+        mWaitingForWinAnimStart = waiting;
+    }
+
+    public void setWindowAnimationStartListener(
+            RecentsActivity.WindowAnimationStartListener startListener) {
+        mWinAnimStartListener = startListener;
+    }
+
+    public RecentsActivity.WindowAnimationStartListener getWindowAnimationListener() {
+        return mWinAnimStartListener;
+    }
+
+    public void onWindowAnimationStart() {
+        if (mWinAnimStartListener != null) {
+            mWinAnimStartListener.onWindowAnimationStart();
+        }
+        mWaitingForWinAnimStart = false;
+    }
+
+    public boolean isWaitingForWindowAnimationStart() {
+        return mWaitingForWinAnimStart;
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
index 7ff7b17..f93da08 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
@@ -51,6 +51,10 @@
         }
     };
 
+    public static interface WindowAnimationStartListener {
+        void onWindowAnimationStart();
+    }
+
     public class TouchOutsideListener implements View.OnTouchListener {
         private StatusBarPanel mPanel;
 
@@ -88,15 +92,15 @@
     @Override
     public void onStart() {
         mShowing = true;
+        if (mRecentsPanel != null) {
+            mRecentsPanel.refreshViews();
+        }
         super.onStart();
     }
 
     @Override
     public void onResume() {
         mForeground = true;
-        if (mRecentsPanel != null) {
-            mRecentsPanel.refreshViews();
-        }
         super.onResume();
     }
 
@@ -150,6 +154,7 @@
         mIntentFilter = new IntentFilter();
         mIntentFilter.addAction(CLOSE_RECENTS_INTENT);
         registerReceiver(mIntentReceiver, mIntentFilter);
+        app.setWindowAnimationStartListener(mRecentsPanel);
         super.onCreate(savedInstanceState);
     }
 
@@ -164,6 +169,7 @@
         final RecentTasksLoader recentTasksLoader = app.getRecentTasksLoader();
         recentTasksLoader.setRecentsPanel(null, mRecentsPanel);
         unregisterReceiver(mIntentReceiver);
+        app.setWindowAnimationStartListener(null);
         super.onDestroy();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 4aa2095..50b32f9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -156,19 +156,19 @@
         }
         setLayoutTransition(transitioner);
 
-        // Scroll to end after layout.
-        final ViewTreeObserver observer = getViewTreeObserver();
+        // Scroll to end after initial layout.
 
         final OnGlobalLayoutListener updateScroll = new OnGlobalLayoutListener() {
                 public void onGlobalLayout() {
                     mLastScrollPosition = scrollPositionOfMostRecent();
                     scrollTo(mLastScrollPosition, 0);
+                    final ViewTreeObserver observer = getViewTreeObserver();
                     if (observer.isAlive()) {
                         observer.removeOnGlobalLayoutListener(this);
                     }
                 }
             };
-        observer.addOnGlobalLayoutListener(updateScroll);
+        getViewTreeObserver().addOnGlobalLayoutListener(updateScroll);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 005b4a2..3a89059 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -18,12 +18,15 @@
 
 import android.animation.Animator;
 import android.animation.LayoutTransition;
+import android.animation.TimeInterpolator;
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -45,6 +48,7 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.BaseAdapter;
@@ -55,6 +59,7 @@
 import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.SystemUIApplication;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.tablet.StatusBarPanel;
@@ -63,7 +68,7 @@
 import java.util.ArrayList;
 
 public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback,
-        StatusBarPanel, Animator.AnimatorListener {
+        StatusBarPanel, Animator.AnimatorListener, RecentsActivity.WindowAnimationStartListener {
     static final String TAG = "RecentsPanelView";
     static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
     private PopupMenu mPopup;
@@ -75,6 +80,7 @@
     private boolean mShowing;
     private boolean mWaitingToShow;
     private int mNumItemsWaitingForThumbnailsAndIcons;
+    private ViewHolder mItemToAnimateInWhenWindowAnimationIsFinished;
 
     private RecentTasksLoader mRecentTasksLoader;
     private ArrayList<TaskDescription> mRecentTaskDescriptions;
@@ -109,6 +115,7 @@
         ImageView iconView;
         TextView labelView;
         TextView descriptionView;
+        View calloutLine;
         TaskDescription taskDescription;
         boolean loadedThumbnailAndIcon;
     }
@@ -148,6 +155,7 @@
                 holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon());
             }
             holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
+            holder.calloutLine = convertView.findViewById(R.id.recents_callout_line);
             holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
 
             convertView.setTag(holder);
@@ -173,6 +181,28 @@
                 updateIcon(holder, td.getIcon(), true, false);
                 mNumItemsWaitingForThumbnailsAndIcons--;
             }
+            if (index == 0) {
+                final Activity activity = (Activity) RecentsPanelView.this.getContext();
+                final SystemUIApplication app = (SystemUIApplication) activity.getApplication();
+                if (app.isWaitingForWindowAnimationStart()) {
+                    mItemToAnimateInWhenWindowAnimationIsFinished = holder;
+                    final int translation = -getResources().getDimensionPixelSize(
+                            R.dimen.status_bar_recents_app_icon_translate_distance);
+                    final Configuration config = getResources().getConfiguration();
+                    if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
+                        for (View v :
+                            new View[] { holder.iconView, holder.labelView, holder.calloutLine }) {
+                            if (v != null) {
+                                v.setAlpha(0f);
+                                v.setTranslationX(translation);
+                            }
+                        }
+                    } else {
+                        holder.iconView.setAlpha(0f);
+                        holder.iconView.setTranslationY(translation);
+                    }
+                }
+            }
 
             holder.thumbnailView.setTag(td);
             holder.thumbnailView.setOnLongClickListener(new OnLongClickDelegate(convertView));
@@ -506,6 +536,23 @@
         return null;
     }
 
+    public void onWindowAnimationStart() {
+        if (mItemToAnimateInWhenWindowAnimationIsFinished != null) {
+            final int startDelay = 100;
+            final int duration = 250;
+            final ViewHolder holder = mItemToAnimateInWhenWindowAnimationIsFinished;
+            final TimeInterpolator cubic = new DecelerateInterpolator(1.5f);
+            for (View v :
+                new View[] { holder.iconView, holder.labelView, holder.calloutLine }) {
+                if (v != null) {
+                    v.animate().translationX(0).translationY(0).alpha(1f).setStartDelay(startDelay)
+                            .setDuration(duration).setInterpolator(cubic);
+                }
+            }
+            mItemToAnimateInWhenWindowAnimationIsFinished = null;
+        }
+    }
+
     public void clearRecentTasksList() {
         // Clear memory used by screenshots
         if (mRecentTaskDescriptions != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index a0f197dd..5e0df49 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -165,19 +165,18 @@
         }
         setLayoutTransition(transitioner);
 
-        // Scroll to end after layout.
-        final ViewTreeObserver observer = getViewTreeObserver();
-
+        // Scroll to end after initial layout.
         final OnGlobalLayoutListener updateScroll = new OnGlobalLayoutListener() {
                 public void onGlobalLayout() {
                     mLastScrollPosition = scrollPositionOfMostRecent();
                     scrollTo(0, mLastScrollPosition);
+                    final ViewTreeObserver observer = getViewTreeObserver();
                     if (observer.isAlive()) {
                         observer.removeOnGlobalLayoutListener(this);
                     }
                 }
             };
-        observer.addOnGlobalLayoutListener(updateScroll);
+        getViewTreeObserver().addOnGlobalLayoutListener(updateScroll);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index d7b1b35..e88f9cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -544,7 +544,7 @@
                             - p.getFontMetricsInt().top;
                     float descriptionTextSize = res
                             .getDimensionPixelSize(R.dimen.status_bar_recents_app_description_text_size);
-                    p.setTextSize(labelTextSize);
+                    p.setTextSize(descriptionTextSize);
                     float descriptionTextHeight = p.getFontMetricsInt().bottom
                             - p.getFontMetricsInt().top;
 
@@ -567,10 +567,17 @@
                             + recentsItemTopPadding + thumbBgPadding + statusBarHeight);
                 }
 
+                final SystemUIApplication app =
+                        (SystemUIApplication) ((Service) mContext).getApplication();
+                app.setWaitingForWinAnimStart(true);
                 ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(
                         getStatusBarView(),
                         first, x, y,
-                        null);
+                        new ActivityOptions.OnAnimationStartedListener() {
+                            public void onAnimationStarted() {
+                                app.onWindowAnimationStart();
+                            }
+                        });
                 mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
                         UserHandle.USER_CURRENT));
             }
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 d63d517..c31e138 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -275,7 +275,8 @@
         timeTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                startSettingsActivity(android.provider.Settings.ACTION_DATE_SETTINGS);
+                // Quick. Clock. Quick. Clock. Quick. Clock.
+                startSettingsActivity(Intent.ACTION_QUICK_CLOCK);
             }
         });
         mModel.addTimeTile(timeTile, new QuickSettingsModel.RefreshCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index f864d04..776cf36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -97,7 +97,6 @@
         }
         
         try {
-            // XXX WHAT TO DO ABOUT MULTI-USER?
             if (visible) {
                 Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                 gpsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -126,7 +125,7 @@
                         GPS_NOTIFICATION_ID, 
                         n,
                         idOut,
-                        UserHandle.USER_CURRENT);
+                        UserHandle.USER_ALL);
 
                 for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
                     cb.onLocationGpsStateChanged(true, text);
@@ -134,7 +133,7 @@
             } else {
                 mNotificationService.cancelNotificationWithTag(
                         mContext.getPackageName(), null,
-                        GPS_NOTIFICATION_ID, UserHandle.USER_CURRENT);
+                        GPS_NOTIFICATION_ID, UserHandle.USER_ALL);
 
                 for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
                     cb.onLocationGpsStateChanged(false, null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/QuickSettingsDateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/QuickSettingsDateView.java
deleted file mode 100644
index c52f94b..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/QuickSettingsDateView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.policy;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.text.format.DateFormat;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewParent;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-import java.util.Date;
-
-public final class QuickSettingsDateView extends DateView {
-
-    public QuickSettingsDateView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    protected void updateClock() {
-        final Context context = getContext();
-        Date now = new Date();
-        CharSequence dow = DateFormat.format("MMM d, yyyy", now);
-        setText(dow);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c94c6c4..93f2aa5 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -730,14 +730,15 @@
         public void run() {
             // The context isn't read
             if (mLongPressOnPowerBehavior < 0) {
-                if (FactoryTest.isLongPressOnPowerOffEnabled()) {
-                    mLongPressOnPowerBehavior = LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
-                } else {
-                    mLongPressOnPowerBehavior = mContext.getResources().getInteger(
-                            com.android.internal.R.integer.config_longPressOnPowerBehavior);
-                }
+                mLongPressOnPowerBehavior = mContext.getResources().getInteger(
+                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
             }
-            switch (mLongPressOnPowerBehavior) {
+            int resolvedBehavior = mLongPressOnPowerBehavior;
+            if (FactoryTest.isLongPressOnPowerOffEnabled()) {
+                resolvedBehavior = LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
+            }
+
+            switch (resolvedBehavior) {
             case LONG_PRESS_POWER_NOTHING:
                 break;
             case LONG_PRESS_POWER_GLOBAL_ACTIONS:
@@ -753,8 +754,7 @@
                 mPowerKeyHandled = true;
                 performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                 sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
-                mWindowManagerFuncs.shutdown(
-                        mLongPressOnPowerBehavior == LONG_PRESS_POWER_SHUT_OFF);
+                mWindowManagerFuncs.shutdown(resolvedBehavior == LONG_PRESS_POWER_SHUT_OFF);
                 break;
             }
         }
@@ -775,7 +775,7 @@
         if (keyguardShowing) {
             // since it took two seconds of long press to bring this up,
             // poke the wake lock so they have some time to see the dialog.
-            mKeyguardMediator.pokeWakelock();
+            mKeyguardMediator.userActivity();
         }
     }
 
@@ -1140,6 +1140,11 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+            if (ActivityManager.isHighEndGfx()) {
+                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+                lp.privateFlags |=
+                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+            }
             lp.format = PixelFormat.TRANSLUCENT;
             lp.setTitle("PointerLocation");
             WindowManager wm = (WindowManager)
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 14633c4..a7fc1a1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -166,6 +166,7 @@
                         // from AudioManager
                         KeyguardHostView.this.addView(mTransportControl);
                         mTransportControl.setVisibility(View.GONE);
+                        showAppropriateWidgetPage();
                     }
                 }
 
@@ -178,6 +179,7 @@
                         mTransportControl.setVisibility(View.VISIBLE);
                         // Once shown, leave it showing
                         mSticky = true;
+                        showAppropriateWidgetPage();
                     }
                 }
             });
@@ -234,7 +236,7 @@
 
         public void userActivity(long timeout) {
             if (mViewMediatorCallback != null) {
-                mViewMediatorCallback.pokeWakelock(timeout);
+                mViewMediatorCallback.userActivity(timeout);
             }
         }
 
@@ -638,7 +640,7 @@
             if (DEBUG) Log.d(TAG, "poking wake lock immediately");
         }
         if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.pokeWakelock();
+            mViewMediatorCallback.wakeUp();
         }
     }
 
@@ -736,6 +738,15 @@
                 addWidget(widgets[i]);
             }
         }
+        showAppropriateWidgetPage();
+    }
+
+    private void showAppropriateWidgetPage() {
+        int page = mAppWidgetContainer.indexOfChild(findViewById(R.id.keyguard_status_view));
+        if (mAppWidgetContainer.indexOfChild(mTransportControl) != -1) {
+            page = mAppWidgetContainer.indexOfChild(mTransportControl);
+        }
+        mAppWidgetContainer.setCurrentPage(page);
     }
 
     private void inflateAndAddUserSelectorWidgetIfNecessary() {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index 6de65b0..4003754 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -80,6 +80,7 @@
 
                 case com.android.internal.R.drawable.ic_lockscreen_unlock_phantom:
                 case com.android.internal.R.drawable.ic_lockscreen_unlock:
+                    mCallback.userActivity(0);
                     mCallback.dismiss(false);
                 break;
             }
@@ -90,6 +91,7 @@
         }
 
         public void onGrabbed(View v, int handle) {
+            mCallback.userActivity(0);
             doTransition(mFadeView, 0.0f);
         }
 
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 1abcc10..a3a9c5f 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -155,6 +155,8 @@
                         WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
             }
             lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
+            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);
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 e4c1214..59aed24 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -104,7 +104,6 @@
         "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
 
     // used for handler messages
-    private static final int TIMEOUT = 1;
     private static final int SHOW = 2;
     private static final int HIDE = 3;
     private static final int RESET = 4;
@@ -167,12 +166,6 @@
     private UserManager mUserManager;
 
     /**
-     * Used to keep the device awake while the keyguard is showing, i.e for
-     * calls to {@link #pokeWakelock()}
-     */
-    private PowerManager.WakeLock mWakeLock;
-
-    /**
      * Used to keep the device awake while to ensure the keyguard finishes opening before
      * we sleep.
      */
@@ -215,8 +208,6 @@
      */
     private int mDelayedShowingSequence;
 
-    private int mWakelockSequence;
-
     /**
      * If the user has disabled the keyguard, then requests to exit, this is
      * how we'll ultimately let them know whether it was successful.  We use this
@@ -262,15 +253,16 @@
     public interface ViewMediatorCallback {
 
         /**
-         * Request the wakelock to be poked for the default amount of time.
+         * Wake the device immediately.
          */
-        void pokeWakelock();
+        void wakeUp();
 
         /**
-         * Request the wakelock to be poked for a specific amount of time.
+         * Reports user activity and requests that the screen stay on for the specified
+         * amount of time.
          * @param millis The amount of time in millis.
          */
-        void pokeWakelock(long millis);
+        void userActivity(long millis);
 
         /**
          * Report that the keyguard is done.
@@ -402,12 +394,12 @@
     };
 
     ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
-        public void pokeWakelock() {
-            KeyguardViewMediator.this.pokeWakelock();
+        public void wakeUp() {
+            KeyguardViewMediator.this.wakeUp();
         }
 
-        public void pokeWakelock(long holdMs) {
-            KeyguardViewMediator.this.pokeWakelock(holdMs);
+        public void userActivity(long holdMs) {
+            KeyguardViewMediator.this.userActivity(holdMs);
         }
 
         public void keyguardDone(boolean authenticated) {
@@ -424,19 +416,18 @@
         }
     };
 
-    public void pokeWakelock() {
-        pokeWakelock(AWAKE_INTERVAL_DEFAULT_MS);
+    public void wakeUp() {
+        mPM.wakeUp(SystemClock.uptimeMillis());
     }
 
-    public void pokeWakelock(long holdMs) {
-        synchronized (this) {
-            if (DBG_WAKE) Log.d(TAG, "pokeWakelock(" + holdMs + ")");
-            mWakeLock.acquire();
-            mHandler.removeMessages(TIMEOUT);
-            mWakelockSequence++;
-            Message msg = mHandler.obtainMessage(TIMEOUT, mWakelockSequence, 0);
-            mHandler.sendMessageDelayed(msg, holdMs);
-        }
+    public void userActivity() {
+        userActivity(AWAKE_INTERVAL_DEFAULT_MS);
+    }
+
+    public void userActivity(long holdMs) {
+        // We ignore the hold time.  Eventually we should remove it.
+        // Instead, the keyguard window has an explicit user activity timeout set on it.
+        mPM.userActivity(SystemClock.uptimeMillis(), false);
     }
 
     /**
@@ -448,9 +439,6 @@
         mContext = context;
         mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mWakeLock = mPM.newWakeLock(
-                PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
-        mWakeLock.setReferenceCounted(false);
         mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
         mShowKeyguardWakeLock.setReferenceCounted(false);
 
@@ -482,19 +470,19 @@
         mScreenOn = mPM.isScreenOn();
 
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
-        String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND);
+        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
         if (soundPath != null) {
             mLockSoundId = mLockSounds.load(soundPath, 1);
         }
         if (soundPath == null || mLockSoundId == 0) {
-            if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath);
+            Log.w(TAG, "failed to load lock sound from " + soundPath);
         }
-        soundPath = Settings.System.getString(cr, Settings.System.UNLOCK_SOUND);
+        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
         if (soundPath != null) {
             mUnlockSoundId = mLockSounds.load(soundPath, 1);
         }
         if (soundPath == null || mUnlockSoundId == 0) {
-            if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath);
+            Log.w(TAG, "failed to load unlock sound from " + soundPath);
         }
         int lockSoundDefaultAttenuation = context.getResources().getInteger(
                 com.android.internal.R.integer.config_lockSoundVolumeDb);
@@ -737,7 +725,6 @@
             if (mHidden != isHidden) {
                 mHidden = isHidden;
                 updateActivityLockScreenState();
-                adjustUserActivityLocked();
                 adjustStatusBarLocked();
             }
         }
@@ -1052,9 +1039,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case TIMEOUT:
-                    handleTimeout(msg.arg1);
-                    return ;
                 case SHOW:
                     handleShow();
                     return ;
@@ -1105,9 +1089,8 @@
         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
         handleHide();
         if (wakeup) {
-            mPM.wakeUp(SystemClock.uptimeMillis());
+            wakeUp();
         }
-        mWakeLock.release();
 
         sendUserPresentBroadcast();
     }
@@ -1139,21 +1122,6 @@
         }
     }
 
-    /**
-     * Handles the message sent by {@link #pokeWakelock}
-     * @param seq used to determine if anything has changed since the message
-     *   was sent.
-     * @see #TIMEOUT
-     */
-    private void handleTimeout(int seq) {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleTimeout");
-            if (seq == mWakelockSequence) {
-                mWakeLock.release();
-            }
-        }
-    }
-
     private void playSounds(boolean locked) {
         // User feedback for keyguard.
 
@@ -1202,8 +1170,8 @@
             mKeyguardViewManager.show();
             mShowing = true;
             updateActivityLockScreenState();
-            adjustUserActivityLocked();
             adjustStatusBarLocked();
+            userActivity();
             try {
                 ActivityManagerNative.getDefault().closeSystemDialogs("lock");
             } catch (RemoteException e) {
@@ -1237,23 +1205,10 @@
             mKeyguardViewManager.hide();
             mShowing = false;
             updateActivityLockScreenState();
-            adjustUserActivityLocked();
             adjustStatusBarLocked();
         }
     }
 
-    private void adjustUserActivityLocked() {
-        // disable user activity if we are shown and not hidden
-        if (DEBUG) Log.d(TAG, "adjustUserActivityLocked mShowing: " + mShowing + " mHidden: " + mHidden);
-        boolean enabled = !mShowing || mHidden;
-        // FIXME: Replace this with a new timeout control mechanism.
-        //mRealPowerManager.enableUserActivity(enabled);
-        if (!enabled && mScreenOn) {
-            // reinstate our short screen timeout policy
-            pokeWakelock();
-        }
-    }
-
     private void adjustStatusBarLocked() {
         if (mStatusBarManager == null) {
             mStatusBarManager = (StatusBarManager)
@@ -1322,7 +1277,7 @@
             if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) {
                 // poke wakelock ourselves if keyguard is no longer active
                 Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves");
-                pokeWakelock();
+                userActivity();
             }
 
             /**
@@ -1330,10 +1285,6 @@
              * release the handoff wakelock
              */
             mWakeAndHandOff.release();
-
-            if (!mWakeLock.isHeld()) {
-                Log.w(TAG, "mWakeLock not held in mKeyguardViewManager.wakeWhenReadyTq");
-            }
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
index 70a6ffa..d17c128 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
@@ -33,7 +33,6 @@
 public class KeyguardWidgetFrame extends FrameLayout {
     private final static PorterDuffXfermode sAddBlendMode =
             new PorterDuffXfermode(PorterDuff.Mode.ADD);
-    private static int sWidgetPagePadding;
     private static Drawable sLeftOverscrollDrawable;
     private static Drawable sRightOverscrollDrawable;
 
@@ -52,13 +51,16 @@
 
     public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        Resources res = context.getResources();
         if (sLeftOverscrollDrawable == null) {
-            Resources res = context.getResources();
             sLeftOverscrollDrawable = res.getDrawable(R.drawable.kg_widget_overscroll_layer_left);
             sRightOverscrollDrawable = res.getDrawable(R.drawable.kg_widget_overscroll_layer_right);
-            sWidgetPagePadding = res.getDimensionPixelSize(R.dimen.kg_widget_page_padding);
         }
-        setPadding(sWidgetPagePadding, sWidgetPagePadding, sWidgetPagePadding, sWidgetPagePadding);
+
+        int hPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_horizontal_padding);
+        int topPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_top_padding);
+        int bottomPadding = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);
+        setPadding(hPadding, topPadding, hPadding, bottomPadding);
     }
 
     @Override
@@ -76,8 +78,8 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mForegroundRect.set(sWidgetPagePadding, sWidgetPagePadding,
-                w - sWidgetPagePadding, h - sWidgetPagePadding);
+        mForegroundRect.set(getPaddingLeft(), getPaddingTop(),
+                w - getPaddingRight(), h - getPaddingBottom());
     }
 
     void setOverScrollAmount(float r, boolean left) {
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 e9cf9a5..f7f23c7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
 import com.android.internal.R;
@@ -70,5 +71,20 @@
     @Override
     public void onPageSwitch(View newPage, int newPageIndex) {
         mPage = newPageIndex;
+
+        // If we're showing the default system status widget, then we want to hide the clock
+        boolean hideClock = false;
+        if ((newPage instanceof ViewGroup)) {
+            ViewGroup vg = (ViewGroup) newPage;
+            if (vg.getChildAt(0) instanceof KeyguardStatusView) {
+                hideClock = true;
+            }
+        }
+
+        if (hideClock) {
+            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK);
+        } else {
+            setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK);
+        }
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/KeyguardViewMediator.java
index 8ff8dad..3de1428 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/KeyguardViewMediator.java
@@ -392,14 +392,14 @@
         mScreenOn = mPM.isScreenOn();
 
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
-        String soundPath = Settings.System.getString(cr, Settings.System.LOCK_SOUND);
+        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
         if (soundPath != null) {
             mLockSoundId = mLockSounds.load(soundPath, 1);
         }
         if (soundPath == null || mLockSoundId == 0) {
             if (DEBUG) Log.d(TAG, "failed to load sound from " + soundPath);
         }
-        soundPath = Settings.System.getString(cr, Settings.System.UNLOCK_SOUND);
+        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
         if (soundPath != null) {
             mUnlockSoundId = mLockSounds.load(soundPath, 1);
         }
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index be0cec9..7862e17 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1716,6 +1716,16 @@
 }
 
 void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
+    if (mFocusedWindowHandle != NULL) {
+        const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
+        if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
+#if DEBUG_DISPATCH_CYCLE
+            ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
+#endif
+            return;
+        }
+    }
+
     int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
     switch (eventEntry->type) {
     case EventEntry::TYPE_MOTION: {
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 3118099..7bd3af7 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -110,6 +110,8 @@
 
     enum {
         INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
+        INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
+        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
     };
 
     sp<InputChannel> inputChannel;
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index a0c1552..2197e31 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -17,9 +17,11 @@
 package com.android.server;
 
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -171,6 +173,9 @@
     private final ArrayList<LocationProviderProxy> mProxyProviders =
             new ArrayList<LocationProviderProxy>();
 
+    // current active user on the device - other users are denied location data
+    private int mCurrentUserId = UserHandle.USER_OWNER;
+
     public LocationManagerService(Context context) {
         super();
         mContext = context;
@@ -224,10 +229,30 @@
         });
         mPackageMonitor.register(mContext, Looper.myLooper(), true);
 
+        // listen for user change
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+
+        mContext.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                    switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+                }
+            }
+        }, UserHandle.ALL, intentFilter, null, null);
+
         updateProvidersLocked();
     }
 
     private void loadProvidersLocked() {
+        // create a passive location provider, which is always enabled
+        PassiveProvider passiveProvider = new PassiveProvider(this);
+        addProviderLocked(passiveProvider);
+        mEnabledProviders.add(passiveProvider.getName());
+        mPassiveProvider = passiveProvider;
+
         if (GpsLocationProvider.isSupported()) {
             // Create a gps location provider
             GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
@@ -237,12 +262,6 @@
             mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
         }
 
-        // create a passive location provider, which is always enabled
-        PassiveProvider passiveProvider = new PassiveProvider(this);
-        addProviderLocked(passiveProvider);
-        mEnabledProviders.add(passiveProvider.getName());
-        mPassiveProvider = passiveProvider;
-
         /*
         Load package name(s) containing location provider support.
         These packages can contain services implementing location providers:
@@ -302,6 +321,19 @@
     }
 
     /**
+     * Called when the device's active user changes.
+     * @param userId the new active user's UserId
+     */
+    private void switchUser(int userId) {
+        //Log.d("LocationManagerService", "switchUser(" + mCurrentUserId + " -> " + userId + ")"); // TODO: remove this
+        synchronized (mLock) {
+            // TODO: inform previous user's Receivers that they will no longer receive updates
+            mCurrentUserId = userId;
+            // TODO: inform new user's Receivers that they are back on the update train
+        }
+    }
+
+    /**
      * A wrapper class holding either an ILocationListener or a PendingIntent to receive
      * location updates.
      */
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b684c90..eaaf33f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -631,11 +631,12 @@
             }
 
             try {
-                Slog.i(TAG, "Wired Accessory Observer");
+                Slog.i(TAG, "Wired Accessory Manager");
                 // Listen for wired headset changes
-                new WiredAccessoryObserver(context);
+                inputManager.setWiredAccessoryCallbacks(
+                        new WiredAccessoryManager(context, inputManager));
             } catch (Throwable e) {
-                reportWtf("starting WiredAccessoryObserver", e);
+                reportWtf("starting WiredAccessoryManager", e);
             }
 
             try {
diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java
new file mode 100644
index 0000000..63e8895
--- /dev/null
+++ b/services/java/com/android/server/WiredAccessoryManager.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.UEventObserver;
+import android.util.Slog;
+import android.media.AudioManager;
+import android.util.Log;
+import android.view.InputDevice;
+
+import com.android.internal.R;
+import com.android.server.input.InputManagerService;
+import com.android.server.input.InputManagerService.WiredAccessoryCallbacks;
+import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT;
+import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT;
+import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT_BIT;
+import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT_BIT;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>WiredAccessoryManager monitors for a wired headset on the main board or dock using
+ * both the InputManagerService notifyWiredAccessoryChanged interface and the UEventObserver
+ * subsystem.
+ */
+final class WiredAccessoryManager implements WiredAccessoryCallbacks {
+    private static final String TAG = WiredAccessoryManager.class.getSimpleName();
+    private static final boolean LOG = true;
+
+    private static final int BIT_HEADSET = (1 << 0);
+    private static final int BIT_HEADSET_NO_MIC = (1 << 1);
+    private static final int BIT_USB_HEADSET_ANLG = (1 << 2);
+    private static final int BIT_USB_HEADSET_DGTL = (1 << 3);
+    private static final int BIT_HDMI_AUDIO = (1 << 4);
+    private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC|
+                                                   BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL|
+                                                   BIT_HDMI_AUDIO);
+
+    private static final String NAME_H2W = "h2w";
+    private static final String NAME_USB_AUDIO = "usb_audio";
+    private static final String NAME_HDMI_AUDIO = "hdmi_audio";
+    private static final String NAME_HDMI = "hdmi";
+
+    private static final int MSG_NEW_DEVICE_STATE = 1;
+
+    private final Object mLock = new Object();
+
+    private final WakeLock mWakeLock;  // held while there is a pending route change
+    private final AudioManager mAudioManager;
+
+    private int mHeadsetState;
+
+    private int mSwitchValues;
+
+    private final WiredAccessoryObserver mObserver;
+    private final InputManagerService mInputManager;
+
+    private final boolean mUseDevInputEventForAudioJack;
+
+    public WiredAccessoryManager(Context context, InputManagerService inputManager) {
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryManager");
+        mWakeLock.setReferenceCounted(false);
+        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
+        mInputManager = inputManager;
+
+        mUseDevInputEventForAudioJack =
+                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
+
+        mObserver = new WiredAccessoryObserver();
+
+        context.registerReceiver(new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context ctx, Intent intent) {
+                        bootCompleted();
+                    }
+                },
+                new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
+    }
+
+    private void bootCompleted() {
+        if (mUseDevInputEventForAudioJack) {
+            int switchValues = 0;
+            if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_HEADPHONE_INSERT) == 1) {
+                switchValues |= SW_HEADPHONE_INSERT_BIT;
+            }
+            if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MICROPHONE_INSERT) == 1) {
+                switchValues |= SW_MICROPHONE_INSERT_BIT;
+            }
+            notifyWiredAccessoryChanged(0, switchValues,
+                    SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT);
+        }
+
+        mObserver.init();
+    }
+
+    @Override
+    public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask) {
+        if (LOG) Slog.v(TAG, "notifyWiredAccessoryChanged: when=" + whenNanos
+                + " bits=" + switchCodeToString(switchValues, switchMask)
+                + " mask=" + Integer.toHexString(switchMask));
+
+        synchronized (mLock) {
+            int headset;
+            mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
+            switch (mSwitchValues & (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT)) {
+                case 0:
+                    headset = 0;
+                    break;
+
+                case SW_HEADPHONE_INSERT_BIT:
+                    headset = BIT_HEADSET_NO_MIC;
+                    break;
+
+                case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
+                    headset = BIT_HEADSET;
+                    break;
+
+                case SW_MICROPHONE_INSERT_BIT:
+                    headset = BIT_HEADSET;
+                    break;
+
+                default:
+                    headset = 0;
+                    break;
+            }
+
+            updateLocked(NAME_H2W, headset);
+        }
+    }
+
+    /**
+     * Compare the existing headset state with the new state and pass along accordingly. Note
+     * that this only supports a single headset at a time. Inserting both a usb and jacked headset
+     * results in support for the last one plugged in. Similarly, unplugging either is seen as
+     * unplugging all.
+     *
+     * @param newName One of the NAME_xxx variables defined above.
+     * @param newState 0 or one of the BIT_xxx variables defined above.
+     */
+    private void updateLocked(String newName, int newState) {
+        // Retain only relevant bits
+        int headsetState = newState & SUPPORTED_HEADSETS;
+        int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
+        int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
+        int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC);
+        boolean h2wStateChange = true;
+        boolean usbStateChange = true;
+        if (LOG) Slog.v(TAG, "newName=" + newName
+                + " newState=" + newState
+                + " headsetState=" + headsetState
+                + " prev headsetState=" + mHeadsetState);
+
+        if (mHeadsetState == headsetState) {
+            Log.e(TAG, "No state change.");
+            return;
+        }
+
+        // reject all suspect transitions: only accept state changes from:
+        // - a: 0 headset to 1 headset
+        // - b: 1 headset to 0 headset
+        if (h2w_headset == (BIT_HEADSET | BIT_HEADSET_NO_MIC)) {
+            Log.e(TAG, "Invalid combination, unsetting h2w flag");
+            h2wStateChange = false;
+        }
+        // - c: 0 usb headset to 1 usb headset
+        // - d: 1 usb headset to 0 usb headset
+        if (usb_headset_anlg == BIT_USB_HEADSET_ANLG && usb_headset_dgtl == BIT_USB_HEADSET_DGTL) {
+            Log.e(TAG, "Invalid combination, unsetting usb flag");
+            usbStateChange = false;
+        }
+        if (!h2wStateChange && !usbStateChange) {
+            Log.e(TAG, "invalid transition, returning ...");
+            return;
+        }
+
+        mWakeLock.acquire();
+
+        Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
+                mHeadsetState, newName);
+        mHandler.sendMessage(msg);
+
+        mHeadsetState = headsetState;
+    }
+
+    private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_NEW_DEVICE_STATE:
+                    setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
+                    mWakeLock.release();
+            }
+        }
+    };
+
+    private void setDevicesState(
+            int headsetState, int prevHeadsetState, String headsetName) {
+        synchronized (mLock) {
+            int allHeadsets = SUPPORTED_HEADSETS;
+            for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
+                if ((curHeadset & allHeadsets) != 0) {
+                    setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
+                    allHeadsets &= ~curHeadset;
+                }
+            }
+        }
+    }
+
+    private void setDeviceStateLocked(int headset,
+            int headsetState, int prevHeadsetState, String headsetName) {
+        if ((headsetState & headset) != (prevHeadsetState & headset)) {
+            int device;
+            int state;
+
+            if ((headsetState & headset) != 0) {
+                state = 1;
+            } else {
+                state = 0;
+            }
+
+            if (headset == BIT_HEADSET) {
+                device = AudioManager.DEVICE_OUT_WIRED_HEADSET;
+            } else if (headset == BIT_HEADSET_NO_MIC){
+                device = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
+            } else if (headset == BIT_USB_HEADSET_ANLG) {
+                device = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
+            } else if (headset == BIT_USB_HEADSET_DGTL) {
+                device = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
+            } else if (headset == BIT_HDMI_AUDIO) {
+                device = AudioManager.DEVICE_OUT_AUX_DIGITAL;
+            } else {
+                Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
+                return;
+            }
+
+            if (LOG)
+                Slog.v(TAG, "device "+headsetName+((state == 1) ? " connected" : " disconnected"));
+
+            mAudioManager.setWiredDeviceConnectionState(device, state, headsetName);
+        }
+    }
+
+    private String switchCodeToString(int switchValues, int switchMask) {
+        StringBuffer sb = new StringBuffer();
+        if ((switchMask & SW_HEADPHONE_INSERT_BIT) != 0 &&
+                (switchValues & SW_HEADPHONE_INSERT_BIT) != 0) {
+            sb.append("SW_HEADPHONE_INSERT ");
+        }
+        if ((switchMask & SW_MICROPHONE_INSERT_BIT) != 0 &&
+                (switchValues & SW_MICROPHONE_INSERT_BIT) != 0) {
+            sb.append("SW_MICROPHONE_INSERT");
+        }
+        return sb.toString();
+    }
+
+    class WiredAccessoryObserver extends UEventObserver {
+        private final List<UEventInfo> mUEventInfo;
+
+        public WiredAccessoryObserver() {
+            mUEventInfo = makeObservedUEventList();
+        }
+
+        void init() {
+            synchronized (mLock) {
+                if (LOG) Slog.v(TAG, "init()");
+                char[] buffer = new char[1024];
+
+                for (int i = 0; i < mUEventInfo.size(); ++i) {
+                    UEventInfo uei = mUEventInfo.get(i);
+                    try {
+                        int curState;
+                        FileReader file = new FileReader(uei.getSwitchStatePath());
+                        int len = file.read(buffer, 0, 1024);
+                        file.close();
+                        curState = Integer.valueOf((new String(buffer, 0, len)).trim());
+
+                        if (curState > 0) {
+                            updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);
+                        }
+                    } catch (FileNotFoundException e) {
+                        Slog.w(TAG, uei.getSwitchStatePath() +
+                                " not found while attempting to determine initial switch state");
+                    } catch (Exception e) {
+                        Slog.e(TAG, "" , e);
+                    }
+                }
+            }
+
+            // At any given time accessories could be inserted
+            // one on the board, one on the dock and one on HDMI:
+            // observe three UEVENTs
+            for (int i = 0; i < mUEventInfo.size(); ++i) {
+                UEventInfo uei = mUEventInfo.get(i);
+                startObserving("DEVPATH="+uei.getDevPath());
+            }
+        }
+
+        private List<UEventInfo> makeObservedUEventList() {
+            List<UEventInfo> retVal = new ArrayList<UEventInfo>();
+            UEventInfo uei;
+
+            // Monitor h2w
+            if (!mUseDevInputEventForAudioJack) {
+                uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC);
+                if (uei.checkSwitchExists()) {
+                    retVal.add(uei);
+                } else {
+                    Slog.w(TAG, "This kernel does not have wired headset support");
+                }
+            }
+
+            // Monitor USB
+            uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL);
+            if (uei.checkSwitchExists()) {
+                retVal.add(uei);
+            } else {
+                Slog.w(TAG, "This kernel does not have usb audio support");
+            }
+
+            // Monitor HDMI
+            //
+            // If the kernel has support for the "hdmi_audio" switch, use that.  It will be
+            // signalled only when the HDMI driver has a video mode configured, and the downstream
+            // sink indicates support for audio in its EDID.
+            //
+            // If the kernel does not have an "hdmi_audio" switch, just fall back on the older
+            // "hdmi" switch instead.
+            uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0);
+            if (uei.checkSwitchExists()) {
+                retVal.add(uei);
+            } else {
+                uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0);
+                if (uei.checkSwitchExists()) {
+                    retVal.add(uei);
+                } else {
+                    Slog.w(TAG, "This kernel does not have HDMI audio support");
+                }
+            }
+
+            return retVal;
+        }
+
+        @Override
+        public void onUEvent(UEventObserver.UEvent event) {
+            if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
+
+            try {
+                String devPath = event.get("DEVPATH");
+                String name = event.get("SWITCH_NAME");
+                int state = Integer.parseInt(event.get("SWITCH_STATE"));
+                synchronized (mLock) {
+                    updateStateLocked(devPath, name, state);
+                }
+            } catch (NumberFormatException e) {
+                Slog.e(TAG, "Could not parse switch state from event " + event);
+            }
+        }
+
+        private void updateStateLocked(String devPath, String name, int state) {
+            for (int i = 0; i < mUEventInfo.size(); ++i) {
+                UEventInfo uei = mUEventInfo.get(i);
+                if (devPath.equals(uei.getDevPath())) {
+                    updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));
+                    return;
+                }
+            }
+        }
+
+        private final class UEventInfo {
+            private final String mDevName;
+            private final int mState1Bits;
+            private final int mState2Bits;
+
+            public UEventInfo(String devName, int state1Bits, int state2Bits) {
+                mDevName = devName;
+                mState1Bits = state1Bits;
+                mState2Bits = state2Bits;
+            }
+
+            public String getDevName() { return mDevName; }
+
+            public String getDevPath() {
+                return String.format("/devices/virtual/switch/%s", mDevName);
+            }
+
+            public String getSwitchStatePath() {
+                return String.format("/sys/class/switch/%s/state", mDevName);
+            }
+
+            public boolean checkSwitchExists() {
+                File f = new File(getSwitchStatePath());
+                return f.exists();
+            }
+
+            public int computeNewHeadsetState(int headsetState, int switchState) {
+                int preserveMask = ~(mState1Bits | mState2Bits);
+                int setBits = ((switchState == 1) ? mState1Bits :
+                              ((switchState == 2) ? mState2Bits : 0));
+
+                return ((headsetState & preserveMask) | setBits);
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
deleted file mode 100644
index 56c0fdf..0000000
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.UEventObserver;
-import android.util.Slog;
-import android.media.AudioManager;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * <p>WiredAccessoryObserver monitors for a wired headset on the main board or dock.
- */
-final class WiredAccessoryObserver extends UEventObserver {
-    private static final String TAG = WiredAccessoryObserver.class.getSimpleName();
-    private static final boolean LOG = true;
-    private static final int BIT_HEADSET = (1 << 0);
-    private static final int BIT_HEADSET_NO_MIC = (1 << 1);
-    private static final int BIT_USB_HEADSET_ANLG = (1 << 2);
-    private static final int BIT_USB_HEADSET_DGTL = (1 << 3);
-    private static final int BIT_HDMI_AUDIO = (1 << 4);
-    private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC|
-                                                   BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL|
-                                                   BIT_HDMI_AUDIO);
-
-    private final Object mLock = new Object();
-
-    private final Context mContext;
-    private final WakeLock mWakeLock;  // held while there is a pending route change
-    private final AudioManager mAudioManager;
-    private final List<UEventInfo> mUEventInfo;
-
-    private int mHeadsetState;
-    private int mPrevHeadsetState;
-    private String mHeadsetName;
-
-    public WiredAccessoryObserver(Context context) {
-        mContext = context;
-
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryObserver");
-        mWakeLock.setReferenceCounted(false);
-        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
-
-        mUEventInfo = makeObservedUEventList();
-
-        context.registerReceiver(new BootCompletedReceiver(),
-            new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
-    }
-
-    @Override
-    public void onUEvent(UEventObserver.UEvent event) {
-        if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
-
-        try {
-            String devPath = event.get("DEVPATH");
-            String name = event.get("SWITCH_NAME");
-            int state = Integer.parseInt(event.get("SWITCH_STATE"));
-            synchronized (mLock) {
-                updateStateLocked(devPath, name, state);
-            }
-        } catch (NumberFormatException e) {
-            Slog.e(TAG, "Could not parse switch state from event " + event);
-        }
-    }
-
-    private void bootCompleted() {
-        synchronized (mLock) {
-            char[] buffer = new char[1024];
-            mPrevHeadsetState = mHeadsetState;
-
-            if (LOG) Slog.v(TAG, "init()");
-
-            for (int i = 0; i < mUEventInfo.size(); ++i) {
-                UEventInfo uei = mUEventInfo.get(i);
-                try {
-                    int curState;
-                    FileReader file = new FileReader(uei.getSwitchStatePath());
-                    int len = file.read(buffer, 0, 1024);
-                    file.close();
-                    curState = Integer.valueOf((new String(buffer, 0, len)).trim());
-
-                    if (curState > 0) {
-                        updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);
-                    }
-                } catch (FileNotFoundException e) {
-                    Slog.w(TAG, uei.getSwitchStatePath() +
-                            " not found while attempting to determine initial switch state");
-                } catch (Exception e) {
-                    Slog.e(TAG, "" , e);
-                }
-            }
-        }
-
-        // At any given time accessories could be inserted
-        // one on the board, one on the dock and one on HDMI:
-        // observe three UEVENTs
-        for (int i = 0; i < mUEventInfo.size(); ++i) {
-            UEventInfo uei = mUEventInfo.get(i);
-            startObserving("DEVPATH="+uei.getDevPath());
-        }
-    }
-
-    private void updateStateLocked(String devPath, String name, int state) {
-        for (int i = 0; i < mUEventInfo.size(); ++i) {
-            UEventInfo uei = mUEventInfo.get(i);
-            if (devPath.equals(uei.getDevPath())) {
-                updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));
-                return;
-            }
-        }
-    }
-
-    private void updateLocked(String newName, int newState) {
-        // Retain only relevant bits
-        int headsetState = newState & SUPPORTED_HEADSETS;
-        int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
-        int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
-        int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC);
-        boolean h2wStateChange = true;
-        boolean usbStateChange = true;
-        // reject all suspect transitions: only accept state changes from:
-        // - a: 0 heaset to 1 headset
-        // - b: 1 headset to 0 headset
-        if (LOG) Slog.v(TAG, "newState = "+newState+", headsetState = "+headsetState+","
-            + "mHeadsetState = "+mHeadsetState);
-        if (mHeadsetState == headsetState || ((h2w_headset & (h2w_headset - 1)) != 0)) {
-            Log.e(TAG, "unsetting h2w flag");
-            h2wStateChange = false;
-        }
-        // - c: 0 usb headset to 1 usb headset
-        // - d: 1 usb headset to 0 usb headset
-        if ((usb_headset_anlg >> 2) == 1 && (usb_headset_dgtl >> 3) == 1) {
-            Log.e(TAG, "unsetting usb flag");
-            usbStateChange = false;
-        }
-        if (!h2wStateChange && !usbStateChange) {
-            Log.e(TAG, "invalid transition, returning ...");
-            return;
-        }
-
-        mHeadsetName = newName;
-        mPrevHeadsetState = mHeadsetState;
-        mHeadsetState = headsetState;
-
-        mWakeLock.acquire();
-
-        Message msg = mHandler.obtainMessage(0, mHeadsetState, mPrevHeadsetState, mHeadsetName);
-        mHandler.sendMessage(msg);
-    }
-
-    private void setDevicesState(
-            int headsetState, int prevHeadsetState, String headsetName) {
-        synchronized (mLock) {
-            int allHeadsets = SUPPORTED_HEADSETS;
-            for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
-                if ((curHeadset & allHeadsets) != 0) {
-                    setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
-                    allHeadsets &= ~curHeadset;
-                }
-            }
-        }
-    }
-
-    private void setDeviceStateLocked(int headset,
-            int headsetState, int prevHeadsetState, String headsetName) {
-        if ((headsetState & headset) != (prevHeadsetState & headset)) {
-            int device;
-            int state;
-
-            if ((headsetState & headset) != 0) {
-                state = 1;
-            } else {
-                state = 0;
-            }
-
-            if (headset == BIT_HEADSET) {
-                device = AudioManager.DEVICE_OUT_WIRED_HEADSET;
-            } else if (headset == BIT_HEADSET_NO_MIC){
-                device = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
-            } else if (headset == BIT_USB_HEADSET_ANLG) {
-                device = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
-            } else if (headset == BIT_USB_HEADSET_DGTL) {
-                device = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
-            } else if (headset == BIT_HDMI_AUDIO) {
-                device = AudioManager.DEVICE_OUT_AUX_DIGITAL;
-            } else {
-                Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
-                return;
-            }
-
-            if (LOG)
-                Slog.v(TAG, "device "+headsetName+((state == 1) ? " connected" : " disconnected"));
-
-            mAudioManager.setWiredDeviceConnectionState(device, state, headsetName);
-        }
-    }
-
-    private static List<UEventInfo> makeObservedUEventList() {
-        List<UEventInfo> retVal = new ArrayList<UEventInfo>();
-        UEventInfo uei;
-
-        // Monitor h2w
-        uei = new UEventInfo("h2w", BIT_HEADSET, BIT_HEADSET_NO_MIC);
-        if (uei.checkSwitchExists()) {
-            retVal.add(uei);
-        } else {
-            Slog.w(TAG, "This kernel does not have wired headset support");
-        }
-
-        // Monitor USB
-        uei = new UEventInfo("usb_audio", BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL);
-        if (uei.checkSwitchExists()) {
-            retVal.add(uei);
-        } else {
-            Slog.w(TAG, "This kernel does not have usb audio support");
-        }
-
-        // Monitor HDMI
-        //
-        // If the kernel has support for the "hdmi_audio" switch, use that.  It will be signalled
-        // only when the HDMI driver has a video mode configured, and the downstream sink indicates
-        // support for audio in its EDID.
-        //
-        // If the kernel does not have an "hdmi_audio" switch, just fall back on the older "hdmi"
-        // switch instead.
-        uei = new UEventInfo("hdmi_audio", BIT_HDMI_AUDIO, 0);
-        if (uei.checkSwitchExists()) {
-            retVal.add(uei);
-        } else {
-            uei = new UEventInfo("hdmi", BIT_HDMI_AUDIO, 0);
-            if (uei.checkSwitchExists()) {
-                retVal.add(uei);
-            } else {
-                Slog.w(TAG, "This kernel does not have HDMI audio support");
-            }
-        }
-
-        return retVal;
-    }
-
-    private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
-        @Override
-        public void handleMessage(Message msg) {
-            setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
-            mWakeLock.release();
-        }
-    };
-
-    private static final class UEventInfo {
-        private final String mDevName;
-        private final int mState1Bits;
-        private final int mState2Bits;
-
-        public UEventInfo(String devName, int state1Bits, int state2Bits) {
-            mDevName = devName;
-            mState1Bits = state1Bits;
-            mState2Bits = state2Bits;
-        }
-
-        public String getDevName() { return mDevName; }
-
-        public String getDevPath() {
-            return String.format("/devices/virtual/switch/%s", mDevName);
-        }
-
-        public String getSwitchStatePath() {
-            return String.format("/sys/class/switch/%s/state", mDevName);
-        }
-
-        public boolean checkSwitchExists() {
-            File f = new File(getSwitchStatePath());
-            return ((null != f) && f.exists());
-        }
-
-        public int computeNewHeadsetState(int headsetState, int switchState) {
-            int preserveMask = ~(mState1Bits | mState2Bits);
-            int setBits = ((switchState == 1) ? mState1Bits :
-                          ((switchState == 2) ? mState2Bits : 0));
-
-            return ((headsetState & preserveMask) | setBits);
-        }
-    }
-
-    private final class BootCompletedReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            bootCompleted();
-        }
-    }
-}
diff --git a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
index f1a03de..eb414fa 100644
--- a/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -119,13 +119,16 @@
             mCurrentDeviceId = deviceId;
         }
         mPm.userActivity(event.getEventTime(), false);
-        MotionEvent motionEvent = (MotionEvent) event;
-        mEventHandler.onMotionEvent(motionEvent, policyFlags);
+        MotionEvent rawEvent = (MotionEvent) event;
+        MotionEvent transformedEvent = MotionEvent.obtain(rawEvent);
+        mEventHandler.onMotionEvent(transformedEvent, rawEvent, policyFlags);
+        transformedEvent.recycle();
     }
 
     @Override
-    public void onMotionEvent(MotionEvent event, int policyFlags) {
-        sendInputEvent(event, policyFlags);
+    public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent,
+            int policyFlags) {
+        sendInputEvent(transformedEvent, policyFlags);
     }
 
     @Override
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 8193a4f..d23e571 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -111,7 +111,7 @@
 
     // TODO: This is arbitrary. When there is time implement this by watching
     //       when that accessibility services are bound.
-    private static final int WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS = 5000;
+    private static final int WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS = 3000;
 
     private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
         "registerUiTestAutomationService";
@@ -659,6 +659,10 @@
                         oldUserState.mUserId, 0).sendToTarget();
             }
 
+            // Announce user changes only if more that one exist.
+            UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+            final boolean announceNewUser = userManager.getUsers().size() > 1;
+
             // The user changed.
             mCurrentUserId = userId;
 
@@ -666,9 +670,11 @@
             mMainHandler.obtainMessage(MainHandler.MSG_SEND_RECREATE_INTERNAL_STATE,
                     mCurrentUserId, 0).sendToTarget();
 
-            // Schedule announcement of the current user if needed.
-            mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
-                    WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
+            if (announceNewUser) {
+                // Schedule announcement of the current user if needed.
+                mMainHandler.sendEmptyMessageDelayed(MainHandler.MSG_ANNOUNCE_NEW_USER_IF_NEEDED,
+                        WAIT_FOR_USER_STATE_FULLY_INITIALIZED_MILLIS);
+            }
         }
     }
 
diff --git a/services/java/com/android/server/accessibility/EventStreamTransformation.java b/services/java/com/android/server/accessibility/EventStreamTransformation.java
index b715570..3289a15 100644
--- a/services/java/com/android/server/accessibility/EventStreamTransformation.java
+++ b/services/java/com/android/server/accessibility/EventStreamTransformation.java
@@ -57,12 +57,15 @@
 interface EventStreamTransformation {
 
     /**
-     * Receives a motion event.
+     * Receives motion event. Passed are the event transformed by previous
+     * transformations and the raw event to which no transformations have
+     * been applied.
      *
-     * @param event The motion event.
+     * @param event The transformed motion event.
+     * @param rawEvent The raw motion event.
      * @param policyFlags Policy flags for the event.
      */
-    public void onMotionEvent(MotionEvent event, int policyFlags);
+    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
 
     /**
      * Receives an accessibility event.
diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java
index b7327080..14762a1 100644
--- a/services/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -183,8 +183,8 @@
                 com.android.internal.R.integer.config_longAnimTime);
         mTapDistanceSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mMultiTapDistanceSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
-        mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
-                Settings.System.WINDOW_ANIMATION_SCALE, DEFAULT_WINDOW_ANIMATION_SCALE);
+        mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.WINDOW_ANIMATION_SCALE, DEFAULT_WINDOW_ANIMATION_SCALE);
 
         mMagnificationController = new MagnificationController(mShortAnimationDuration);
         mDisplayProvider = new DisplayProvider(context, mWindowManager);
@@ -203,14 +203,15 @@
     }
 
     @Override
-    public void onMotionEvent(MotionEvent event, int policyFlags) {
+    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent,
+            int policyFlags) {
         mMagnifiedContentInteractonStateHandler.onMotionEvent(event);
         switch (mCurrentState) {
             case STATE_DELEGATING: {
-                handleMotionEventStateDelegating(event, policyFlags);
+                handleMotionEventStateDelegating(event, rawEvent, policyFlags);
             } break;
             case STATE_DETECTING: {
-                mDetectingStateHandler.onMotionEvent(event, policyFlags);
+                mDetectingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
             } break;
             case STATE_VIEWPORT_DRAGGING: {
                 mStateViewportDraggingHandler.onMotionEvent(event, policyFlags);
@@ -259,7 +260,8 @@
         mScreenStateObserver.destroy();
     }
 
-    private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
+    private void handleMotionEventStateDelegating(MotionEvent event,
+            MotionEvent rawEvent, int policyFlags) {
         if (event.getActionMasked() == MotionEvent.ACTION_UP) {
             if (mDetectingStateHandler.mDelayedEventQueue == null) {
                 transitionToState(STATE_DETECTING);
@@ -290,7 +292,7 @@
                         coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
                         event.getFlags());
             }
-            mNext.onMotionEvent(event, policyFlags);
+            mNext.onMotionEvent(event, rawEvent, policyFlags);
         }
     }
 
@@ -533,8 +535,8 @@
             }
         };
 
-        public void onMotionEvent(MotionEvent event, int policyFlags) {
-            cacheDelayedMotionEvent(event, policyFlags);
+        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+            cacheDelayedMotionEvent(event, rawEvent, policyFlags);
             final int action = event.getActionMasked();
             switch (action) {
                 case MotionEvent.ACTION_DOWN: {
@@ -640,8 +642,10 @@
             }
         }
 
-        private void cacheDelayedMotionEvent(MotionEvent event, int policyFlags) {
-            MotionEventInfo info = MotionEventInfo.obtain(event, policyFlags);
+        private void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent,
+                int policyFlags) {
+            MotionEventInfo info = MotionEventInfo.obtain(event, rawEvent,
+                    policyFlags);
             if (mDelayedEventQueue == null) {
                 mDelayedEventQueue = info;
             } else {
@@ -657,7 +661,8 @@
             while (mDelayedEventQueue != null) {
                 MotionEventInfo info = mDelayedEventQueue;
                 mDelayedEventQueue = info.mNext;
-                ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mPolicyFlags);
+                ScreenMagnifier.this.onMotionEvent(info.mEvent, info.mRawEvent,
+                        info.mPolicyFlags);
                 info.recycle();
             }
         }
@@ -738,9 +743,11 @@
         private boolean mInPool;
 
         public MotionEvent mEvent;
+        public MotionEvent mRawEvent;
         public int mPolicyFlags;
 
-        public static MotionEventInfo obtain(MotionEvent event, int policyFlags) {
+        public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent,
+                int policyFlags) {
             synchronized (sLock) {
                 MotionEventInfo info;
                 if (sPoolSize > 0) {
@@ -752,13 +759,15 @@
                 } else {
                     info = new MotionEventInfo();
                 }
-                info.initialize(event, policyFlags);
+                info.initialize(event, rawEvent, policyFlags);
                 return info;
             }
         }
 
-        private void initialize(MotionEvent event, int policyFlags) {
+        private void initialize(MotionEvent event, MotionEvent rawEvent,
+                int policyFlags) {
             mEvent = MotionEvent.obtain(event);
+            mRawEvent = MotionEvent.obtain(rawEvent);
             mPolicyFlags = policyFlags;
         }
 
@@ -780,6 +789,8 @@
         private void clear() {
             mEvent.recycle();
             mEvent = null;
+            mRawEvent.recycle();
+            mRawEvent = null;
             mPolicyFlags = 0;
         }
     }
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 6e57d1f..616bc13 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -162,7 +162,7 @@
     private EventStreamTransformation mNext;
 
     // Helper to track gesture velocity.
-    private VelocityTracker mVelocityTracker;
+    private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
 
     // Helper class to track received pointers.
     private final ReceivedPointerTracker mReceivedPointerTracker;
@@ -309,18 +309,18 @@
     }
 
     @Override
-    public void onMotionEvent(MotionEvent event, int policyFlags) {
+    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
         if (DEBUG) {
             Slog.d(LOG_TAG, "Received event: " + event + ", policyFlags=0x"
                     + Integer.toHexString(policyFlags));
             Slog.d(LOG_TAG, getStateSymbolicName(mCurrentState));
         }
 
-        mReceivedPointerTracker.onMotionEvent(event);
+        mReceivedPointerTracker.onMotionEvent(rawEvent);
 
         switch(mCurrentState) {
             case STATE_TOUCH_EXPLORING: {
-                handleMotionEventStateTouchExploring(event, policyFlags);
+                handleMotionEventStateTouchExploring(event, rawEvent, policyFlags);
             } break;
             case STATE_DRAGGING: {
                 handleMotionEventStateDragging(event, policyFlags);
@@ -329,7 +329,7 @@
                 handleMotionEventStateDelegating(event, policyFlags);
             } break;
             case STATE_GESTURE_DETECTING: {
-                handleMotionEventGestureDetecting(event, policyFlags);
+                handleMotionEventGestureDetecting(rawEvent, policyFlags);
             } break;
             default:
                 throw new IllegalStateException("Illegal state: " + mCurrentState);
@@ -382,16 +382,15 @@
      * Handles a motion event in touch exploring state.
      *
      * @param event The event to be handled.
+     * @param rawEvent The raw (unmodified) motion event.
      * @param policyFlags The policy flags associated with the event.
      */
-    private void handleMotionEventStateTouchExploring(MotionEvent event, int policyFlags) {
+    private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent,
+            int policyFlags) {
         ReceivedPointerTracker receivedTracker = mReceivedPointerTracker;
         final int activePointerCount = receivedTracker.getActivePointerCount();
 
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        mVelocityTracker.addMovement(event);
+        mVelocityTracker.addMovement(rawEvent);
 
         mDoubleTapDetector.onMotionEvent(event, policyFlags);
 
@@ -410,7 +409,7 @@
                 // have a distance slop before getting into gesture detection
                 // mode and not using the points within this slop significantly
                 // decreases the quality of gesture recognition.
-                handleMotionEventGestureDetecting(event, policyFlags);
+                handleMotionEventGestureDetecting(rawEvent, policyFlags);
                 //$FALL-THROUGH$
             case MotionEvent.ACTION_POINTER_DOWN: {
                 switch (activePointerCount) {
@@ -471,12 +470,13 @@
                             // have a distance slop before getting into gesture detection
                             // mode and not using the points within this slop significantly
                             // decreases the quality of gesture recognition.
-                            handleMotionEventGestureDetecting(event, policyFlags);
-
+                            handleMotionEventGestureDetecting(rawEvent, policyFlags);
+                            // It is *important* to use the distance traveled by the pointers
+                            // on the screen which may or may not be magnified.
                             final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId)
-                                - event.getX(pointerIndex);
+                                - rawEvent.getX(pointerIndex);
                             final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId)
-                                - event.getY(pointerIndex);
+                                - rawEvent.getY(pointerIndex);
                             final double moveDelta = Math.hypot(deltaX, deltaY);
                             // The user has moved enough for us to decide.
                             if (moveDelta > mDoubleTapSlop) {
@@ -491,6 +491,7 @@
                                     // We have to perform gesture detection, so
                                     // clear the current state and try to detect.
                                     mCurrentState = STATE_GESTURE_DETECTING;
+                                    mVelocityTracker.clear();
                                     mSendHoverEnterDelayed.remove();
                                     mSendHoverExitDelayed.remove();
                                     mPerformLongPressDelayed.remove();
@@ -535,10 +536,12 @@
                             // If the user is touch exploring the second pointer may be
                             // performing a double tap to activate an item without need
                             // for the user to lift his exploring finger.
+                            // It is *important* to use the distance traveled by the pointers
+                            // on the screen which may or may not be magnified.
                             final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId)
-                                    - event.getX(pointerIndex);
+                                    - rawEvent.getX(pointerIndex);
                             final float deltaY = receivedTracker.getReceivedPointerDownY(pointerId)
-                                    - event.getY(pointerIndex);
+                                    - rawEvent.getY(pointerIndex);
                             final double moveDelta = Math.hypot(deltaX, deltaY);
                             if (moveDelta < mDoubleTapSlop) {
                                 break;
@@ -565,6 +568,7 @@
                             mCurrentState = STATE_DELEGATING;
                             sendDownForAllActiveNotInjectedPointers(event, policyFlags);
                         }
+                        mVelocityTracker.clear();
                     } break;
                     default: {
                         // More than one pointer so the user is not touch exploring
@@ -585,6 +589,7 @@
                         // More than two pointers are delegated to the view hierarchy.
                         mCurrentState = STATE_DELEGATING;
                         sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                        mVelocityTracker.clear();
                     }
                 }
             } break;
@@ -615,10 +620,7 @@
                         }
                     } break;
                 }
-                if (mVelocityTracker != null) {
-                    mVelocityTracker.clear();
-                    mVelocityTracker = null;
-                }
+                mVelocityTracker.clear();
             } break;
             case MotionEvent.ACTION_CANCEL: {
                 clear(event, policyFlags);
@@ -1046,7 +1048,10 @@
         // Make sure that the user will see the event.
         policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
         if (mNext != null) {
-            mNext.onMotionEvent(event, policyFlags);
+            // TODO: For now pass null for the raw event since the touch
+            //       explorer is the last event transformation and it does
+            //       not care about the raw event.
+            mNext.onMotionEvent(event, null, policyFlags);
         }
 
         mInjectedPointerTracker.onMotionEvent(event);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 35f1b59..e90eef9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -181,6 +181,7 @@
     static final boolean DEBUG_VISBILITY = localLOGV || false;
     static final boolean DEBUG_PROCESSES = localLOGV || false;
     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
+    static final boolean DEBUG_CLEANUP = localLOGV || false;
     static final boolean DEBUG_PROVIDER = localLOGV || false;
     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -1968,7 +1969,7 @@
             } else {
                 // An application record is attached to a previous process,
                 // clean it up now.
-                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
+                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
                 handleAppDiedLocked(app, true, true);
             }
         }
@@ -2925,7 +2926,8 @@
 
         // Just in case...
         if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
-            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
+            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
+                    "App died while pausing: " + mMainStack.mPausingActivity);
             mMainStack.mPausingActivity = null;
         }
         if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
@@ -2933,61 +2935,7 @@
         }
 
         // Remove this application's activities from active lists.
-        mMainStack.removeHistoryRecordsForAppLocked(app);
-
-        boolean atTop = true;
-        boolean hasVisibleActivities = false;
-
-        // Clean out the history list.
-        int i = mMainStack.mHistory.size();
-        if (localLOGV) Slog.v(
-            TAG, "Removing app " + app + " from history with " + i + " entries");
-        while (i > 0) {
-            i--;
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-            if (localLOGV) Slog.v(
-                TAG, "Record #" + i + " " + r + ": app=" + r.app);
-            if (r.app == app) {
-                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
-                    if (ActivityStack.DEBUG_ADD_REMOVE) {
-                        RuntimeException here = new RuntimeException("here");
-                        here.fillInStackTrace();
-                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
-                                + ": haveState=" + r.haveState
-                                + " stateNotNeeded=" + r.stateNotNeeded
-                                + " finishing=" + r.finishing
-                                + " state=" + r.state, here);
-                    }
-                    if (!r.finishing) {
-                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
-                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
-                                r.userId, System.identityHashCode(r),
-                                r.task.taskId, r.shortComponentName,
-                                "proc died without state saved");
-                    }
-                    mMainStack.removeActivityFromHistoryLocked(r);
-
-                } else {
-                    // We have the current state for this activity, so
-                    // it can be restarted later when needed.
-                    if (localLOGV) Slog.v(
-                        TAG, "Keeping entry, setting app to null");
-                    if (r.visible) {
-                        hasVisibleActivities = true;
-                    }
-                    r.app = null;
-                    r.nowVisible = false;
-                    if (!r.haveState) {
-                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
-                                "App died, clearing saved state of " + r);
-                        r.icicle = null;
-                    }
-                }
-
-                r.stack.cleanUpActivityLocked(r, true, true);
-            }
-            atTop = false;
-        }
+        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
 
         app.activities.clear();
         
@@ -3053,7 +3001,7 @@
                         + ") has died.");
             }
             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
-            if (localLOGV) Slog.v(
+            if (DEBUG_CLEANUP) Slog.v(
                 TAG, "Dying app: " + app + ", pid: " + pid
                 + ", thread: " + thread.asBinder());
             boolean doLowMem = app.instrumentationClass == null;
@@ -10757,7 +10705,8 @@
         
         // If the app is undergoing backup, tell the backup manager about it
         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
-            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
+            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
+                    + mBackupTarget.appInfo + " died during backup");
             try {
                 IBackupManager bm = IBackupManager.Stub.asInterface(
                         ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -10783,7 +10732,7 @@
         }
 
         if (!app.persistent || app.isolated) {
-            if (DEBUG_PROCESSES) Slog.v(TAG,
+            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
                     "Removing non-persistent process during cleanup: " + app);
             mProcessNames.remove(app.processName, app.uid);
             mIsolatedProcesses.remove(app.uid);
@@ -10801,7 +10750,7 @@
                 restart = true;
             }
         }
-        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
+        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
                 "Clean-up removing on hold: " + app);
         mProcessesOnHold.remove(app);
 
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2d445274..90a7abc 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -81,6 +81,7 @@
     static final boolean DEBUG_RESULTS = ActivityManagerService.DEBUG_RESULTS;
     static final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
     static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
+    static final boolean DEBUG_CLEANUP = ActivityManagerService.DEBUG_CLEANUP;
     
     static final boolean DEBUG_STATES = false;
     static final boolean DEBUG_ADD_REMOVE = false;
@@ -1142,9 +1143,13 @@
             resumeTopActivityLocked(prev);
         } else {
             checkReadyForSleepLocked();
-            if (topRunningActivityLocked(null) == null) {
-                // If there are no more activities available to run, then
-                // do resume anyway to start something.
+            ActivityRecord top = topRunningActivityLocked(null);
+            if (top == null || (prev != null && top != prev)) {
+                // If there are no more activities available to run,
+                // do resume anyway to start something.  Also if the top
+                // activity on the stack is not the just paused activity,
+                // we need to go ahead and resume it to ensure we complete
+                // an in-flight app switch.
                 resumeTopActivityLocked(null);
             }
         }
@@ -1461,7 +1466,8 @@
         // If we are currently pausing an activity, then don't do anything
         // until that is done.
         if (mPausingActivity != null) {
-            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
+            if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG,
+                    "Skip resume: pausing=" + mPausingActivity);
             return false;
         }
 
@@ -3862,6 +3868,7 @@
         if (setState) {
             if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (cleaning up)");
             r.state = ActivityState.DESTROYED;
+            r.app = null;
         }
 
         // Make sure this record is no longer in the pending finishes list.
@@ -3905,26 +3912,26 @@
     }
 
     final void removeActivityFromHistoryLocked(ActivityRecord r) {
-        if (r.state != ActivityState.DESTROYED) {
-            finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
-            r.makeFinishing();
-            if (DEBUG_ADD_REMOVE) {
-                RuntimeException here = new RuntimeException("here");
-                here.fillInStackTrace();
-                Slog.i(TAG, "Removing activity " + r + " from stack");
-            }
-            mHistory.remove(r);
-            r.takeFromHistory();
-            if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
-                    + " (removed from history)");
-            r.state = ActivityState.DESTROYED;
-            mService.mWindowManager.removeAppToken(r.appToken);
-            if (VALIDATE_TOKENS) {
-                validateAppTokensLocked();
-            }
-            cleanUpActivityServicesLocked(r);
-            r.removeUriPermissionsLocked();
+        finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
+        r.makeFinishing();
+        if (DEBUG_ADD_REMOVE) {
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "Removing activity " + r + " from stack");
         }
+        mHistory.remove(r);
+        r.takeFromHistory();
+        removeTimeoutsForActivityLocked(r);
+        if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
+                + " (removed from history)");
+        r.state = ActivityState.DESTROYED;
+        r.app = null;
+        mService.mWindowManager.removeAppToken(r.appToken);
+        if (VALIDATE_TOKENS) {
+            validateAppTokensLocked();
+        }
+        cleanUpActivityServicesLocked(r);
+        r.removeUriPermissionsLocked();
     }
     
     /**
@@ -3992,7 +3999,7 @@
      */
     final boolean destroyActivityLocked(ActivityRecord r,
             boolean removeFromApp, boolean oomAdj, String reason) {
-        if (DEBUG_SWITCH) Slog.v(
+        if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(
             TAG, "Removing activity from " + reason + ": token=" + r
               + ", app=" + (r.app != null ? r.app.processName : "(null)"));
         EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
@@ -4000,11 +4007,11 @@
                 r.task.taskId, r.shortComponentName, reason);
 
         boolean removedFromHistory = false;
-        
+
         cleanUpActivityLocked(r, false, false);
 
         final boolean hadApp = r.app != null;
-        
+
         if (hadApp) {
             if (removeFromApp) {
                 int idx = r.app.activities.indexOf(r);
@@ -4040,7 +4047,6 @@
                 }
             }
 
-            r.app = null;
             r.nowVisible = false;
             
             // If the activity is finishing, we need to wait on removing it
@@ -4061,6 +4067,7 @@
                 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
                         + " (destroy skipped)");
                 r.state = ActivityState.DESTROYED;
+                r.app = null;
             }
         } else {
             // remove this record from the history.
@@ -4071,6 +4078,7 @@
                 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
                         + " (no app)");
                 r.state = ActivityState.DESTROYED;
+                r.app = null;
             }
         }
 
@@ -4106,30 +4114,85 @@
         }
     }
     
-    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
+    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
+            String listName) {
         int i = list.size();
-        if (localLOGV) Slog.v(
-            TAG, "Removing app " + app + " from list " + list
+        if (DEBUG_CLEANUP) Slog.v(
+            TAG, "Removing app " + app + " from list " + listName
             + " with " + i + " entries");
         while (i > 0) {
             i--;
             ActivityRecord r = (ActivityRecord)list.get(i);
-            if (localLOGV) Slog.v(
-                TAG, "Record #" + i + " " + r + ": app=" + r.app);
+            if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
             if (r.app == app) {
-                if (localLOGV) Slog.v(TAG, "Removing this entry!");
+                if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
                 list.remove(i);
                 removeTimeoutsForActivityLocked(r);
             }
         }
     }
 
-    void removeHistoryRecordsForAppLocked(ProcessRecord app) {
-        removeHistoryRecordsForAppLocked(mLRUActivities, app);
-        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
-        removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app);
-        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
-        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
+    boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
+        removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
+        removeHistoryRecordsForAppLocked(mStoppingActivities, app, "mStoppingActivities");
+        removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities");
+        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app,
+                "mWaitingVisibleActivities");
+        removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities");
+
+        boolean hasVisibleActivities = false;
+
+        // Clean out the history list.
+        int i = mHistory.size();
+        if (DEBUG_CLEANUP) Slog.v(
+            TAG, "Removing app " + app + " from history with " + i + " entries");
+        while (i > 0) {
+            i--;
+            ActivityRecord r = (ActivityRecord)mHistory.get(i);
+            if (DEBUG_CLEANUP) Slog.v(
+                TAG, "Record #" + i + " " + r + ": app=" + r.app);
+            if (r.app == app) {
+                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
+                    if (ActivityStack.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
+                        RuntimeException here = new RuntimeException("here");
+                        here.fillInStackTrace();
+                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
+                                + ": haveState=" + r.haveState
+                                + " stateNotNeeded=" + r.stateNotNeeded
+                                + " finishing=" + r.finishing
+                                + " state=" + r.state, here);
+                    }
+                    if (!r.finishing) {
+                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+                                r.userId, System.identityHashCode(r),
+                                r.task.taskId, r.shortComponentName,
+                                "proc died without state saved");
+                    }
+                    removeActivityFromHistoryLocked(r);
+
+                } else {
+                    // We have the current state for this activity, so
+                    // it can be restarted later when needed.
+                    if (localLOGV) Slog.v(
+                        TAG, "Keeping entry, setting app to null");
+                    if (r.visible) {
+                        hasVisibleActivities = true;
+                    }
+                    r.app = null;
+                    r.nowVisible = false;
+                    if (!r.haveState) {
+                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
+                                "App died, clearing saved state of " + r);
+                        r.icicle = null;
+                    }
+                }
+
+                r.stack.cleanUpActivityLocked(r, true, true);
+            }
+        }
+
+        return hasVisibleActivities;
     }
     
     /**
@@ -4375,7 +4438,7 @@
             return null;
         }
 
-        // Remove all of this task's activies starting at the sub task.
+        // Remove all of this task's activities starting at the sub task.
         TaskAccessInfo.SubTask subtask = info.subtasks.get(subTaskIndex);
         performClearTaskAtIndexLocked(taskId, subtask.index);
         return subtask.activity;
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index d533c94..39d042f 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -639,9 +639,9 @@
     }
 
     private void handlePeersChanged() {
-        if (mWfdEnabled) {
-            requestPeers();
-        }
+        // Even if wfd is disabled, it is best to get the latest set of peers to
+        // keep in sync with the p2p framework
+        requestPeers();
     }
 
     private void handleConnectionChanged(NetworkInfo networkInfo) {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 7b0c452..5e4907e 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -113,6 +113,7 @@
     private final InputManagerHandler mHandler;
 
     private WindowManagerCallbacks mWindowManagerCallbacks;
+    private WiredAccessoryCallbacks mWiredAccessoryCallbacks;
     private boolean mSystemReady;
     private NotificationManager mNotificationManager;
 
@@ -197,7 +198,7 @@
 
     // Key states (may be returned by queries about the current state of a
     // particular key code, scan code or switch).
-    
+
     /** The key state is unknown or the requested key itself is not supported. */
     public static final int KEY_STATE_UNKNOWN = -1;
 
@@ -213,17 +214,41 @@
     /** Scan code: Mouse / trackball button. */
     public static final int BTN_MOUSE = 0x110;
 
+    // Switch code values must match bionic/libc/kernel/common/linux/input.h
     /** Switch code: Lid switch.  When set, lid is shut. */
     public static final int SW_LID = 0x00;
 
     /** Switch code: Keypad slide.  When set, keyboard is exposed. */
     public static final int SW_KEYPAD_SLIDE = 0x0a;
 
+    /** Switch code: Headphone.  When set, headphone is inserted. */
+    public static final int SW_HEADPHONE_INSERT = 0x02;
+
+    /** Switch code: Microphone.  When set, microphone is inserted. */
+    public static final int SW_MICROPHONE_INSERT = 0x04;
+
+    /** Switch code: Headphone/Microphone Jack.  When set, something is inserted. */
+    public static final int SW_JACK_PHYSICAL_INSERT = 0x07;
+
+    public static final int SW_LID_BIT = 1 << SW_LID;
+    public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
+    public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT;
+    public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
+    public static final int SW_JACK_PHYSICAL_INSERT_BIT = 1 << SW_JACK_PHYSICAL_INSERT;
+    public static final int SW_JACK_BITS =
+            SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT;
+
+    /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
+    final boolean mUseDevInputEventForAudioJack;
+
     public InputManagerService(Context context, Handler handler) {
         this.mContext = context;
         this.mHandler = new InputManagerHandler(handler.getLooper());
 
-        Slog.i(TAG, "Initializing input manager");
+        mUseDevInputEventForAudioJack =
+                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
+        Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+                + mUseDevInputEventForAudioJack);
         mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
     }
 
@@ -231,6 +256,10 @@
         mWindowManagerCallbacks = callbacks;
     }
 
+    public void setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks) {
+        mWiredAccessoryCallbacks = callbacks;
+    }
+
     public void start() {
         Slog.i(TAG, "Starting input manager");
         nativeStart(mPtr);
@@ -335,7 +364,7 @@
     public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
         return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode);
     }
-    
+
     /**
      * Gets the current state of a key or button by scan code.
      * @param deviceId The input device id, or -1 to consult all devices.
@@ -513,7 +542,7 @@
 
     /**
      * Gets information about the input device with the specified id.
-     * @param id The device id.
+     * @param deviceId The device id.
      * @return The input device or null if not found.
      */
     @Override // Binder call
@@ -976,8 +1005,8 @@
     // Must be called on handler.
     private void handleSwitchKeyboardLayout(int deviceId, int direction) {
         final InputDevice device = getInputDevice(deviceId);
-        final String inputDeviceDescriptor = device.getDescriptor();
         if (device != null) {
+            final String inputDeviceDescriptor = device.getDescriptor();
             final boolean changed;
             final String keyboardLayoutDescriptor;
             synchronized (mDataStore) {
@@ -1214,6 +1243,7 @@
     }
 
     // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
+    @Override
     public void monitor() {
         synchronized (mInputFilterLock) { }
         nativeMonitor(mPtr);
@@ -1244,10 +1274,15 @@
                     + ", mask=" + Integer.toHexString(switchMask));
         }
 
-        if ((switchMask & (1 << SW_LID)) != 0) {
-            final boolean lidOpen = ((switchValues & (1 << SW_LID)) == 0);
+        if ((switchMask & SW_LID_BIT) != 0) {
+            final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0);
             mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
         }
+
+        if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) {
+            mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues,
+                    switchMask);
+        }
     }
 
     // Native callback.
@@ -1431,7 +1466,6 @@
         return null;
     }
 
-
     /**
      * Callback interface implemented by the Window Manager.
      */
@@ -1459,6 +1493,13 @@
     }
 
     /**
+     * Callback interface implemented by WiredAccessoryObserver.
+     */
+    public interface WiredAccessoryCallbacks {
+        public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask);
+    }
+
+    /**
      * Private handler for the input manager.
      */
     private final class InputManagerHandler extends Handler {
@@ -1498,6 +1539,7 @@
             mDisconnected = true;
         }
 
+        @Override
         public void sendInputEvent(InputEvent event, int policyFlags) {
             if (event == null) {
                 throw new IllegalArgumentException("event must not be null");
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 84adb83..a254d74 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -40,10 +40,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-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;
@@ -75,7 +73,6 @@
 import java.util.Date;
 import java.util.Map.Entry;
 import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * A GPS implementation of LocationProvider used by LocationManager.
@@ -287,12 +284,8 @@
     private Bundle mLocationExtras = new Bundle();
     private ArrayList<Listener> mListeners = new ArrayList<Listener>();
 
-    // GpsLocationProvider's handler thread
-    private final Thread mThread;
-    // Handler for processing events in mThread.
+    // Handler for processing events
     private Handler mHandler;
-    // Used to signal when our main thread has initialized everything
-    private final CountDownLatch mInitializedLatch = new CountDownLatch(1);
 
     private String mAGpsApn;
     private int mAGpsDataConnectionState;
@@ -437,21 +430,6 @@
         mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
         mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
 
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
-        intentFilter.addDataScheme("sms");
-        intentFilter.addDataAuthority("localhost","7275");
-        context.registerReceiver(mBroadcastReciever, intentFilter);
-
-        intentFilter = new IntentFilter();
-        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
-        try {
-            intentFilter.addDataType("application/vnd.omaloc-supl-init");
-        } catch (IntentFilter.MalformedMimeTypeException e) {
-            Log.w(TAG, "Malformed SUPL init mime type");
-        }
-        context.registerReceiver(mBroadcastReciever, intentFilter);
-
         mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
         // Battery statistics service to be notified when GPS turns on or off
@@ -487,26 +465,43 @@
             Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
         }
 
-        // wait until we are fully initialized before returning
-        mThread = new GpsLocationProviderThread();
-        mThread.start();
-        while (true) {
-            try {
-                mInitializedLatch.await();
-                break;
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
+        // construct handler, listen for events
+        mHandler = new ProviderHandler();
+        listenForBroadcasts();
+
+        // also listen for PASSIVE_PROVIDER updates
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                LocationManager locManager =
+                        (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+                locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
+                        0, 0, new NetworkLocationListener(), mHandler.getLooper());                
             }
-        }
+        });
     }
 
-    private void initialize() {
-        // register our receiver on our thread rather than the main thread
+    private void listenForBroadcasts() {
         IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
+        intentFilter.addDataScheme("sms");
+        intentFilter.addDataAuthority("localhost","7275");
+        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
+
+        intentFilter = new IntentFilter();
+        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
+        try {
+            intentFilter.addDataType("application/vnd.omaloc-supl-init");
+        } catch (IntentFilter.MalformedMimeTypeException e) {
+            Log.w(TAG, "Malformed SUPL init mime type");
+        }
+        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
+
+        intentFilter = new IntentFilter();
         intentFilter.addAction(ALARM_WAKEUP);
         intentFilter.addAction(ALARM_TIMEOUT);
         intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-        mContext.registerReceiver(mBroadcastReciever, intentFilter);
+        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
     }
 
     /**
@@ -1536,29 +1531,6 @@
         }
     };
 
-    private final class GpsLocationProviderThread extends Thread {
-
-        public GpsLocationProviderThread() {
-            super("GpsLocationProvider");
-        }
-
-        @Override
-        public void run() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            initialize();
-            Looper.prepare();
-
-            LocationManager locManager =
-                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-            mHandler = new ProviderHandler();
-            // signal when we are initialized and ready to go
-            mInitializedLatch.countDown();
-            locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
-                    0, 0, new NetworkLocationListener(), Looper.myLooper());
-            Looper.loop();
-        }
-    }
-
     private final class NetworkLocationListener implements LocationListener {
         @Override
         public void onLocationChanged(Location location) {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 75bc265..564a805 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -9027,9 +9027,9 @@
         mSystemReady = true;
 
         // Read the compatibilty setting when the system is ready.
-        boolean compatibilityModeEnabled = android.provider.Settings.System.getInt(
+        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
                 mContext.getContentResolver(),
-                android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
+                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
         if (DEBUG_SETTINGS) {
             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index 5f4a786..4f8cdde 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -44,7 +44,6 @@
 import android.view.Display;
 
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.concurrent.Executor;
 
 /**
@@ -95,7 +94,8 @@
     // when it is especially dark outside.  The light sensor tends to perform
     // poorly at low light levels so we compensate for it by making an
     // assumption about the environment.
-    private static final boolean USE_TWILIGHT_ADJUSTMENT = true;
+    private static final boolean USE_TWILIGHT_ADJUSTMENT =
+            PowerManager.useTwilightAdjustmentFeature();
 
     // Specifies the maximum magnitude of the time of day adjustment.
     private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index b35fa11..664125a 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -266,6 +266,11 @@
     // Use -1 to disable.
     private int mScreenBrightnessOverrideFromWindowManager = -1;
 
+    // The user activity timeout override from the window manager
+    // to allow the current foreground activity to override the user activity timeout.
+    // Use -1 to disable.
+    private long mUserActivityTimeoutOverrideFromWindowManager = -1;
+
     // The screen brightness setting override from the settings application
     // to temporarily adjust the brightness until next updated,
     // Use -1 to disable.
@@ -277,6 +282,9 @@
     // Use NaN to disable.
     private float mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;
 
+    // Time when we last logged a warning about calling userActivity() without permission.
+    private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
+
     private native void nativeInit();
     private static native void nativeShutdown();
     private static native void nativeReboot(String reason) throws IOException;
@@ -683,12 +691,29 @@
 
     @Override // Binder call
     public void userActivity(long eventTime, int event, int flags) {
+        final long now = SystemClock.uptimeMillis();
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
+                != PackageManager.PERMISSION_GRANTED) {
+            // Once upon a time applications could call userActivity().
+            // Now we require the DEVICE_POWER permission.  Log a warning and ignore the
+            // request instead of throwing a SecurityException so we don't break old apps.
+            synchronized (mLock) {
+                if (now >= mLastWarningAboutUserActivityPermission + (5 * 60 * 1000)) {
+                    mLastWarningAboutUserActivityPermission = now;
+                    Slog.w(TAG, "Ignoring call to PowerManager.userActivity() because the "
+                            + "caller does not have DEVICE_POWER permission.  "
+                            + "Please fix your app!  "
+                            + " pid=" + Binder.getCallingPid()
+                            + " uid=" + Binder.getCallingUid());
+                }
+            }
+            return;
+        }
+
         if (eventTime > SystemClock.uptimeMillis()) {
             throw new IllegalArgumentException("event time must not be in the future");
         }
 
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
-
         final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -1156,6 +1181,9 @@
         if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
             timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
         }
+        if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
+            timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
+        }
         return Math.max(timeout, MINIMUM_SCREEN_OFF_TIMEOUT);
     }
 
@@ -1573,12 +1601,6 @@
         }
     }
 
-    @Override // Binder call
-    public void setPokeLock(int pokey, IBinder lock, String tag) {
-        // TODO Auto-generated method stub
-        // Only used by phone app, delete this
-    }
-
     /**
      * Set the setting that determines whether the device stays on when plugged in.
      * The argument is a bit string, with each bit specifying a power source that,
@@ -1721,6 +1743,36 @@
     }
 
     /**
+     * Used by the window manager to override the user activity timeout based on the
+     * current foreground activity.  It can only be used to make the timeout shorter
+     * than usual, not longer.
+     *
+     * This method must only be called by the window manager.
+     *
+     * @param timeoutMillis The overridden timeout, or -1 to disable the override.
+     */
+    public void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            setUserActivityTimeoutOverrideFromWindowManagerInternal(timeoutMillis);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) {
+        synchronized (mLock) {
+            if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) {
+                mUserActivityTimeoutOverrideFromWindowManager = timeoutMillis;
+                mDirty |= DIRTY_SETTINGS;
+                updatePowerStateLocked();
+            }
+        }
+    }
+
+    /**
      * Used by the settings application and brightness control widgets to
      * temporarily override the current screen brightness setting so that the
      * user can observe the effect of an intended settings change without applying
@@ -1869,6 +1921,8 @@
             pw.println("  mScreenBrightnessModeSetting=" + mScreenBrightnessModeSetting);
             pw.println("  mScreenBrightnessOverrideFromWindowManager="
                     + mScreenBrightnessOverrideFromWindowManager);
+            pw.println("  mUserActivityTimeoutOverrideFromWindowManager="
+                    + mUserActivityTimeoutOverrideFromWindowManager);
             pw.println("  mTemporaryScreenBrightnessSettingOverride="
                     + mTemporaryScreenBrightnessSettingOverride);
             pw.println("  mTemporaryScreenAutoBrightnessAdjustmentSettingOverride="
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d530f47..ae805c3 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -598,6 +598,7 @@
         private boolean mSyswin = false;
         private float mScreenBrightness = -1;
         private float mButtonBrightness = -1;
+        private long mUserActivityTimeout = -1;
         private boolean mUpdateRotation = false;
 
         private static final int DISPLAY_CONTENT_UNKNOWN = 0;
@@ -810,12 +811,12 @@
         mBatteryStats = BatteryStatsService.getService();
 
         // Get persisted window scale setting
-        mWindowAnimationScale = Settings.System.getFloat(context.getContentResolver(),
-                Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
-        mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
-                Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
-        setAnimatorDurationScale(Settings.System.getFloat(context.getContentResolver(),
-                Settings.System.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
+        mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
+        mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+        setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
+                Settings.Global.ANIMATOR_DURATION_SCALE, mTransitionAnimationScale));
 
         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
         IntentFilter filter = new IntentFilter();
@@ -7479,12 +7480,12 @@
                 }
 
                 case PERSIST_ANIMATION_SCALE: {
-                    Settings.System.putFloat(mContext.getContentResolver(),
-                            Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
-                    Settings.System.putFloat(mContext.getContentResolver(),
-                            Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
-                    Settings.System.putFloat(mContext.getContentResolver(),
-                            Settings.System.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
+                    Settings.Global.putFloat(mContext.getContentResolver(),
+                            Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
+                    Settings.Global.putFloat(mContext.getContentResolver(),
+                            Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+                    Settings.Global.putFloat(mContext.getContentResolver(),
+                            Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
                     break;
                 }
 
@@ -8775,6 +8776,11 @@
                     && mInnerFields.mButtonBrightness < 0) {
                 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
             }
+            if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
+                    && mInnerFields.mUserActivityTimeout < 0) {
+                mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
+            }
+
             final int type = attrs.type;
             if (canBeSeen
                     && (type == TYPE_SYSTEM_DIALOG
@@ -8874,7 +8880,9 @@
         mInnerFields.mHoldScreen = null;
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
+        mInnerFields.mUserActivityTimeout = -1;
         mInnerFields.mDisplayHasContent = LayoutFields.DISPLAY_CONTENT_UNKNOWN;
+
         mTransactionSequence++;
 
         final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
@@ -9349,6 +9357,8 @@
                 mPowerManager.setButtonBrightnessOverrideFromWindowManager(
                         toBrightnessOverride(mInnerFields.mButtonBrightness));
             }
+            mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
+                    mInnerFields.mUserActivityTimeout);
         }
 
         if (mTurnOnScreen) {
diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
index e38bb6c..0cab10de 100644
--- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
@@ -21,9 +21,7 @@
 import android.os.IPowerManager;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
-import android.os.RemoteException;
 import android.os.Handler;
-import android.os.LocalPowerManager;
 import android.os.ServiceManager;
 import android.os.PowerManager;
 
@@ -106,69 +104,5 @@
                 }, 5000);
             }
         },
-        new Test("Touch events don't poke") {
-            public void run() {
-                mPokeState |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
-
-        new Test("Touch events poke") {
-            public void run() {
-                mPokeState &= ~LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_EVENTS;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
-        new Test("Short timeout") {
-            public void run() {
-                mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
-                mPokeState |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
-        new Test("Medium timeout") {
-            public void run() {
-                mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
-                mPokeState |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
-        new Test("Normal timeout") {
-            public void run() {
-                mPokeState &= ~LocalPowerManager.POKE_LOCK_TIMEOUT_MASK;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
-        new Test("Illegal timeout") {
-            public void run() {
-                mPokeState |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT
-                        | LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
-                try {
-                    mPowerManager.setPokeLock(mPokeState, mPokeToken, TAG);
-                } catch (RemoteException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        },
     };
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 6175b0d..5e23f24 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -90,11 +90,6 @@
     }
 
     @Override
-    public void setPokeLock(int arg0, IBinder arg1, String arg2) throws RemoteException {
-        // pass for now.
-    }
-
-    @Override
     public void setStayOnSetting(int arg0) throws RemoteException {
         // pass for now.
     }