Merge "Fix service binding for singleUser services" into jb-mr1-dev
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index f874d56..f7460c4 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -958,13 +958,7 @@
         } else if (!mInitialized) {
             initAnimation();
         }
-        // The final value set on the target varies, depending on whether the animation
-        // was supposed to repeat an odd number of times
-        if (mRepeatCount > 0 && (mRepeatCount & 0x01) == 1) {
-            animateValue(0f);
-        } else {
-            animateValue(1f);
-        }
+        animateValue(mPlayingBackwards ? 0f : 1f);
         endAnimation(handler);
     }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1739205..9ea523d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2616,6 +2616,12 @@
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED);
             MOVED_TO_GLOBAL.add(Settings.Global.WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS);
             MOVED_TO_GLOBAL.add(Settings.Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON);
+            MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_ENABLE);
+            MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_TIMEOUT);
+            MOVED_TO_GLOBAL.add(Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE);
+            MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS);
+            MOVED_TO_GLOBAL.add(Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS);
+            MOVED_TO_GLOBAL.add(Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS);
             MOVED_TO_GLOBAL.add(Settings.Global.WTF_IS_FATAL);
         }
 
@@ -4254,30 +4260,28 @@
                 Global.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT;
 
         /**
-         * The number of milliseconds to delay when checking for data stalls during
-         * non-aggressive detection. (screen is turned off.)
+         * @deprecated Moved to Settings.Global
          * @hide
          */
+        @Deprecated
         public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
-                "data_stall_alarm_non_aggressive_delay_in_ms";
+                Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS;
 
         /**
-         * The number of milliseconds to delay when checking for data stalls during
-         * aggressive detection. (screen on or suspected data stall)
+         * @deprecated Moved to Settings.Global
          * @hide
          */
+        @Deprecated
         public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
-                "data_stall_alarm_aggressive_delay_in_ms";
+                Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS;
 
         /**
-         * The interval in milliseconds at which to check gprs registration
-         * after the first registration mismatch of gprs and voice service,
-         * to detect possible data network registration problems.
-         *
+         * @deprecated Moved to Settings.Global
          * @hide
          */
+        @Deprecated
         public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
-                "gprs_register_check_period_ms";
+                Global.GPRS_REGISTER_CHECK_PERIOD_MS;
 
         /**
          * @deprecated Use {@link android.provider.Settings.Global#NITZ_UPDATE_SPACING} instead
@@ -5604,6 +5608,32 @@
        public static final String WIFI_P2P_DEVICE_NAME = "wifi_p2p_device_name";
 
        /**
+        * The number of milliseconds to delay when checking for data stalls during
+        * non-aggressive detection. (screen is turned off.)
+        * @hide
+        */
+       public static final String DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS =
+               "data_stall_alarm_non_aggressive_delay_in_ms";
+
+       /**
+        * The number of milliseconds to delay when checking for data stalls during
+        * aggressive detection. (screen on or suspected data stall)
+        * @hide
+        */
+       public static final String DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS =
+               "data_stall_alarm_aggressive_delay_in_ms";
+
+       /**
+        * The interval in milliseconds at which to check gprs registration
+        * after the first registration mismatch of gprs and voice service,
+        * to detect possible data network registration problems.
+        *
+        * @hide
+        */
+       public static final String GPRS_REGISTER_CHECK_PERIOD_MS =
+               "gprs_register_check_period_ms";
+
+       /**
         * Nonzero causes Log.wtf() to crash.
         * @hide
         */
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 395a2cb..ae10fbe 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5726,7 +5726,7 @@
         /**
          * Sets the relative start margin.
          *
-         * @param start the start marging size
+         * @param start the start margin size
          *
          * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
          */
@@ -5755,7 +5755,7 @@
         /**
          * Sets the relative end margin.
          *
-         * @param end the end marging size
+         * @param end the end margin size
          *
          * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
          */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3006b5d..e1312c1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3612,8 +3612,31 @@
                 finishInputEvent(q, true);
             } else {
                 if (q.mEvent instanceof KeyEvent) {
+                    KeyEvent event = (KeyEvent)q.mEvent;
+                    if (event.getAction() != KeyEvent.ACTION_UP) {
+                        // If the window doesn't currently have input focus, then drop
+                        // this event.  This could be an event that came back from the
+                        // IME dispatch but the window has lost focus in the meantime.
+                        if (!mAttachInfo.mHasWindowFocus) {
+                            Slog.w(TAG, "Dropping event due to no window focus: " + event);
+                            finishInputEvent(q, true);
+                            return;
+                        }
+                    }
                     deliverKeyEventPostIme(q);
                 } else {
+                    MotionEvent event = (MotionEvent)q.mEvent;
+                    if (event.getAction() != MotionEvent.ACTION_CANCEL
+                            && event.getAction() != MotionEvent.ACTION_UP) {
+                        // If the window doesn't currently have input focus, then drop
+                        // this event.  This could be an event that came back from the
+                        // IME dispatch but the window has lost focus in the meantime.
+                        if (!mAttachInfo.mHasWindowFocus) {
+                            Slog.w(TAG, "Dropping event due to no window focus: " + event);
+                            finishInputEvent(q, true);
+                            return;
+                        }
+                    }
                     final int source = q.mEvent.getSource();
                     if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
                         deliverTrackballEventPostIme(q);
diff --git a/core/res/res/layout/keyguard_transport_control_view.xml b/core/res/res/layout/keyguard_transport_control_view.xml
index c40aa66..8e76164 100644
--- a/core/res/res/layout/keyguard_transport_control_view.xml
+++ b/core/res/res/layout/keyguard_transport_control_view.xml
@@ -20,6 +20,7 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center_horizontal"
+    android:layerType="hardware"
     android:id="@+id/keyguard_transport_control">
 
     <!-- FrameLayout used as scrim to show between album art and buttons -->
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 6c204ab..8b5609f 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -69,10 +69,14 @@
      *          rectangle.
      */
     public Rect(Rect r) {
-        left = r.left;
-        top = r.top;
-        right = r.right;
-        bottom = r.bottom;
+        if (r == null) {
+            left = top = right = bottom = 0;
+        } else {
+            left = r.left;
+            top = r.top;
+            right = r.right;
+            bottom = r.bottom;
+        }
     }
 
     @Override
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 108b7f9..53178b0 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -66,17 +66,25 @@
      *          rectangle.
      */
     public RectF(RectF r) {
-        left = r.left;
-        top = r.top;
-        right = r.right;
-        bottom = r.bottom;
+        if (r == null) {
+            left = top = right = bottom = 0.0f;
+        } else {
+            left = r.left;
+            top = r.top;
+            right = r.right;
+            bottom = r.bottom;
+        }
     }
     
     public RectF(Rect r) {
-        left = r.left;
-        top = r.top;
-        right = r.right;
-        bottom = r.bottom;
+        if (r == null) {
+            left = top = right = bottom = 0.0f;
+        } else {
+            left = r.left;
+            top = r.top;
+            right = r.right;
+            bottom = r.bottom;
+        }
     }
 
     @Override
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
index 3450ef1..8618804 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
@@ -72,9 +72,7 @@
             "void main() {\n" +
             "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
             "  vec4 mask = texture2D(tex_sampler_1, v_texcoord);\n" +
-            "  gl_FragColor = vec4(mask.a, mask.a, mask.a, 1.0) * intensity + color * (1.0 - intensity);\n" +
             "  if (mask.a > 0.0) {\n" +
-            "    gl_FragColor.r = 0.0;\n" +
             "    float green_blue = color.g + color.b;\n" +
             "    float red_intensity = color.r / green_blue;\n" +
             "    if (red_intensity > intensity) {\n" +
@@ -105,8 +103,8 @@
                 ShaderProgram shaderProgram = new ShaderProgram(context, mRedEyeShader);
                 shaderProgram.setMaximumTileSize(mTileSize);
                 mProgram = shaderProgram;
+                mProgram.setHostValue("intensity", DEFAULT_RED_INTENSITY);
                 break;
-
             default:
                 throw new RuntimeException("Filter RedEye does not support frames of " +
                     "target " + target + "!");
@@ -180,8 +178,6 @@
     }
 
     private void updateProgramParams() {
-        mProgram.setHostValue("intensity", DEFAULT_RED_INTENSITY);
-
         if ( mCenters.length % 2 == 1) {
             throw new RuntimeException("The size of center array must be even.");
         }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 05673c3..23b4b59 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -67,7 +67,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 = 87;
+    private static final int DATABASE_VERSION = 88;
 
     private Context mContext;
     private int mUserHandle;
@@ -1305,6 +1305,23 @@
             upgradeVersion = 87;
         }
 
+        if (upgradeVersion == 87) {
+            db.beginTransaction();
+            try {
+                String[] settingsToMove = {
+                        Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
+                        Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
+                        Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS
+                };
+                moveSettingsToNewTable(db, TABLE_SECURE, TABLE_GLOBAL, settingsToMove, true);
+
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+            upgradeVersion = 88;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 523b95e..e1a5b52 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -195,6 +195,12 @@
         sSecureGlobalKeys.add(Settings.Secure.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED);
         sSecureGlobalKeys.add(Settings.Secure.WIFI_WATCHDOG_RSSI_FETCH_INTERVAL_MS);
         sSecureGlobalKeys.add(Settings.Secure.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON);
+        sSecureGlobalKeys.add(Settings.Secure.PACKAGE_VERIFIER_ENABLE);
+        sSecureGlobalKeys.add(Settings.Secure.PACKAGE_VERIFIER_TIMEOUT);
+        sSecureGlobalKeys.add(Settings.Secure.PACKAGE_VERIFIER_DEFAULT_RESPONSE);
+        sSecureGlobalKeys.add(Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS);
+        sSecureGlobalKeys.add(Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS);
+        sSecureGlobalKeys.add(Settings.Secure.GPRS_REGISTER_CHECK_PERIOD_MS);
         sSecureGlobalKeys.add(Settings.Secure.WTF_IS_FATAL);
 
         // Keys from the 'system' table now moved to 'global'
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_ime.xml b/packages/SystemUI/res/layout/quick_settings_tile_ime.xml
index 93db6db..528b54f 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_ime.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_ime.xml
@@ -15,9 +15,12 @@
 -->
 <TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ime_textview"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:layout_gravity="center"
     android:gravity="center"
+    android:drawableTop="@drawable/stat_sys_roaming_cdma_0"
     android:text="@string/quick_settings_ime_label"
-    android:singleLine="true"
+    android:textAppearance="@style/TextAppearance.QuickSettings.TileView"
     />
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index bee63ee..91f29a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -360,6 +360,10 @@
         mBar = panelBar;
     }
 
+    public void setImeWindowStatus(boolean visible) {
+        // To be implemented by classes extending PanelView
+    }
+
     public void setup(NetworkController network, BluetoothController bt, BatteryController batt,
             LocationController location) {
         // To be implemented by classes extending PanelView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 6231d0d..b335b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1413,10 +1413,11 @@
         mCommandQueue.setNavigationIconHints(
                 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
                         : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
+        mSettingsPanel.setImeWindowStatus(vis > 0);
     }
 
     @Override
-    public void setHardKeyboardStatus(boolean available, boolean enabled) { }
+    public void setHardKeyboardStatus(boolean available, boolean enabled) {}
 
     @Override
     protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
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 1c3cb2e..39e1429 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.Dialog;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,8 +33,8 @@
 import android.hardware.display.WifiDisplay;
 import android.hardware.display.WifiDisplayStatus;
 import android.net.Uri;
-import android.os.UserHandle;
 import android.provider.ContactsContract;
+import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -103,6 +104,10 @@
         mBar = bar;
     }
 
+    public void setImeWindowStatus(boolean visible) {
+        mModel.onImeWindowStatusChanged(visible);
+    }
+
     void setup(NetworkController networkController, BluetoothController bluetoothController,
             BatteryController batteryController, LocationController locationController) {
         networkController.addNetworkSignalChangedCallback(mModel);
@@ -247,29 +252,31 @@
         });
         parent.addView(wifiTile);
 
-        // RSSI
-        QuickSettingsTileView rssiTile = (QuickSettingsTileView)
-                inflater.inflate(R.layout.quick_settings_tile, parent, false);
-        rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
-        rssiTile.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                Intent intent = new Intent();
-                intent.setComponent(new ComponentName(
-                        "com.android.settings",
-                        "com.android.settings.Settings$DataUsageSummaryActivity"));
-                startSettingsActivity(intent);
-            }
-        });
-        mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
-            @Override
-            public void refreshView(QuickSettingsTileView view, State state) {
-                TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
-                tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
-                tv.setText(state.label);
-            }
-        });
-        parent.addView(rssiTile);
+        if (mModel.deviceSupportsTelephony()) {
+            // RSSI
+            QuickSettingsTileView rssiTile = (QuickSettingsTileView)
+                    inflater.inflate(R.layout.quick_settings_tile, parent, false);
+            rssiTile.setContent(R.layout.quick_settings_tile_rssi, inflater);
+            rssiTile.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    Intent intent = new Intent();
+                    intent.setComponent(new ComponentName(
+                            "com.android.settings",
+                            "com.android.settings.Settings$DataUsageSummaryActivity"));
+                    startSettingsActivity(intent);
+                }
+            });
+            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
+                @Override
+                public void refreshView(QuickSettingsTileView view, State state) {
+                    TextView tv = (TextView) view.findViewById(R.id.rssi_textview);
+                    tv.setCompoundDrawablesRelativeWithIntrinsicBounds(0, state.iconId, 0, 0);
+                    tv.setText(state.label);
+                }
+            });
+            parent.addView(rssiTile);
+        }
 
         // Battery
         QuickSettingsTileView batteryTile = (QuickSettingsTileView)
@@ -386,6 +393,29 @@
         });
         parent.addView(wifiDisplayTile);
 
+        // IME
+        QuickSettingsTileView imeTile = (QuickSettingsTileView)
+                inflater.inflate(R.layout.quick_settings_tile, parent, false);
+        imeTile.setContent(R.layout.quick_settings_tile_ime, inflater);
+        imeTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    mBar.collapseAllPanels(true);
+                    Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
+                    PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+                    pendingIntent.send();
+                } catch (Exception e) {}
+            }
+        });
+        mModel.addImeTile(imeTile, new QuickSettingsModel.RefreshCallback() {
+            @Override
+            public void refreshView(QuickSettingsTileView view, State state) {
+                view.setVisibility(state.enabled ? View.VISIBLE : View.GONE);
+            }
+        });
+        parent.addView(imeTile);
+
         /*
         QuickSettingsTileView mediaTile = (QuickSettingsTileView)
                 inflater.inflate(R.layout.quick_settings_tile, parent, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index aa40f3c..ab3e66e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.display.WifiDisplayStatus;
@@ -126,6 +127,10 @@
     private RefreshCallback mLocationCallback;
     private State mLocationState = new State();
 
+    private QuickSettingsTileView mImeTile;
+    private RefreshCallback mImeCallback;
+    private State mImeState = new State();
+
     public QuickSettingsModel(Context context) {
         mContext = context;
         mHandler = new Handler();
@@ -234,20 +239,26 @@
         mRSSICallback = cb;
         mRSSICallback.refreshView(mRSSITile, mRSSIState);
     }
+    boolean deviceSupportsTelephony() {
+        PackageManager pm = mContext.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
     // NetworkSignalChanged callback
     @Override
     public void onMobileDataSignalChanged(boolean enabled, String description) {
-        // TODO: If view is in awaiting state, disable
-        Resources r = mContext.getResources();
-        // TODO: Check if RSSI is enabled
-        mRSSIState.enabled = enabled;
-        mRSSIState.iconId = (enabled ?
-                R.drawable.ic_qs_rssi_enabled :
-                R.drawable.ic_qs_rssi_normal);
-        mRSSIState.label = (enabled ?
-                description :
-                r.getString(R.string.quick_settings_rssi_emergency_only));
-        mRSSICallback.refreshView(mRSSITile, mRSSIState);
+        if (deviceSupportsTelephony()) {
+            // TODO: If view is in awaiting state, disable
+            Resources r = mContext.getResources();
+            // TODO: Check if RSSI is enabled
+            mRSSIState.enabled = enabled;
+            mRSSIState.iconId = (enabled ?
+                    R.drawable.ic_qs_rssi_enabled :
+                    R.drawable.ic_qs_rssi_normal);
+            mRSSIState.label = (enabled ?
+                    description :
+                    r.getString(R.string.quick_settings_rssi_emergency_only));
+            mRSSICallback.refreshView(mRSSITile, mRSSIState);
+        }
     }
 
     // Bluetooth
@@ -320,4 +331,15 @@
 
     }
 
+    // IME
+    void addImeTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mImeTile = view;
+        mImeCallback = cb;
+        mImeCallback.refreshView(mImeTile, mImeState);
+    }
+    void onImeWindowStatusChanged(boolean visible) {
+        mImeState.enabled = visible;
+        mImeCallback.refreshView(mImeTile, mImeState);
+    }
+
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index f896d57..4a7a424 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -59,6 +59,13 @@
     }
 
     @Override
+    public void setImeWindowStatus(boolean visible) {
+        if (mQS != null) {
+            mQS.setImeWindowStatus(visible);
+        }
+    }
+
+    @Override
     public void setup(NetworkController networkController, BluetoothController bluetoothController,
             BatteryController batteryController, LocationController locationController) {
         super.setup(networkController, bluetoothController, batteryController, locationController);
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 fca7a35..1405260 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -142,10 +142,11 @@
                 (KeyguardTransportControlView) findViewById(R.id.keyguard_transport_control);
         if (mTransportControl != null) {
             mTransportControl.setKeyguardCallback(new TransportCallback() {
+                boolean mSticky = false;
                 @Override
                 public void hide() {
                     int page = getWidgetPosition(R.id.keyguard_transport_control);
-                    if (page != -1) {
+                    if (page != -1 && !mSticky) {
                         if (page == mAppWidgetContainer.getCurrentPage()) {
                             // Switch back to clock view if music was showing.
                             mAppWidgetContainer
@@ -166,6 +167,8 @@
                         mAppWidgetContainer.addView(mTransportControl,
                                 getWidgetPosition(R.id.keyguard_status_view) + 1);
                         mTransportControl.setVisibility(View.VISIBLE);
+                        // Once shown, leave it showing
+                        mSticky = true;
                     }
                 }
             });
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4398441..90783b7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -55,6 +55,7 @@
 import com.android.server.input.InputManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
+import com.android.server.pm.Installer;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.UserManagerService;
 import com.android.server.power.PowerManagerService;
@@ -117,6 +118,7 @@
                 : Integer.parseInt(factoryTestStr);
         final boolean headless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
 
+        Installer installer = null;
         AccountManagerService accountManager = null;
         ContentService contentService = null;
         LightsService lights = null;
@@ -195,6 +197,13 @@
         // Critical services...
         boolean onlyCore = false;
         try {
+            // Wait for installd to finished starting up so that it has a chance to
+            // create critical directories such as /data/user with the appropriate
+            // permissions.  We need this to complete before we initialize other services.
+            Slog.i(TAG, "Waiting for installd to be ready.");
+            installer = new Installer();
+            installer.ping();
+
             Slog.i(TAG, "Entropy Mixer");
             ServiceManager.addService("entropy", new EntropyMixer());
 
@@ -234,7 +243,7 @@
                 onlyCore = true;
             }
 
-            pm = PackageManagerService.main(context,
+            pm = PackageManagerService.main(context, installer,
                     factoryTest != SystemServer.FACTORY_TEST_OFF,
                     onlyCore);
             boolean firstBoot = false;
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 85de349..ad85c0d 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -25,7 +25,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-class Installer {
+public final class Installer {
     private static final String TAG = "Installer";
 
     private static final boolean LOCAL_DEBUG = false;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 01a9b4b..ba63efd 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -937,9 +937,10 @@
         }
     }
 
-    public static final IPackageManager main(Context context, boolean factoryTest,
-            boolean onlyCore) {
-        PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
+    public static final IPackageManager main(Context context, Installer installer,
+            boolean factoryTest, boolean onlyCore) {
+        PackageManagerService m = new PackageManagerService(context, installer,
+                factoryTest, onlyCore);
         ServiceManager.addService("package", m);
         return m;
     }
@@ -966,7 +967,8 @@
         return res;
     }
 
-    public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {
+    public PackageManagerService(Context context, Installer installer,
+            boolean factoryTest, boolean onlyCore) {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                 SystemClock.uptimeMillis());
 
@@ -1004,7 +1006,7 @@
             mSeparateProcesses = null;
         }
 
-        mInstaller = new Installer();
+        mInstaller = installer;
 
         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
         Display d = wm.getDefaultDisplay();