Merge "Issue 2667801: [Audio Effect Framework] AudioFlinger, AudioMixer AudioTrack modifications." into kraken
diff --git a/Android.mk b/Android.mk
index 5c95d20..54ce115 100644
--- a/Android.mk
+++ b/Android.mk
@@ -86,7 +86,6 @@
 	core/java/android/app/ISearchManager.aidl \
 	core/java/android/app/ISearchManagerCallback.aidl \
 	core/java/android/app/IServiceConnection.aidl \
-	core/java/android/app/IStatusBar.aidl \
 	core/java/android/app/IThumbnailReceiver.aidl \
 	core/java/android/app/ITransientNotification.aidl \
 	core/java/android/app/IUiModeManager.aidl \
@@ -155,6 +154,8 @@
 	core/java/com/android/internal/backup/IBackupTransport.aidl \
 	core/java/com/android/internal/os/IDropBoxManagerService.aidl \
 	core/java/com/android/internal/os/IResultReceiver.aidl \
+	core/java/com/android/internal/statusbar/IStatusBar.aidl \
+	core/java/com/android/internal/statusbar/IStatusBarService.aidl \
 	core/java/com/android/internal/view/IInputContext.aidl \
 	core/java/com/android/internal/view/IInputContextCallback.aidl \
 	core/java/com/android/internal/view/IInputMethod.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 6455103..26d8a1b 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -53,6 +53,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/FrameworkTest_intermediates/)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android.policy*)
 $(call add-clean-step, rm -rf $(TARGET_OUT_JAVA_LIBRARIES)/android.policy.jar)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
 
 
 # ************************************************
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 0235599..da8c9e5 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -138,7 +138,7 @@
     public Dialog(Context context, int theme) {
         mContext = new ContextThemeWrapper(
             context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
-        mWindowManager = (WindowManager)context.getSystemService("window");
+        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
         Window w = PolicyManager.makeNewWindow(mContext);
         mWindow = w;
         w.setCallback(this);
diff --git a/core/java/android/app/IStatusBar.aidl b/core/java/android/app/IStatusBar.aidl
deleted file mode 100644
index c64fa50..0000000
--- a/core/java/android/app/IStatusBar.aidl
+++ /dev/null
@@ -1,29 +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.app;
-
-/** @hide */
-interface IStatusBar
-{
-    void activate();
-    void deactivate();
-    void toggle();
-    void disable(int what, IBinder token, String pkg);
-    IBinder addIcon(String slot, String iconPackage, int iconId, int iconLevel);
-    void updateIcon(IBinder key, String slot, String iconPackage, int iconId, int iconLevel);
-    void removeIcon(IBinder key);
-}
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index 84a57b5..4bf5518 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -18,9 +18,7 @@
 
 import android.os.Bundle;
 import android.os.Handler;
-import android.view.KeyEvent;
 import android.view.View;
-import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
 import android.widget.ListView;
@@ -68,7 +66,7 @@
  *               android:layout_weight="1"
  *               android:drawSelectorOnTop="false"/>
  *
- *     <TextView id="@id/android:empty"
+ *     <TextView android:id="@id/android:empty"
  *               android:layout_width="match_parent"
  *               android:layout_height="match_parent"
  *               android:background="#FF0000"
@@ -316,7 +314,7 @@
     }
 
     private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() {
-        public void onItemClick(AdapterView parent, View v, int position, long id)
+        public void onItemClick(AdapterView<?> parent, View v, int position, long id)
         {
             onListItemClick((ListView)parent, v, position, id);
         }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4d72f73..739aca3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -341,6 +341,44 @@
         iconLevel = parcel.readInt();
     }
 
+    public Notification clone() {
+        Notification that = new Notification();
+
+        that.when = this.when;
+        that.icon = this.icon;
+        that.number = this.number;
+
+        // PendingIntents are global, so there's no reason (or way) to clone them.
+        that.contentIntent = this.contentIntent;
+        that.deleteIntent = this.deleteIntent;
+
+        if (this.tickerText != null) {
+            that.tickerText = this.tickerText.toString();
+        }
+        if (this.contentView != null) {
+            that.contentView = this.contentView.clone();
+        }
+        that.iconLevel = that.iconLevel;
+        that.sound = this.sound; // android.net.Uri is immutable
+        that.audioStreamType = this.audioStreamType;
+
+        final long[] vibrate = this.vibrate;
+        if (vibrate != null) {
+            final int N = vibrate.length;
+            final long[] vib = that.vibrate = new long[N];
+            System.arraycopy(vibrate, 0, vib, 0, N);
+        }
+
+        that.ledARGB = this.ledARGB;
+        that.ledOnMS = this.ledOnMS;
+        that.ledOffMS = this.ledOffMS;
+        that.defaults = this.defaults;
+        
+        that.flags = this.flags;
+
+        return that;
+    }
+
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 72ec616..de544fb 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -23,6 +23,8 @@
 import android.os.IBinder;
 import android.os.ServiceManager;
 
+import com.android.internal.statusbar.IStatusBarService;
+
 /**
  * Allows an app to control the status bar.
  *
@@ -58,12 +60,12 @@
     public static final int DISABLE_NONE = 0x00000000;
 
     private Context mContext;
-    private IStatusBar mService;
+    private IStatusBarService mService;
     private IBinder mToken = new Binder();
 
     StatusBarManager(Context context) {
         mContext = context;
-        mService = IStatusBar.Stub.asInterface(
+        mService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
     }
 
@@ -85,7 +87,7 @@
      */
     public void expand() {
         try {
-            mService.activate();
+            mService.expand();
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
@@ -97,46 +99,34 @@
      */
     public void collapse() {
         try {
-            mService.deactivate();
-        } catch (RemoteException ex) {
-            // system process is dead anyway.
-            throw new RuntimeException(ex);
-        }
-    }
-    
-    /**
-     * Toggle the status bar.
-     */
-    public void toggle() {
-        try {
-            mService.toggle();
+            mService.collapse();
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
         }
     }
 
-    public IBinder addIcon(String slot, int iconId, int iconLevel) {
+    public void setIcon(String slot, int iconId, int iconLevel) {
         try {
-            return mService.addIcon(slot, mContext.getPackageName(), iconId, iconLevel);
+            mService.setIcon(slot, mContext.getPackageName(), iconId, iconLevel);
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
         }
     }
 
-    public void updateIcon(IBinder key, String slot, int iconId, int iconLevel) {
+    public void removeIcon(String slot) {
         try {
-            mService.updateIcon(key, slot, mContext.getPackageName(), iconId, iconLevel);
+            mService.removeIcon(slot);
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
         }
     }
 
-    public void removeIcon(IBinder key) {
+    public void setIconVisibility(String slot, boolean visible) {
         try {
-            mService.removeIcon(key);
+            mService.setIconVisibility(slot, visible);
         } catch (RemoteException ex) {
             // system process is dead anyway.
             throw new RuntimeException(ex);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index d4f9b20..0e798dc 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -33,6 +33,8 @@
 import android.util.Log;
 import android.util.Pair;
 
+import dalvik.system.BlockGuard;
+
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.text.SimpleDateFormat;
@@ -1339,6 +1341,7 @@
         if (!isOpen()) {
             throw new IllegalStateException("database not open");
         }
+        BlockGuard.getThreadPolicy().onReadFromDisk();
         long timeStart = 0;
 
         if (Config.LOGV || mSlowQueryThreshold != -1) {
@@ -1497,6 +1500,7 @@
      */
     public long insertWithOnConflict(String table, String nullColumnHack,
             ContentValues initialValues, int conflictAlgorithm) {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         if (!isOpen()) {
             throw new IllegalStateException("database not open");
         }
@@ -1588,6 +1592,7 @@
      *         whereClause.
      */
     public int delete(String table, String whereClause, String[] whereArgs) {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         lock();
         if (!isOpen()) {
             throw new IllegalStateException("database not open");
@@ -1643,6 +1648,7 @@
      */
     public int updateWithOnConflict(String table, ContentValues values,
             String whereClause, String[] whereArgs, int conflictAlgorithm) {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         if (values == null || values.size() == 0) {
             throw new IllegalArgumentException("Empty values");
         }
@@ -1725,6 +1731,7 @@
      * @throws SQLException If the SQL string is invalid for some reason
      */
     public void execSQL(String sql) throws SQLException {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         long timeStart = SystemClock.uptimeMillis();
         lock();
         if (!isOpen()) {
@@ -1760,6 +1767,7 @@
      * @throws SQLException If the SQL string is invalid for some reason
      */
     public void execSQL(String sql, Object[] bindArgs) throws SQLException {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         if (bindArgs == null) {
             throw new IllegalArgumentException("Empty bindArgs");
         }
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 47cca87..9e425c3 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -18,6 +18,8 @@
 
 import android.os.SystemClock;
 
+import dalvik.system.BlockGuard;
+
 /**
  * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
  * The statement cannot return multiple rows, but 1x1 result sets are allowed.
@@ -47,6 +49,7 @@
      *         some reason
      */
     public void execute() {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         if (!mDatabase.isOpen()) {
             throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
         }
@@ -73,6 +76,7 @@
      *         some reason
      */
     public long executeInsert() {
+        BlockGuard.getThreadPolicy().onWriteToDisk();
         if (!mDatabase.isOpen()) {
             throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
         }
@@ -99,6 +103,7 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public long simpleQueryForLong() {
+        BlockGuard.getThreadPolicy().onReadFromDisk();
         if (!mDatabase.isOpen()) {
             throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
         }
@@ -125,6 +130,7 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public String simpleQueryForString() {
+        BlockGuard.getThreadPolicy().onReadFromDisk();
         if (!mDatabase.isOpen()) {
             throw new IllegalStateException("database " + mDatabase.getPath() + " already closed");
         }
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 54aa363..025db4a 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -763,6 +763,7 @@
         private static final String KEY_ZOOM_SUPPORTED = "zoom-supported";
         private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported";
         private static final String KEY_FOCUS_DISTANCES = "focus-distances";
+        private static final String KEY_METERING_MODE = "metering-mode";
 
         // Parameter key suffix for supported values.
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -965,6 +966,26 @@
          */
         public static final String FOCUS_MODE_CONTINUOUS = "continuous";
 
+        /**
+         * The camera determines the exposure by giving more weight to the
+         * central part of the scene.
+         * @hide
+         */
+        public static final String METERING_MODE_CENTER_WEIGHTED = "center-weighted";
+
+        /**
+         * The camera determines the exposure by averaging the entire scene,
+         * giving no weighting to any particular area.
+         * @hide
+         */
+        public static final String METERING_MODE_FRAME_AVERAGE = "frame-average";
+
+        /**
+         * The camera determines the exposure by a very small area of the scene,
+         * typically the center.
+         * @hide
+         */
+        public static final String METERING_MODE_SPOT = "spot";
 
         // Formats for setPreviewFormat and setPictureFormat.
         private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
@@ -1930,6 +1951,45 @@
             output[2] = distances.get(2);
         }
 
+        /**
+         * Gets the supported metering modes.
+         *
+         * @return a list of supported metering modes. null if metering mode
+         *         setting is not supported.
+         * @see #getMeteringMode()
+         * @hide
+         */
+        public List<String> getSupportedMeteringModes() {
+            String str = get(KEY_METERING_MODE + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+        /**
+         * Gets the current metering mode, which affects how camera determines
+         * exposure.
+         *
+         * @return current metering mode. If the camera does not support
+         *         metering setting, this should return null.
+         * @see #METERING_MODE_CENTER_WEIGHTED
+         * @see #METERING_MODE_FRAME_AVERAGE
+         * @see #METERING_MODE_SPOT
+         * @hide
+         */
+        public String getMeteringMode() {
+            return get(KEY_METERING_MODE);
+        }
+
+        /**
+         * Sets the metering mode.
+         *
+         * @param value metering mode.
+         * @see #getMeteringMode()
+         * @hide
+         */
+        public void setMeteringMode(String value) {
+            set(KEY_METERING_MODE, value);
+        }
+
         // Splits a comma delimited string to an ArrayList of String.
         // Return null if the passing string is null or the size is 0.
         private ArrayList<String> split(String str) {
diff --git a/core/java/android/text/util/Rfc822Tokenizer.java b/core/java/android/text/util/Rfc822Tokenizer.java
index 952d833..69cf93c 100644
--- a/core/java/android/text/util/Rfc822Tokenizer.java
+++ b/core/java/android/text/util/Rfc822Tokenizer.java
@@ -84,8 +84,10 @@
                     if (c == '"') {
                         i++;
                         break;
-                    } else if (c == '\\' && i + 1 < cursor) {
-                        name.append(text.charAt(i + 1));
+                    } else if (c == '\\') {
+                        if (i + 1 < cursor) {
+                            name.append(text.charAt(i + 1));
+                        }
                         i += 2;
                     } else {
                         name.append(c);
@@ -110,8 +112,10 @@
                         comment.append(c);
                         level++;
                         i++;
-                    } else if (c == '\\' && i + 1 < cursor) {
-                        comment.append(text.charAt(i + 1));
+                    } else if (c == '\\') {
+                        if (i + 1 < cursor) {
+                            comment.append(text.charAt(i + 1));
+                        }
                         i += 2;
                     } else {
                         comment.append(c);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index d648e96..eefbf7a 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -255,17 +255,19 @@
     }
 
     static private MotionEvent obtain() {
+        final MotionEvent ev;
         synchronized (gRecyclerLock) {
             if (gRecyclerTop == null) {
                 return new MotionEvent();
             }
-            MotionEvent ev = gRecyclerTop;
+            ev = gRecyclerTop;
             gRecyclerTop = ev.mNext;
             gRecyclerUsed--;
-            ev.mRecycledLocation = null;
-            ev.mRecycled = false;
-            return ev;
         }
+        ev.mRecycledLocation = null;
+        ev.mRecycled = false;
+        ev.mNext = null;
+        return ev;
     }
 
     /**
@@ -620,11 +622,14 @@
                 throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
             }
             mRecycledLocation = new RuntimeException("Last recycled here");
-        } else if (mRecycled) {
-            throw new RuntimeException(toString() + " recycled twice!");
+            //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation);
+        } else {
+            if (mRecycled) {
+                throw new RuntimeException(toString() + " recycled twice!");
+            }
+            mRecycled = true;
         }
 
-        //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation);
         synchronized (gRecyclerLock) {
             if (gRecyclerUsed < MAX_RECYCLED) {
                 gRecyclerUsed++;
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index c246c247..39b1377 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -123,7 +123,7 @@
     }
 
     private void initFloatingWindow() {
-        mWindowManager = (WindowManager)mContext.getSystemService("window");
+        mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mWindow = PolicyManager.makeNewWindow(mContext);
         mWindow.setWindowManager(mWindowManager, null, null);
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 3003580..7a70c80 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -100,6 +100,7 @@
      * Base class for all actions that can be performed on an 
      * inflated view.
      *
+     *  SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
      */
     private abstract static class Action implements Parcelable {
         public abstract void apply(View root) throws ActionException;
@@ -568,6 +569,14 @@
         }
     }
 
+    public RemoteViews clone() {
+        final RemoteViews that = new RemoteViews(mPackage, mLayoutId);
+        if (mActions != null) {
+            that.mActions = (ArrayList<Action>)mActions.clone();
+        }
+        return that;
+    }
+
     public String getPackage() {
         return mPackage;
     }
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
new file mode 100644
index 0000000..4501bd7
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -0,0 +1,34 @@
+/**
+ * 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 com.android.internal.statusbar;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarNotification;
+
+/** @hide */
+oneway interface IStatusBar
+{
+    void setIcon(int index, in StatusBarIcon icon);
+    void removeIcon(int index);
+    void addNotification(IBinder key, in StatusBarNotification notification);
+    void updateNotification(IBinder key, in StatusBarNotification notification);
+    void removeNotification(IBinder key);
+    void disable(int state);
+    void animateExpand();
+    void animateCollapse();
+}
+
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
new file mode 100644
index 0000000..1f25b37
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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 com.android.internal.statusbar;
+
+import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.StatusBarNotification;
+
+/** @hide */
+interface IStatusBarService
+{
+    void expand();
+    void collapse();
+    void disable(int what, IBinder token, String pkg);
+    void setIcon(String slot, String iconPackage, int iconId, int iconLevel);
+    void setIconVisibility(String slot, boolean visible);
+    void removeIcon(String slot);
+
+    // ---- Methods below are for use by the status bar policy services ----
+    void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList,
+            out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications);
+    void visibilityChanged(boolean visible);
+    void onNotificationClick(String pkg, String tag, int id);
+    void onClearAllNotifications();
+}
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.aidl b/core/java/com/android/internal/statusbar/StatusBarIcon.aidl
new file mode 100644
index 0000000..311a077
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+parcelable StatusBarIcon;
+
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
new file mode 100644
index 0000000..ae2cac2
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @hide
+ */
+public class StatusBarIcon implements Parcelable {
+    public String iconPackage;
+    public int iconId;
+    public int iconLevel;
+    public boolean visible = true;
+    public int number;
+
+    private StatusBarIcon() {
+    }
+
+    public StatusBarIcon(String iconPackage, int iconId, int iconLevel) {
+        this.iconPackage = iconPackage;
+        this.iconId = iconId;
+        this.iconLevel = iconLevel;
+    }
+
+    public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number) {
+        this.iconPackage = iconPackage;
+        this.iconId = iconId;
+        this.iconLevel = iconLevel;
+        this.number = number;
+    }
+
+    public String toString() {
+        return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId)
+                + " level=" + this.iconLevel + " visible=" + visible
+                + " num=" + this.number + " )";
+    }
+
+    public StatusBarIcon clone() {
+        StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel);
+        that.visible = this.visible;
+        that.number = this.number;
+        return that;
+    }
+
+    /**
+     * Unflatten the StatusBarIcon from a parcel.
+     */
+    public StatusBarIcon(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public void readFromParcel(Parcel in) {
+        this.iconPackage = in.readString();
+        this.iconId = in.readInt();
+        this.iconLevel = in.readInt();
+        this.visible = in.readInt() != 0;
+        this.number = in.readInt();
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(this.iconPackage);
+        out.writeInt(this.iconId);
+        out.writeInt(this.iconLevel);
+        out.writeInt(this.visible ? 1 : 0);
+        out.writeInt(this.number);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Parcelable.Creator that instantiates StatusBarIcon objects
+     */
+    public static final Parcelable.Creator<StatusBarIcon> CREATOR
+            = new Parcelable.Creator<StatusBarIcon>()
+    {
+        public StatusBarIcon createFromParcel(Parcel parcel)
+        {
+            return new StatusBarIcon(parcel);
+        }
+
+        public StatusBarIcon[] newArray(int size)
+        {
+            return new StatusBarIcon[size];
+        }
+    };
+}
+
diff --git a/core/java/com/android/internal/statusbar/StatusBarIconList.aidl b/core/java/com/android/internal/statusbar/StatusBarIconList.aidl
new file mode 100644
index 0000000..c745120
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarIconList.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+parcelable StatusBarIconList;
+
diff --git a/core/java/com/android/internal/statusbar/StatusBarIconList.java b/core/java/com/android/internal/statusbar/StatusBarIconList.java
new file mode 100644
index 0000000..478d245
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarIconList.java
@@ -0,0 +1,161 @@
+/*
+ * 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 com.android.internal.statusbar;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.PrintWriter;
+
+public class StatusBarIconList implements Parcelable {
+    private String[] mSlots;
+    private StatusBarIcon[] mIcons;
+
+    public StatusBarIconList() {
+    }
+
+    public StatusBarIconList(Parcel in) {
+        readFromParcel(in);
+    }
+    
+    public void readFromParcel(Parcel in) {
+        this.mSlots = in.readStringArray();
+        final int N = in.readInt();
+        if (N < 0) {
+            mIcons = null;
+        } else {
+            mIcons = new StatusBarIcon[N];
+            for (int i=0; i<N; i++) {
+                if (in.readInt() != 0) {
+                    mIcons[i] = new StatusBarIcon(in);
+                }
+            }
+        }
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeStringArray(mSlots);
+        if (mIcons == null) {
+            out.writeInt(-1);
+        } else {
+            final int N = mIcons.length;
+            out.writeInt(N);
+            for (int i=0; i<N; i++) {
+                StatusBarIcon ic = mIcons[i];
+                if (ic == null) {
+                    out.writeInt(0);
+                } else {
+                    out.writeInt(1);
+                    ic.writeToParcel(out, flags);
+                }
+            }
+        }
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Parcelable.Creator that instantiates StatusBarIconList objects
+     */
+    public static final Parcelable.Creator<StatusBarIconList> CREATOR
+            = new Parcelable.Creator<StatusBarIconList>()
+    {
+        public StatusBarIconList createFromParcel(Parcel parcel)
+        {
+            return new StatusBarIconList(parcel);
+        }
+
+        public StatusBarIconList[] newArray(int size)
+        {
+            return new StatusBarIconList[size];
+        }
+    };
+
+    public void defineSlots(String[] slots) {
+        final int N = slots.length;
+        String[] s = mSlots = new String[N];
+        for (int i=0; i<N; i++) {
+            s[i] = slots[i];
+        }
+        mIcons = new StatusBarIcon[N];
+    }
+
+    public int getSlotIndex(String slot) {
+        final int N = mSlots.length;
+        for (int i=0; i<N; i++) {
+            if (slot.equals(mSlots[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public int size() {
+        return mSlots.length;
+    }
+
+    public void setIcon(int index, StatusBarIcon icon) {
+        mIcons[index] = icon.clone();
+    }
+
+    public void removeIcon(int index) {
+        mIcons[index] = null;
+    }
+
+    public String getSlot(int index) {
+        return mSlots[index];
+    }
+
+    public StatusBarIcon getIcon(int index) {
+        return mIcons[index];
+    }
+
+    public int getViewIndex(int index) {
+        int count = 0;
+        for (int i=0; i<index; i++) {
+            if (mIcons[i] != null) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    public void copyFrom(StatusBarIconList that) {
+        if (that.mSlots == null) {
+            this.mSlots = null;
+            this.mIcons = null;
+        } else {
+            final int N = that.mSlots.length;
+            this.mSlots = new String[N];
+            this.mIcons = new StatusBarIcon[N];
+            for (int i=0; i<N; i++) {
+                this.mSlots[i] = that.mSlots[i];
+                this.mIcons[i] = that.mIcons[i] != null ? that.mIcons[i].clone() : null;
+            }
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        final int N = mSlots.length;
+        pw.println("Icon list:");
+        for (int i=0; i<N; i++) {
+            pw.printf("  %2d: (%s) %s\n", i, mSlots[i], mIcons[i]);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.aidl b/core/java/com/android/internal/statusbar/StatusBarNotification.aidl
new file mode 100644
index 0000000..bd9e89c
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+parcelable StatusBarNotification;
+
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java
new file mode 100644
index 0000000..5499676
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java
@@ -0,0 +1,116 @@
+/*
+ * 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.internal.statusbar;
+
+import android.app.Notification;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.RemoteViews;
+
+
+/*
+boolean clearable = !n.ongoingEvent && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
+
+
+// TODO: make this restriction do something smarter like never fill
+// more than two screens.  "Why would anyone need more than 80 characters." :-/
+final int maxTickerLen = 80;
+if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) {
+    truncatedTicker = truncatedTicker.subSequence(0, maxTickerLen);
+}
+*/
+
+public class StatusBarNotification implements Parcelable {
+    public String pkg;
+    public int id;
+    public String tag;
+    public Notification notification;
+
+    public StatusBarNotification() {
+    }
+
+    public StatusBarNotification(String pkg, int id, String tag, Notification notification) {
+        if (pkg == null) throw new NullPointerException();
+        if (notification == null) throw new NullPointerException();
+
+        this.pkg = pkg;
+        this.id = id;
+        this.tag = tag;
+        this.notification = notification;
+    }
+
+    public StatusBarNotification(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public void readFromParcel(Parcel in) {
+        this.pkg = in.readString();
+        this.id = in.readInt();
+        if (in.readInt() != 0) {
+            this.tag = in.readString();
+        } else {
+            this.tag = null;
+        }
+        this.notification = new Notification(in);
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(this.pkg);
+        out.writeInt(this.id);
+        if (this.tag != null) {
+            out.writeInt(1);
+            out.writeString(this.tag);
+        } else {
+            out.writeInt(0);
+        }
+        this.notification.writeToParcel(out, flags);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<StatusBarNotification> CREATOR
+            = new Parcelable.Creator<StatusBarNotification>()
+    {
+        public StatusBarNotification createFromParcel(Parcel parcel)
+        {
+            return new StatusBarNotification(parcel);
+        }
+
+        public StatusBarNotification[] newArray(int size)
+        {
+            return new StatusBarNotification[size];
+        }
+    };
+
+    public StatusBarNotification clone() {
+        return new StatusBarNotification(this.pkg, this.id, this.tag, this.notification.clone());
+    }
+
+    public String toString() {
+        return "StatusBarNotification(package=" + pkg + " id=" + id + " tag=" + tag
+                + " notification=" + notification + ")";
+    }
+
+    public boolean isOngoing() {
+        return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
+    }
+
+}
+
+
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl b/core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl
new file mode 100644
index 0000000..10abeee
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+parcelable StatusBarNotificationList;
+
diff --git a/core/res/res/drawable-hdpi/battery_charge_fill_empty.9.png b/core/res/res/drawable-hdpi/battery_charge_fill_empty.9.png
deleted file mode 100644
index c4e70a8..0000000
--- a/core/res/res/drawable-hdpi/battery_charge_fill_empty.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/battery_charge_fill_full.9.png b/core/res/res/drawable-hdpi/battery_charge_fill_full.9.png
deleted file mode 100644
index ac66f5a..0000000
--- a/core/res/res/drawable-hdpi/battery_charge_fill_full.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/battery_charge_fill_warning.9.png b/core/res/res/drawable-hdpi/battery_charge_fill_warning.9.png
deleted file mode 100644
index 32d99c6..0000000
--- a/core/res/res/drawable-hdpi/battery_charge_fill_warning.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png b/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
index 96dc085..7a8b78f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_charge_fill_full.9.png b/core/res/res/drawable-mdpi/battery_charge_fill_full.9.png
deleted file mode 100644
index 8e6aaca..0000000
--- a/core/res/res/drawable-mdpi/battery_charge_fill_full.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_charge_fill_warning.9.png b/core/res/res/drawable-mdpi/battery_charge_fill_warning.9.png
deleted file mode 100644
index d3287db..0000000
--- a/core/res/res/drawable-mdpi/battery_charge_fill_warning.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/battery_charge_fill.xml b/core/res/res/drawable/battery_charge_fill.xml
deleted file mode 100644
index 7f65733..0000000
--- a/core/res/res/drawable/battery_charge_fill.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="29" android:drawable="@android:drawable/battery_charge_fill_empty" />
-    <item android:maxLevel="49" android:drawable="@android:drawable/battery_charge_fill_warning" />
-    <item android:maxLevel="100" android:drawable="@android:drawable/battery_charge_fill_full" />
-</level-list>
-
diff --git a/core/res/res/layout/battery_status.xml b/core/res/res/layout/battery_status.xml
deleted file mode 100644
index 7cfec05..0000000
--- a/core/res/res/layout/battery_status.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/frame"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:gravity="center_horizontal"
-    >
-    
-    <FrameLayout
-        android:layout_width="141px" 
-        android:layout_height="184px"
-        android:background="@drawable/battery_charge_background"
-        android:paddingTop="25px"
-        android:paddingLeft="1px"
-        >
-
-        <LinearLayout
-            android:id="@+id/meter"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:orientation="vertical"
-            >
-
-            <ImageView
-                android:layout_width="match_parent"
-                android:layout_height="15dip"
-                />
-            <ImageView
-                android:id="@+id/spacer"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                />
-            <ImageView
-                android:id="@+id/level"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-            />
-        
-        </LinearLayout>
-
-        <TextView android:id="@+id/level_percent"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:textStyle="bold"
-            android:textSize="48dp"
-            android:textColor="#ffffffff"
-            android:gravity="center"
-            />
-    </FrameLayout>
-
-    <TextView android:id="@+id/status"
-        android:paddingTop="35dp"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:textStyle="bold"
-        android:textSize="30dp"
-        android:textColor="#ffffffff"
-        android:gravity="center_horizontal"
-        android:text="@string/battery_status_charging"
-        />
-
-</LinearLayout>
-
-
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index ea6200a..c64b90e 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -12,7 +12,8 @@
         android:orientation="horizontal"
         android:paddingTop="3dp"
         >
-        <com.android.server.status.AnimatedImageView android:id="@+id/icon"
+        <!--com.android.server.status.AnimatedImageView android:id="@+id/icon" -->
+        <ImageView android:id="@+id/icon"
             android:layout_width="25dp"
             android:layout_height="25dp"
             android:scaleType="fitCenter"
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index a0bc5b3..04937565 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -120,25 +120,25 @@
     <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
          icons in the status bar that are not notifications. -->
     <string-array name="status_bar_icon_order">
-        <item><xliff:g id="id">clock</xliff:g></item>
-        <item><xliff:g id="id">secure</xliff:g></item>
-        <item><xliff:g id="id">alarm_clock</xliff:g></item>
-        <item><xliff:g id="id">battery</xliff:g></item>
-        <item><xliff:g id="id">phone_signal</xliff:g></item>
-        <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
-        <item><xliff:g id="id">data_connection</xliff:g></item>
-        <item><xliff:g id="id">cdma_eri</xliff:g></item>
-        <item><xliff:g id="id">wifi</xliff:g></item>
-        <item><xliff:g id="id">tty</xliff:g></item>
-        <item><xliff:g id="id">volume</xliff:g></item>
-        <item><xliff:g id="id">mute</xliff:g></item>
-        <item><xliff:g id="id">speakerphone</xliff:g></item>
-        <item><xliff:g id="id">tty</xliff:g></item>
-        <item><xliff:g id="id">bluetooth</xliff:g></item>
-        <item><xliff:g id="id">gps</xliff:g></item>
-        <item><xliff:g id="id">sync_active</xliff:g></item>
-        <item><xliff:g id="id">sync_failing</xliff:g></item>
-        <item><xliff:g id="id">ime</xliff:g></item>
+       <item><xliff:g id="id">ime</xliff:g></item>
+       <item><xliff:g id="id">sync_failing</xliff:g></item>
+       <item><xliff:g id="id">sync_active</xliff:g></item>
+       <item><xliff:g id="id">gps</xliff:g></item>
+       <item><xliff:g id="id">bluetooth</xliff:g></item>
+       <item><xliff:g id="id">tty</xliff:g></item>
+       <item><xliff:g id="id">speakerphone</xliff:g></item>
+       <item><xliff:g id="id">mute</xliff:g></item>
+       <item><xliff:g id="id">volume</xliff:g></item>
+       <item><xliff:g id="id">tty</xliff:g></item>
+       <item><xliff:g id="id">wifi</xliff:g></item>
+       <item><xliff:g id="id">cdma_eri</xliff:g></item>
+       <item><xliff:g id="id">data_connection</xliff:g></item>
+       <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
+       <item><xliff:g id="id">phone_signal</xliff:g></item>
+       <item><xliff:g id="id">battery</xliff:g></item>
+       <item><xliff:g id="id">alarm_clock</xliff:g></item>
+       <item><xliff:g id="id">secure</xliff:g></item>
+       <item><xliff:g id="id">clock</xliff:g></item>
     </string-array>
 
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 64f05fe..cd47ae9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -220,9 +220,6 @@
     <!-- Allow the menu hard key to be disabled in LockScreen on some devices -->
     <bool name="config_disableMenuKeyInLockScreen">false</bool>
 
-    <!-- Control whether status bar should distinguish HSPA data icon form UMTS data icon on devices -->
-    <bool name="config_hspa_data_distinguishable">false</bool>
-
     <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.
          The N entries of this array define N + 1 zones as follows:
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1e007d36..613a9a2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1567,45 +1567,6 @@
     <!-- A format string for 12-hour time of day, just the hour, not the minute, with capital "AM" or "PM" (example: "3PM"). -->
     <string name="hour_cap_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="PM">%p</xliff:g>"</string>
 
-    <!-- The text for the button in the notification window-shade that clears
-         all of the currently visible notifications. -->
-    <string name="status_bar_clear_all_button">Clear</string>
-
-    <!-- The label in the bar at the top of the status bar when there are no notifications
-         showing. -->
-    <string name="status_bar_no_notifications_title">No notifications</string>
-
-    <!-- The label for the group of notifications for ongoing events in the opened version of
-         the status bar.  An ongoing call is the prime example of this.  The MP3 music player
-         might be another example.  -->
-    <string name="status_bar_ongoing_events_title">Ongoing</string>
-
-    <!-- The label for the group of notifications for recent events in the opened version of
-         the status bar.  Recently received text messsages (SMS), emails, calendar alerts, etc. -->
-    <string name="status_bar_latest_events_title">Notifications</string>
-
-    <!-- The big percent text in the middle of the battery icon that appears when you plug in
-         the charger. -->
-    <string name="battery_status_text_percent_format"><xliff:g id="number" example="50">%d</xliff:g><xliff:g id="percent" example="%">%%</xliff:g></string>
-
-    <!-- The big percent text in the middle of the battery icon that appears when you plug in
-         the charger. This indicates the current status of the battery.  -->
-    <string name="battery_status_charging">Charging\u2026</string>
-
-    <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert. -->
-    <string name="battery_low_title">Please connect charger</string>
-
-    <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. -->
-    <string name="battery_low_subtitle">The battery is getting low:</string>
-
-    <!-- A message that appears when the battery level is getting low in a dialog.  This is appened to the subtitle of the low battery alert. -->
-    <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g>
-    or less remaining.</string>
-
-    <!-- When the battery is low, this is the label of the button to go to the
-         power usage activity to find out what drained the battery. -->
-    <string name="battery_low_why">Battery use</string>
-
     <!-- Title of the alert when something went wrong in the factory test. -->
     <string name="factorytest_failed">Factory test failed</string>
     <!-- Error message displayed when a non-system application tries to start a factory test. -->
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index 5b427be..a5229cc 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -26,6 +26,8 @@
 import android.text.TextPaint;
 import android.text.TextUtils;
 import android.text.style.StyleSpan;
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
 import android.test.MoreAsserts;
 
 import com.android.common.Rfc822Validator;
@@ -269,6 +271,24 @@
         }
     }
 
+    @SmallTest
+    public void testRfc822TokenizerFullAddress() {
+        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
+        assertNotNull(tokens);
+        assertEquals(1, tokens.length);
+        assertEquals("foo@google.com", tokens[0].getAddress());
+        assertEquals("Foo Bar", tokens[0].getName());
+        assertEquals("something",tokens[0].getComment());
+    }
+
+    @SmallTest
+    public void testRfc822TokenizeItemWithError() {
+        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("\"Foo Bar\\");
+        assertNotNull(tokens);
+        assertEquals(1, tokens.length);
+        assertEquals("Foo Bar", tokens[0].getAddress());
+    }
+
     @LargeTest
     public void testEllipsize() {
         CharSequence s1 = "The quick brown fox jumps over \u00FEhe lazy dog.";
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index 74117d6..aad0f92 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -445,7 +445,7 @@
 <p>For an example implementation of {@link android.app.backup.BackupAgent}, see the <a
 href="{@docRoot}resources/samples/BackupRestore/src/com/example/android/backuprestore/ExampleAgent.html">{@code
 ExampleAgent}</a> class in the <a
-href="{@docRoot}}resources/samples/BackupRestore/index.html">Backup and Restore</a> sample
+href="{@docRoot}resources/samples/BackupRestore/index.html">Backup and Restore</a> sample
 application.</p>
 </div>
 
diff --git a/docs/html/guide/topics/security/security.jd b/docs/html/guide/topics/security/security.jd
index da201c4..dbc9866 100644
--- a/docs/html/guide/topics/security/security.jd
+++ b/docs/html/guide/topics/security/security.jd
@@ -40,15 +40,14 @@
 e-mails), reading or writing another application's files, performing
 network access, keeping the device awake, etc.<p>
 
-<p>An application's process is a secure sandbox.  It can't disrupt other
-applications, except by explicitly declaring the <em>permissions</em> it needs
-for additional capabilities not provided by the basic sandbox.  These
-permissions it requests can be handled by the operating in various ways,
-typically by automatically allowing or disallowing based on certificates or
-by prompting the user.  The permissions required by an application are declared
-statically in that application, so they can be known up-front at install time
-and will not change after that.</p>
-
+<p>An application's process runs in a security sandbox. The sandbox is designed
+to prevent applications from disrupting each other, except by explicitly
+declaring the <em>permissions</em> they need for additional capabilities not
+provided by the basic sandbox. The system handles requests for permissions
+in various ways, typically by automatically allowing or disallowing based on
+certificates or by prompting the user.  The permissions required by an
+application are declared statically in that application, so they can be known
+up-front at install time and will not change after that.</p>
 
 <a name="signing"></a>
 <h2>Application Signing</h2>
diff --git a/docs/html/resources/tutorials/views/hello-webview.jd b/docs/html/resources/tutorials/views/hello-webview.jd
index 17b2646..2d07647 100644
--- a/docs/html/resources/tutorials/views/hello-webview.jd
+++ b/docs/html/resources/tutorials/views/hello-webview.jd
@@ -12,7 +12,7 @@
    <li>Open the <code>res/layout/main.xml</code> file and insert the following:
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?>
-&lt;WebView
+&lt;WebView  xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/webview"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -79,7 +79,7 @@
   </li>
   <li>Then towards the end of the {@link android.app.Activity#onCreate(Bundle)} method, set an
   instance of the <code>HelloWebViewClient</code> as the {@link android.webkit.WebViewClient}:
-   <pre>mWebView.setWebViewClient(new WebViewClientDemo());</pre>
+   <pre>mWebView.setWebViewClient(new HelloWebViewClient());</pre>
 
     <p>This line can go anywhere following the initialization of the {@link
     android.webkit.WebView} object.</p>
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 2b7a86eb..4840b40 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -250,6 +250,10 @@
     // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
     static const char KEY_VIDEO_FRAME_FORMAT[];
 
+    // Metering mode. This affects how camera determines exposure.
+    // Example value: "spot" or METERING_MODE_XXX constants. Read/write.
+    static const char KEY_METERING_MODE[];
+
     // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
     static const char TRUE[];
 
@@ -347,6 +351,15 @@
     // callback will be only called once as soon as the picture is in focus.
     static const char FOCUS_MODE_CONTINUOUS[];
 
+    // The camera determines the exposure by giving more weight to the
+    // central part of the scene.
+    static const char METERING_MODE_CENTER_WEIGHTED[];
+    // The camera determines the exposure by averaging the entire scene,
+    // giving no weighting to any particular area.
+    static const char METERING_MODE_FRAME_AVERAGE[];
+    // The camera determines the exposure by a very small area of the scene,
+    // typically the center.
+    static const char METERING_MODE_SPOT[];
 
 private:
     DefaultKeyedVector<String8,String8>    mMap;
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index e4d5bb3..c11d18f 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -71,6 +71,7 @@
 const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
 const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
 const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
+const char CameraParameters::KEY_METERING_MODE[] = "metering-mode";
 
 const char CameraParameters::TRUE[] = "true";
 const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
@@ -142,6 +143,11 @@
 const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
 const char CameraParameters::FOCUS_MODE_CONTINUOUS[] = "continuous";
 
+// Values for metering mode settings.
+const char METERING_MODE_CENTER_WEIGHTED[] = "center-weighted";
+const char METERING_MODE_FRAME_AVERAGE[] = "frame-average";
+const char METERING_MODE_SPOT[] = "spot";
+
 CameraParameters::CameraParameters()
                 : mMap()
 {
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 8f6564a..7672f0f 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -344,7 +344,9 @@
  *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
  *          PlaybackCompleted}</p></td>
  *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ *     <td>Successful invoke of this method does not change the state. In order for the
+ *         target audio stream type to become effective, this method must be called before
+ *         prepare() or prepareAsync().</p></td></tr>
  * <tr><td>setDataSource </p></td>
  *     <td>{Idle} </p></td>
  *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
@@ -1112,7 +1114,9 @@
 
     /**
      * Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
-     * for a list of stream types.
+     * for a list of stream types. Must call this method before prepare() or
+     * prepareAsync() in order for the target stream type to become effective
+     * thereafter.
      *
      * @param streamtype the audio stream type
      * @see android.media.AudioManager
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 944a0c1..b6ed56b 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -58,13 +58,14 @@
     status_t mFinalStatus;
     int64_t mSeekTimeUs;
     int64_t mCacheDurationUs;
+    size_t mCacheSizeBytes;
     bool mPrefetcherStopped;
     bool mCurrentlyPrefetching;
 
     List<MediaBuffer *> mCachedBuffers;
 
     // Returns true iff source is currently caching.
-    bool getCacheDurationUs(int64_t *durationUs);
+    bool getCacheDurationUs(int64_t *durationUs, size_t *totalSize = NULL);
 
     void updateCacheDuration_l();
     void clearCache_l();
@@ -125,21 +126,31 @@
     return 0;
 }
 
-// Cache about 10secs for each source.
-static int64_t kMaxCacheDurationUs = 10000000ll;
+// Cache at most 1 min for each source.
+static int64_t kMaxCacheDurationUs = 60 * 1000000ll;
+
+// At the same time cache at most 5MB per source.
+static size_t kMaxCacheSizeBytes = 5 * 1024 * 1024;
+
+// If the amount of cached data drops below this,
+// fill the cache up to the max duration again.
+static int64_t kLowWaterDurationUs = 5000000ll;
 
 void Prefetcher::threadFunc() {
+    bool fillingCache = false;
+
     for (;;) {
         sp<PrefetchedSource> minSource;
+        int64_t minCacheDurationUs = -1;
 
         {
             Mutex::Autolock autoLock(mLock);
             if (mDone) {
                 break;
             }
-            mCondition.waitRelative(mLock, 10000000ll);
+            mCondition.waitRelative(
+                    mLock, fillingCache ? 10000000ll : 1000000000ll);
 
-            int64_t minCacheDurationUs = -1;
             ssize_t minIndex = -1;
             for (size_t i = 0; i < mSources.size(); ++i) {
                 sp<PrefetchedSource> source = mSources[i].promote();
@@ -149,11 +160,18 @@
                 }
 
                 int64_t cacheDurationUs;
-                if (!source->getCacheDurationUs(&cacheDurationUs)) {
+                size_t cacheSizeBytes;
+                if (!source->getCacheDurationUs(&cacheDurationUs, &cacheSizeBytes)) {
                     continue;
                 }
 
-                if (cacheDurationUs >= kMaxCacheDurationUs) {
+                if (cacheSizeBytes > kMaxCacheSizeBytes) {
+                    LOGI("max cache size reached");
+                    continue;
+                }
+
+                if (mSources.size() > 1 && cacheDurationUs >= kMaxCacheDurationUs) {
+                    LOGI("max duration reached, size = %d bytes", cacheSizeBytes);
                     continue;
                 }
 
@@ -165,14 +183,26 @@
             }
 
             if (minIndex < 0) {
+                if (fillingCache) {
+                    LOGV("[%p] done filling the cache, above high water mark.",
+                         this);
+                    fillingCache = false;
+                }
                 continue;
             }
         }
 
-        // Make sure not to hold the lock while calling into the source.
-        // The lock guards the list of sources, not the individual sources
-        // themselves.
-        minSource->cacheMore();
+        if (!fillingCache && minCacheDurationUs < kLowWaterDurationUs) {
+            LOGI("[%p] cache below low water mark, filling cache.", this);
+            fillingCache = true;
+        }
+
+        if (fillingCache) {
+            // Make sure not to hold the lock while calling into the source.
+            // The lock guards the list of sources, not the individual sources
+            // themselves.
+            minSource->cacheMore();
+        }
     }
 
     Mutex::Autolock autoLock(mLock);
@@ -250,6 +280,7 @@
       mReachedEOS(false),
       mSeekTimeUs(0),
       mCacheDurationUs(0),
+      mCacheSizeBytes(0),
       mPrefetcherStopped(false),
       mCurrentlyPrefetching(false) {
 }
@@ -323,6 +354,7 @@
     *out = *mCachedBuffers.begin();
     mCachedBuffers.erase(mCachedBuffers.begin());
     updateCacheDuration_l();
+    mCacheSizeBytes -= (*out)->size();
 
     return OK;
 }
@@ -331,10 +363,14 @@
     return mSource->getFormat();
 }
 
-bool PrefetchedSource::getCacheDurationUs(int64_t *durationUs) {
+bool PrefetchedSource::getCacheDurationUs(
+        int64_t *durationUs, size_t *totalSize) {
     Mutex::Autolock autoLock(mLock);
 
     *durationUs = mCacheDurationUs;
+    if (totalSize != NULL) {
+        *totalSize = mCacheSizeBytes;
+    }
 
     if (!mStarted || mReachedEOS) {
         return false;
@@ -397,6 +433,7 @@
 
     mCachedBuffers.push_back(copy);
     updateCacheDuration_l();
+    mCacheSizeBytes += copy->size();
 
     mCurrentlyPrefetching = false;
     mCondition.signal();
@@ -425,6 +462,7 @@
     }
 
     updateCacheDuration_l();
+    mCacheSizeBytes = 0;
 }
 
 void PrefetchedSource::onPrefetcherStopped() {
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
new file mode 100644
index 0000000..4c83768
--- /dev/null
+++ b/packages/SystemUI/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := services
+
+LOCAL_PACKAGE_NAME := SystemUI
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
new file mode 100644
index 0000000..3f5b69d
--- /dev/null
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.systemui"
+        android:sharedUserId="android.uid.system">
+
+    <application
+        android:allowClearUserData="false"
+        android:label="@string/app_label"
+        android:icon="@drawable/ic_launcher_settings">
+                 
+        <receiver
+            android:name=".statusbar.StatusBarStarter"
+            >
+            <intent-filter>
+                <action android:name="com.android.internal.policy.statusbar.START" />
+            </intent-filter>
+        </receiver>
+        <service
+            android:name=".statusbar.PhoneStatusBarService"
+            android:exported="false"
+            />
+    </application>
+</manifest>
diff --git a/packages/SystemUI/MODULE_LICENSE_APACHE2 b/packages/SystemUI/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/SystemUI/MODULE_LICENSE_APACHE2
diff --git a/packages/SystemUI/NOTICE b/packages/SystemUI/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/SystemUI/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/core/res/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
similarity index 100%
rename from core/res/res/drawable-hdpi/battery_low_battery.png
rename to packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png
new file mode 100644
index 0000000..baafed6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png
new file mode 100644
index 0000000..175197b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png
new file mode 100644
index 0000000..ec1feff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png
new file mode 100644
index 0000000..c1f9a0f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png
new file mode 100644
index 0000000..0ea3f40
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png b/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png
new file mode 100644
index 0000000..ff34a7f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
new file mode 100644
index 0000000..744178f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/shade_bg.png b/packages/SystemUI/res/drawable-hdpi/shade_bg.png
new file mode 100644
index 0000000..3d00cd0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/shade_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/shade_handlebar.9.png b/packages/SystemUI/res/drawable-hdpi/shade_handlebar.9.png
new file mode 100644
index 0000000..f313ffb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/shade_handlebar.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/shade_header_background.9.png b/packages/SystemUI/res/drawable-hdpi/shade_header_background.9.png
new file mode 100644
index 0000000..37b5fef
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/shade_header_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_notify_alarm.png
rename to packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png
new file mode 100755
index 0000000..1c7f9db
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
new file mode 100644
index 0000000..96dc085
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_connected_3g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_connected_e.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_connected_g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_connected_h.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_in_3g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_in_e.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_in_g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_in_h.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_inandout_3g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_inandout_e.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_inandout_g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_inandout_h.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_out_3g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_out_e.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_out_g.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_data_out_h.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_gps_acquiring.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_no_sim.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_r_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_r_signal_0.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_r_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_r_signal_1.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_r_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_r_signal_2.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_r_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_r_signal_3.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_r_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_r_signal_4.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_ringer_silent.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_ringer_vibrate.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_0.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_1.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_2.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_3.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_4.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_flightmode.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_signal_null.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_tty_mode.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_wifi_signal_0.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_wifi_signal_1.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_wifi_signal_2.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_wifi_signal_3.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
similarity index 100%
rename from core/res/res/drawable-hdpi/stat_sys_wifi_signal_4.png
rename to packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png
new file mode 100644
index 0000000..a4be298
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png
new file mode 100644
index 0000000..4fbfa4f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png
new file mode 100644
index 0000000..0876bc6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_focus.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png
new file mode 100644
index 0000000..c01c018
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png
new file mode 100644
index 0000000..343e4ca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_item_background_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/title_bar_portrait.9.png b/packages/SystemUI/res/drawable-hdpi/title_bar_portrait.9.png
new file mode 100644
index 0000000..70f7cc2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/title_bar_portrait.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png
new file mode 100644
index 0000000..e6dab63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
similarity index 100%
rename from core/res/res/drawable-mdpi/battery_low_battery.png
rename to packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png
new file mode 100644
index 0000000..bcedd5f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png
new file mode 100644
index 0000000..ac6260f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png
new file mode 100644
index 0000000..4ee1b3f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png
new file mode 100644
index 0000000..25e38f4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png
new file mode 100644
index 0000000..cc209c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png b/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png
new file mode 100644
index 0000000..b08ad3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
similarity index 76%
copy from core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
copy to packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
index 9ed20ba..1a3063c4 100644
--- a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/shade_bg.png b/packages/SystemUI/res/drawable-mdpi/shade_bg.png
new file mode 100644
index 0000000..941d3b1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/shade_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/shade_handlebar.9.png b/packages/SystemUI/res/drawable-mdpi/shade_handlebar.9.png
new file mode 100644
index 0000000..9cbd9fe
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/shade_handlebar.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png b/packages/SystemUI/res/drawable-mdpi/shade_header_background.9.png
similarity index 76%
copy from core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
copy to packages/SystemUI/res/drawable-mdpi/shade_header_background.9.png
index 9ed20ba..fa9a90c 100644
--- a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/shade_header_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_notify_alarm.png
rename to packages/SystemUI/res/drawable-mdpi/stat_notify_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png
new file mode 100644
index 0000000..e129ba9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_more.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_connected_3g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_connected_e.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_connected_g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_connected_h.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_in_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_in_3g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_3g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_in_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_in_e.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_e.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_in_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_in_g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_in_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_in_h.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_in_h.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_inandout_3g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_3g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_inandout_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_e.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_inandout_e.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_e.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_inandout_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_inandout_g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_inandout_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_inandout_h.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_inandout_h.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_out_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_out_3g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_3g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_out_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_out_e.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_e.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_out_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_out_g.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_g.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_out_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_data_out_h.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_data_out_h.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_gps_acquiring.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_no_sim.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_r_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_0.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_r_signal_0.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_r_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_1.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_r_signal_1.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_r_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_2.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_r_signal_2.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_r_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_3.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_r_signal_3.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_r_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_4.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_r_signal_4.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_r_signal_4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_ringer_silent.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_ringer_vibrate.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_0.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_1.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_2.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_3.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_4.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_flightmode.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_signal_null.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_tty_mode.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_wifi_signal_0.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_wifi_signal_1.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_wifi_signal_2.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_wifi_signal_3.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
similarity index 100%
rename from core/res/res/drawable-mdpi/stat_sys_wifi_signal_4.png
rename to packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png
new file mode 100644
index 0000000..eb7c1a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png
similarity index 78%
rename from core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
rename to packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png
index 9ed20ba..c079615 100644
--- a/core/res/res/drawable-mdpi/battery_charge_fill_empty.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png
new file mode 100644
index 0000000..c3e24158
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_focus.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png
new file mode 100644
index 0000000..b8e399d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png
new file mode 100644
index 0000000..02b4e9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_item_background_pressed.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/title_bar_portrait.9.png b/packages/SystemUI/res/drawable-mdpi/title_bar_portrait.9.png
new file mode 100644
index 0000000..13b18d8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/title_bar_portrait.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png
new file mode 100644
index 0000000..dbcefee
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/btn_default_small.xml b/packages/SystemUI/res/drawable/btn_default_small.xml
new file mode 100644
index 0000000..5485ea0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/btn_default_small.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="true"
+        android:drawable="@drawable/btn_default_small_normal" />
+    <item android:state_window_focused="false" android:state_enabled="false"
+        android:drawable="@drawable/btn_default_small_normal_disable" />
+    <item android:state_pressed="true" 
+        android:drawable="@drawable/btn_default_small_pressed" />
+    <item android:state_focused="true" android:state_enabled="true"
+        android:drawable="@drawable/btn_default_small_selected" />
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_default_small_normal" />
+    <item android:state_focused="true"
+        android:drawable="@drawable/btn_default_small_normal_disable_focused" />
+    <item
+         android:drawable="@drawable/btn_default_small_normal_disable" />
+</selector>
+
diff --git a/core/res/res/drawable/stat_sys_gps_acquiring_anim.xml b/packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml
similarity index 90%
rename from core/res/res/drawable/stat_sys_gps_acquiring_anim.xml
rename to packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml
index 954c19c..393697c 100644
--- a/core/res/res/drawable/stat_sys_gps_acquiring_anim.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml
@@ -21,5 +21,5 @@
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:oneshot="false">
     <item android:drawable="@drawable/stat_sys_gps_acquiring" android:duration="500" />
-    <item android:drawable="@drawable/stat_sys_gps_on" android:duration="500" />
+    <item android:drawable="@*android:drawable/stat_sys_gps_on" android:duration="500" />
 </animation-list>
diff --git a/core/res/res/drawable/stat_sys_roaming_cdma_flash.xml b/packages/SystemUI/res/drawable/stat_sys_roaming_cdma_flash.xml
similarity index 100%
rename from core/res/res/drawable/stat_sys_roaming_cdma_flash.xml
rename to packages/SystemUI/res/drawable/stat_sys_roaming_cdma_flash.xml
diff --git a/core/res/res/layout/battery_low.xml b/packages/SystemUI/res/layout/battery_low.xml
similarity index 100%
rename from core/res/res/layout/battery_low.xml
rename to packages/SystemUI/res/layout/battery_low.xml
diff --git a/core/res/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
similarity index 70%
rename from core/res/res/layout/status_bar.xml
rename to packages/SystemUI/res/layout/status_bar.xml
index 2237ee4..5fe8e79 100644
--- a/core/res/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -19,8 +19,9 @@
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
-<com.android.server.status.StatusBarView xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:background="@drawable/statusbar_background"
+<com.android.systemui.statusbar.StatusBarView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:background="@drawable/status_bar_background"
     android:orientation="vertical"
     android:focusable="true"
     android:descendantFocusability="afterDescendants"
@@ -31,7 +32,7 @@
         android:layout_height="match_parent"
         android:orientation="horizontal">
             
-        <com.android.server.status.IconMerger android:id="@+id/notificationIcons"
+        <com.android.systemui.statusbar.IconMerger android:id="@+id/notificationIcons"
             android:layout_width="0dip"
             android:layout_weight="1"
             android:layout_height="match_parent"
@@ -47,6 +48,17 @@
             android:paddingRight="6dip"
             android:gravity="center_vertical"
             android:orientation="horizontal"/>    
+
+        <com.android.systemui.statusbar.Clock
+            android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:singleLine="true"
+            android:paddingRight="6dip"
+            android:textSize="16sp"
+            android:textStyle="bold"
+            android:gravity="center_vertical|left"
+            />
     </LinearLayout>
         
     <LinearLayout android:id="@+id/ticker"
@@ -60,44 +72,44 @@
             android:layout_height="match_parent"
             android:layout_marginRight="8dip"
             >
-            <com.android.server.status.AnimatedImageView
+            <com.android.systemui.statusbar.AnimatedImageView
                 android:layout_width="25dip"
                 android:layout_height="25dip"
                 />
-            <com.android.server.status.AnimatedImageView
+            <com.android.systemui.statusbar.AnimatedImageView
                 android:layout_width="25dip"
                 android:layout_height="25dip"
                 />
         </ImageSwitcher>
-        <com.android.server.status.TickerView android:id="@+id/tickerText"
+        <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"
             android:layout_width="0dip"
             android:layout_weight="1"
             android:layout_height="wrap_content"
             android:paddingTop="2dip"
             android:paddingRight="10dip">
             <TextView
-                android:textAppearance="@style/TextAppearance.StatusBar.Ticker"
+                android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
                 />
             <TextView
-                android:textAppearance="@style/TextAppearance.StatusBar.Ticker"
+                android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:singleLine="true"
                 />
-        </com.android.server.status.TickerView>
+        </com.android.systemui.statusbar.TickerView>
     </LinearLayout>
 
-    <com.android.server.status.DateView android:id="@+id/date"
-        android:textAppearance="@style/TextAppearance.StatusBar.Icon"
+    <com.android.systemui.statusbar.DateView android:id="@+id/date"
+        android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:singleLine="true"
         android:gravity="center_vertical|left"
         android:paddingLeft="6px"
         android:paddingRight="6px"
-        android:background="@drawable/statusbar_background"
+        android:background="@drawable/status_bar_background"
         />
-</com.android.server.status.StatusBarView>
+</com.android.systemui.statusbar.StatusBarView>
diff --git a/core/res/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
similarity index 77%
rename from core/res/res/layout/status_bar_expanded.xml
rename to packages/SystemUI/res/layout/status_bar_expanded.xml
index 68eb922..b5b1b50 100644
--- a/core/res/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -18,7 +18,7 @@
 */
 -->
 
-<com.android.server.status.ExpandedView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.systemui.statusbar.ExpandedView xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:focusable="true"
     android:descendantFocusability="afterDescendants"
@@ -31,9 +31,9 @@
         android:paddingTop="3dp"
         android:paddingBottom="5dp"
         android:paddingRight="3dp"
-        android:background="@drawable/status_bar_header_background"
+        android:background="@drawable/shade_header_background"
         >
-        <LinearLayout
+        <com.android.systemui.statusbar.CarrierLabel
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
@@ -41,25 +41,10 @@
             android:layout_marginLeft="5dp"
             android:layout_gravity="center_vertical"
             android:paddingBottom="1dp"
-            android:orientation="vertical"
-            >
-                <TextView android:id="@+id/plmnLabel"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
-                    android:textAppearance="?android:attr/textAppearanceLarge"
-                    android:textColor="?android:attr/textColorSecondary"
-                    android:paddingLeft="4dp"
-                    />
-                <TextView android:id="@+id/spnLabel"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
-                    android:textAppearance="?android:attr/textAppearanceLarge"
-                    android:textColor="?android:attr/textColorSecondary"
-                    android:paddingLeft="4dp"
-                    />
-        </LinearLayout>
+            android:paddingLeft="4dp"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:textColor="?android:attr/textColorSecondary"
+            />
         <TextView android:id="@+id/clear_all_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -67,7 +52,7 @@
             android:layout_marginTop="4dp"
             android:layout_marginBottom="1dp"
             android:textSize="14sp"
-            android:textColor="?android:attr/textColorPrimaryInverse"
+            android:textColor="#ff000000"
             android:text="@string/status_bar_clear_all_button"
             style="?android:attr/buttonStyle"
             android:paddingLeft="15dp"
@@ -87,7 +72,7 @@
             android:layout_height="match_parent"
             android:fadingEdge="none"
             >
-            <com.android.server.status.NotificationLinearLayout
+            <com.android.systemui.statusbar.NotificationLinearLayout
                 android:id="@+id/notificationLinearLayout"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -130,7 +115,7 @@
                     android:layout_height="wrap_content"
                     android:orientation="vertical"
                     />
-            </com.android.server.status.NotificationLinearLayout>
+            </com.android.systemui.statusbar.NotificationLinearLayout>
         </ScrollView>
 
         <ImageView
@@ -141,4 +126,4 @@
         />
 
     </FrameLayout>
-</com.android.server.status.ExpandedView>
+</com.android.systemui.statusbar.ExpandedView>
diff --git a/core/res/res/layout/status_bar_icon.xml b/packages/SystemUI/res/layout/status_bar_icon.xml
similarity index 95%
rename from core/res/res/layout/status_bar_icon.xml
rename to packages/SystemUI/res/layout/status_bar_icon.xml
index 0536792..21d606f 100644
--- a/core/res/res/layout/status_bar_icon.xml
+++ b/packages/SystemUI/res/layout/status_bar_icon.xml
@@ -25,7 +25,7 @@
     android:layout_height="25dp"
     >
 
-    <com.android.server.status.AnimatedImageView android:id="@+id/image"
+    <com.android.systemui.statusbar.AnimatedImageView android:id="@+id/image"
         android:layout_width="match_parent" 
         android:layout_height="match_parent"
         />
diff --git a/core/res/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
similarity index 77%
rename from core/res/res/layout/status_bar_tracking.xml
rename to packages/SystemUI/res/layout/status_bar_tracking.xml
index c0a7a97..a2b40e6 100644
--- a/core/res/res/layout/status_bar_tracking.xml
+++ b/packages/SystemUI/res/layout/status_bar_tracking.xml
@@ -15,7 +15,8 @@
     limitations under the License.
 -->
 
-<com.android.server.status.TrackingView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.systemui.statusbar.TrackingView
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:visibility="gone"
     android:focusable="true"
@@ -25,13 +26,13 @@
     android:paddingRight="0px"
     >
 
-    <com.android.server.status.TrackingPatternView
+    <com.android.systemui.statusbar.TrackingPatternView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_weight="1"
         />
 
-    <com.android.server.status.CloseDragHandle android:id="@+id/close"
+    <com.android.systemui.statusbar.CloseDragHandle android:id="@+id/close"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
@@ -41,8 +42,9 @@
             android:layout_height="wrap_content"
             android:layout_gravity="bottom"
             android:scaleType="fitXY"
-            android:src="@drawable/status_bar_close_on"/>
+            android:src="@drawable/shade_handlebar"
+            />
 
-    </com.android.server.status.CloseDragHandle>
+    </com.android.systemui.statusbar.CloseDragHandle>
 
-</com.android.server.status.TrackingView>
+</com.android.systemui.statusbar.TrackingView>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
new file mode 100644
index 0000000..dbb0e0f
--- /dev/null
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, 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">
+
+    <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
+         icons in the status bar that are not notifications. -->
+    <string-array name="status_bar_icon_order">
+        <item><xliff:g id="id">TODO: Remove; not used.</xliff:g></item>
+    </string-array>
+
+</resources>
diff --git a/core/res/res/drawable/status_icon_background.xml b/packages/SystemUI/res/values/config.xml
similarity index 61%
rename from core/res/res/drawable/status_icon_background.xml
rename to packages/SystemUI/res/values/config.xml
index 9846165..8ea46e5 100644
--- a/core/res/res/drawable/status_icon_background.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/drawable/status_icon_background.xml
-**
-** Copyright 2007, The Android Open Source Project
+/*
+** Copyright 2009, 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. 
@@ -18,7 +17,10 @@
 */
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_selected="true" android:drawable="@drawable/icon_highlight_rectangle" />
-    <item android:drawable="@color/transparent" />
-</selector>
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds. -->
+<resources>
+    <!-- Control whether status bar should distinguish HSPA data icon form UMTS data icon on devices -->
+    <bool name="config_hspa_data_distinguishable">false</bool>
+</resources>
+
diff --git a/packages/SystemUI/res/values/defaults.xml b/packages/SystemUI/res/values/defaults.xml
new file mode 100644
index 0000000..34302c4
--- /dev/null
+++ b/packages/SystemUI/res/values/defaults.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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>
+    <bool name="def_dim_screen">true</bool>
+    <integer name="def_screen_off_timeout">60000</integer>
+    <bool name="def_airplane_mode_on">false</bool>
+    <!-- Comma-separated list of bluetooth, wifi, and cell. -->
+    <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
+    <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
+    <bool name="def_auto_time">true</bool>
+    <bool name="def_accelerometer_rotation">true</bool>
+    <!-- Default screen brightness, from 0 to 255.  102 is 40%. -->
+    <integer name="def_screen_brightness">102</integer>
+    <bool name="def_screen_brightness_automatic_mode">false</bool>
+    <fraction name="def_window_animation_scale">100%</fraction>
+    <fraction name="def_window_transition_scale">100%</fraction>
+    <bool name="def_haptic_feedback">true</bool>
+    
+    <bool name="def_bluetooth_on">false</bool>
+    <bool name="def_install_non_market_apps">false</bool>
+    <!-- Comma-separated list of location providers. 
+         Network location is off by default because it requires
+         user opt-in via Setup Wizard or Settings.  
+    -->
+    <string name="def_location_providers_allowed" translatable="false">gps</string>
+    <bool name="assisted_gps_enabled">true</bool>
+    <!--  0 == mobile, 1 == wifi. -->
+    <integer name="def_network_preference">1</integer>
+    <bool name="def_usb_mass_storage_enabled">true</bool>
+    <bool name="def_wifi_on">false</bool>
+    <bool name="def_networks_available_notification_on">true</bool>
+    
+    <bool name="def_backup_enabled">false</bool>
+    <string name="def_backup_transport" translatable="false"></string>
+    <!-- Default value for whether or not to pulse the notification LED when there is a 
+         pending notification -->
+    <bool name="def_notification_pulse">true</bool>
+
+    <bool name="def_mount_play_notification_snd">true</bool>
+    <bool name="def_mount_ums_autostart">false</bool>
+    <bool name="def_mount_ums_prompt">true</bool>
+    <bool name="def_mount_ums_notify_enabled">true</bool>
+    <!-- Enable User preference for setting install location -->
+    <bool name="set_install_location">true</bool>
+    <!-- Default install location if user preference for setting install location is turned on. -->
+    <integer name="def_install_location">2</integer>
+
+    <!-- user interface sound effects -->
+    <integer name="def_power_sounds_enabled">1</integer>
+    <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
+    <integer name="def_dock_sounds_enabled">0</integer>
+    <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
+    <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
+    <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
+    <string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
+    <integer name="def_lockscreen_sounds_enabled">0</integer>
+    <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
+    <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
+
+    <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
+    <bool name="def_vibrate_in_silent">true</bool>
+</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
new file mode 100644
index 0000000..93cf377
--- /dev/null
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2006, 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>
+    <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
+    <dimen name="status_bar_edge_ignore">5dp</dimen>
+</resources>
+
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
new file mode 100644
index 0000000..ba3a3d1
--- /dev/null
+++ b/packages/SystemUI/res/values/strings.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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">
+    <!-- Name of the status bar as seen in the applications info settings page. -->
+    <string name="app_label">Status Bar</string>
+
+    <!-- The text for the button in the notification window-shade that clears
+         all of the currently visible notifications. -->
+    <string name="status_bar_clear_all_button">Clear</string>
+
+    <!-- The label in the bar at the top of the status bar when there are no notifications
+         showing. -->
+    <string name="status_bar_no_notifications_title">No notifications</string>
+
+    <!-- The label for the group of notifications for ongoing events in the opened version of
+         the status bar.  An ongoing call is the prime example of this.  The MP3 music player
+         might be another example.  -->
+    <string name="status_bar_ongoing_events_title">Ongoing</string>
+
+    <!-- The label for the group of notifications for recent events in the opened version of
+         the status bar.  Recently received text messsages (SMS), emails, calendar alerts, etc. -->
+    <string name="status_bar_latest_events_title">Notifications</string>
+
+    <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert. -->
+    <string name="battery_low_title">Please connect charger</string>
+
+    <!-- When the battery is low, this is displayed to the user in a dialog. The subtitle of the low battery alert. -->
+    <string name="battery_low_subtitle">The battery is getting low:</string>
+
+    <!-- A message that appears when the battery level is getting low in a dialog.  This is appened to the subtitle of the low battery alert. -->
+    <string name="battery_low_percent_format"><xliff:g id="number">%d%%</xliff:g>
+    or less remaining.</string>
+
+    <!-- When the battery is low, this is the label of the button to go to the
+         power usage activity to find out what drained the battery. -->
+    <string name="battery_low_why">Battery use</string>
+
+</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
new file mode 100644
index 0000000..10fa930
--- /dev/null
+++ b/packages/SystemUI/res/values/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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:android="http://schemas.android.com/apk/res/android">
+
+    <style name="TextAppearance.StatusBar.Title" parent="@android:style/TextAppearance.StatusBar">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+    </style>
+
+
+
+</resources>
diff --git a/packages/SystemUI/res/xml/bookmarks.xml b/packages/SystemUI/res/xml/bookmarks.xml
new file mode 100644
index 0000000..dfaeeaf
--- /dev/null
+++ b/packages/SystemUI/res/xml/bookmarks.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<bookmarks>
+    <bookmark
+        package="com.android.browser"
+        class="com.android.browser.BrowserActivity"
+        shortcut="b" />
+    <bookmark
+        package="com.android.contacts"
+        class="com.android.contacts.DialtactsContactsEntryActivity"
+        shortcut="c" />
+    <bookmark
+        package="com.android.email"
+        class="com.android.email.activity.Welcome"
+        shortcut="e" />
+    <bookmark
+        package="com.google.android.gm"
+        class="com.google.android.gm.ConversationListActivityGmail"
+        shortcut="g" />
+    <bookmark
+        package="com.android.im"
+        class="com.android.im.app.LandingPage"
+        shortcut="i" />
+    <bookmark
+        package="com.android.calendar"
+        class="com.android.calendar.LaunchActivity"
+        shortcut="l" />
+<!--
+    <bookmark
+        package="com.google.android.apps.maps"
+        class="com.google.android.maps.MapsActivity"
+        shortcut="m" />
+-->
+    <bookmark
+        package="com.android.music"
+        class="com.android.music.MusicBrowserActivity"
+        shortcut="p" />
+    <bookmark
+        package="com.android.mms"
+        class="com.android.mms.ui.ConversationList"
+        shortcut="s" />
+</bookmarks>
diff --git a/services/java/com/android/server/status/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
similarity index 97%
rename from services/java/com/android/server/status/AnimatedImageView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index 97df065..70d4d6a 100644
--- a/services/java/com/android/server/status/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.graphics.drawable.AnimationDrawable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java
new file mode 100644
index 0000000..d89d093
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CarrierLabel.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2006 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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Telephony;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.TextView;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import com.android.internal.R;
+
+/**
+ * This widget display an analogic clock with two hands for hours and
+ * minutes.
+ */
+public class CarrierLabel extends TextView {
+    private boolean mAttached;
+
+    public CarrierLabel(Context context) {
+        this(context, null);
+    }
+
+    public CarrierLabel(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CarrierLabel(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        updateNetworkName(false, null, false, null);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (!mAttached) {
+            mAttached = true;
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+            getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mAttached) {
+            getContext().unregisterReceiver(mIntentReceiver);
+            mAttached = false;
+        }
+    }
+
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
+                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+            }
+        }
+    };
+
+    void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
+        if (false) {
+            Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
+        }
+        StringBuilder str = new StringBuilder();
+        boolean something = false;
+        if (showPlmn && plmn != null) {
+            str.append(plmn);
+            something = true;
+        }
+        if (showSpn && spn != null) {
+            if (something) {
+                str.append(' ');
+            }
+            str.append(spn);
+            something = true;
+        }
+        if (something) {
+            setText(str.toString());
+        } else {
+            setText(com.android.internal.R.string.lockscreen_carrier_default);
+        }
+    }
+
+    
+}
+
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/Clock.java
new file mode 100644
index 0000000..9fc8df5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/Clock.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2006 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;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.format.DateFormat;
+import android.text.style.CharacterStyle;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.StyleSpan;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import com.android.internal.R;
+
+/**
+ * This widget display an analogic clock with two hands for hours and
+ * minutes.
+ */
+public class Clock extends TextView {
+    private boolean mAttached;
+    private Calendar mCalendar;
+    private String mClockFormatString;
+    private SimpleDateFormat mClockFormat;
+
+    private static final int AM_PM_STYLE_NORMAL  = 0;
+    private static final int AM_PM_STYLE_SMALL   = 1;
+    private static final int AM_PM_STYLE_GONE    = 2;
+
+    private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
+
+    public Clock(Context context) {
+        this(context, null);
+    }
+
+    public Clock(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public Clock(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (!mAttached) {
+            mAttached = true;
+            IntentFilter filter = new IntentFilter();
+
+            filter.addAction(Intent.ACTION_TIME_TICK);
+            filter.addAction(Intent.ACTION_TIME_CHANGED);
+            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+            filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+
+            getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
+        }
+
+        // NOTE: It's safe to do these after registering the receiver since the receiver always runs
+        // in the main thread, therefore the receiver can't run before this method returns.
+
+        // The time zone may have changed while the receiver wasn't registered, so update the Time
+        mCalendar = Calendar.getInstance(TimeZone.getDefault());
+
+        // Make sure we update to the current time
+        updateClock();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mAttached) {
+            getContext().unregisterReceiver(mIntentReceiver);
+            mAttached = false;
+        }
+    }
+
+    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
+                String tz = intent.getStringExtra("time-zone");
+                mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));
+                if (mClockFormat != null) {
+                    mClockFormat.setTimeZone(mCalendar.getTimeZone());
+                }
+            }
+            updateClock();
+        }
+    };
+
+    final void updateClock() {
+        mCalendar.setTimeInMillis(System.currentTimeMillis());
+        setText(getSmallTime());
+    }
+
+    private final CharSequence getSmallTime() {
+        Context context = getContext();
+        boolean b24 = DateFormat.is24HourFormat(context);
+        int res;
+
+        if (b24) {
+            res = R.string.twenty_four_hour_time_format;
+        } else {
+            res = R.string.twelve_hour_time_format;
+        }
+
+        final char MAGIC1 = '\uEF00';
+        final char MAGIC2 = '\uEF01';
+
+        SimpleDateFormat sdf;
+        String format = context.getString(res);
+        if (!format.equals(mClockFormatString)) {
+            /*
+             * Search for an unquoted "a" in the format string, so we can
+             * add dummy characters around it to let us find it again after
+             * formatting and change its size.
+             */
+            if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
+                int a = -1;
+                boolean quoted = false;
+                for (int i = 0; i < format.length(); i++) {
+                    char c = format.charAt(i);
+
+                    if (c == '\'') {
+                        quoted = !quoted;
+                    }
+                    if (!quoted && c == 'a') {
+                        a = i;
+                        break;
+                    }
+                }
+
+                if (a >= 0) {
+                    // Move a back so any whitespace before AM/PM is also in the alternate size.
+                    final int b = a;
+                    while (a > 0 && Character.isWhitespace(format.charAt(a-1))) {
+                        a--;
+                    }
+                    format = format.substring(0, a) + MAGIC1 + format.substring(a, b)
+                        + "a" + MAGIC2 + format.substring(b + 1);
+                }
+            }
+
+            mClockFormat = sdf = new SimpleDateFormat(format);
+            mClockFormatString = format;
+        } else {
+            sdf = mClockFormat;
+        }
+        String result = sdf.format(mCalendar.getTime());
+
+        if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
+            int magic1 = result.indexOf(MAGIC1);
+            int magic2 = result.indexOf(MAGIC2);
+            if (magic1 >= 0 && magic2 > magic1) {
+                SpannableStringBuilder formatted = new SpannableStringBuilder(result);
+                if (AM_PM_STYLE == AM_PM_STYLE_GONE) {
+                    formatted.delete(magic1, magic2+1);
+                } else {
+                    if (AM_PM_STYLE == AM_PM_STYLE_SMALL) {
+                        CharacterStyle style = new RelativeSizeSpan(0.7f);
+                        formatted.setSpan(style, magic1, magic2,
+                                          Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
+                    }
+                    formatted.delete(magic2, magic2 + 1);
+                    formatted.delete(magic1, magic1 + 1);
+                }
+                return formatted;
+            }
+        }
+ 
+        return result;
+
+    }
+}
+
diff --git a/services/java/com/android/server/status/CloseDragHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java
similarity index 94%
rename from services/java/com/android/server/status/CloseDragHandle.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java
index ad1ac4d..0f6723e 100644
--- a/services/java/com/android/server/status/CloseDragHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -23,7 +23,7 @@
 
 
 public class CloseDragHandle extends LinearLayout {
-    StatusBarService mService;
+    PhoneStatusBarService mService;
 
     public CloseDragHandle(Context context, AttributeSet attrs) {
         super(context, attrs);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
new file mode 100644
index 0000000..f9347b1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2010 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;
+
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+
+import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.StatusBarNotification;
+
+/**
+ * This class takes the functions from IStatusBar that come in on
+ * binder pool threads and posts messages to get them onto the main
+ * thread, and calls onto Callbacks.  It also takes care of
+ * coalescing these calls so they don't stack up.  For the calls
+ * are coalesced, note that they are all idempotent.
+ */
+class CommandQueue extends IStatusBar.Stub {
+    private static final String TAG = "StatusBar.CommandQueue";
+
+    private static final int MSG_MASK = 0xffff0000;
+    private static final int INDEX_MASK = 0x0000ffff;
+
+    private static final int MSG_ICON = 0x00010000;
+    private static final int OP_SET_ICON = 1;
+    private static final int OP_REMOVE_ICON = 2;
+
+    private static final int MSG_ADD_NOTIFICATION = 0x00020000;
+    private static final int MSG_UPDATE_NOTIFICATION = 0x00030000;
+    private static final int MSG_REMOVE_NOTIFICATION = 0x00040000;
+
+    private static final int MSG_DISABLE = 0x00050000;
+
+    private static final int MSG_SET_VISIBILITY = 0x00060000;
+    private static final int OP_EXPAND = 1;
+    private static final int OP_COLLAPSE = 2;
+
+    private StatusBarIconList mList;
+    private Callbacks mCallbacks;
+    private Handler mHandler = new H();
+
+    private class NotificationQueueEntry {
+        IBinder key;
+        StatusBarNotification notification;
+    }
+
+    /**
+     * These methods are called back on the main thread.
+     */
+    public interface Callbacks {
+        public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon);
+        public void updateIcon(String slot, int index, int viewIndex,
+                StatusBarIcon old, StatusBarIcon icon);
+        public void removeIcon(String slot, int index, int viewIndex);
+        public void addNotification(IBinder key, StatusBarNotification notification);
+        public void updateNotification(IBinder key, StatusBarNotification notification);
+        public void removeNotification(IBinder key);
+        public void disable(int state);
+        public void animateExpand();
+        public void animateCollapse();
+    }
+
+    public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
+        mCallbacks = callbacks;
+        mList = list;
+    }
+
+    public void setIcon(int index, StatusBarIcon icon) {
+        synchronized (mList) {
+            int what = MSG_ICON | index;
+            mHandler.removeMessages(what);
+            mHandler.obtainMessage(what, OP_SET_ICON, 0, icon.clone()).sendToTarget();
+        }
+    }
+
+    public void removeIcon(int index) {
+        synchronized (mList) {
+            int what = MSG_ICON | index;
+            mHandler.removeMessages(what);
+            mHandler.obtainMessage(what, OP_REMOVE_ICON, 0, null).sendToTarget();
+        }
+    }
+
+    public void addNotification(IBinder key, StatusBarNotification notification) {
+        synchronized (mList) {
+            NotificationQueueEntry ne = new NotificationQueueEntry();
+            ne.key = key;
+            ne.notification = notification;
+            mHandler.obtainMessage(MSG_ADD_NOTIFICATION, 0, 0, ne).sendToTarget();
+        }
+    }
+
+    public void updateNotification(IBinder key, StatusBarNotification notification) {
+        synchronized (mList) {
+            NotificationQueueEntry ne = new NotificationQueueEntry();
+            ne.key = key;
+            ne.notification = notification;
+            mHandler.obtainMessage(MSG_UPDATE_NOTIFICATION, 0, 0, ne).sendToTarget();
+        }
+    }
+
+    public void removeNotification(IBinder key) {
+        synchronized (mList) {
+            mHandler.obtainMessage(MSG_REMOVE_NOTIFICATION, 0, 0, key).sendToTarget();
+        }
+    }
+
+    public void disable(int state) {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_DISABLE);
+            mHandler.obtainMessage(MSG_DISABLE, state, 0, null).sendToTarget();
+        }
+    }
+
+    public void animateExpand() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SET_VISIBILITY);
+            mHandler.obtainMessage(MSG_SET_VISIBILITY, OP_EXPAND, 0, null).sendToTarget();
+        }
+    }
+
+    public void animateCollapse() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SET_VISIBILITY);
+            mHandler.obtainMessage(MSG_SET_VISIBILITY, OP_COLLAPSE, 0, null).sendToTarget();
+        }
+    }
+
+    private final class H extends Handler {
+        public void handleMessage(Message msg) {
+            final int what = msg.what & MSG_MASK;
+            switch (what) {
+                case MSG_ICON: {
+                    final int index = msg.what & INDEX_MASK;
+                    final int viewIndex = mList.getViewIndex(index);
+                    switch (msg.arg1) {
+                        case OP_SET_ICON: {
+                            StatusBarIcon icon = (StatusBarIcon)msg.obj;
+                            StatusBarIcon old = mList.getIcon(index);
+                            if (old == null) {
+                                mList.setIcon(index, icon);
+                                mCallbacks.addIcon(mList.getSlot(index), index, viewIndex, icon);
+                            } else {
+                                mList.setIcon(index, icon);
+                                mCallbacks.updateIcon(mList.getSlot(index), index, viewIndex,
+                                        old, icon);
+                            }
+                            break;
+                        }
+                        case OP_REMOVE_ICON:
+                            mList.removeIcon(index);
+                            mCallbacks.removeIcon(mList.getSlot(index), index, viewIndex);
+                            break;
+                    }
+                    break;
+                }
+                case MSG_ADD_NOTIFICATION: {
+                    final NotificationQueueEntry ne = (NotificationQueueEntry)msg.obj;
+                    mCallbacks.addNotification(ne.key, ne.notification);
+                    break;
+                }
+                case MSG_UPDATE_NOTIFICATION: {
+                    final NotificationQueueEntry ne = (NotificationQueueEntry)msg.obj;
+                    mCallbacks.updateNotification(ne.key, ne.notification);
+                    break;
+                }
+                case MSG_REMOVE_NOTIFICATION: {
+                    mCallbacks.removeNotification((IBinder)msg.obj);
+                    break;
+                }
+                case MSG_DISABLE:
+                    mCallbacks.disable(msg.arg1);
+                    break;
+                case MSG_SET_VISIBILITY:
+                    if (msg.arg1 == OP_EXPAND) {
+                        mCallbacks.animateExpand();
+                    } else {
+                        mCallbacks.animateCollapse();
+                    }
+            }
+        }
+    }
+}
+
diff --git a/services/java/com/android/server/status/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DateView.java
similarity index 98%
rename from services/java/com/android/server/status/DateView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/DateView.java
index c04fb45..e6d3a7e 100644
--- a/services/java/com/android/server/status/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DateView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
diff --git a/services/java/com/android/server/status/ExpandedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java
similarity index 84%
rename from services/java/com/android/server/status/ExpandedView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java
index cb37f90..c5b901f 100644
--- a/services/java/com/android/server/status/ExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -27,7 +27,7 @@
 
 
 public class ExpandedView extends LinearLayout {
-    StatusBarService mService;
+    PhoneStatusBarService mService;
     int mPrevHeight = -1;
 
     public ExpandedView(Context context, AttributeSet attrs) {
@@ -50,9 +50,10 @@
          super.onLayout(changed, left, top, right, bottom);
          int height = bottom - top;
          if (height != mPrevHeight) {
-             //Slog.d(StatusBarService.TAG, "height changed old=" + mPrevHeight + " new=" + height);
+             //Slog.d(PhoneStatusBarService.TAG, "height changed old=" + mPrevHeight
+             //     + " new=" + height);
              mPrevHeight = height;
-             mService.updateExpandedViewPos(StatusBarService.EXPANDED_LEAVE_ALONE);
+             mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE);
          }
      }
 }
diff --git a/services/java/com/android/server/status/FixedSizeDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java
similarity index 97%
rename from services/java/com/android/server/status/FixedSizeDrawable.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java
index dbfcb2c..eb22b61 100644
--- a/services/java/com/android/server/status/FixedSizeDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FixedSizeDrawable.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.graphics.drawable.Drawable;
 import android.graphics.Canvas;
diff --git a/services/java/com/android/server/status/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
similarity index 80%
rename from services/java/com/android/server/status/IconMerger.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
index aa702ae..027bed4a 100644
--- a/services/java/com/android/server/status/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
@@ -14,23 +14,39 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.os.Handler;
 import android.util.AttributeSet;
+import android.util.Slog;
 import android.view.View;
 import android.widget.LinearLayout;
 
+import com.android.systemui.R;
+
 
 public class IconMerger extends LinearLayout {
-    StatusBarService service;
-    StatusBarIcon moreIcon;
+    private static final String TAG = "IconMerger";
+
+    private StatusBarIconView mMoreView;
 
     public IconMerger(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
+    public void addMoreView(StatusBarIconView v, LinearLayout.LayoutParams lp) {
+        super.addView(v, lp);
+        mMoreView = v;
+    }
+
+    public void addView(StatusBarIconView v, int index, LinearLayout.LayoutParams lp) {
+        if (index == 0) {
+            throw new RuntimeException("Attempt to put view before the more view: " + v);
+        }
+        super.addView(v, index, lp);
+    }
+
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
@@ -50,13 +66,12 @@
         }
 
         // find the first visible one that isn't the more icon
-        View moreView = null;
+        final StatusBarIconView moreView = mMoreView;
         int fitLeft = -1;
         int startIndex = -1;
         for (i=0; i<N; i++) {
             final View child = getChildAt(i);
-            if (com.android.internal.R.drawable.stat_notify_more == child.getId()) {
-                moreView = child;
+            if (child == moreView) {
                 startIndex = i+1;
             }
             else if (child.getVisibility() != GONE) {
@@ -66,7 +81,11 @@
         }
 
         if (moreView == null || startIndex < 0) {
-            throw new RuntimeException("Status Bar / IconMerger moreView == null");
+            return;
+            /*
+            throw new RuntimeException("Status Bar / IconMerger moreView == " + moreView
+                    + " startIndex=" + startIndex);
+            */
         }
         
         // if it fits without the more icon, then hide the more icon and update fitLeft
@@ -84,14 +103,14 @@
         int breakingPoint = fitLeft + extra + adjust;
         int number = 0;
         for (i=startIndex; i<N; i++) {
-            final View child = getChildAt(i);
+            final StatusBarIconView child = (StatusBarIconView)getChildAt(i);
             if (child.getVisibility() != GONE) {
                 int childLeft = child.getLeft();
                 int childRight = child.getRight();
                 if (childLeft < breakingPoint) {
                     // hide this one
                     child.layout(0, child.getTop(), 0, child.getBottom());
-                    int n = this.service.getIconNumberForView(child);
+                    int n = child.getStatusBarIcon().number;
                     if (n == 0) {
                         number += 1;
                     } else if (n > 0) {
@@ -115,7 +134,7 @@
         // and provide the value later.  We're the only one changing this value show it
         // should be ordered correctly.
         if (false) {
-            this.moreIcon.update(number);
+            // TODO this.moreIcon.update(number);
         } else {
             mBugWorkaroundNumber = number;
             mBugWorkaroundHandler.post(mBugWorkaroundRunnable);
@@ -126,8 +145,10 @@
     private Handler mBugWorkaroundHandler = new Handler();
     private Runnable mBugWorkaroundRunnable = new Runnable() {
         public void run() {
+            /* TODO
             IconMerger.this.moreIcon.update(mBugWorkaroundNumber);
             IconMerger.this.moreIcon.view.invalidate();
+            */
         }
     };
 }
diff --git a/services/java/com/android/server/status/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
similarity index 67%
copy from services/java/com/android/server/status/NotificationLinearLayout.java
copy to packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
index 2fdf956..1e89624 100644
--- a/services/java/com/android/server/status/NotificationLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
@@ -14,16 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.widget.LinearLayout;
+import android.util.Slog;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
 
+public class LatestItemView extends FrameLayout {
 
-public class NotificationLinearLayout extends LinearLayout {
-    public NotificationLinearLayout(Context context, AttributeSet attrs) {
+    public LatestItemView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
-}
 
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        return onTouchEvent(ev);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
new file mode 100644
index 0000000..7a82267
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import android.app.Notification;
+import android.os.IBinder;
+import android.view.View;
+
+import com.android.internal.statusbar.StatusBarNotification;
+
+import java.util.ArrayList;
+
+/**
+ * The list of currently displaying notifications.
+ */
+public class NotificationData {
+    public static final class Entry {
+        public IBinder key;
+        public StatusBarNotification notification;
+        public StatusBarIconView icon;
+        public View row; // the outer expanded view
+        public View content; // takes the click events and sends the PendingIntent
+        public View expanded; // the inflated RemoteViews
+    }
+    private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
+
+    public int size() {
+        return mEntries.size();
+    }
+
+    public Entry getEntryAt(int index) {
+        return mEntries.get(index);
+    }
+
+    public int findEntry(IBinder key) {
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.key == key) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public int add(IBinder key, StatusBarNotification notification, View row, View content,
+            View expanded, StatusBarIconView icon) {
+        Entry entry = new Entry();
+        entry.key = key;
+        entry.notification = notification;
+        entry.row = row;
+        entry.content = content;
+        entry.expanded = expanded;
+        entry.icon = icon;
+        final int index = chooseIndex(notification.notification.when);
+        mEntries.add(index, entry);
+        return index;
+    }
+
+    public Entry remove(IBinder key) {
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.key == key) {
+                mEntries.remove(i);
+                return entry;
+            }
+        }
+        return null;
+    }
+
+    private int chooseIndex(final long when) {
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.notification.notification.when > when) {
+                return i;
+            }
+        }
+        return N;
+    }
+
+    /**
+     * Return whether there are any visible items (i.e. items without an error).
+     */
+    public boolean hasVisibleItems() {
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.expanded != null) { // the view successfully inflated
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return whether there are any clearable items (that aren't errors).
+     */
+    public boolean hasClearableItems() {
+        final int N = mEntries.size();
+        for (int i=0; i<N; i++) {
+            Entry entry = mEntries.get(i);
+            if (entry.expanded != null) { // the view successfully inflated
+                if ((entry.notification.notification.flags & Notification.FLAG_NO_CLEAR) == 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/services/java/com/android/server/status/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java
similarity index 95%
rename from services/java/com/android/server/status/NotificationLinearLayout.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java
index 2fdf956..8105352 100644
--- a/services/java/com/android/server/status/NotificationLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLinearLayout.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
new file mode 100644
index 0000000..e9ae69a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -0,0 +1,1419 @@
+/*
+ * Copyright (C) 2010 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;
+
+import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarNotification;
+
+import android.app.ActivityManagerNative;
+import android.app.Dialog;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.LinearLayout;
+import android.widget.RemoteViews;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.FrameLayout;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.StatusBarPolicy;
+
+public class PhoneStatusBarService extends StatusBarService {
+    static final String TAG = "PhoneStatusBarService";
+    static final boolean SPEW = false;
+
+    public static final String ACTION_STATUSBAR_START
+            = "com.android.internal.policy.statusbar.START";
+
+    static final int EXPANDED_LEAVE_ALONE = -10000;
+    static final int EXPANDED_FULL_OPEN = -10001;
+
+    private static final int MSG_ANIMATE = 1000;
+    private static final int MSG_ANIMATE_REVEAL = 1001;
+
+    public interface NotificationCallbacks {
+        void onSetDisabled(int status);
+        void onClearAll();
+        void onNotificationClick(String pkg, String tag, int id);
+        void onPanelRevealed();
+    }
+
+    private class ExpandedDialog extends Dialog {
+        ExpandedDialog(Context context) {
+            super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
+        }
+
+        @Override
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
+            switch (event.getKeyCode()) {
+            case KeyEvent.KEYCODE_BACK:
+                if (!down) {
+                    animateCollapse();
+                }
+                return true;
+            }
+            return super.dispatchKeyEvent(event);
+        }
+    }
+
+    StatusBarPolicy mIconPolicy;
+    
+    int mHeight;
+    int mIconWidth;
+
+    Display mDisplay;
+    StatusBarView mStatusBarView;
+    int mPixelFormat;
+    H mHandler = new H();
+    Object mQueueLock = new Object();
+    
+    // icons
+    String[] mRightIconSlots;
+    LinearLayout mIcons;
+    IconMerger mNotificationIcons;
+    LinearLayout mStatusIcons;
+
+    // expanded notifications
+    Dialog mExpandedDialog;
+    ExpandedView mExpandedView;
+    WindowManager.LayoutParams mExpandedParams;
+    ScrollView mScrollView;
+    View mNotificationLinearLayout;
+    View mExpandedContents;
+    // top bar
+    TextView mNoNotificationsTitle;
+    TextView mClearButton;
+    // drag bar
+    CloseDragHandle mCloseView;
+    // ongoing
+    NotificationData mOngoing = new NotificationData();
+    TextView mOngoingTitle;
+    LinearLayout mOngoingItems;
+    // latest
+    NotificationData mLatest = new NotificationData();
+    TextView mLatestTitle;
+    LinearLayout mLatestItems;
+    // position
+    int[] mPositionTmp = new int[2];
+    boolean mExpanded;
+    boolean mExpandedVisible;
+
+    // the date view
+    DateView mDateView;
+
+    // the tracker view
+    TrackingView mTrackingView;
+    WindowManager.LayoutParams mTrackingParams;
+    int mTrackingPosition; // the position of the top of the tracking view.
+
+    // ticker
+    private Ticker mTicker;
+    private View mTickerView;
+    private boolean mTicking;
+    
+    // Tracking finger for opening/closing.
+    int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
+    boolean mTracking;
+    VelocityTracker mVelocityTracker;
+    
+    static final int ANIM_FRAME_DURATION = (1000/60);
+    
+    boolean mAnimating;
+    long mCurAnimationTime;
+    float mDisplayHeight;
+    float mAnimY;
+    float mAnimVel;
+    float mAnimAccel;
+    long mAnimLastTime;
+    boolean mAnimatingReveal = false;
+    int mViewDelta;
+    int[] mAbsPos = new int[2];
+    
+    // for disabling the status bar
+    int mDisabled = 0;
+
+    /**
+     * Construct the service, add the status bar view to the window manager
+     */
+    @Override
+    public void onCreate() {
+        // First set up our views and stuff.
+        mDisplay = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+        makeStatusBarView(this);
+
+        // Next, call super.onCreate(), which will populate our views.
+        super.onCreate();
+
+        // Lastly, call to the icon policy to install/update all the icons.
+        mIconPolicy = new StatusBarPolicy(this);
+    }
+
+    // ================================================================================
+    // Constructing the view
+    // ================================================================================
+    private void makeStatusBarView(Context context) {
+        Resources res = context.getResources();
+        mRightIconSlots = res.getStringArray(R.array.status_bar_icon_order);
+
+        mHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+        mIconWidth = mHeight;
+
+        ExpandedView expanded = (ExpandedView)View.inflate(context,
+                R.layout.status_bar_expanded, null);
+        expanded.mService = this;
+        StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null);
+        sb.mService = this;
+
+        // figure out which pixel-format to use for the status bar.
+        mPixelFormat = PixelFormat.TRANSLUCENT;
+        Drawable bg = sb.getBackground();
+        if (bg != null) {
+            mPixelFormat = bg.getOpacity();
+        }
+
+        mStatusBarView = sb;
+        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
+        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
+        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
+        mTickerView = sb.findViewById(R.id.ticker);
+        mDateView = (DateView)sb.findViewById(R.id.date);
+
+        mExpandedDialog = new ExpandedDialog(context);
+        mExpandedView = expanded;
+        mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);
+        mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle);
+        mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems);
+        mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle);
+        mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems);
+        mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
+        mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button);
+        mClearButton.setOnClickListener(mClearButtonListener);
+        mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
+        mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
+
+        mOngoingTitle.setVisibility(View.GONE);
+        mLatestTitle.setVisibility(View.GONE);
+        
+        mTicker = new MyTicker(context, sb);
+
+        TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
+        tickerView.mTicker = mTicker;
+
+        mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null);
+        mTrackingView.mService = this;
+        mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close);
+        mCloseView.mService = this;
+
+        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
+
+        // the more notifications icon
+        StatusBarIconView moreView = new StatusBarIconView(this, "more");
+        moreView.set(new StatusBarIcon(null, R.drawable.stat_notify_more, 0));
+        mNotificationIcons.addMoreView(moreView,
+                new LinearLayout.LayoutParams(mIconWidth, mHeight));
+
+        // set the inital view visibility
+        setAreThereNotifications();
+        mDateView.setVisibility(View.INVISIBLE);
+
+        // receive broadcasts
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        context.registerReceiver(mBroadcastReceiver, filter);
+    }
+
+    @Override
+    protected void addStatusBarView() {
+        final StatusBarView view = mStatusBarView;
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                mHeight,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
+                PixelFormat.RGBX_8888);
+        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
+        lp.setTitle("StatusBar");
+        // TODO lp.windowAnimations = R.style.Animation_StatusBar;
+
+        WindowManagerImpl.getDefault().addView(view, lp);
+    }
+
+    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
+        Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+                + " icon=" + icon);
+        StatusBarIconView view = new StatusBarIconView(this, slot);
+        view.set(icon);
+        mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconWidth, mHeight));
+    }
+
+    public void updateIcon(String slot, int index, int viewIndex,
+            StatusBarIcon old, StatusBarIcon icon) {
+        Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+                + " old=" + old + " icon=" + icon);
+        StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
+        view.set(icon);
+    }
+
+    public void removeIcon(String slot, int index, int viewIndex) {
+        Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
+        mStatusIcons.removeViewAt(viewIndex);
+    }
+
+    public void addNotification(IBinder key, StatusBarNotification notification) {
+        addNotificationViews(key, notification);
+
+        // show the ticker
+        tick(notification);
+
+        // Recalculate the position of the sliding windows and the titles.
+        setAreThereNotifications();
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+    }
+
+    public void updateNotification(IBinder key, StatusBarNotification notification) {
+        Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification);
+
+        NotificationData oldList;
+        int oldIndex = mOngoing.findEntry(key);
+        if (oldIndex >= 0) {
+            oldList = mOngoing;
+        } else {
+            oldIndex = mLatest.findEntry(key);
+            if (oldIndex < 0) {
+                Slog.w(TAG, "updateNotification for unknown key: " + key);
+                return;
+            }
+            oldList = mLatest;
+        }
+        final NotificationData.Entry oldEntry = oldList.getEntryAt(oldIndex);
+        final StatusBarNotification oldNotification = oldEntry.notification;
+        final RemoteViews oldContentView = oldNotification.notification.contentView;
+
+        final RemoteViews contentView = notification.notification.contentView;
+
+        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
+        // didn't change.
+        if (notification.notification.when == oldNotification.notification.when
+                && notification.isOngoing() == oldNotification.isOngoing()
+                && oldEntry.expanded != null
+                && contentView != null && oldContentView != null
+                && contentView.getPackage() != null
+                && oldContentView.getPackage() != null
+                && oldContentView.getPackage().equals(contentView.getPackage())
+                && oldContentView.getLayoutId() == contentView.getLayoutId()) {
+            Slog.d(TAG, "reusing notification");
+            oldEntry.notification = notification;
+            try {
+                // Reapply the RemoteViews
+                contentView.reapply(this, oldEntry.content);
+                // update the contentIntent
+                final PendingIntent contentIntent = notification.notification.contentIntent;
+                if (contentIntent != null) {
+                    oldEntry.content.setOnClickListener(new Launcher(contentIntent,
+                                notification.pkg, notification.tag, notification.id));
+                }
+            }
+            catch (RuntimeException e) {
+                // It failed to add cleanly.  Log, and remove the view from the panel.
+                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
+                removeNotificationViews(key);
+                addNotificationViews(key, notification);
+            }
+            // Update the icon.
+            oldEntry.icon.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
+                    notification.notification.iconLevel, notification.notification.number));
+        } else {
+            Slog.d(TAG, "not reusing notification");
+            removeNotificationViews(key);
+            addNotificationViews(key, notification);
+        }
+
+        // Restart the ticker if it's still running
+        tick(notification);
+
+        // Recalculate the position of the sliding windows and the titles.
+        setAreThereNotifications();
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+    }
+
+    public void removeNotification(IBinder key) {
+        Slog.d(TAG, "removeNotification key=" + key);
+        StatusBarNotification old = removeNotificationViews(key);
+
+        if (old != null) {
+            // Cancel the ticker if it's still running
+            mTicker.removeEntry(old);
+
+            // Recalculate the position of the sliding windows and the titles.
+            setAreThereNotifications();
+            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+        }
+    }
+
+    private int chooseIconIndex(boolean isOngoing, int viewIndex) {
+        final int latestSize = mLatest.size();
+        if (isOngoing) {
+            return latestSize + (mOngoing.size() - viewIndex);
+        } else {
+            return latestSize - viewIndex;
+        }
+    }
+
+    View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
+        Notification n = notification.notification;
+        RemoteViews remoteViews = n.contentView;
+        if (remoteViews == null) {
+            return null;
+        }
+
+        // create the row view
+        LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View row = inflater.inflate(com.android.internal.R.layout.status_bar_latest_event,
+                parent, false);
+
+        // bind the click event to the content area
+        ViewGroup content = (ViewGroup)row.findViewById(com.android.internal.R.id.content);
+        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+        content.setOnFocusChangeListener(mFocusChangeListener);
+        PendingIntent contentIntent = n.contentIntent;
+        if (contentIntent != null) {
+            content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
+                        notification.tag, notification.id));
+        }
+
+        View expanded = null;
+        Exception exception = null;
+        try {
+            expanded = remoteViews.apply(this, content);
+        }
+        catch (RuntimeException e) {
+            exception = e;
+        }
+        if (expanded == null) {
+            Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
+            row.setVisibility(View.GONE);
+        } else {
+            content.addView(expanded);
+            row.setDrawingCacheEnabled(true);
+        }
+
+        return new View[] { row, content, expanded };
+    }
+
+    void addNotificationViews(IBinder key, StatusBarNotification notification) {
+        NotificationData list;
+        ViewGroup parent;
+        final boolean isOngoing = notification.isOngoing();
+        if (isOngoing) {
+            list = mOngoing;
+            parent = mOngoingItems;
+        } else {
+            list = mLatest;
+            parent = mLatestItems;
+        }
+        // Construct the expanded view.
+        final View[] views = makeNotificationView(notification, parent);
+        final View row = views[0];
+        final View content = views[1];
+        final View expanded = views[2];
+        // Construct the icon.
+        StatusBarIconView iconView = new StatusBarIconView(this,
+                notification.pkg + "/0x" + Integer.toHexString(notification.id));
+        iconView.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
+                    notification.notification.iconLevel, notification.notification.number));
+        // Add the expanded view.
+        final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
+        parent.addView(row, viewIndex);
+        // Add the icon.
+        final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
+        mNotificationIcons.addView(iconView, iconIndex,
+                new LinearLayout.LayoutParams(mIconWidth, mHeight));
+    }
+
+    StatusBarNotification removeNotificationViews(IBinder key) {
+        NotificationData.Entry entry = mOngoing.remove(key);
+        if (entry == null) {
+            entry = mLatest.remove(key);
+            if (entry == null) {
+                Slog.w(TAG, "removeNotification for unknown key: " + key);
+                return null;
+            }
+        }
+        // Remove the expanded view.
+        ((ViewGroup)entry.row.getParent()).removeView(entry.row);
+        // Remove the icon.
+        ((ViewGroup)entry.icon.getParent()).removeView(entry.icon);
+
+        return entry.notification;
+    }
+
+    private void setAreThereNotifications() {
+        boolean ongoing = mOngoing.hasVisibleItems();
+        boolean latest = mLatest.hasVisibleItems();
+
+        // (no ongoing notifications are clearable)
+        if (mLatest.hasClearableItems()) {
+            mClearButton.setVisibility(View.VISIBLE);
+        } else {
+            mClearButton.setVisibility(View.INVISIBLE);
+        }
+
+        mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
+        mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
+
+        if (ongoing || latest) {
+            mNoNotificationsTitle.setVisibility(View.GONE);
+        } else {
+            mNoNotificationsTitle.setVisibility(View.VISIBLE);
+        }
+    }
+
+
+    /**
+     * State is one or more of the DISABLE constants from StatusBarManager.
+     */
+    public void disable(int state) {
+        final int old = mDisabled;
+        final int diff = state ^ old;
+        mDisabled = state;
+
+        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
+            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
+                Slog.d(TAG, "DISABLE_EXPAND: yes");
+                animateCollapse();
+            }
+        }
+        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
+                if (mTicking) {
+                    mTicker.halt();
+                } else {
+                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
+                }
+            } else {
+                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
+                if (!mExpandedVisible) {
+                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
+                }
+            }
+        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
+            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
+                Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");
+                mTicker.halt();
+            }
+        }
+    }
+
+    /**
+     * All changes to the status bar and notifications funnel through here and are batched.
+     */
+    private class H extends Handler {
+        public void handleMessage(Message m) {
+            switch (m.what) {
+                case MSG_ANIMATE:
+                    doAnimation();
+                    break;
+                case MSG_ANIMATE_REVEAL:
+                    doRevealAnimation();
+                    break;
+            }
+        }
+    }
+
+    View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
+        public void onFocusChange(View v, boolean hasFocus) {
+            // Because 'v' is a ViewGroup, all its children will be (un)selected
+            // too, which allows marqueeing to work.
+            v.setSelected(hasFocus);
+        }
+    };
+
+    private void makeExpandedVisible() {
+        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
+        if (mExpandedVisible) {
+            return;
+        }
+        mExpandedVisible = true;
+        visibilityChanged(true);
+        
+        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+        mExpandedView.requestFocus(View.FOCUS_FORWARD);
+        mTrackingView.setVisibility(View.VISIBLE);
+        
+        if (!mTicking) {
+            setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
+        }
+    }
+    
+    public void animateExpand() {
+        if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
+        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+            return ;
+        }
+        if (mExpanded) {
+            return;
+        }
+
+        prepareTracking(0, true);
+        performFling(0, 2000.0f, true);
+    }
+    
+    public void animateCollapse() {
+        if (SPEW) {
+            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
+                    + " mExpandedVisible=" + mExpandedVisible
+                    + " mExpanded=" + mExpanded
+                    + " mAnimating=" + mAnimating
+                    + " mAnimY=" + mAnimY
+                    + " mAnimVel=" + mAnimVel);
+        }
+        
+        if (!mExpandedVisible) {
+            return;
+        }
+
+        int y;
+        if (mAnimating) {
+            y = (int)mAnimY;
+        } else {
+            y = mDisplay.getHeight()-1;
+        }
+        // Let the fling think that we're open so it goes in the right direction
+        // and doesn't try to re-open the windowshade.
+        mExpanded = true;
+        prepareTracking(y, false);
+        performFling(y, -2000.0f, true);
+    }
+    
+    void performExpand() {
+        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);
+        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+            return ;
+        }
+        if (mExpanded) {
+            return;
+        }
+
+        mExpanded = true;
+        makeExpandedVisible();
+        updateExpandedViewPos(EXPANDED_FULL_OPEN);
+
+        if (false) postStartTracing();
+    }
+
+    void performCollapse() {
+        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
+                + " mExpandedVisible=" + mExpandedVisible);
+        
+        if (!mExpandedVisible) {
+            return;
+        }
+        mExpandedVisible = false;
+        visibilityChanged(false);
+        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+        mTrackingView.setVisibility(View.GONE);
+
+        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
+            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
+        }
+        setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
+        
+        if (!mExpanded) {
+            return;
+        }
+        mExpanded = false;
+    }
+
+    void doAnimation() {
+        if (mAnimating) {
+            if (SPEW) Slog.d(TAG, "doAnimation");
+            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
+            incrementAnim();
+            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
+            if (mAnimY >= mDisplay.getHeight()-1) {
+                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
+                mAnimating = false;
+                updateExpandedViewPos(EXPANDED_FULL_OPEN);
+                performExpand();
+            }
+            else if (mAnimY < mStatusBarView.getHeight()) {
+                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
+                mAnimating = false;
+                updateExpandedViewPos(0);
+                performCollapse();
+            }
+            else {
+                updateExpandedViewPos((int)mAnimY);
+                mCurAnimationTime += ANIM_FRAME_DURATION;
+                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
+            }
+        }
+    }
+
+    void stopTracking() {
+        mTracking = false;
+        mVelocityTracker.recycle();
+        mVelocityTracker = null;
+    }
+
+    void incrementAnim() {
+        long now = SystemClock.uptimeMillis();
+        float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s
+        final float y = mAnimY;
+        final float v = mAnimVel;                                   // px/s
+        final float a = mAnimAccel;                                 // px/s/s
+        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
+        mAnimVel = v + (a*t);                                       // px/s
+        mAnimLastTime = now;                                        // ms
+        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
+        //        + " mAnimAccel=" + mAnimAccel);
+    }
+
+    void doRevealAnimation() {
+        final int h = mCloseView.getHeight() + mStatusBarView.getHeight();
+        if (mAnimatingReveal && mAnimating && mAnimY < h) {
+            incrementAnim();
+            if (mAnimY >= h) {
+                mAnimY = h;
+                updateExpandedViewPos((int)mAnimY);
+            } else {
+                updateExpandedViewPos((int)mAnimY);
+                mCurAnimationTime += ANIM_FRAME_DURATION;
+                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
+                        mCurAnimationTime);
+            }
+        }
+    }
+    
+    void prepareTracking(int y, boolean opening) {
+        mTracking = true;
+        mVelocityTracker = VelocityTracker.obtain();
+        if (opening) {
+            mAnimAccel = 2000.0f;
+            mAnimVel = 200;
+            mAnimY = mStatusBarView.getHeight();
+            updateExpandedViewPos((int)mAnimY);
+            mAnimating = true;
+            mAnimatingReveal = true;
+            mHandler.removeMessages(MSG_ANIMATE);
+            mHandler.removeMessages(MSG_ANIMATE_REVEAL);
+            long now = SystemClock.uptimeMillis();
+            mAnimLastTime = now;
+            mCurAnimationTime = now + ANIM_FRAME_DURATION;
+            mAnimating = true;
+            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
+                    mCurAnimationTime);
+            makeExpandedVisible();
+        } else {
+            // it's open, close it?
+            if (mAnimating) {
+                mAnimating = false;
+                mHandler.removeMessages(MSG_ANIMATE);
+            }
+            updateExpandedViewPos(y + mViewDelta);
+        }
+    }
+    
+    void performFling(int y, float vel, boolean always) {
+        mAnimatingReveal = false;
+        mDisplayHeight = mDisplay.getHeight();
+
+        mAnimY = y;
+        mAnimVel = vel;
+
+        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
+
+        if (mExpanded) {
+            if (!always && (
+                    vel > 200.0f
+                    || (y > (mDisplayHeight-25) && vel > -200.0f))) {
+                // We are expanded, but they didn't move sufficiently to cause
+                // us to retract.  Animate back to the expanded position.
+                mAnimAccel = 2000.0f;
+                if (vel < 0) {
+                    mAnimVel = 0;
+                }
+            }
+            else {
+                // We are expanded and are now going to animate away.
+                mAnimAccel = -2000.0f;
+                if (vel > 0) {
+                    mAnimVel = 0;
+                }
+            }
+        } else {
+            if (always || (
+                    vel > 200.0f
+                    || (y > (mDisplayHeight/2) && vel > -200.0f))) {
+                // We are collapsed, and they moved enough to allow us to
+                // expand.  Animate in the notifications.
+                mAnimAccel = 2000.0f;
+                if (vel < 0) {
+                    mAnimVel = 0;
+                }
+            }
+            else {
+                // We are collapsed, but they didn't move sufficiently to cause
+                // us to retract.  Animate back to the collapsed position.
+                mAnimAccel = -2000.0f;
+                if (vel > 0) {
+                    mAnimVel = 0;
+                }
+            }
+        }
+        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
+        //        + " mAnimAccel=" + mAnimAccel);
+
+        long now = SystemClock.uptimeMillis();
+        mAnimLastTime = now;
+        mCurAnimationTime = now + ANIM_FRAME_DURATION;
+        mAnimating = true;
+        mHandler.removeMessages(MSG_ANIMATE);
+        mHandler.removeMessages(MSG_ANIMATE_REVEAL);
+        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
+        stopTracking();
+    }
+    
+    boolean interceptTouchEvent(MotionEvent event) {
+        if (SPEW) {
+            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
+                + mDisabled);
+        }
+
+        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+            return false;
+        }
+        
+        final int statusBarSize = mStatusBarView.getHeight();
+        final int hitSize = statusBarSize*2;
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            final int y = (int)event.getRawY();
+
+            if (!mExpanded) {
+                mViewDelta = statusBarSize - y;
+            } else {
+                mTrackingView.getLocationOnScreen(mAbsPos);
+                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
+            }
+            if ((!mExpanded && y < hitSize) ||
+                    (mExpanded && y > (mDisplay.getHeight()-hitSize))) {
+
+                // We drop events at the edge of the screen to make the windowshade come
+                // down by accident less, especially when pushing open a device with a keyboard
+                // that rotates (like g1 and droid)
+                int x = (int)event.getRawX();
+                final int edgeBorder = mEdgeBorder;
+                if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) {
+                    prepareTracking(y, !mExpanded);// opening if we're not already fully visible
+                    mVelocityTracker.addMovement(event);
+                }
+            }
+        } else if (mTracking) {
+            mVelocityTracker.addMovement(event);
+            final int minY = statusBarSize + mCloseView.getHeight();
+            if (event.getAction() == MotionEvent.ACTION_MOVE) {
+                int y = (int)event.getRawY();
+                if (mAnimatingReveal && y < minY) {
+                    // nothing
+                } else  {
+                    mAnimatingReveal = false;
+                    updateExpandedViewPos(y + mViewDelta);
+                }
+            } else if (event.getAction() == MotionEvent.ACTION_UP) {
+                mVelocityTracker.computeCurrentVelocity(1000);
+
+                float yVel = mVelocityTracker.getYVelocity();
+                boolean negative = yVel < 0;
+
+                float xVel = mVelocityTracker.getXVelocity();
+                if (xVel < 0) {
+                    xVel = -xVel;
+                }
+                if (xVel > 150.0f) {
+                    xVel = 150.0f; // limit how much we care about the x axis
+                }
+
+                float vel = (float)Math.hypot(yVel, xVel);
+                if (negative) {
+                    vel = -vel;
+                }
+                
+                performFling((int)event.getRawY(), vel, false);
+            }
+            
+        }
+        return false;
+    }
+
+    private class Launcher implements View.OnClickListener {
+        private PendingIntent mIntent;
+        private String mPkg;
+        private String mTag;
+        private int mId;
+
+        Launcher(PendingIntent intent, String pkg, String tag, int id) {
+            mIntent = intent;
+            mPkg = pkg;
+            mTag = tag;
+            mId = id;
+        }
+
+        public void onClick(View v) {
+            try {
+                // The intent we are sending is for the application, which
+                // won't have permission to immediately start an activity after
+                // the user switches to home.  We know it is safe to do at this
+                // point, so make sure new activity switches are now allowed.
+                ActivityManagerNative.getDefault().resumeAppSwitches();
+            } catch (RemoteException e) {
+            }
+            int[] pos = new int[2];
+            v.getLocationOnScreen(pos);
+            Intent overlay = new Intent();
+            overlay.setSourceBounds(
+                    new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
+            try {
+                mIntent.send(PhoneStatusBarService.this, 0, overlay);
+            } catch (PendingIntent.CanceledException e) {
+                // the stack trace isn't very helpful here.  Just log the exception message.
+                Slog.w(TAG, "Sending contentIntent failed: " + e);
+            }
+            try {
+                mBarService.onNotificationClick(mPkg, mTag, mId);
+            } catch (RemoteException ex) {
+                // system process is dead if we're here.
+            }
+            animateCollapse();
+        }
+    }
+
+    private void tick(StatusBarNotification n) {
+        // Show the ticker if one is requested. Also don't do this
+        // until status bar window is attached to the window manager,
+        // because...  well, what's the point otherwise?  And trying to
+        // run a ticker without being attached will crash!
+        if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) {
+            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
+                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
+                mTicker.addEntry(n);
+            }
+        }
+    }
+
+    private class MyTicker extends Ticker {
+        MyTicker(Context context, StatusBarView sb) {
+            super(context, sb);
+        }
+        
+        @Override
+        void tickerStarting() {
+            mTicking = true;
+            mIcons.setVisibility(View.GONE);
+            mTickerView.setVisibility(View.VISIBLE);
+            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
+            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
+            if (mExpandedVisible) {
+                setDateViewVisibility(false, com.android.internal.R.anim.push_up_out);
+            }
+        }
+
+        @Override
+        void tickerDone() {
+            mIcons.setVisibility(View.VISIBLE);
+            mTickerView.setVisibility(View.GONE);
+            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
+            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
+                        mTickingDoneListener));
+            if (mExpandedVisible) {
+                setDateViewVisibility(true, com.android.internal.R.anim.push_down_in);
+            }
+        }
+
+        void tickerHalting() {
+            mIcons.setVisibility(View.VISIBLE);
+            mTickerView.setVisibility(View.GONE);
+            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
+            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
+                        mTickingDoneListener));
+            if (mExpandedVisible) {
+                setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
+            }
+        }
+    }
+
+    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
+        public void onAnimationEnd(Animation animation) {
+            mTicking = false;
+        }
+        public void onAnimationRepeat(Animation animation) {
+        }
+        public void onAnimationStart(Animation animation) {
+        }
+    };
+
+    private Animation loadAnim(int id, Animation.AnimationListener listener) {
+        Animation anim = AnimationUtils.loadAnimation(PhoneStatusBarService.this, id);
+        if (listener != null) {
+            anim.setAnimationListener(listener);
+        }
+        return anim;
+    }
+
+    public String viewInfo(View v) {
+        return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
+                + " " + v.getWidth() + "x" + v.getHeight() + ")";
+    }
+
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump StatusBar from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+        
+        synchronized (mQueueLock) {
+            pw.println("Current Status Bar state:");
+            pw.println("  mExpanded=" + mExpanded
+                    + ", mExpandedVisible=" + mExpandedVisible);
+            pw.println("  mTicking=" + mTicking);
+            pw.println("  mTracking=" + mTracking);
+            pw.println("  mAnimating=" + mAnimating
+                    + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
+                    + ", mAnimAccel=" + mAnimAccel);
+            pw.println("  mCurAnimationTime=" + mCurAnimationTime
+                    + " mAnimLastTime=" + mAnimLastTime);
+            pw.println("  mDisplayHeight=" + mDisplayHeight
+                    + " mAnimatingReveal=" + mAnimatingReveal
+                    + " mViewDelta=" + mViewDelta);
+            pw.println("  mDisplayHeight=" + mDisplayHeight);
+            pw.println("  mExpandedParams: " + mExpandedParams);
+            pw.println("  mExpandedView: " + viewInfo(mExpandedView));
+            pw.println("  mExpandedDialog: " + mExpandedDialog);
+            pw.println("  mTrackingParams: " + mTrackingParams);
+            pw.println("  mTrackingView: " + viewInfo(mTrackingView));
+            pw.println("  mOngoingTitle: " + viewInfo(mOngoingTitle));
+            pw.println("  mOngoingItems: " + viewInfo(mOngoingItems));
+            pw.println("  mLatestTitle: " + viewInfo(mLatestTitle));
+            pw.println("  mLatestItems: " + viewInfo(mLatestItems));
+            pw.println("  mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
+            pw.println("  mCloseView: " + viewInfo(mCloseView));
+            pw.println("  mTickerView: " + viewInfo(mTickerView));
+            pw.println("  mScrollView: " + viewInfo(mScrollView)
+                    + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
+            pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));
+        }
+        /*
+        synchronized (mNotificationData) {
+            int N = mNotificationData.ongoingCount();
+            pw.println("  ongoingCount.size=" + N);
+            for (int i=0; i<N; i++) {
+                StatusBarNotification n = mNotificationData.getOngoing(i);
+                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
+                pw.println("           data=" + n.data);
+            }
+            N = mNotificationData.latestCount();
+            pw.println("  ongoingCount.size=" + N);
+            for (int i=0; i<N; i++) {
+                StatusBarNotification n = mNotificationData.getLatest(i);
+                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
+                pw.println("           data=" + n.data);
+            }
+        }
+        */
+        
+        if (false) {
+            pw.println("see the logcat for a dump of the views we have created.");
+            // must happen on ui thread
+            mHandler.post(new Runnable() {
+                    public void run() {
+                        mStatusBarView.getLocationOnScreen(mAbsPos);
+                        Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+                                + ") " + mStatusBarView.getWidth() + "x"
+                                + mStatusBarView.getHeight());
+                        mStatusBarView.debug();
+
+                        mExpandedView.getLocationOnScreen(mAbsPos);
+                        Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+                                + ") " + mExpandedView.getWidth() + "x"
+                                + mExpandedView.getHeight());
+                        mExpandedView.debug();
+
+                        mTrackingView.getLocationOnScreen(mAbsPos);
+                        Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+                                + ") " + mTrackingView.getWidth() + "x"
+                                + mTrackingView.getHeight());
+                        mTrackingView.debug();
+                    }
+                });
+        }
+    }
+
+    void onBarViewAttached() {
+        WindowManager.LayoutParams lp;
+        int pixelFormat;
+        Drawable bg;
+
+        /// ---------- Tracking View --------------
+        pixelFormat = PixelFormat.RGBX_8888;
+        bg = mTrackingView.getBackground();
+        if (bg != null) {
+            pixelFormat = bg.getOpacity();
+        }
+
+        lp = new WindowManager.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                pixelFormat);
+//        lp.token = mStatusBarView.getWindowToken();
+        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
+        lp.setTitle("TrackingView");
+        lp.y = mTrackingPosition;
+        mTrackingParams = lp;
+
+        WindowManagerImpl.getDefault().addView(mTrackingView, lp);
+    }
+
+    void onTrackingViewAttached() {
+        WindowManager.LayoutParams lp;
+        int pixelFormat;
+        Drawable bg;
+
+        /// ---------- Expanded View --------------
+        pixelFormat = PixelFormat.TRANSLUCENT;
+
+        final int disph = mDisplay.getHeight();
+        lp = mExpandedDialog.getWindow().getAttributes();
+        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
+        lp.height = getExpandedHeight();
+        lp.x = 0;
+        mTrackingPosition = lp.y = -disph; // sufficiently large negative
+        lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+        lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_DITHER
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        lp.format = pixelFormat;
+        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
+        lp.setTitle("StatusBarExpanded");
+        mExpandedDialog.getWindow().setAttributes(lp);
+        mExpandedDialog.getWindow().setFormat(pixelFormat);
+        mExpandedParams = lp;
+
+        mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+        mExpandedDialog.setContentView(mExpandedView,
+                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+                                           ViewGroup.LayoutParams.MATCH_PARENT));
+        mExpandedDialog.getWindow().setBackgroundDrawable(null);
+        mExpandedDialog.show();
+        FrameLayout hack = (FrameLayout)mExpandedView.getParent();
+    }
+
+    void setDateViewVisibility(boolean visible, int anim) {
+        mDateView.setUpdates(visible);
+        mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+        mDateView.startAnimation(loadAnim(anim, null));
+    }
+
+    void setNotificationIconVisibility(boolean visible, int anim) {
+        int old = mNotificationIcons.getVisibility();
+        int v = visible ? View.VISIBLE : View.INVISIBLE;
+        if (old != v) {
+            mNotificationIcons.setVisibility(v);
+            mNotificationIcons.startAnimation(loadAnim(anim, null));
+        }
+    }
+
+    void updateExpandedViewPos(int expandedPosition) {
+        if (SPEW) {
+            Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
+                    + " mTrackingParams.y=" + mTrackingParams.y
+                    + " mTrackingPosition=" + mTrackingPosition);
+        }
+
+        int h = mStatusBarView.getHeight();
+        int disph = mDisplay.getHeight();
+
+        // If the expanded view is not visible, make sure they're still off screen.
+        // Maybe the view was resized.
+        if (!mExpandedVisible) {
+            if (mTrackingView != null) {
+                mTrackingPosition = -disph;
+                if (mTrackingParams != null) {
+                    mTrackingParams.y = mTrackingPosition;
+                    WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
+                }
+            }
+            if (mExpandedParams != null) {
+                mExpandedParams.y = -disph;
+                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+            }
+            return;
+        }
+
+        // tracking view...
+        int pos;
+        if (expandedPosition == EXPANDED_FULL_OPEN) {
+            pos = h;
+        }
+        else if (expandedPosition == EXPANDED_LEAVE_ALONE) {
+            pos = mTrackingPosition;
+        }
+        else {
+            if (expandedPosition <= disph) {
+                pos = expandedPosition;
+            } else {
+                pos = disph;
+            }
+            pos -= disph-h;
+        }
+        mTrackingPosition = mTrackingParams.y = pos;
+        mTrackingParams.height = disph-h;
+        WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
+
+        if (mExpandedParams != null) {
+            mCloseView.getLocationInWindow(mPositionTmp);
+            final int closePos = mPositionTmp[1];
+
+            mExpandedContents.getLocationInWindow(mPositionTmp);
+            final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
+
+            mExpandedParams.y = pos + mTrackingView.getHeight()
+                    - (mTrackingParams.height-closePos) - contentsBottom;
+            int max = h;
+            if (mExpandedParams.y > max) {
+                mExpandedParams.y = max;
+            }
+            int min = mTrackingPosition;
+            if (mExpandedParams.y < min) {
+                mExpandedParams.y = min;
+            }
+
+            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
+            if (!visible) {
+                // if the contents aren't visible, move the expanded view way off screen
+                // because the window itself extends below the content view.
+                mExpandedParams.y = -disph;
+            }
+            visibilityChanged(visible);
+            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+        }
+
+        if (SPEW) {
+            Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition
+                    + " mTrackingParams.y=" + mTrackingParams.y
+                    + " mTrackingPosition=" + mTrackingPosition
+                    + " mExpandedParams.y=" + mExpandedParams.y
+                    + " mExpandedParams.height=" + mExpandedParams.height);
+        }
+    }
+
+    int getExpandedHeight() {
+        return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();
+    }
+
+    void updateExpandedHeight() {
+        if (mExpandedView != null) {
+            mExpandedParams.height = getExpandedHeight();
+            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
+        }
+    }
+
+    /**
+     * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
+     * This was added last-minute and is inconsistent with the way the rest of the notifications
+     * are handled, because the notification isn't really cancelled.  The lights are just
+     * turned off.  If any other notifications happen, the lights will turn back on.  Steve says
+     * this is what he wants. (see bug 1131461)
+     */
+    private boolean mPanelSlightlyVisible;
+    void visibilityChanged(boolean visible) {
+        if (mPanelSlightlyVisible != visible) {
+            mPanelSlightlyVisible = visible;
+            try {
+                mBarService.visibilityChanged(visible);
+            } catch (RemoteException ex) {
+                // Won't fail unless the world has ended.
+            }
+        }
+    }
+
+    void performDisableActions(int net) {
+        int old = mDisabled;
+        int diff = net ^ old;
+        mDisabled = net;
+
+        // act accordingly
+        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
+            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
+                Slog.d(TAG, "DISABLE_EXPAND: yes");
+                animateCollapse();
+            }
+        }
+        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
+                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
+                if (mTicking) {
+                    mNotificationIcons.setVisibility(View.INVISIBLE);
+                    mTicker.halt();
+                } else {
+                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
+                }
+            } else {
+                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
+                if (!mExpandedVisible) {
+                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
+                }
+            }
+        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
+            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
+                mTicker.halt();
+            }
+        }
+    }
+
+    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            try {
+                mBarService.onClearAllNotifications();
+            } catch (RemoteException ex) {
+                // system process is dead if we're here.
+            }
+            animateCollapse();
+        }
+    };
+
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
+                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
+                //collapse();
+            }
+            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+                updateResources();
+            }
+        }
+    };
+
+    /**
+     * Reload some of our resources when the configuration changes.
+     * 
+     * We don't reload everything when the configuration changes -- we probably
+     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
+     * meantime, just update the things that we know change.
+     */
+    void updateResources() {
+        Resources res = getResources();
+
+        mClearButton.setText(getText(R.string.status_bar_clear_all_button));
+        mOngoingTitle.setText(getText(R.string.status_bar_ongoing_events_title));
+        mLatestTitle.setText(getText(R.string.status_bar_latest_events_title));
+        mNoNotificationsTitle.setText(getText(R.string.status_bar_no_notifications_title));
+
+        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
+
+        if (false) Slog.v(TAG, "updateResources");
+    }
+
+    //
+    // tracing
+    //
+
+    void postStartTracing() {
+        mHandler.postDelayed(mStartTracing, 3000);
+    }
+
+    void vibrate() {
+        android.os.Vibrator vib = (android.os.Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+        vib.vibrate(250);
+    }
+
+    Runnable mStartTracing = new Runnable() {
+        public void run() {
+            vibrate();
+            SystemClock.sleep(250);
+            Slog.d(TAG, "startTracing");
+            android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
+            mHandler.postDelayed(mStopTracing, 10000);
+        }
+    };
+
+    Runnable mStopTracing = new Runnable() {
+        public void run() {
+            android.os.Debug.stopMethodTracing();
+            Slog.d(TAG, "stopTracing");
+            vibrate();
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
new file mode 100644
index 0000000..5eb0d683
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -0,0 +1,134 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.Canvas;
+import android.util.Slog;
+import android.view.ViewDebug;
+import android.widget.FrameLayout;
+
+import com.android.internal.statusbar.StatusBarIcon;
+
+public class StatusBarIconView extends AnimatedImageView {
+    private static final String TAG = "StatusBarIconView";
+
+    private StatusBarIcon mIcon;
+    @ViewDebug.ExportedProperty private String mSlot;
+    @ViewDebug.ExportedProperty private boolean mError;
+
+    public StatusBarIconView(Context context, String slot) {
+        super(context);
+        mSlot = slot;
+    }
+
+    private static boolean streq(String a, String b) {
+        if (a == b) {
+            return true;
+        }
+        if (a == null && b != null) {
+            return false;
+        }
+        if (a != null && b == null) {
+            return false;
+        }
+        return a.equals(b);
+    }
+
+    public void set(StatusBarIcon icon) {
+        error: {
+            final boolean iconEquals = !mError
+                    && mIcon != null
+                    && streq(mIcon.iconPackage, icon.iconPackage)
+                    && mIcon.iconId == icon.iconId;
+            final boolean levelEquals = !mError
+                    && iconEquals
+                    && mIcon.iconLevel == icon.iconLevel;
+            final boolean visibilityEquals = !mError
+                    && mIcon != null
+                    && mIcon.visible == icon.visible;
+            mError = false;
+            if (!iconEquals) {
+                Drawable drawable = getIcon(icon);
+                if (drawable == null) {
+                    mError = true;
+                    Slog.w(PhoneStatusBarService.TAG, "No icon ID for slot " + mSlot);
+                    break error;
+                }
+                setImageDrawable(drawable);
+            }
+            if (!levelEquals) {
+                setImageLevel(icon.iconLevel);
+            }
+            if (!visibilityEquals) {
+                setVisibility(icon.visible ? VISIBLE : GONE);
+            }
+            mIcon = icon.clone();
+        }
+        if (mError) {
+            setVisibility(GONE);
+        }
+    }
+
+    private Drawable getIcon(StatusBarIcon icon) {
+        return getIcon(getContext(), icon);
+    }
+
+    /**
+     * Returns the right icon to use for this item, respecting the iconId and
+     * iconPackage (if set)
+     * 
+     * @param context Context to use to get resources if iconPackage is not set
+     * @return Drawable for this item, or null if the package or item could not
+     *         be found
+     */
+    public static Drawable getIcon(Context context, StatusBarIcon icon) {
+        Resources r = null;
+
+        if (icon.iconPackage != null) {
+            try {
+                r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
+            } catch (PackageManager.NameNotFoundException ex) {
+                Slog.e(PhoneStatusBarService.TAG, "Icon package not found: "+icon.iconPackage, ex);
+                return null;
+            }
+        } else {
+            r = context.getResources();
+        }
+
+        if (icon.iconId == 0) {
+            return null;
+        }
+        
+        try {
+            return r.getDrawable(icon.iconId);
+        } catch (RuntimeException e) {
+            Slog.w(PhoneStatusBarService.TAG, "Icon not found in "
+                  + (icon.iconPackage != null ? icon.iconId : "<system>")
+                  + ": " + Integer.toHexString(icon.iconId));
+        }
+
+        return null;
+    }
+
+    public StatusBarIcon getStatusBarIcon() {
+        return mIcon;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
new file mode 100644
index 0000000..9ef9d0d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
@@ -0,0 +1,1160 @@
+/*
+ * 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.app.StatusBarManager;
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothPbap;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.TypedArray;
+import android.graphics.PixelFormat;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.location.LocationManager;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.storage.StorageManager;
+import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.text.format.DateFormat;
+import android.text.style.CharacterStyle;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.util.Slog;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.cdma.EriInfo;
+import com.android.internal.telephony.cdma.TtyIntent;
+import com.android.server.am.BatteryStatsService;
+
+import com.android.systemui.R;
+
+/**
+ * This class contains all of the policy about which icons are installed in the status
+ * bar at boot time.  It goes through the normal API for icons, even though it probably
+ * strictly doesn't need to.
+ */
+public class StatusBarPolicy {
+    private static final String TAG = "StatusBarPolicy";
+
+    // message codes for the handler
+    private static final int EVENT_BATTERY_CLOSE = 4;
+
+    private static final int AM_PM_STYLE_NORMAL  = 0;
+    private static final int AM_PM_STYLE_SMALL   = 1;
+    private static final int AM_PM_STYLE_GONE    = 2;
+
+    private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
+
+    private final Context mContext;
+    private final StatusBarManager mService;
+    private final Handler mHandler = new StatusBarHandler();
+    private final IBatteryStats mBatteryStats;
+
+    // storage
+    private StorageManager mStorageManager;
+
+    // battery
+    private boolean mBatteryFirst = true;
+    private boolean mBatteryPlugged;
+    private int mBatteryLevel;
+    private AlertDialog mLowBatteryDialog;
+    private TextView mBatteryLevelTextView;
+    private View mBatteryView;
+    private int mBatteryViewSequence;
+    private boolean mBatteryShowLowOnEndCall = false;
+    private static final boolean SHOW_LOW_BATTERY_WARNING = true;
+    private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
+
+    // phone
+    private TelephonyManager mPhone;
+    private int mPhoneSignalIconId;
+
+    //***** Signal strength icons
+    //GSM/UMTS
+    private static final int[] sSignalImages = new int[] {
+        R.drawable.stat_sys_signal_0,
+        R.drawable.stat_sys_signal_1,
+        R.drawable.stat_sys_signal_2,
+        R.drawable.stat_sys_signal_3,
+        R.drawable.stat_sys_signal_4
+    };
+    private static final int[] sSignalImages_r = new int[] {
+        R.drawable.stat_sys_r_signal_0,
+        R.drawable.stat_sys_r_signal_1,
+        R.drawable.stat_sys_r_signal_2,
+        R.drawable.stat_sys_r_signal_3,
+        R.drawable.stat_sys_r_signal_4
+    };
+    private static final int[] sRoamingIndicatorImages_cdma = new int[] {
+        R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
+        // 1 is Standard Roaming Indicator OFF
+        // TODO T: image never used, remove and put 0 instead?
+        R.drawable.stat_sys_roaming_cdma_0,
+
+        // 2 is Standard Roaming Indicator FLASHING
+        // TODO T: image never used, remove and put 0 instead?
+        R.drawable.stat_sys_roaming_cdma_0,
+
+        // 3-12 Standard ERI
+        R.drawable.stat_sys_roaming_cdma_0, //3
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+
+        // 13-63 Reserved for Standard ERI
+        R.drawable.stat_sys_roaming_cdma_0, //13
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+
+        // 64-127 Reserved for Non Standard (Operator Specific) ERI
+        R.drawable.stat_sys_roaming_cdma_0, //64
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0 //83
+
+        // 128-255 Reserved
+    };
+
+    //***** Data connection icons
+    private int[] mDataIconList = sDataNetType_g;
+    //GSM/UMTS
+    private static final int[] sDataNetType_g = new int[] {
+            R.drawable.stat_sys_data_connected_g,
+            R.drawable.stat_sys_data_in_g,
+            R.drawable.stat_sys_data_out_g,
+            R.drawable.stat_sys_data_inandout_g,
+        };
+    private static final int[] sDataNetType_3g = new int[] {
+            R.drawable.stat_sys_data_connected_3g,
+            R.drawable.stat_sys_data_in_3g,
+            R.drawable.stat_sys_data_out_3g,
+            R.drawable.stat_sys_data_inandout_3g,
+        };
+    private static final int[] sDataNetType_e = new int[] {
+            R.drawable.stat_sys_data_connected_e,
+            R.drawable.stat_sys_data_in_e,
+            R.drawable.stat_sys_data_out_e,
+            R.drawable.stat_sys_data_inandout_e,
+        };
+    //3.5G
+    private static final int[] sDataNetType_h = new int[] {
+            R.drawable.stat_sys_data_connected_h,
+            R.drawable.stat_sys_data_in_h,
+            R.drawable.stat_sys_data_out_h,
+            R.drawable.stat_sys_data_inandout_h,
+    };
+
+    //CDMA
+    // Use 3G icons for EVDO data and 1x icons for 1XRTT data
+    private static final int[] sDataNetType_1x = new int[] {
+        R.drawable.stat_sys_data_connected_1x,
+        R.drawable.stat_sys_data_in_1x,
+        R.drawable.stat_sys_data_out_1x,
+        R.drawable.stat_sys_data_inandout_1x,
+    };
+
+    // Assume it's all good unless we hear otherwise.  We don't always seem
+    // to get broadcasts that it *is* there.
+    IccCard.State mSimState = IccCard.State.READY;
+    int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
+    int mDataState = TelephonyManager.DATA_DISCONNECTED;
+    int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+    ServiceState mServiceState;
+    SignalStrength mSignalStrength;
+
+    // data connection
+    private boolean mDataIconVisible;
+    private boolean mHspaDataDistinguishable;
+
+    // ringer volume
+    private boolean mVolumeVisible;
+
+    // bluetooth device status
+    private int mBluetoothHeadsetState;
+    private boolean mBluetoothA2dpConnected;
+    private int mBluetoothPbapState;
+    private boolean mBluetoothEnabled;
+
+    // wifi
+    private static final int[] sWifiSignalImages = new int[] {
+            R.drawable.stat_sys_wifi_signal_1,
+            R.drawable.stat_sys_wifi_signal_2,
+            R.drawable.stat_sys_wifi_signal_3,
+            R.drawable.stat_sys_wifi_signal_4,
+        };
+    private static final int sWifiTemporarilyNotConnectedImage =
+            R.drawable.stat_sys_wifi_signal_0;
+
+    private int mLastWifiSignalLevel = -1;
+    private boolean mIsWifiConnected = false;
+
+    // sync state
+    // If sync is active the SyncActive icon is displayed. If sync is not active but
+    // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed.
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                updateBattery(intent);
+            }
+            else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
+                updateAlarm(intent);
+            }
+            else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
+                updateSyncState(intent);
+            }
+            else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
+                onBatteryLow(intent);
+            }
+            else if (action.equals(Intent.ACTION_BATTERY_OKAY)
+                    || action.equals(Intent.ACTION_POWER_CONNECTED)) {
+                onBatteryOkay(intent);
+            }
+            else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
+                    action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
+                    action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
+                    action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
+                updateBluetooth(intent);
+            }
+            else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) ||
+                    action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
+                    action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+                updateWifi(intent);
+            }
+            else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) ||
+                    action.equals(LocationManager.GPS_FIX_CHANGE_ACTION)) {
+                updateGps(intent);
+            }
+            else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
+                    action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
+                updateVolume();
+            }
+            else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+                updateSimState(intent);
+            }
+            else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
+                updateTTY(intent);
+            }
+        }
+    };
+
+    public StatusBarPolicy(Context context) {
+        mContext = context;
+        mService = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
+        mSignalStrength = new SignalStrength();
+        mBatteryStats = BatteryStatsService.getService();
+
+        // storage
+        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+        mStorageManager.registerListener(
+                new com.android.server.status.StorageNotification(context));
+
+        // battery
+        mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0);
+
+        // phone_signal
+        mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
+        mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+        mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+
+        // register for phone state notifications.
+        ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
+                .listen(mPhoneStateListener,
+                          PhoneStateListener.LISTEN_SERVICE_STATE
+                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+                        | PhoneStateListener.LISTEN_CALL_STATE
+                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+                        | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+        // data_connection
+        mService.setIcon("data_connection", R.drawable.stat_sys_data_connected_g, 0);
+        mService.setIconVisibility("data_connection", false);
+
+        // wifi
+        mService.setIcon("wifi", sWifiSignalImages[0], 0);
+        mService.setIconVisibility("wifi", false);
+        // wifi will get updated by the sticky intents
+
+        // TTY status
+        mService.setIcon("tty",  R.drawable.stat_sys_tty_mode, 0);
+        mService.setIconVisibility("tty", false);
+
+        // Cdma Roaming Indicator, ERI
+        mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0);
+        mService.setIconVisibility("cdma_eri", false);
+
+        // bluetooth status
+        mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0);
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null) {
+            mBluetoothEnabled = adapter.isEnabled();
+        } else {
+            mBluetoothEnabled = false;
+        }
+        mBluetoothA2dpConnected = false;
+        mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
+        mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
+        mService.setIconVisibility("bluetooth", mBluetoothEnabled);
+
+        // Gps status
+        mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
+        mService.setIconVisibility("gps", false);
+
+        // Alarm clock
+        mService.setIcon("alarm_clock", R.drawable.stat_notify_alarm, 0);
+        mService.setIconVisibility("alarm_clock", false);
+
+        // Sync state
+        mService.setIcon("sync_active", com.android.internal.R.drawable.stat_notify_sync_anim0, 0);
+        mService.setIcon("sync_failing", com.android.internal.R.drawable.stat_notify_sync_error, 0);
+        mService.setIconVisibility("sync_active", false);
+        mService.setIconVisibility("sync_failing", false);
+
+        // volume
+        mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0);
+        mService.setIconVisibility("volume", false);
+        updateVolume();
+
+        IntentFilter filter = new IntentFilter();
+
+        // Register for Intent broadcasts for...
+        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_BATTERY_LOW);
+        filter.addAction(Intent.ACTION_BATTERY_OKAY);
+        filter.addAction(Intent.ACTION_POWER_CONNECTED);
+        filter.addAction(Intent.ACTION_ALARM_CHANGED);
+        filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
+        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+        filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
+        filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
+        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
+        filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION);
+        filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION);
+        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+        filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
+        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
+
+        // load config to determine if to distinguish Hspa data icon
+        try {
+            mHspaDataDistinguishable = mContext.getResources().getBoolean(
+                    R.bool.config_hspa_data_distinguishable);
+        } catch (Exception e) {
+            mHspaDataDistinguishable = false;
+        }
+    }
+
+    private final void updateAlarm(Intent intent) {
+        boolean alarmSet = intent.getBooleanExtra("alarmSet", false);
+        mService.setIconVisibility("alarm_clock", alarmSet);
+    }
+
+    private final void updateSyncState(Intent intent) {
+        boolean isActive = intent.getBooleanExtra("active", false);
+        boolean isFailing = intent.getBooleanExtra("failing", false);
+        mService.setIconVisibility("sync_active", isActive);
+        // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
+        //mService.setIconVisibility("sync_failing", isFailing && !isActive);
+    }
+
+    private final void updateBattery(Intent intent) {
+        final int id = intent.getIntExtra("icon-small", 0);
+        int level = intent.getIntExtra("level", 0);
+        mService.setIcon("battery", id, level);
+
+        boolean plugged = intent.getIntExtra("plugged", 0) != 0;
+        level = intent.getIntExtra("level", -1);
+        if (false) {
+            Slog.d(TAG, "updateBattery level=" + level
+                    + " plugged=" + plugged
+                    + " mBatteryPlugged=" + mBatteryPlugged
+                    + " mBatteryLevel=" + mBatteryLevel
+                    + " mBatteryFirst=" + mBatteryFirst);
+        }
+
+        boolean oldPlugged = mBatteryPlugged;
+
+        mBatteryPlugged = plugged;
+        mBatteryLevel = level;
+
+        if (mBatteryFirst) {
+            mBatteryFirst = false;
+        }
+        /*
+         * No longer showing the battery view because it draws attention away
+         * from the USB storage notification. We could still show it when
+         * connected to a brick, but that could lead to the user into thinking
+         * the device does not charge when plugged into USB (since he/she would
+         * not see the same battery screen on USB as he sees on brick).
+         */
+        if (false) {
+            Slog.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
+        }
+    }
+
+    private void onBatteryLow(Intent intent) {
+        if (SHOW_LOW_BATTERY_WARNING) {
+            if (false) {
+                Slog.d(TAG, "mPhoneState=" + mPhoneState
+                      + " mLowBatteryDialog=" + mLowBatteryDialog
+                      + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
+            }
+
+            if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
+                showLowBatteryWarning();
+            } else {
+                mBatteryShowLowOnEndCall = true;
+            }
+        }
+    }
+
+    private void onBatteryOkay(Intent intent) {
+        if (mLowBatteryDialog != null
+                && SHOW_LOW_BATTERY_WARNING) {
+            mLowBatteryDialog.dismiss();
+            mBatteryShowLowOnEndCall = false;
+        }
+    }
+
+    private void setBatteryLevel(View parent, int id, int height, int background, int level) {
+        ImageView v = (ImageView)parent.findViewById(id);
+        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams();
+        lp.weight = height;
+        if (background != 0) {
+            v.setBackgroundResource(background);
+            Drawable bkg = v.getBackground();
+            bkg.setLevel(level);
+        }
+    }
+
+    private void showLowBatteryWarning() {
+        closeLastBatteryView();
+
+        // Show exact battery level.
+        CharSequence levelText = mContext.getString(
+                    R.string.battery_low_percent_format, mBatteryLevel);
+
+        if (mBatteryLevelTextView != null) {
+            mBatteryLevelTextView.setText(levelText);
+        } else {
+            View v = View.inflate(mContext, R.layout.battery_low, null);
+            mBatteryLevelTextView=(TextView)v.findViewById(R.id.level_percent);
+
+            mBatteryLevelTextView.setText(levelText);
+
+            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
+                b.setCancelable(true);
+                b.setTitle(R.string.battery_low_title);
+                b.setView(v);
+                b.setIcon(android.R.drawable.ic_dialog_alert);
+                b.setPositiveButton(android.R.string.ok, null);
+
+                final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                        | Intent.FLAG_ACTIVITY_NO_HISTORY);
+                if (intent.resolveActivity(mContext.getPackageManager()) != null) {
+                    b.setNegativeButton(R.string.battery_low_why,
+                            new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            mContext.startActivity(intent);
+                            if (mLowBatteryDialog != null) {
+                                mLowBatteryDialog.dismiss();
+                            }
+                        }
+                    });
+                }
+
+            AlertDialog d = b.create();
+            d.setOnDismissListener(mLowBatteryListener);
+            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            d.show();
+            mLowBatteryDialog = d;
+        }
+
+        final ContentResolver cr = mContext.getContentResolver();
+        if (Settings.System.getInt(cr,
+                Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)
+        {
+            final String soundPath = Settings.System.getString(cr,
+                Settings.System.LOW_BATTERY_SOUND);
+            if (soundPath != null) {
+                final Uri soundUri = Uri.parse("file://" + soundPath);
+                if (soundUri != null) {
+                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+                    if (sfx != null) {
+                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+                        sfx.play();
+                    }
+                }
+            }
+        }
+    }
+
+    private final void updateCallState(int state) {
+        mPhoneState = state;
+        if (false) {
+            Slog.d(TAG, "mPhoneState=" + mPhoneState
+                    + " mLowBatteryDialog=" + mLowBatteryDialog
+                    + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
+        }
+        if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
+            if (mBatteryShowLowOnEndCall) {
+                if (!mBatteryPlugged) {
+                    showLowBatteryWarning();
+                }
+                mBatteryShowLowOnEndCall = false;
+            }
+        } else {
+            if (mLowBatteryDialog != null) {
+                mLowBatteryDialog.dismiss();
+                mBatteryShowLowOnEndCall = true;
+            }
+        }
+    }
+
+    private DialogInterface.OnDismissListener mLowBatteryListener
+            = new DialogInterface.OnDismissListener() {
+        public void onDismiss(DialogInterface dialog) {
+            mLowBatteryDialog = null;
+            mBatteryLevelTextView = null;
+        }
+    };
+
+    private void scheduleCloseBatteryView() {
+        Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE);
+        m.arg1 = (++mBatteryViewSequence);
+        mHandler.sendMessageDelayed(m, 3000);
+    }
+
+    private void closeLastBatteryView() {
+        if (mBatteryView != null) {
+            //mBatteryView.debug();
+            WindowManagerImpl.getDefault().removeView(mBatteryView);
+            mBatteryView = null;
+        }
+    }
+
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            mSignalStrength = signalStrength;
+            updateSignalStrength();
+        }
+
+        @Override
+        public void onServiceStateChanged(ServiceState state) {
+            mServiceState = state;
+            updateSignalStrength();
+            updateCdmaRoamingIcon(state);
+            updateDataIcon();
+        }
+
+        @Override
+        public void onCallStateChanged(int state, String incomingNumber) {
+            updateCallState(state);
+            // In cdma, if a voice call is made, RSSI should switch to 1x.
+            if (isCdma()) {
+                updateSignalStrength();
+            }
+        }
+
+        @Override
+        public void onDataConnectionStateChanged(int state, int networkType) {
+            mDataState = state;
+            updateDataNetType(networkType);
+            updateDataIcon();
+        }
+
+        @Override
+        public void onDataActivity(int direction) {
+            mDataActivity = direction;
+            updateDataIcon();
+        }
+    };
+
+    private final void updateSimState(Intent intent) {
+        String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
+        if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+            mSimState = IccCard.State.ABSENT;
+        }
+        else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+            mSimState = IccCard.State.READY;
+        }
+        else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+            final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+            if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                mSimState = IccCard.State.PIN_REQUIRED;
+            }
+            else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                mSimState = IccCard.State.PUK_REQUIRED;
+            }
+            else {
+                mSimState = IccCard.State.NETWORK_LOCKED;
+            }
+        } else {
+            mSimState = IccCard.State.UNKNOWN;
+        }
+        updateDataIcon();
+    }
+
+    private boolean isCdma() {
+        return (mSignalStrength != null) && !mSignalStrength.isGsm();
+    }
+
+    private boolean isEvdo() {
+        return ( (mServiceState != null)
+                 && ((mServiceState.getRadioTechnology()
+                        == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
+                     || (mServiceState.getRadioTechnology()
+                        == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
+                     || (mServiceState.getRadioTechnology()
+                        == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
+    }
+
+    private boolean hasService() {
+        if (mServiceState != null) {
+            switch (mServiceState.getState()) {
+                case ServiceState.STATE_OUT_OF_SERVICE:
+                case ServiceState.STATE_POWER_OFF:
+                    return false;
+                default:
+                    return true;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    private final void updateSignalStrength() {
+        int iconLevel = -1;
+        int[] iconList;
+
+        // Display signal strength while in "emergency calls only" mode
+        if (!hasService() && !mServiceState.isEmergencyOnly()) {
+            //Slog.d(TAG, "updateSignalStrength: no service");
+            if (Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
+                mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
+            } else {
+                mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+            }
+            mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+            return;
+        }
+
+        if (!isCdma()) {
+            int asu = mSignalStrength.getGsmSignalStrength();
+
+            // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+            // asu = 0 (-113dB or less) is very weak
+            // signal, its better to show 0 bars to the user in such cases.
+            // asu = 99 is a special case, where the signal strength is unknown.
+            if (asu <= 2 || asu == 99) iconLevel = 0;
+            else if (asu >= 12) iconLevel = 4;
+            else if (asu >= 8)  iconLevel = 3;
+            else if (asu >= 5)  iconLevel = 2;
+            else iconLevel = 1;
+
+            // Though mPhone is a Manager, this call is not an IPC
+            if (mPhone.isNetworkRoaming()) {
+                iconList = sSignalImages_r;
+            } else {
+                iconList = sSignalImages;
+            }
+        } else {
+            iconList = this.sSignalImages;
+
+            // If 3G(EV) and 1x network are available than 3G should be
+            // displayed, displayed RSSI should be from the EV side.
+            // If a voice call is made then RSSI should switch to 1x.
+            if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
+                iconLevel = getEvdoLevel();
+                if (false) {
+                    Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
+                }
+            } else {
+                iconLevel = getCdmaLevel();
+            }
+        }
+        mPhoneSignalIconId = iconList[iconLevel];
+        mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+    }
+
+    private int getCdmaLevel() {
+        final int cdmaDbm = mSignalStrength.getCdmaDbm();
+        final int cdmaEcio = mSignalStrength.getCdmaEcio();
+        int levelDbm = 0;
+        int levelEcio = 0;
+
+        if (cdmaDbm >= -75) levelDbm = 4;
+        else if (cdmaDbm >= -85) levelDbm = 3;
+        else if (cdmaDbm >= -95) levelDbm = 2;
+        else if (cdmaDbm >= -100) levelDbm = 1;
+        else levelDbm = 0;
+
+        // Ec/Io are in dB*10
+        if (cdmaEcio >= -90) levelEcio = 4;
+        else if (cdmaEcio >= -110) levelEcio = 3;
+        else if (cdmaEcio >= -130) levelEcio = 2;
+        else if (cdmaEcio >= -150) levelEcio = 1;
+        else levelEcio = 0;
+
+        return (levelDbm < levelEcio) ? levelDbm : levelEcio;
+    }
+
+    private int getEvdoLevel() {
+        int evdoDbm = mSignalStrength.getEvdoDbm();
+        int evdoSnr = mSignalStrength.getEvdoSnr();
+        int levelEvdoDbm = 0;
+        int levelEvdoSnr = 0;
+
+        if (evdoDbm >= -65) levelEvdoDbm = 4;
+        else if (evdoDbm >= -75) levelEvdoDbm = 3;
+        else if (evdoDbm >= -90) levelEvdoDbm = 2;
+        else if (evdoDbm >= -105) levelEvdoDbm = 1;
+        else levelEvdoDbm = 0;
+
+        if (evdoSnr >= 7) levelEvdoSnr = 4;
+        else if (evdoSnr >= 5) levelEvdoSnr = 3;
+        else if (evdoSnr >= 3) levelEvdoSnr = 2;
+        else if (evdoSnr >= 1) levelEvdoSnr = 1;
+        else levelEvdoSnr = 0;
+
+        return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+    }
+
+    private final void updateDataNetType(int net) {
+        switch (net) {
+        case TelephonyManager.NETWORK_TYPE_EDGE:
+            mDataIconList = sDataNetType_e;
+            break;
+        case TelephonyManager.NETWORK_TYPE_UMTS:
+            mDataIconList = sDataNetType_3g;
+            break;
+        case TelephonyManager.NETWORK_TYPE_HSDPA:
+        case TelephonyManager.NETWORK_TYPE_HSUPA:
+        case TelephonyManager.NETWORK_TYPE_HSPA:
+            if (mHspaDataDistinguishable) {
+                mDataIconList = sDataNetType_h;
+            } else {
+                mDataIconList = sDataNetType_3g;
+            }
+            break;
+        case TelephonyManager.NETWORK_TYPE_CDMA:
+            // display 1xRTT for IS95A/B
+            mDataIconList = this.sDataNetType_1x;
+            break;
+        case TelephonyManager.NETWORK_TYPE_1xRTT:
+            mDataIconList = this.sDataNetType_1x;
+            break;
+        case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
+        case TelephonyManager.NETWORK_TYPE_EVDO_A:
+        case TelephonyManager.NETWORK_TYPE_EVDO_B:
+            mDataIconList = sDataNetType_3g;
+            break;
+        default:
+            mDataIconList = sDataNetType_g;
+        break;
+        }
+    }
+
+    private final void updateDataIcon() {
+        int iconId;
+        boolean visible = true;
+
+        if (!isCdma()) {
+            // GSM case, we have to check also the sim state
+            if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
+                if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
+                    switch (mDataActivity) {
+                        case TelephonyManager.DATA_ACTIVITY_IN:
+                            iconId = mDataIconList[1];
+                            break;
+                        case TelephonyManager.DATA_ACTIVITY_OUT:
+                            iconId = mDataIconList[2];
+                            break;
+                        case TelephonyManager.DATA_ACTIVITY_INOUT:
+                            iconId = mDataIconList[3];
+                            break;
+                        default:
+                            iconId = mDataIconList[0];
+                            break;
+                    }
+                    mService.setIcon("data_connection", iconId, 0);
+                } else {
+                    visible = false;
+                }
+            } else {
+                iconId = R.drawable.stat_sys_no_sim;
+                mService.setIcon("data_connection", iconId, 0);
+            }
+        } else {
+            // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
+            if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
+                switch (mDataActivity) {
+                    case TelephonyManager.DATA_ACTIVITY_IN:
+                        iconId = mDataIconList[1];
+                        break;
+                    case TelephonyManager.DATA_ACTIVITY_OUT:
+                        iconId = mDataIconList[2];
+                        break;
+                    case TelephonyManager.DATA_ACTIVITY_INOUT:
+                        iconId = mDataIconList[3];
+                        break;
+                    case TelephonyManager.DATA_ACTIVITY_DORMANT:
+                    default:
+                        iconId = mDataIconList[0];
+                        break;
+                }
+                mService.setIcon("data_connection", iconId, 0);
+            } else {
+                visible = false;
+            }
+        }
+
+        long ident = Binder.clearCallingIdentity();
+        try {
+            mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
+        } catch (RemoteException e) {
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+
+        if (mDataIconVisible != visible) {
+            mService.setIconVisibility("data_connection", visible);
+            mDataIconVisible = visible;
+        }
+    }
+
+    private final void updateVolume() {
+        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        final int ringerMode = audioManager.getRingerMode();
+        final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
+                ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+        final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
+                ? R.drawable.stat_sys_ringer_vibrate
+                : R.drawable.stat_sys_ringer_silent;
+
+        if (visible) {
+            mService.setIcon("volume", iconId, 0);
+        }
+        if (visible != mVolumeVisible) {
+            mService.setIconVisibility("volume", visible);
+            mVolumeVisible = visible;
+        }
+    }
+
+    private final void updateBluetooth(Intent intent) {
+        int iconId = R.drawable.stat_sys_data_bluetooth;
+        String action = intent.getAction();
+        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+            mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
+        } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
+            mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                    BluetoothHeadset.STATE_ERROR);
+        } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
+            BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
+            if (a2dp.getConnectedSinks().size() != 0) {
+                mBluetoothA2dpConnected = true;
+            } else {
+                mBluetoothA2dpConnected = false;
+            }
+        } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
+            mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
+                    BluetoothPbap.STATE_DISCONNECTED);
+        } else {
+            return;
+        }
+
+        if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
+                mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
+            iconId = R.drawable.stat_sys_data_bluetooth_connected;
+        }
+
+        mService.setIcon("bluetooth", iconId, 0);
+        mService.setIconVisibility("bluetooth", mBluetoothEnabled);
+    }
+
+    private final void updateWifi(Intent intent) {
+        final String action = intent.getAction();
+        if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+
+            final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+
+            if (!enabled) {
+                // If disabled, hide the icon. (We show icon when connected.)
+                mService.setIconVisibility("wifi", false);
+            }
+
+        } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
+            final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,
+                                                           false);
+            if (!enabled) {
+                mService.setIconVisibility("wifi", false);
+            }
+        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+
+            final NetworkInfo networkInfo = (NetworkInfo)
+                    intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+
+            int iconId;
+            if (networkInfo != null && networkInfo.isConnected()) {
+                mIsWifiConnected = true;
+                if (mLastWifiSignalLevel == -1) {
+                    iconId = sWifiSignalImages[0];
+                } else {
+                    iconId = sWifiSignalImages[mLastWifiSignalLevel];
+                }
+
+                // Show the icon since wi-fi is connected
+                mService.setIconVisibility("wifi", true);
+
+            } else {
+                mLastWifiSignalLevel = -1;
+                mIsWifiConnected = false;
+                iconId = sWifiSignalImages[0];
+
+                // Hide the icon since we're not connected
+                mService.setIconVisibility("wifi", false);
+            }
+
+            mService.setIcon("wifi", iconId, 0);
+        } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
+            int iconId;
+            final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
+            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
+                                                                  sWifiSignalImages.length);
+            if (newSignalLevel != mLastWifiSignalLevel) {
+                mLastWifiSignalLevel = newSignalLevel;
+                if (mIsWifiConnected) {
+                    iconId = sWifiSignalImages[newSignalLevel];
+                } else {
+                    iconId = sWifiTemporarilyNotConnectedImage;
+                }
+                mService.setIcon("wifi", iconId, 0);
+            }
+        }
+    }
+
+    private final void updateGps(Intent intent) {
+        final String action = intent.getAction();
+        final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false);
+
+        if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
+            // GPS is getting fixes
+            mService.setIcon("gps", com.android.internal.R.drawable.stat_sys_gps_on, 0);
+            mService.setIconVisibility("gps", true);
+        } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
+            // GPS is off
+            mService.setIconVisibility("gps", false);
+        } else {
+            // GPS is on, but not receiving fixes
+            mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
+            mService.setIconVisibility("gps", true);
+        }
+    }
+
+    private final void updateTTY(Intent intent) {
+        final String action = intent.getAction();
+        final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
+
+        if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
+
+        if (enabled) {
+            // TTY is on
+            if (false) Slog.v(TAG, "updateTTY: set TTY on");
+            mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
+            mService.setIconVisibility("tty", true);
+        } else {
+            // TTY is off
+            if (false) Slog.v(TAG, "updateTTY: set TTY off");
+            mService.setIconVisibility("tty", false);
+        }
+    }
+
+    private final void updateCdmaRoamingIcon(ServiceState state) {
+        if (!hasService()) {
+            mService.setIconVisibility("cdma_eri", false);
+            return;
+        }
+
+        if (!isCdma()) {
+            mService.setIconVisibility("cdma_eri", false);
+            return;
+        }
+
+        int[] iconList = sRoamingIndicatorImages_cdma;
+        int iconIndex = state.getCdmaEriIconIndex();
+        int iconMode = state.getCdmaEriIconMode();
+
+        if (iconIndex == -1) {
+            Slog.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update");
+            return;
+        }
+
+        if (iconMode == -1) {
+            Slog.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update");
+            return;
+        }
+
+        if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) {
+            if (false) Slog.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon");
+            mService.setIconVisibility("cdma_eri", false);
+            return;
+        }
+
+        switch (iconMode) {
+            case EriInfo.ROAMING_ICON_MODE_NORMAL:
+                mService.setIcon("cdma_eri", iconList[iconIndex], 0);
+                mService.setIconVisibility("cdma_eri", true);
+                break;
+            case EriInfo.ROAMING_ICON_MODE_FLASH:
+                mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_flash, 0);
+                mService.setIconVisibility("cdma_eri", true);
+                break;
+
+        }
+        mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+    }
+
+
+    private class StatusBarHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case EVENT_BATTERY_CLOSE:
+                if (msg.arg1 == mBatteryViewSequence) {
+                    closeLastBatteryView();
+                }
+                break;
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
new file mode 100644
index 0000000..4d9e695
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 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;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
+
+import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.StatusBarNotification;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+
+public abstract class StatusBarService extends Service implements CommandQueue.Callbacks {
+    private static final String TAG = "StatusBarService";
+
+    CommandQueue mCommandQueue;
+    IStatusBarService mBarService;
+
+    /* TODO
+    H mHandler = new H();
+    Object mQueueLock = new Object();
+    NotificationCallbacks mNotificationCallbacks;
+    */
+
+    @Override
+    public void onCreate() {
+        // Connect in to the status bar manager service
+        StatusBarIconList iconList = new StatusBarIconList();
+        ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
+        ArrayList<StatusBarNotification> notifications = new ArrayList<StatusBarNotification>();
+        mCommandQueue = new CommandQueue(this, iconList);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        try {
+            mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications);
+        } catch (RemoteException ex) {
+            // If the system process isn't there we're doomed anyway.
+        }
+
+        // Set up the initial icon state
+        int N = iconList.size();
+        int viewIndex = 0;
+        for (int i=0; i<N; i++) {
+            StatusBarIcon icon = iconList.getIcon(i);
+            if (icon != null) {
+                addIcon(iconList.getSlot(i), i, viewIndex, icon);
+                viewIndex++;
+            }
+        }
+
+        // Set up the initial notification state
+        N = notificationKeys.size();
+        if (N == notifications.size()) {
+            for (int i=0; i<N; i++) {
+                addNotification(notificationKeys.get(i), notifications.get(i));
+            }
+        } else {
+            Log.wtf(TAG, "Notification list length mismatch: keys=" + N
+                    + " notifications=" + notifications.size());
+        }
+
+        // Put up the view
+        addStatusBarView();
+    }
+
+    @Override
+    public void onDestroy() {
+        // we're never destroyed
+    }
+
+    /**
+     * Nobody binds to us.
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    /**
+     * Implement this to add the main status bar view.
+     */
+    protected abstract void addStatusBarView();
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java
new file mode 100644
index 0000000..2b9dfb0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStarter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 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;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.BroadcastReceiver;
+import android.util.Log;
+
+/**
+ * Receive a broadcast from the StatusBarManagerService at boot time, and
+ * kick off the StatusBarService.
+ */
+public class StatusBarStarter extends BroadcastReceiver {
+    private static final String TAG = "StatusBarStarter";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "StatusBarStarter onReceive intent=" + intent);
+        context.startService(new Intent(context, PhoneStatusBarService.class));
+    }
+}
+
+
diff --git a/services/java/com/android/server/status/StatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
similarity index 96%
rename from services/java/com/android/server/status/StatusBarView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
index 5e1f572..466cc75 100644
--- a/services/java/com/android/server/status/StatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.content.res.Configuration;
@@ -27,14 +27,14 @@
 import android.view.ViewParent;
 import android.widget.FrameLayout;
 
-import com.android.internal.R;
+import com.android.systemui.R;
 
 public class StatusBarView extends FrameLayout {
     private static final String TAG = "StatusBarView";
 
     static final int DIM_ANIM_TIME = 400;
     
-    StatusBarService mService;
+    PhoneStatusBarService mService;
     boolean mTracking;
     int mStartX, mStartY;
     ViewGroup mNotificationIcons;
@@ -94,7 +94,7 @@
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mService.updateExpandedViewPos(StatusBarService.EXPANDED_LEAVE_ALONE);
+        mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE);
     }
 
     @Override
diff --git a/services/java/com/android/server/status/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java
similarity index 79%
rename from services/java/com/android/server/status/Ticker.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java
index e47185b..07e8653 100644
--- a/services/java/com/android/server/status/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
-
-import com.android.internal.R;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -35,12 +33,24 @@
 
 import java.util.ArrayList;
 
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.util.CharSequences;
+import com.android.systemui.R;
 
-abstract class Ticker {
+public abstract class Ticker {
     private static final int TICKER_SEGMENT_DELAY = 3000;
     
+    private Context mContext;
+    private Handler mHandler = new Handler();
+    private ArrayList<Segment> mSegments = new ArrayList();
+    private TextPaint mPaint;
+    private View mTickerView;
+    private ImageSwitcher mIconSwitcher;
+    private TextSwitcher mTextSwitcher;
+
     private final class Segment {
-        NotificationData notificationData;
+        StatusBarNotification notification;
         Drawable icon;
         CharSequence text;
         int current;
@@ -116,8 +126,8 @@
             return null;
         }
 
-        Segment(NotificationData n, Drawable icon, CharSequence text) {
-            this.notificationData = n;
+        Segment(StatusBarNotification n, Drawable icon, CharSequence text) {
+            this.notification = n;
             this.icon = icon;
             this.text = text;
             int index = 0;
@@ -131,14 +141,8 @@
         }
     };
 
-    private Handler mHandler = new Handler();
-    private ArrayList<Segment> mSegments = new ArrayList();
-    private TextPaint mPaint;
-    private View mTickerView;
-    private ImageSwitcher mIconSwitcher;
-    private TextSwitcher mTextSwitcher;
-
     Ticker(Context context, StatusBarView sb) {
+        mContext = context;
         mTickerView = sb.findViewById(R.id.ticker);
 
         mIconSwitcher = (ImageSwitcher)sb.findViewById(R.id.tickerIcon);
@@ -158,20 +162,34 @@
         mPaint = text.getPaint();
     }
 
-    void addEntry(NotificationData n, Drawable icon, CharSequence text) {
+
+    void addEntry(StatusBarNotification n) {
         int initialCount = mSegments.size();
 
-        Segment newSegment = new Segment(n, icon, text);
+        // If what's being displayed has the same text and icon, just drop it
+        // (which will let the current one finish, this happens when apps do
+        // a notification storm).
+        if (initialCount > 0) {
+            final Segment seg = mSegments.get(0);
+            if (n.pkg.equals(seg.notification.pkg)
+                    && n.notification.icon == seg.notification.notification.icon
+                    && n.notification.iconLevel == seg.notification.notification.iconLevel
+                    && CharSequences.equals(seg.notification.notification.tickerText,
+                        n.notification.tickerText)) {
+                return;
+            }
+        }
 
-        // prune out any preexisting ones for this notification, but not the current one.
-        // let that finish, even if it's the same id
-        for (int i=1; i<initialCount; i++) {
+        final Drawable icon = StatusBarIconView.getIcon(mContext,
+                new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0));
+        final Segment newSegment = new Segment(n, icon, n.notification.tickerText);
+
+        // If there's already a notification schedule for this package and id, remove it.
+        for (int i=0; i<initialCount; i++) {
             Segment seg = mSegments.get(i);
-            if (n.id == seg.notificationData.id && n.pkg.equals(seg.notificationData.pkg)) {
+            if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) {
                 // just update that one to use this new data instead
-                mSegments.set(i, newSegment);
-                // and since we know initialCount != 0, just return
-                return ;
+                mSegments.remove(i);
             }
         }
 
@@ -194,6 +212,15 @@
         }
     }
 
+    void removeEntry(StatusBarNotification n) {
+        for (int i=mSegments.size()-1; i>=0; i--) {
+            Segment seg = mSegments.get(i);
+            if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) {
+                mSegments.remove(i);
+            }
+        }
+    }
+
     void halt() {
         mHandler.removeCallbacks(mAdvanceTicker);
         mSegments.clear();
diff --git a/services/java/com/android/server/status/TickerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java
similarity index 95%
rename from services/java/com/android/server/status/TickerView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java
index 099dffb..9749ae4 100644
--- a/services/java/com/android/server/status/TickerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/services/java/com/android/server/status/TrackingPatternView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java
similarity index 97%
rename from services/java/com/android/server/status/TrackingPatternView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java
index 2c91aa4..ba6f15d 100644
--- a/services/java/com/android/server/status/TrackingPatternView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingPatternView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.content.res.TypedArray;
diff --git a/services/java/com/android/server/status/TrackingView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java
similarity index 93%
rename from services/java/com/android/server/status/TrackingView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java
index 8ec39c0..c59eb6a 100644
--- a/services/java/com/android/server/status/TrackingView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.status;
+package com.android.systemui.statusbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -26,7 +26,7 @@
 
 public class TrackingView extends LinearLayout {
     final Display mDisplay;
-    StatusBarService mService;
+    PhoneStatusBarService mService;
     boolean mTracking;
     int mStartX, mStartY;
 
@@ -48,7 +48,7 @@
         switch (event.getKeyCode()) {
         case KeyEvent.KEYCODE_BACK:
             if (down) {
-                mService.deactivate();
+                //mService.deactivate();
             }
             return true;
         }
diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
index c255041..eb61f5e 100644
--- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -145,8 +145,8 @@
     private Context mContext;
     private AlarmManager mAlarmManager;
     private StatusBarManager mStatusBarManager;
-    private boolean mShowLockIcon = false;
-    private IBinder mSecureLockIcon = null;
+    private boolean mShowLockIcon;
+    private boolean mShowingLockIcon;
 
     private boolean mSystemReady;
 
@@ -1036,14 +1036,15 @@
             if (mShowLockIcon) {
                 // Give feedback to user when secure keyguard is active and engaged
                 if (mShowing && isSecure()) {
-                    if (mSecureLockIcon == null) {
-                        mSecureLockIcon = mStatusBarManager.addIcon("secure",
-                            com.android.internal.R.drawable.stat_sys_secure, 0);
+                    if (!mShowingLockIcon) {
+                        mStatusBarManager.setIcon("secure",
+                                com.android.internal.R.drawable.stat_sys_secure, 0);
+                        mShowingLockIcon = true;
                     }
                 } else {
-                    if (mSecureLockIcon != null) {
-                        mStatusBarManager.removeIcon(mSecureLockIcon);
-                        mSecureLockIcon = null;
+                    if (mShowingLockIcon) {
+                        mStatusBarManager.removeIcon("secure");
+                        mShowingLockIcon = false;
                     }
                 }
             }
diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
index a7c278b..73a57ee 100755
--- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -19,7 +19,6 @@
 import android.app.Activity;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
-import android.app.IStatusBar;
 import android.app.IUiModeManager;
 import android.app.UiModeManager;
 import android.content.ActivityNotFoundException;
@@ -47,6 +46,7 @@
 import android.provider.Settings;
 
 import com.android.internal.policy.PolicyManager;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.widget.PointerLocationView;
 
@@ -1140,22 +1140,6 @@
                     return true;
                 }
             }
-        } else if (code == KeyEvent.KEYCODE_NOTIFICATION) {
-            if (down) {
-                // this key doesn't exist on current hardware, but if a device
-                // didn't have a touchscreen, it would want one of these to open
-                // the status bar.
-                IStatusBar sbs = IStatusBar.Stub.asInterface(ServiceManager.getService("statusbar"));
-                if (sbs != null) {
-                    try {
-                        sbs.toggle();
-                    } catch (RemoteException e) {
-                        // we're screwed anyway, since it's in this process
-                        throw new RuntimeException(e);
-                    }
-                }
-            }
-            return true;
         } else if (code == KeyEvent.KEYCODE_SEARCH) {
             if (down) {
                 if (repeatCount == 0) {
@@ -1537,11 +1521,11 @@
         }
         
         if (changes != 0 && hiding) {
-            IStatusBar sbs = IStatusBar.Stub.asInterface(ServiceManager.getService("statusbar"));
+            IStatusBarService sbs = IStatusBarService.Stub.asInterface(ServiceManager.getService("statusbar"));
             if (sbs != null) {
                 try {
                     // Make sure the window shade is hidden.
-                    sbs.deactivate();
+                    sbs.collapse();
                 } catch (RemoteException e) {
                 }
             }
diff --git a/preloaded-classes b/preloaded-classes
index f300fe7..b602039 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -31,7 +31,6 @@
 android.app.IActivityManager
 android.app.IActivityManager$ContentProviderHolder
 android.app.IAlarmManager$Stub
-android.app.IStatusBar$Stub
 android.app.ITransientNotification$Stub
 android.app.Instrumentation
 android.app.IntentService
@@ -654,6 +653,11 @@
 com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
 com.android.internal.policy.impl.PhoneWindowManager
 com.android.internal.policy.impl.Policy
+com.android.internal.statusbar.IStatusBar
+com.android.internal.statusbar.IStatusBar$Stub
+com.android.internal.statusbar.IStatusBarService$Stub
+com.android.internal.statusbar.IStatusBarService$Stub
+com.android.internal.statusbar.StatusBarIcon
 com.android.internal.telephony.GsmAlphabet
 com.android.internal.telephony.ITelephony$Stub
 com.android.internal.telephony.ITelephony$Stub$Proxy
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 5bf66e4..a1f26f2 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -26,8 +26,7 @@
 import com.android.internal.view.IInputMethodSession;
 import com.android.internal.view.InputBindResult;
 
-import com.android.server.status.IconData;
-import com.android.server.status.StatusBarService;
+import com.android.server.status.StatusBarManagerService;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -110,9 +109,7 @@
     final Context mContext;
     final Handler mHandler;
     final SettingsObserver mSettingsObserver;
-    final StatusBarService mStatusBar;
-    final IBinder mInputMethodIcon;
-    final IconData mInputMethodData;
+    final StatusBarManagerService mStatusBar;
     final IWindowManager mIWindowManager;
     final HandlerCaller mCaller;
 
@@ -447,7 +444,7 @@
         }
     }
 
-    public InputMethodManagerService(Context context, StatusBarService statusBar) {
+    public InputMethodManagerService(Context context, StatusBarManagerService statusBar) {
         mContext = context;
         mHandler = new Handler(this);
         mIWindowManager = IWindowManager.Stub.asInterface(
@@ -508,9 +505,7 @@
         }
 
         mStatusBar = statusBar;
-        mInputMethodData = IconData.makeIcon("ime", null, 0, 0, 0);
-        mInputMethodIcon = statusBar.addIcon(mInputMethodData, null);
-        statusBar.setIconVisibility(mInputMethodIcon, false);
+        statusBar.setIconVisibility("ime", false);
 
         mSettingsObserver = new SettingsObserver(mHandler);
         updateFromSettingsLocked();
@@ -912,7 +907,7 @@
             mEnabledSession = null;
             mCurMethod = null;
         }
-        mStatusBar.setIconVisibility(mInputMethodIcon, false);
+        mStatusBar.setIconVisibility("ime", false);
     }
 
     public void onServiceDisconnected(ComponentName name) {
@@ -946,13 +941,11 @@
             synchronized (mMethodMap) {
                 if (iconId == 0) {
                     if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
-                    mStatusBar.setIconVisibility(mInputMethodIcon, false);
+                    mStatusBar.setIconVisibility("ime", false);
                 } else if (packageName != null) {
                     if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
-                    mInputMethodData.iconId = iconId;
-                    mInputMethodData.iconPackage = packageName;
-                    mStatusBar.updateIcon(mInputMethodIcon, mInputMethodData, null);
-                    mStatusBar.setIconVisibility(mInputMethodIcon, true);
+                    mStatusBar.setIcon("ime", packageName, iconId, 0);
+                    mStatusBar.setIconVisibility("ime", true);
                 }
             }
         } finally {
@@ -1734,8 +1727,6 @@
                 p.println("    sessionRequested=" + ci.sessionRequested);
                 p.println("    curSession=" + ci.curSession);
             }
-            p.println("  mInputMethodIcon=" + mInputMethodIcon);
-            p.println("  mInputMethodData=" + mInputMethodData);
             p.println("  mCurMethodId=" + mCurMethodId);
             client = mCurClient;
             p.println("  mCurClient=" + client + " mCurSeq=" + mCurSeq);
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 73d17ea..ac3b23b 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -16,9 +16,8 @@
 
 package com.android.server;
 
-import com.android.server.status.IconData;
-import com.android.server.status.NotificationData;
-import com.android.server.status.StatusBarService;
+import com.android.internal.statusbar.StatusBarNotification;
+import com.android.server.status.StatusBarManagerService;
 
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
@@ -86,7 +85,7 @@
     final IBinder mForegroundToken = new Binder();
 
     private WorkerHandler mHandler;
-    private StatusBarService mStatusBarService;
+    private StatusBarManagerService mStatusBar;
     private LightsService mLightsService;
     private LightsService.Light mBatteryLight;
     private LightsService.Light mNotificationLight;
@@ -238,8 +237,8 @@
         }
     }
 
-    private StatusBarService.NotificationCallbacks mNotificationCallbacks
-            = new StatusBarService.NotificationCallbacks() {
+    private StatusBarManagerService.NotificationCallbacks mNotificationCallbacks
+            = new StatusBarManagerService.NotificationCallbacks() {
 
         public void onSetDisabled(int status) {
             synchronized (mNotificationList) {
@@ -405,7 +404,7 @@
         }
     }
 
-    NotificationManagerService(Context context, StatusBarService statusBar,
+    NotificationManagerService(Context context, StatusBarManagerService statusBar,
             LightsService lights)
     {
         super();
@@ -417,7 +416,7 @@
         mToastQueue = new ArrayList<ToastRecord>();
         mHandler = new WorkerHandler();
 
-        mStatusBarService = statusBar;
+        mStatusBar = statusBar;
         statusBar.setNotificationCallbacks(mNotificationCallbacks);
 
         mBatteryLight = lights.getLight(LightsService.LIGHT_ID_BATTERY);
@@ -705,36 +704,12 @@
             }
 
             if (notification.icon != 0) {
-                IconData icon = IconData.makeIcon(null, pkg, notification.icon,
-                                                    notification.iconLevel,
-                                                    notification.number);
-                CharSequence truncatedTicker = notification.tickerText;
-
-                // TODO: make this restriction do something smarter like never fill
-                // more than two screens.  "Why would anyone need more than 80 characters." :-/
-                final int maxTickerLen = 80;
-                if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) {
-                    truncatedTicker = truncatedTicker.subSequence(0, maxTickerLen);
-                }
-
-                NotificationData n = new NotificationData();
-                n.pkg = pkg;
-                n.tag = tag;
-                n.id = id;
-                n.when = notification.when;
-                n.tickerText = truncatedTicker;
-                n.ongoingEvent = (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
-                if (!n.ongoingEvent && (notification.flags & Notification.FLAG_NO_CLEAR) == 0) {
-                    n.clearable = true;
-                }
-                n.contentView = notification.contentView;
-                n.contentIntent = notification.contentIntent;
-                n.deleteIntent = notification.deleteIntent;
+                StatusBarNotification n = new StatusBarNotification(pkg, id, tag, notification);
                 if (old != null && old.statusBarKey != null) {
                     r.statusBarKey = old.statusBarKey;
                     long identity = Binder.clearCallingIdentity();
                     try {
-                        mStatusBarService.updateIcon(r.statusBarKey, icon, n);
+                        mStatusBar.updateNotification(r.statusBarKey, n);
                     }
                     finally {
                         Binder.restoreCallingIdentity(identity);
@@ -742,21 +717,19 @@
                 } else {
                     long identity = Binder.clearCallingIdentity();
                     try {
-                        r.statusBarKey = mStatusBarService.addIcon(icon, n);
+                        r.statusBarKey = mStatusBar.addNotification(n);
                         mAttentionLight.pulse();
                     }
                     finally {
                         Binder.restoreCallingIdentity(identity);
                     }
                 }
-
                 sendAccessibilityEvent(notification, pkg);
-
             } else {
                 if (old != null && old.statusBarKey != null) {
                     long identity = Binder.clearCallingIdentity();
                     try {
-                        mStatusBarService.removeIcon(old.statusBarKey);
+                        mStatusBar.removeNotification(old.statusBarKey);
                     }
                     finally {
                         Binder.restoreCallingIdentity(identity);
@@ -864,7 +837,7 @@
         if (r.notification.icon != 0) {
             long identity = Binder.clearCallingIdentity();
             try {
-                mStatusBarService.removeIcon(r.statusBarKey);
+                mStatusBar.removeNotification(r.statusBarKey);
             }
             finally {
                 Binder.restoreCallingIdentity(identity);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9d5d035..4307cdc 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -17,7 +17,7 @@
 package com.android.server;
 
 import com.android.server.am.ActivityManagerService;
-import com.android.server.status.StatusBarService;
+import com.android.server.status.StatusBarManagerService;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 
@@ -206,7 +206,7 @@
         }
 
         DevicePolicyManagerService devicePolicy = null;
-        StatusBarService statusBar = null;
+        StatusBarManagerService statusBar = null;
         InputMethodManagerService imm = null;
         AppWidgetService appWidget = null;
         NotificationManagerService notification = null;
@@ -224,10 +224,10 @@
 
             try {
                 Slog.i(TAG, "Status Bar");
-                statusBar = new StatusBarService(context);
+                statusBar = new StatusBarManagerService(context);
                 ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
             } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting StatusBarService", e);
+                Slog.e(TAG, "Failure starting StatusBarManagerService", e);
             }
 
             try {
@@ -405,12 +405,6 @@
             }
 
             try {
-                com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure installing status bar icons", e);
-            }
-
-            try {
                 Slog.i(TAG, "DiskStats Service");
                 ServiceManager.addService("diskstats", new DiskStatsService(context));
             } catch (Throwable e) {
@@ -464,6 +458,7 @@
         }
 
         // These are needed to propagate to the runnable below.
+        final StatusBarManagerService statusBarF = statusBar;
         final BatteryService batteryF = battery;
         final ConnectivityService connectivityF = connectivity;
         final DockObserver dockF = dock;
@@ -485,6 +480,7 @@
             public void run() {
                 Slog.i(TAG, "Making services ready");
 
+                if (statusBarF != null) statusBarF.systemReady2();
                 if (batteryF != null) batteryF.systemReady();
                 if (connectivityF != null) connectivityF.systemReady();
                 if (dockF != null) dockF.systemReady();
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 3606629d..9493161 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -545,7 +545,7 @@
             mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
         }
 
-        // Fear not: StatusBarService manages a list of requests to disable
+        // Fear not: StatusBarManagerService manages a list of requests to disable
         // features of the status bar; these are ORed together to form the
         // active disabled list. So if (for example) the device is locked and
         // the status bar should be totally disabled, the calls below will
diff --git a/services/java/com/android/server/status/IconData.java b/services/java/com/android/server/status/IconData.java
deleted file mode 100644
index fd226f9..0000000
--- a/services/java/com/android/server/status/IconData.java
+++ /dev/null
@@ -1,122 +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.status;
-
-import android.util.Slog;
-
-public class IconData {
-    /**
-     * Indicates ths item represents a piece of text.
-     */
-    public static final int TEXT = 1;
-    
-    /**
-     * Indicates ths item represents an icon.
-     */
-    public static final int ICON = 2;
-
-    /**
-     * The type of this item. One of TEXT, ICON, or LEVEL_ICON.
-     */
-    public int type;
-
-    /**
-     * The slot that this icon will be in if it is not a notification
-     */
-    public String slot;
-
-    /**
-     * The package containting the icon to draw for this item. Valid if this is
-     * an ICON type.
-     */
-    public String iconPackage;
-    
-    /**
-     * The icon to draw for this item. Valid if this is an ICON type.
-     */
-    public int iconId;
-    
-    /**
-     * The level associated with the icon. Valid if this is a LEVEL_ICON type.
-     */
-    public int iconLevel;
-    
-    /**
-     * The "count" number.
-     */
-    public int number;
-
-    /**
-     * The text associated with the icon. Valid if this is a TEXT type.
-     */
-    public CharSequence text;
-
-    private IconData() {
-    }
-
-    public static IconData makeIcon(String slot,
-            String iconPackage, int iconId, int iconLevel, int number) {
-        IconData data = new IconData();
-        data.type = ICON;
-        data.slot = slot;
-        data.iconPackage = iconPackage;
-        data.iconId = iconId;
-        data.iconLevel = iconLevel;
-        data.number = number;
-        return data;
-    }
-    
-    public static IconData makeText(String slot, CharSequence text) {
-        IconData data = new IconData();
-        data.type = TEXT;
-        data.slot = slot;
-        data.text = text;
-        return data;
-    }
-
-    public void copyFrom(IconData that) {
-        this.type = that.type;
-        this.slot = that.slot;
-        this.iconPackage = that.iconPackage;
-        this.iconId = that.iconId;
-        this.iconLevel = that.iconLevel;
-        this.number = that.number;
-        this.text = that.text; // should we clone this?
-    }
-
-    public IconData clone() {
-        IconData that = new IconData();
-        that.copyFrom(this);
-        return that;
-    }
-
-    public String toString() {
-        if (this.type == TEXT) {
-            return "IconData(slot=" + (this.slot != null ? "'" + this.slot + "'" : "null")
-                    + " text='" + this.text + "')"; 
-        }
-        else if (this.type == ICON) {
-            return "IconData(slot=" + (this.slot != null ? "'" + this.slot + "'" : "null")
-                    + " package=" + this.iconPackage
-                    + " iconId=" + Integer.toHexString(this.iconId)
-                    + " iconLevel=" + this.iconLevel + ")"; 
-        }
-        else {
-            return "IconData(type=" + type + ")";
-        }
-    }
-}
diff --git a/services/java/com/android/server/status/NotificationData.java b/services/java/com/android/server/status/NotificationData.java
deleted file mode 100644
index 71f01ca..0000000
--- a/services/java/com/android/server/status/NotificationData.java
+++ /dev/null
@@ -1,44 +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.status;
-
-import android.app.PendingIntent;
-import android.widget.RemoteViews;
-
-public class NotificationData {
-    public String pkg;
-    public String tag;
-    public int id;
-    public CharSequence tickerText;
-
-    public long when;
-    public boolean ongoingEvent;
-    public boolean clearable;
-
-    public RemoteViews contentView;
-    public PendingIntent contentIntent;
-
-    public PendingIntent deleteIntent;
-
-    public String toString() {
-        return "NotificationData(package=" + pkg + " id=" + id + " tickerText=" + tickerText
-                + " ongoingEvent=" + ongoingEvent + " contentIntent=" + contentIntent
-                + " deleteIntent=" + deleteIntent
-                + " clearable=" + clearable
-                + " contentView=" + contentView + " when=" + when + ")";
-    }
-}
diff --git a/services/java/com/android/server/status/NotificationViewList.java b/services/java/com/android/server/status/NotificationViewList.java
deleted file mode 100644
index 1bb56a7..0000000
--- a/services/java/com/android/server/status/NotificationViewList.java
+++ /dev/null
@@ -1,276 +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.status;
-
-import android.os.IBinder;
-import android.util.Slog;
-import android.view.View;
-import java.util.ArrayList;
-
-class NotificationViewList {
-    private ArrayList<StatusBarNotification> mOngoing = new ArrayList();
-    private ArrayList<StatusBarNotification> mLatest = new ArrayList();
-
-    NotificationViewList() {
-    }
-
-    private static final int indexInList(ArrayList<StatusBarNotification> list, NotificationData n){
-        final int N = list.size();
-        for (int i=0; i<N; i++) {
-            StatusBarNotification that = list.get(i);
-            if (that.data == n) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    int getIconIndex(NotificationData n) {
-        final int ongoingSize = mOngoing.size();
-        final int latestSize = mLatest.size();
-        if (n.ongoingEvent) {
-            int index = indexInList(mOngoing, n);
-            if (index >= 0) {
-                return latestSize + index + 1;
-            } else {
-                return -1;
-            }
-        } else {
-            return indexInList(mLatest, n) + 1;
-        }
-    }
-
-    void remove(StatusBarNotification notification) {
-        NotificationData n = notification.data;
-        int index;
-        index = indexInList(mOngoing, n);
-        if (index >= 0) {
-            mOngoing.remove(index);
-            return;
-        }
-        index = indexInList(mLatest, n);
-        if (index >= 0) {
-            mLatest.remove(index);
-            return;
-        }
-    }
-
-    ArrayList<StatusBarNotification> notificationsForPackage(String packageName) {
-        ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>();
-        int N = mOngoing.size();
-        for (int i=0; i<N; i++) {
-            if (matchPackage(mOngoing.get(i), packageName)) {
-                list.add(mOngoing.get(i));
-            }
-        }
-        N = mLatest.size();
-        for (int i=0; i<N; i++) {
-            if (matchPackage(mLatest.get(i), packageName)) {
-                list.add(mLatest.get(i));
-            }
-        }
-        return list;
-    }
-    
-    private final boolean matchPackage(StatusBarNotification snb, String packageName) {
-        if (snb.data.contentIntent != null) {
-            if (snb.data.contentIntent.getTargetPackage().equals(packageName)) {
-                return true;
-            }
-        } else if (snb.data.pkg != null && snb.data.pkg.equals(packageName)) {
-            return true;
-        }
-        return false;
-    }
-    
-    private static final int indexForKey(ArrayList<StatusBarNotification> list, IBinder key) {
-        final int N = list.size();
-        for (int i=0; i<N; i++) {
-            if (list.get(i).key == key) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    StatusBarNotification get(IBinder key) {
-        int index;
-        index = indexForKey(mOngoing, key);
-        if (index >= 0) {
-            return mOngoing.get(index);
-        }
-        index = indexForKey(mLatest, key);
-        if (index >= 0) {
-            return mLatest.get(index);
-        }
-        return null;
-    }
-
-    // gets the index of the notification's view in its expanded parent view
-    int getExpandedIndex(StatusBarNotification notification) {
-        ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
-        final IBinder key = notification.key;
-        int index = 0;
-        // (the view order is backwards from this list order)
-        for (int i=list.size()-1; i>=0; i--) {
-            StatusBarNotification item = list.get(i);
-            if (item.key == key) {
-                return index;
-            }
-            if (item.view != null) {
-                index++;
-            }
-        }
-        Slog.e(StatusBarService.TAG, "Couldn't find notification in NotificationViewList.");
-        Slog.e(StatusBarService.TAG, "notification=" + notification);
-        dump(notification);
-        return 0;
-    }
-
-    void clearViews() {
-        int N = mOngoing.size();
-        for (int i=0; i<N; i++) {
-            mOngoing.get(i).view = null;
-        }
-        N = mLatest.size();
-        for (int i=0; i<N; i++) {
-            mLatest.get(i).view = null;
-        }
-    }
-    
-    int ongoingCount() {
-        return mOngoing.size();
-    }
-
-    int latestCount() {
-        return mLatest.size();
-    }
-
-    StatusBarNotification getOngoing(int index) {
-        return mOngoing.get(index);
-    }
-
-    StatusBarNotification getLatest(int index) {
-        return mLatest.get(index);
-    }
-
-    int size() {
-        return mOngoing.size() + mLatest.size();
-    }
-
-    void add(StatusBarNotification notification) {
-        if (StatusBarService.SPEW) {
-            Slog.d(StatusBarService.TAG, "before add NotificationViewList"
-                    + " notification.data.ongoingEvent=" + notification.data.ongoingEvent);
-            dump(notification);
-        }
-
-        ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
-        long when = notification.data.when;
-        final int N = list.size();
-        int index = N;
-        for (int i=0; i<N; i++) {
-            StatusBarNotification that = list.get(i);
-            if (that.data.when > when) {
-                index = i;
-                break;
-            }
-        }
-        list.add(index, notification);
-
-        if (StatusBarService.SPEW) {
-            Slog.d(StatusBarService.TAG, "after add NotificationViewList index=" + index);
-            dump(notification);
-        }
-    }
-
-    void dump(StatusBarNotification notification) {
-        if (StatusBarService.SPEW) {
-            boolean showTime = false;
-            String s = "";
-            for (int i=0; i<mOngoing.size(); i++) {
-                StatusBarNotification that = mOngoing.get(i);
-                if (that.key == notification.key) {
-                    s += "[";
-                }
-                if (showTime) {
-                    s += that.data.when;
-                } else {
-                    s += that.data.pkg + "/" + that.data.id + "/" + that.view;
-                }
-                if (that.key == notification.key) {
-                    s += "]";
-                }
-                s += " ";
-            }
-            Slog.d(StatusBarService.TAG, "NotificationViewList ongoing: " + s);
-
-            s = "";
-            for (int i=0; i<mLatest.size(); i++) {
-                StatusBarNotification that = mLatest.get(i);
-                if (that.key == notification.key) {
-                    s += "[";
-                }
-                if (showTime) {
-                    s += that.data.when;
-                } else {
-                    s += that.data.pkg + "/" + that.data.id + "/" + that.view;
-                }
-                if (that.key == notification.key) {
-                    s += "]";
-                }
-                s += " ";
-            }
-            Slog.d(StatusBarService.TAG, "NotificationViewList latest:  " + s);
-        }
-    }
-
-    StatusBarNotification get(View view) {
-        int N = mOngoing.size();
-        for (int i=0; i<N; i++) {
-            StatusBarNotification notification = mOngoing.get(i);
-            View v = notification.view;
-            if (v == view) {
-                return notification;
-            }
-        }
-        N = mLatest.size();
-        for (int i=0; i<N; i++) {
-            StatusBarNotification notification = mLatest.get(i);
-            View v = notification.view;
-            if (v == view) {
-                return notification;
-            }
-        }
-        return null;
-    }
-
-    void update(StatusBarNotification notification) {
-        remove(notification);
-        add(notification);
-    }
-
-    boolean hasClearableItems() {
-        int N = mLatest.size();
-        for (int i=0; i<N; i++) {
-            if (mLatest.get(i).data.clearable) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/services/java/com/android/server/status/StatusBarException.java b/services/java/com/android/server/status/StatusBarException.java
deleted file mode 100644
index be58f59..0000000
--- a/services/java/com/android/server/status/StatusBarException.java
+++ /dev/null
@@ -1,23 +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.status;
-
-public class StatusBarException extends RuntimeException {
-    StatusBarException(String msg) {
-        super(msg);
-    }
-}
diff --git a/services/java/com/android/server/status/StatusBarIcon.java b/services/java/com/android/server/status/StatusBarIcon.java
deleted file mode 100644
index f77b550..0000000
--- a/services/java/com/android/server/status/StatusBarIcon.java
+++ /dev/null
@@ -1,183 +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.status;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.util.Slog;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-class StatusBarIcon {
-    // TODO: get this from a resource
-    private static final int ICON_GAP = 8;
-    private static final int ICON_WIDTH = 25;
-    private static final int ICON_HEIGHT = 25;
-
-    public View view;
-
-    IconData mData;
-    
-    private TextView mTextView;
-    private AnimatedImageView mImageView;
-    private TextView mNumberView;
-
-    public StatusBarIcon(Context context, IconData data, ViewGroup parent) {
-        mData = data.clone();
-
-        switch (data.type) {
-            case IconData.TEXT: {
-                TextView t;
-                t = new TextView(context, null, com.android.internal.R.style.TextAppearance_StatusBar_Icon);
-                mTextView = t;
-                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
-                        LinearLayout.LayoutParams.WRAP_CONTENT,
-                        LinearLayout.LayoutParams.MATCH_PARENT);
-                t.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
-                t.setPadding(6, 0, 0, 0);
-                t.setLayoutParams(layoutParams);
-                t.setText(data.text);
-                this.view = t;
-                break;
-            }
-
-            case IconData.ICON: {
-                // container
-                LayoutInflater inflater = (LayoutInflater)context.getSystemService(
-                                                Context.LAYOUT_INFLATER_SERVICE);
-                View v = inflater.inflate(com.android.internal.R.layout.status_bar_icon, parent, false);
-                this.view = v;
-
-                // icon
-                AnimatedImageView im = (AnimatedImageView)v.findViewById(com.android.internal.R.id.image);
-                im.setImageDrawable(getIcon(context, data));
-                im.setImageLevel(data.iconLevel);
-                mImageView = im;
-
-                // number
-                TextView nv = (TextView)v.findViewById(com.android.internal.R.id.number);
-                mNumberView = nv;
-                if (data.number > 0) {
-                    nv.setText("" + data.number);
-                    nv.setVisibility(View.VISIBLE);
-                } else {
-                    nv.setVisibility(View.GONE);
-                }
-                break;
-            }
-        }
-    }
-
-    public void update(Context context, IconData data) throws StatusBarException {
-        if (mData.type != data.type) {
-            throw new StatusBarException("status bar entry type can't change");
-        }
-        switch (data.type) {
-        case IconData.TEXT:
-            if (!TextUtils.equals(mData.text, data.text)) {
-                TextView tv = mTextView;
-                tv.setText(data.text);
-            }
-            break;
-        case IconData.ICON:
-            if (((mData.iconPackage != null && data.iconPackage != null)
-                        && !mData.iconPackage.equals(data.iconPackage))
-                    || mData.iconId != data.iconId
-                    || mData.iconLevel != data.iconLevel) {
-                ImageView im = mImageView;
-                im.setImageDrawable(getIcon(context, data));
-                im.setImageLevel(data.iconLevel);
-            }
-            if (mData.number != data.number) {
-                TextView nv = mNumberView;
-                if (data.number > 0) {
-                    nv.setText("" + data.number);
-                } else {
-                    nv.setText("");
-                }
-            }
-            break;
-        }
-        mData.copyFrom(data);
-    }
-
-    public void update(int number) {
-        if (mData.number != number) {
-            TextView nv = mNumberView;
-            if (number > 0) {
-                nv.setText("" + number);
-            } else {
-                nv.setText("");
-            }
-        }
-        mData.number = number;
-    }
-
-
-    /**
-     * Returns the right icon to use for this item, respecting the iconId and
-     * iconPackage (if set)
-     * 
-     * @param context Context to use to get resources if iconPackage is not set
-     * @return Drawable for this item, or null if the package or item could not
-     *         be found
-     */
-    static Drawable getIcon(Context context, IconData data) {
-
-        Resources r = null;
-
-        if (data.iconPackage != null) {
-            try {
-                r = context.getPackageManager().getResourcesForApplication(data.iconPackage);
-            } catch (PackageManager.NameNotFoundException ex) {
-                Slog.e(StatusBarService.TAG, "Icon package not found: " + data.iconPackage, ex);
-                return null;
-            }
-        } else {
-            r = context.getResources();
-        }
-
-        if (data.iconId == 0) {
-            Slog.w(StatusBarService.TAG, "No icon ID for slot " + data.slot);
-            return null;
-        }
-        
-        try {
-            return r.getDrawable(data.iconId);
-        } catch (RuntimeException e) {
-            Slog.w(StatusBarService.TAG, "Icon not found in "
-                  + (data.iconPackage != null ? data.iconId : "<system>")
-                  + ": " + Integer.toHexString(data.iconId));
-        }
-
-        return null;
-    }
-
-    int getNumber() {
-        return mData.number;
-    }
-}
-
diff --git a/services/java/com/android/server/status/StatusBarManagerService.java b/services/java/com/android/server/status/StatusBarManagerService.java
new file mode 100644
index 0000000..0af1ebb
--- /dev/null
+++ b/services/java/com/android/server/status/StatusBarManagerService.java
@@ -0,0 +1,465 @@
+/*
+ * 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 com.android.server.status;
+
+import android.app.PendingIntent;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import com.android.internal.statusbar.IStatusBar;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.StatusBarNotification;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * A note on locking:  We rely on the fact that calls onto mBar are oneway or
+ * if they are local, that they just enqueue messages to not deadlock.
+ */
+public class StatusBarManagerService extends IStatusBarService.Stub
+{
+    static final String TAG = "StatusBarManagerService";
+    static final boolean SPEW = true;
+
+    public static final String ACTION_STATUSBAR_START
+            = "com.android.internal.policy.statusbar.START";
+
+    final Context mContext;
+    Handler mHandler = new Handler();
+    NotificationCallbacks mNotificationCallbacks;
+    volatile IStatusBar mBar;
+    StatusBarIconList mIcons = new StatusBarIconList();
+    HashMap<IBinder,StatusBarNotification> mNotifications
+            = new HashMap<IBinder,StatusBarNotification>();
+
+    // for disabling the status bar
+    ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
+    int mDisabled = 0;
+
+    private class DisableRecord implements IBinder.DeathRecipient {
+        String pkg;
+        int what;
+        IBinder token;
+
+        public void binderDied() {
+            Slog.i(TAG, "binder died for pkg=" + pkg);
+            disable(0, token, pkg);
+            token.unlinkToDeath(this, 0);
+        }
+    }
+
+    public interface NotificationCallbacks {
+        void onSetDisabled(int status);
+        void onClearAll();
+        void onNotificationClick(String pkg, String tag, int id);
+        void onPanelRevealed();
+    }
+
+    /**
+     * Construct the service, add the status bar view to the window manager
+     */
+    public StatusBarManagerService(Context context) {
+        mContext = context;
+
+        final Resources res = context.getResources();
+        mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.status_bar_icon_order));
+    }
+
+    public void setNotificationCallbacks(NotificationCallbacks listener) {
+        mNotificationCallbacks = listener;
+    }
+
+    // ================================================================================
+    // Constructing the view
+    // ================================================================================
+
+    public void systemReady() {
+    }
+
+    public void systemReady2() {
+        // Start the status bar app
+        Intent intent = new Intent(ACTION_STATUSBAR_START);
+        mContext.sendBroadcast(intent /** permission  **/);
+    }
+
+    // ================================================================================
+    // From IStatusBarService
+    // ================================================================================
+    public void expand() {
+        enforceExpandStatusBar();
+
+        if (mBar != null) {
+            try {
+                mBar.animateExpand();
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
+    public void collapse() {
+        enforceExpandStatusBar();
+
+        if (mBar != null) {
+            try {
+                mBar.animateCollapse();
+            } catch (RemoteException ex) {
+            }
+        }
+    }
+
+    public void disable(int what, IBinder token, String pkg) {
+        enforceStatusBar();
+
+        // It's important that the the callback and the call to mBar get done
+        // in the same order when multiple threads are calling this function
+        // so they are paired correctly.  The messages on the handler will be
+        // handled in the order they were enqueued, but will be outside the lock.
+        synchronized (mDisableRecords) {
+            manageDisableListLocked(what, token, pkg);
+            final int net = gatherDisableActionsLocked();
+            Slog.d(TAG, "disable... net=0x" + Integer.toHexString(net));
+            if (net != mDisabled) {
+                mDisabled = net;
+                mHandler.post(new Runnable() {
+                        public void run() {
+                            mNotificationCallbacks.onSetDisabled(net);
+                        }
+                    });
+                if (mBar != null) {
+                    try {
+                        mBar.disable(net);
+                    } catch (RemoteException ex) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void setIcon(String slot, String iconPackage, int iconId, int iconLevel) {
+        enforceStatusBar();
+
+        synchronized (mIcons) {
+            int index = mIcons.getSlotIndex(slot);
+            if (index < 0) {
+                throw new SecurityException("invalid status bar icon slot: " + slot);
+            }
+
+            StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel);
+            //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
+            mIcons.setIcon(index, icon);
+
+            if (mBar != null) {
+                try {
+                    mBar.setIcon(index, icon);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
+    }
+
+    public void setIconVisibility(String slot, boolean visible) {
+        enforceStatusBar();
+
+        synchronized (mIcons) {
+            int index = mIcons.getSlotIndex(slot);
+            if (index < 0) {
+                throw new SecurityException("invalid status bar icon slot: " + slot);
+            }
+
+            StatusBarIcon icon = mIcons.getIcon(index);
+            if (icon == null) {
+                return;
+            }
+
+            if (icon.visible != visible) {
+                icon.visible = visible;
+
+                if (mBar != null) {
+                    try {
+                        mBar.setIcon(index, icon);
+                    } catch (RemoteException ex) {
+                    }
+                }
+            }
+        }
+    }
+
+    public void removeIcon(String slot) {
+        enforceStatusBar();
+
+        synchronized (mIcons) {
+            int index = mIcons.getSlotIndex(slot);
+            if (index < 0) {
+                throw new SecurityException("invalid status bar icon slot: " + slot);
+            }
+
+            mIcons.removeIcon(index);
+
+            if (mBar != null) {
+                try {
+                    mBar.removeIcon(index);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
+    }
+
+    private void enforceStatusBar() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
+                "StatusBarManagerService");
+    }
+
+    private void enforceExpandStatusBar() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.EXPAND_STATUS_BAR,
+                "StatusBarManagerService");
+    }
+
+
+    // ================================================================================
+    // Callbacks from the status bar service.
+    // ================================================================================
+    public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList,
+            List<IBinder> notificationKeys, List<StatusBarNotification> notifications) {
+        Slog.i(TAG, "registerStatusBar bar=" + bar);
+        mBar = bar;
+        synchronized (mIcons) {
+            iconList.copyFrom(mIcons);
+        }
+        synchronized (mNotifications) {
+            for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
+                notificationKeys.add(e.getKey());
+                notifications.add(e.getValue());
+            }
+        }
+    }
+
+    /**
+     * The status bar service should call this when the user changes whether
+     * the status bar is visible or not.
+     */
+    public void visibilityChanged(boolean visible) {
+        //Slog.d(TAG, "visibilityChanged visible=" + visible);
+    }
+
+    public void onNotificationClick(String pkg, String tag, int id) {
+        mNotificationCallbacks.onNotificationClick(pkg, tag, id);
+    }
+
+    public void onClearAllNotifications() {
+        mNotificationCallbacks.onClearAll();
+    }
+
+    // ================================================================================
+    // Callbacks for NotificationManagerService.
+    // ================================================================================
+    public IBinder addNotification(StatusBarNotification notification) {
+        synchronized (mNotifications) {
+            IBinder key = new Binder();
+            mNotifications.put(key, notification);
+            if (mBar != null) {
+                try {
+                    mBar.addNotification(key, notification);
+                } catch (RemoteException ex) {
+                }
+            }
+            return key;
+        }
+    }
+
+    public void updateNotification(IBinder key, StatusBarNotification notification) {
+        synchronized (mNotifications) {
+            if (!mNotifications.containsKey(key)) {
+                throw new IllegalArgumentException("updateNotification key not found: " + key);
+            }
+            mNotifications.put(key, notification);
+            if (mBar != null) {
+                try {
+                    mBar.updateNotification(key, notification);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
+    }
+
+    public void removeNotification(IBinder key) {
+        synchronized (mNotifications) {
+            final StatusBarNotification n = mNotifications.remove(key);
+            if (n == null) {
+                throw new IllegalArgumentException("removeNotification key not found: " + key);
+            }
+            if (mBar != null) {
+                try {
+                    mBar.removeNotification(key);
+                } catch (RemoteException ex) {
+                }
+            }
+        }
+    }
+
+    // ================================================================================
+    // Can be called from any thread
+    // ================================================================================
+
+    // lock on mDisableRecords
+    void manageDisableListLocked(int what, IBinder token, String pkg) {
+        if (SPEW) {
+            Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
+        }
+        // update the list
+        synchronized (mDisableRecords) {
+            final int N = mDisableRecords.size();
+            DisableRecord tok = null;
+            int i;
+            for (i=0; i<N; i++) {
+                DisableRecord t = mDisableRecords.get(i);
+                if (t.token == token) {
+                    tok = t;
+                    break;
+                }
+            }
+            if (what == 0 || !token.isBinderAlive()) {
+                if (tok != null) {
+                    mDisableRecords.remove(i);
+                    tok.token.unlinkToDeath(tok, 0);
+                }
+            } else {
+                if (tok == null) {
+                    tok = new DisableRecord();
+                    try {
+                        token.linkToDeath(tok, 0);
+                    }
+                    catch (RemoteException ex) {
+                        return; // give up
+                    }
+                    mDisableRecords.add(tok);
+                }
+                tok.what = what;
+                tok.token = token;
+                tok.pkg = pkg;
+            }
+        }
+    }
+
+    // lock on mDisableRecords
+    int gatherDisableActionsLocked() {
+        final int N = mDisableRecords.size();
+        // gather the new net flags
+        int net = 0;
+        for (int i=0; i<N; i++) {
+            net |= mDisableRecords.get(i).what;
+        }
+        return net;
+    }
+
+    // ================================================================================
+    // Always called from UI thread
+    // ================================================================================
+
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump StatusBar from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        synchronized (mIcons) {
+            mIcons.dump(pw);
+        }
+
+        synchronized (mNotifications) {
+            int i=0;
+            pw.println("Notification list:");
+            for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) {
+                pw.printf("  %2d: %s\n", i, e.getValue().toString());
+                i++;
+            }
+        }
+
+        synchronized (mDisableRecords) {
+            final int N = mDisableRecords.size();
+            pw.println("  mDisableRecords.size=" + N
+                    + " mDisabled=0x" + Integer.toHexString(mDisabled));
+            for (int i=0; i<N; i++) {
+                DisableRecord tok = mDisableRecords.get(i);
+                pw.println("    [" + i + "] what=0x" + Integer.toHexString(tok.what)
+                                + " pkg=" + tok.pkg + " token=" + tok.token);
+            }
+        }
+    }
+
+    /**
+     * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
+     * This was added last-minute and is inconsistent with the way the rest of the notifications
+     * are handled, because the notification isn't really cancelled.  The lights are just
+     * turned off.  If any other notifications happen, the lights will turn back on.  Steve says
+     * this is what he wants. (see bug 1131461)
+     */
+    private boolean mPanelSlightlyVisible;
+    void panelSlightlyVisible(boolean visible) {
+        if (mPanelSlightlyVisible != visible) {
+            mPanelSlightlyVisible = visible;
+            if (visible) {
+                // tell the notification manager to turn off the lights.
+                mNotificationCallbacks.onPanelRevealed();
+            }
+        }
+    }
+
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
+                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
+                collapse();
+            }
+            /*
+            else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
+                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
+                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
+            }
+            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+                updateResources();
+            }
+            */
+        }
+    };
+
+}
diff --git a/services/java/com/android/server/status/StatusBarNotification.java b/services/java/com/android/server/status/StatusBarNotification.java
deleted file mode 100644
index e5773f7..0000000
--- a/services/java/com/android/server/status/StatusBarNotification.java
+++ /dev/null
@@ -1,27 +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.status;
-
-import android.os.IBinder;
-import android.view.View;
-
-class StatusBarNotification {
-    IBinder key;
-    NotificationData data;
-    View view;
-    View contentView;
-}
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
deleted file mode 100644
index cab2662..0000000
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ /dev/null
@@ -1,1411 +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.status;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothPbap;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.location.LocationManager;
-import android.media.AudioManager;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.text.format.DateFormat;
-import android.text.style.CharacterStyle;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.util.Slog;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.cdma.EriInfo;
-import com.android.internal.telephony.cdma.TtyIntent;
-import com.android.server.am.BatteryStatsService;
-
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-/**
- * This class contains all of the policy about which icons are installed in the status
- * bar at boot time.  In reality, it should go into the android.policy package, but
- * putting it here is the first step from extracting it.
- */
-public class StatusBarPolicy {
-    private static final String TAG = "StatusBarPolicy";
-
-    private static StatusBarPolicy sInstance;
-
-    // message codes for the handler
-    private static final int EVENT_BATTERY_CLOSE = 4;
-
-    private static final int AM_PM_STYLE_NORMAL  = 0;
-    private static final int AM_PM_STYLE_SMALL   = 1;
-    private static final int AM_PM_STYLE_GONE    = 2;
-
-    private static final int AM_PM_STYLE = AM_PM_STYLE_GONE;
-
-    private final Context mContext;
-    private final StatusBarService mService;
-    private final Handler mHandler = new StatusBarHandler();
-    private final IBatteryStats mBatteryStats;
-
-    // clock
-    private Calendar mCalendar;
-    private String mClockFormatString;
-    private SimpleDateFormat mClockFormat;
-    private IBinder mClockIcon;
-    private IconData mClockData;
-
-    // storage
-    private StorageManager mStorageManager;
-
-    // battery
-    private IBinder mBatteryIcon;
-    private IconData mBatteryData;
-    private boolean mBatteryFirst = true;
-    private boolean mBatteryPlugged;
-    private int mBatteryLevel;
-    private AlertDialog mLowBatteryDialog;
-    private TextView mBatteryLevelTextView;
-    private View mBatteryView;
-    private int mBatteryViewSequence;
-    private boolean mBatteryShowLowOnEndCall = false;
-    private static final boolean SHOW_LOW_BATTERY_WARNING = true;
-    private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
-
-    // phone
-    private TelephonyManager mPhone;
-    private IBinder mPhoneIcon;
-
-    //***** Signal strength icons
-    private IconData mPhoneData;
-    //GSM/UMTS
-    private static final int[] sSignalImages = new int[] {
-        com.android.internal.R.drawable.stat_sys_signal_0,
-        com.android.internal.R.drawable.stat_sys_signal_1,
-        com.android.internal.R.drawable.stat_sys_signal_2,
-        com.android.internal.R.drawable.stat_sys_signal_3,
-        com.android.internal.R.drawable.stat_sys_signal_4
-    };
-    private static final int[] sSignalImages_r = new int[] {
-        com.android.internal.R.drawable.stat_sys_r_signal_0,
-        com.android.internal.R.drawable.stat_sys_r_signal_1,
-        com.android.internal.R.drawable.stat_sys_r_signal_2,
-        com.android.internal.R.drawable.stat_sys_r_signal_3,
-        com.android.internal.R.drawable.stat_sys_r_signal_4
-    };
-    private static final int[] sRoamingIndicatorImages_cdma = new int[] {
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //Standard Roaming Indicator
-        // 1 is Standard Roaming Indicator OFF
-        // TODO T: image never used, remove and put 0 instead?
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-
-        // 2 is Standard Roaming Indicator FLASHING
-        // TODO T: image never used, remove and put 0 instead?
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-
-        // 3-12 Standard ERI
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //3
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-
-        // 13-63 Reserved for Standard ERI
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //13
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-
-        // 64-127 Reserved for Non Standard (Operator Specific) ERI
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0, //64
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0,
-        com.android.internal.R.drawable.stat_sys_roaming_cdma_0 //83
-
-        // 128-255 Reserved
-    };
-
-    //***** Data connection icons
-    private int[] mDataIconList = sDataNetType_g;
-    //GSM/UMTS
-    private static final int[] sDataNetType_g = new int[] {
-            com.android.internal.R.drawable.stat_sys_data_connected_g,
-            com.android.internal.R.drawable.stat_sys_data_in_g,
-            com.android.internal.R.drawable.stat_sys_data_out_g,
-            com.android.internal.R.drawable.stat_sys_data_inandout_g,
-        };
-    private static final int[] sDataNetType_3g = new int[] {
-            com.android.internal.R.drawable.stat_sys_data_connected_3g,
-            com.android.internal.R.drawable.stat_sys_data_in_3g,
-            com.android.internal.R.drawable.stat_sys_data_out_3g,
-            com.android.internal.R.drawable.stat_sys_data_inandout_3g,
-        };
-    private static final int[] sDataNetType_e = new int[] {
-            com.android.internal.R.drawable.stat_sys_data_connected_e,
-            com.android.internal.R.drawable.stat_sys_data_in_e,
-            com.android.internal.R.drawable.stat_sys_data_out_e,
-            com.android.internal.R.drawable.stat_sys_data_inandout_e,
-        };
-    //3.5G
-    private static final int[] sDataNetType_h = new int[] {
-            com.android.internal.R.drawable.stat_sys_data_connected_h,
-            com.android.internal.R.drawable.stat_sys_data_in_h,
-            com.android.internal.R.drawable.stat_sys_data_out_h,
-            com.android.internal.R.drawable.stat_sys_data_inandout_h,
-    };
-
-    //CDMA
-    // Use 3G icons for EVDO data and 1x icons for 1XRTT data
-    private static final int[] sDataNetType_1x = new int[] {
-        com.android.internal.R.drawable.stat_sys_data_connected_1x,
-        com.android.internal.R.drawable.stat_sys_data_in_1x,
-        com.android.internal.R.drawable.stat_sys_data_out_1x,
-        com.android.internal.R.drawable.stat_sys_data_inandout_1x,
-    };
-
-    // Assume it's all good unless we hear otherwise.  We don't always seem
-    // to get broadcasts that it *is* there.
-    IccCard.State mSimState = IccCard.State.READY;
-    int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
-    int mDataState = TelephonyManager.DATA_DISCONNECTED;
-    int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-    ServiceState mServiceState;
-    SignalStrength mSignalStrength;
-
-    // data connection
-    private IBinder mDataIcon;
-    private IconData mDataData;
-    private boolean mDataIconVisible;
-    private boolean mHspaDataDistinguishable;
-
-    // ringer volume
-    private IBinder mVolumeIcon;
-    private IconData mVolumeData;
-    private boolean mVolumeVisible;
-
-    // bluetooth device status
-    private IBinder mBluetoothIcon;
-    private IconData mBluetoothData;
-    private int mBluetoothHeadsetState;
-    private boolean mBluetoothA2dpConnected;
-    private int mBluetoothPbapState;
-    private boolean mBluetoothEnabled;
-
-    // wifi
-    private static final int[] sWifiSignalImages = new int[] {
-            com.android.internal.R.drawable.stat_sys_wifi_signal_1,
-            com.android.internal.R.drawable.stat_sys_wifi_signal_2,
-            com.android.internal.R.drawable.stat_sys_wifi_signal_3,
-            com.android.internal.R.drawable.stat_sys_wifi_signal_4,
-        };
-    private static final int sWifiTemporarilyNotConnectedImage =
-            com.android.internal.R.drawable.stat_sys_wifi_signal_0;
-
-    private int mLastWifiSignalLevel = -1;
-    private boolean mIsWifiConnected = false;
-    private IBinder mWifiIcon;
-    private IconData mWifiData;
-
-    // gps
-    private IBinder mGpsIcon;
-    private IconData mGpsEnabledIconData;
-    private IconData mGpsFixIconData;
-
-    // alarm clock
-    // Icon lit when clock is set
-    private IBinder mAlarmClockIcon;
-    private IconData mAlarmClockIconData;
-
-    // sync state
-    // If sync is active the SyncActive icon is displayed. If sync is not active but
-    // sync is failing the SyncFailing icon is displayed. Otherwise neither are displayed.
-    private IBinder mSyncActiveIcon;
-    private IBinder mSyncFailingIcon;
-
-    // TTY mode
-    // Icon lit when TTY mode is enabled
-    private IBinder mTTYModeIcon;
-    private IconData mTTYModeEnableIconData;
-
-    // Cdma Roaming Indicator, ERI
-    private IBinder mCdmaRoamingIndicatorIcon;
-    private IconData mCdmaRoamingIndicatorIconData;
-
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(Intent.ACTION_TIME_TICK)) {
-                updateClock();
-            }
-            else if (action.equals(Intent.ACTION_TIME_CHANGED)) {
-                updateClock();
-            }
-            else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
-                updateBattery(intent);
-            }
-            else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
-                updateClock();
-            }
-            else if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
-                String tz = intent.getStringExtra("time-zone");
-                mCalendar = Calendar.getInstance(TimeZone.getTimeZone(tz));
-                if (mClockFormat != null) {
-                    mClockFormat.setTimeZone(mCalendar.getTimeZone());
-                }
-                updateClock();
-            }
-            else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {
-                updateAlarm(intent);
-            }
-            else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
-                updateSyncState(intent);
-            }
-            else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
-                onBatteryLow(intent);
-            }
-            else if (action.equals(Intent.ACTION_BATTERY_OKAY)
-                    || action.equals(Intent.ACTION_POWER_CONNECTED)) {
-                onBatteryOkay(intent);
-            }
-            else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
-                    action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
-                    action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
-                    action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
-                updateBluetooth(intent);
-            }
-            else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) ||
-                    action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
-                    action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-                updateWifi(intent);
-            }
-            else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) ||
-                    action.equals(LocationManager.GPS_FIX_CHANGE_ACTION)) {
-                updateGps(intent);
-            }
-            else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
-                    action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
-                updateVolume();
-            }
-            else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
-                updateSimState(intent);
-            }
-            else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) {
-                updateTTY(intent);
-            }
-        }
-    };
-
-    private StatusBarPolicy(Context context, StatusBarService service) {
-        mContext = context;
-        mService = service;
-        mSignalStrength = new SignalStrength();
-        mBatteryStats = BatteryStatsService.getService();
-
-        // clock
-        mCalendar = Calendar.getInstance(TimeZone.getDefault());
-        mClockData = IconData.makeText("clock", "");
-        mClockIcon = service.addIcon(mClockData, null);
-        updateClock();
-
-        // storage
-        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
-        mStorageManager.registerListener(
-                new com.android.server.status.StorageNotification(context));
-
-        // battery
-        mBatteryData = IconData.makeIcon("battery",
-                null, com.android.internal.R.drawable.stat_sys_battery_unknown, 0, 0);
-        mBatteryIcon = service.addIcon(mBatteryData, null);
-
-        // phone_signal
-        mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
-        mPhoneData = IconData.makeIcon("phone_signal",
-                null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0);
-        mPhoneIcon = service.addIcon(mPhoneData, null);
-
-        // register for phone state notifications.
-        ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
-                .listen(mPhoneStateListener,
-                          PhoneStateListener.LISTEN_SERVICE_STATE
-                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
-                        | PhoneStateListener.LISTEN_CALL_STATE
-                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
-                        | PhoneStateListener.LISTEN_DATA_ACTIVITY);
-
-        // data_connection
-        mDataData = IconData.makeIcon("data_connection",
-                null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0);
-        mDataIcon = service.addIcon(mDataData, null);
-        service.setIconVisibility(mDataIcon, false);
-
-        // wifi
-        mWifiData = IconData.makeIcon("wifi", null, sWifiSignalImages[0], 0, 0);
-        mWifiIcon = service.addIcon(mWifiData, null);
-        service.setIconVisibility(mWifiIcon, false);
-        // wifi will get updated by the sticky intents
-
-        // TTY status
-        mTTYModeEnableIconData = IconData.makeIcon("tty",
-                null, com.android.internal.R.drawable.stat_sys_tty_mode, 0, 0);
-        mTTYModeIcon = service.addIcon(mTTYModeEnableIconData, null);
-        service.setIconVisibility(mTTYModeIcon, false);
-
-        // Cdma Roaming Indicator, ERI
-        mCdmaRoamingIndicatorIconData = IconData.makeIcon("cdma_eri",
-                null, com.android.internal.R.drawable.stat_sys_roaming_cdma_0, 0, 0);
-        mCdmaRoamingIndicatorIcon = service.addIcon(mCdmaRoamingIndicatorIconData, null);
-        service.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
-
-        // bluetooth status
-        mBluetoothData = IconData.makeIcon("bluetooth",
-                null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
-        mBluetoothIcon = service.addIcon(mBluetoothData, null);
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null) {
-            mBluetoothEnabled = adapter.isEnabled();
-        } else {
-            mBluetoothEnabled = false;
-        }
-        mBluetoothA2dpConnected = false;
-        mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED;
-        mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED;
-        mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
-
-        // Gps status
-        mGpsEnabledIconData = IconData.makeIcon("gps",
-                null, com.android.internal.R.drawable.stat_sys_gps_acquiring_anim, 0, 0);
-        mGpsFixIconData = IconData.makeIcon("gps",
-                null, com.android.internal.R.drawable.stat_sys_gps_on, 0, 0);
-        mGpsIcon = service.addIcon(mGpsEnabledIconData, null);
-        service.setIconVisibility(mGpsIcon, false);
-
-        // Alarm clock
-        mAlarmClockIconData = IconData.makeIcon(
-                "alarm_clock",
-                null, com.android.internal.R.drawable.stat_notify_alarm, 0, 0);
-        mAlarmClockIcon = service.addIcon(mAlarmClockIconData, null);
-        service.setIconVisibility(mAlarmClockIcon, false);
-
-        // Sync state
-        mSyncActiveIcon = service.addIcon(IconData.makeIcon("sync_active",
-                null, R.drawable.stat_notify_sync_anim0, 0, 0), null);
-        mSyncFailingIcon = service.addIcon(IconData.makeIcon("sync_failing",
-                null, R.drawable.stat_notify_sync_error, 0, 0), null);
-        service.setIconVisibility(mSyncActiveIcon, false);
-        service.setIconVisibility(mSyncFailingIcon, false);
-
-        // volume
-        mVolumeData = IconData.makeIcon("volume",
-                null, com.android.internal.R.drawable.stat_sys_ringer_silent, 0, 0);
-        mVolumeIcon = service.addIcon(mVolumeData, null);
-        service.setIconVisibility(mVolumeIcon, false);
-        updateVolume();
-
-        IntentFilter filter = new IntentFilter();
-
-        // Register for Intent broadcasts for...
-        filter.addAction(Intent.ACTION_TIME_TICK);
-        filter.addAction(Intent.ACTION_TIME_CHANGED);
-        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_BATTERY_LOW);
-        filter.addAction(Intent.ACTION_BATTERY_OKAY);
-        filter.addAction(Intent.ACTION_POWER_CONNECTED);
-        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-        filter.addAction(Intent.ACTION_ALARM_CHANGED);
-        filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
-        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
-        filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
-        filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION);
-        filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION);
-        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
-        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
-
-        // load config to determine if to distinguish Hspa data icon
-        try {
-            mHspaDataDistinguishable = mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_hspa_data_distinguishable);
-        } catch (Exception e) {
-            mHspaDataDistinguishable = false;
-        }
-    }
-
-    public static void installIcons(Context context, StatusBarService service) {
-        sInstance = new StatusBarPolicy(context, service);
-    }
-
-    private final CharSequence getSmallTime() {
-        boolean b24 = DateFormat.is24HourFormat(mContext);
-        int res;
-
-        if (b24) {
-            res = R.string.twenty_four_hour_time_format;
-        } else {
-            res = R.string.twelve_hour_time_format;
-        }
-
-        final char MAGIC1 = '\uEF00';
-        final char MAGIC2 = '\uEF01';
-
-        SimpleDateFormat sdf;
-        String format = mContext.getString(res);
-        if (!format.equals(mClockFormatString)) {
-            /*
-             * Search for an unquoted "a" in the format string, so we can
-             * add dummy characters around it to let us find it again after
-             * formatting and change its size.
-             */
-            if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
-                int a = -1;
-                boolean quoted = false;
-                for (int i = 0; i < format.length(); i++) {
-                    char c = format.charAt(i);
-
-                    if (c == '\'') {
-                        quoted = !quoted;
-                    }
-
-                    if (!quoted && c == 'a') {
-                        a = i;
-                        break;
-                    }
-                }
-
-                if (a >= 0) {
-                    // Move a back so any whitespace before the AM/PM is also in the alternate size.
-                    final int b = a;
-                    while (a > 0 && Character.isWhitespace(format.charAt(a-1))) {
-                        a--;
-                    }
-                    format = format.substring(0, a) + MAGIC1 + format.substring(a, b)
-                            + "a" + MAGIC2 + format.substring(b + 1);
-                }
-            }
-
-            mClockFormat = sdf = new SimpleDateFormat(format);
-            mClockFormatString = format;
-        } else {
-            sdf = mClockFormat;
-        }
-        String result = sdf.format(mCalendar.getTime());
-
-        if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {
-            int magic1 = result.indexOf(MAGIC1);
-            int magic2 = result.indexOf(MAGIC2);
-
-            if (magic1 >= 0 && magic2 > magic1) {
-                SpannableStringBuilder formatted = new SpannableStringBuilder(result);
-
-                if (AM_PM_STYLE == AM_PM_STYLE_GONE) {
-                    formatted.delete(magic1, magic2+1);
-                } else {
-                    if (AM_PM_STYLE == AM_PM_STYLE_SMALL) {
-                        CharacterStyle style = new RelativeSizeSpan(0.7f);
-                        formatted.setSpan(style, magic1, magic2,
-                                          Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-                    }
-
-                    formatted.delete(magic2, magic2 + 1);
-                    formatted.delete(magic1, magic1 + 1);
-                }
-
-                return formatted;
-            }
-        }
- 
-        return result;
-    }
-
-    private final void updateClock() {
-        mCalendar.setTimeInMillis(System.currentTimeMillis());
-        mClockData.text = getSmallTime();
-        mService.updateIcon(mClockIcon, mClockData, null);
-    }
-
-    private final void updateAlarm(Intent intent) {
-        boolean alarmSet = intent.getBooleanExtra("alarmSet", false);
-        mService.setIconVisibility(mAlarmClockIcon, alarmSet);
-    }
-
-    private final void updateSyncState(Intent intent) {
-        boolean isActive = intent.getBooleanExtra("active", false);
-        boolean isFailing = intent.getBooleanExtra("failing", false);
-        mService.setIconVisibility(mSyncActiveIcon, isActive);
-        // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
-        //mService.setIconVisibility(mSyncFailingIcon, isFailing && !isActive);
-    }
-
-    private final void updateBattery(Intent intent) {
-        mBatteryData.iconId = intent.getIntExtra("icon-small", 0);
-        mBatteryData.iconLevel = intent.getIntExtra("level", 0);
-        mService.updateIcon(mBatteryIcon, mBatteryData, null);
-
-        boolean plugged = intent.getIntExtra("plugged", 0) != 0;
-        int level = intent.getIntExtra("level", -1);
-        if (false) {
-            Slog.d(TAG, "updateBattery level=" + level
-                    + " plugged=" + plugged
-                    + " mBatteryPlugged=" + mBatteryPlugged
-                    + " mBatteryLevel=" + mBatteryLevel
-                    + " mBatteryFirst=" + mBatteryFirst);
-        }
-
-        boolean oldPlugged = mBatteryPlugged;
-
-        mBatteryPlugged = plugged;
-        mBatteryLevel = level;
-
-        if (mBatteryFirst) {
-            mBatteryFirst = false;
-        }
-        /*
-         * No longer showing the battery view because it draws attention away
-         * from the USB storage notification. We could still show it when
-         * connected to a brick, but that could lead to the user into thinking
-         * the device does not charge when plugged into USB (since he/she would
-         * not see the same battery screen on USB as he sees on brick).
-         */
-        /* else {
-            if (plugged && !oldPlugged) {
-                showBatteryView();
-            }
-        }
-        */
-        if (false) {
-            Slog.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
-        }
-    }
-
-    private void onBatteryLow(Intent intent) {
-        if (SHOW_LOW_BATTERY_WARNING) {
-            if (false) {
-                Slog.d(TAG, "mPhoneState=" + mPhoneState
-                      + " mLowBatteryDialog=" + mLowBatteryDialog
-                      + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
-            }
-
-            if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
-                showLowBatteryWarning();
-            } else {
-                mBatteryShowLowOnEndCall = true;
-            }
-        }
-    }
-
-    private void onBatteryOkay(Intent intent) {
-        if (mLowBatteryDialog != null
-                && SHOW_LOW_BATTERY_WARNING) {
-            mLowBatteryDialog.dismiss();
-            mBatteryShowLowOnEndCall = false;
-        }
-    }
-
-    private void showBatteryView() {
-        closeLastBatteryView();
-        if (mLowBatteryDialog != null) {
-            mLowBatteryDialog.dismiss();
-        }
-
-        int level = mBatteryLevel;
-
-        View v = View.inflate(mContext, com.android.internal.R.layout.battery_status, null);
-        mBatteryView = v;
-        int pixelFormat = PixelFormat.TRANSLUCENT;
-        Drawable bg = v.getBackground();
-        if (bg != null) {
-            pixelFormat = bg.getOpacity();
-        }
-
-        int flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-
-        if (!mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_sf_slowBlur)) {
-            flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
-        }
-
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_TOAST,
-                flags, pixelFormat);
-
-        // Get the dim amount from the theme
-        TypedArray a = mContext.obtainStyledAttributes(
-                com.android.internal.R.styleable.Theme);
-        lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f);
-        a.recycle();
-
-        lp.setTitle("Battery");
-
-        TextView levelTextView = (TextView)v.findViewById(com.android.internal.R.id.level_percent);
-        levelTextView.setText(mContext.getString(
-                    com.android.internal.R.string.battery_status_text_percent_format, level));
-
-        setBatteryLevel(v, com.android.internal.R.id.spacer, 100-level, 0, 0);
-        setBatteryLevel(v, com.android.internal.R.id.level, level,
-                com.android.internal.R.drawable.battery_charge_fill, level);
-
-        WindowManagerImpl.getDefault().addView(v, lp);
-
-        scheduleCloseBatteryView();
-    }
-
-    private void setBatteryLevel(View parent, int id, int height, int background, int level) {
-        ImageView v = (ImageView)parent.findViewById(id);
-        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)v.getLayoutParams();
-        lp.weight = height;
-        if (background != 0) {
-            v.setBackgroundResource(background);
-            Drawable bkg = v.getBackground();
-            bkg.setLevel(level);
-        }
-    }
-
-    private void showLowBatteryWarning() {
-        closeLastBatteryView();
-
-        // Show exact battery level.
-        CharSequence levelText = mContext.getString(
-                    com.android.internal.R.string.battery_low_percent_format, mBatteryLevel);
-
-        if (mBatteryLevelTextView != null) {
-            mBatteryLevelTextView.setText(levelText);
-        } else {
-            View v = View.inflate(mContext, com.android.internal.R.layout.battery_low, null);
-            mBatteryLevelTextView=(TextView)v.findViewById(com.android.internal.R.id.level_percent);
-
-            mBatteryLevelTextView.setText(levelText);
-
-            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
-                b.setCancelable(true);
-                b.setTitle(com.android.internal.R.string.battery_low_title);
-                b.setView(v);
-                b.setIcon(android.R.drawable.ic_dialog_alert);
-                b.setPositiveButton(android.R.string.ok, null);
-
-                final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                        | Intent.FLAG_ACTIVITY_NO_HISTORY);
-                if (intent.resolveActivity(mContext.getPackageManager()) != null) {
-                    b.setNegativeButton(com.android.internal.R.string.battery_low_why,
-                            new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            mContext.startActivity(intent);
-                            if (mLowBatteryDialog != null) {
-                                mLowBatteryDialog.dismiss();
-                            }
-                        }
-                    });
-                }
-
-            AlertDialog d = b.create();
-            d.setOnDismissListener(mLowBatteryListener);
-            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            d.show();
-            mLowBatteryDialog = d;
-        }
-
-        final ContentResolver cr = mContext.getContentResolver();
-        if (Settings.System.getInt(cr,
-                Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)
-        {
-            final String soundPath = Settings.System.getString(cr,
-                Settings.System.LOW_BATTERY_SOUND);
-            if (soundPath != null) {
-                final Uri soundUri = Uri.parse("file://" + soundPath);
-                if (soundUri != null) {
-                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
-                    if (sfx != null) {
-                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);
-                        sfx.play();
-                    }
-                }
-            }
-        }
-    }
-
-    private final void updateCallState(int state) {
-        mPhoneState = state;
-        if (false) {
-            Slog.d(TAG, "mPhoneState=" + mPhoneState
-                    + " mLowBatteryDialog=" + mLowBatteryDialog
-                    + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
-        }
-        if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
-            if (mBatteryShowLowOnEndCall) {
-                if (!mBatteryPlugged) {
-                    showLowBatteryWarning();
-                }
-                mBatteryShowLowOnEndCall = false;
-            }
-        } else {
-            if (mLowBatteryDialog != null) {
-                mLowBatteryDialog.dismiss();
-                mBatteryShowLowOnEndCall = true;
-            }
-        }
-    }
-
-    private DialogInterface.OnDismissListener mLowBatteryListener
-            = new DialogInterface.OnDismissListener() {
-        public void onDismiss(DialogInterface dialog) {
-            mLowBatteryDialog = null;
-            mBatteryLevelTextView = null;
-        }
-    };
-
-    private void scheduleCloseBatteryView() {
-        Message m = mHandler.obtainMessage(EVENT_BATTERY_CLOSE);
-        m.arg1 = (++mBatteryViewSequence);
-        mHandler.sendMessageDelayed(m, 3000);
-    }
-
-    private void closeLastBatteryView() {
-        if (mBatteryView != null) {
-            //mBatteryView.debug();
-            WindowManagerImpl.getDefault().removeView(mBatteryView);
-            mBatteryView = null;
-        }
-    }
-
-    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-            mSignalStrength = signalStrength;
-            updateSignalStrength();
-        }
-
-        @Override
-        public void onServiceStateChanged(ServiceState state) {
-            mServiceState = state;
-            updateSignalStrength();
-            updateCdmaRoamingIcon(state);
-            updateDataIcon();
-        }
-
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            updateCallState(state);
-            // In cdma, if a voice call is made, RSSI should switch to 1x.
-            if (isCdma()) {
-                updateSignalStrength();
-            }
-        }
-
-        @Override
-        public void onDataConnectionStateChanged(int state, int networkType) {
-            mDataState = state;
-            updateDataNetType(networkType);
-            updateDataIcon();
-        }
-
-        @Override
-        public void onDataActivity(int direction) {
-            mDataActivity = direction;
-            updateDataIcon();
-        }
-    };
-
-    private final void updateSimState(Intent intent) {
-        String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
-        if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-            mSimState = IccCard.State.ABSENT;
-        }
-        else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-            mSimState = IccCard.State.READY;
-        }
-        else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
-            final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
-            if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                mSimState = IccCard.State.PIN_REQUIRED;
-            }
-            else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                mSimState = IccCard.State.PUK_REQUIRED;
-            }
-            else {
-                mSimState = IccCard.State.NETWORK_LOCKED;
-            }
-        } else {
-            mSimState = IccCard.State.UNKNOWN;
-        }
-        updateDataIcon();
-    }
-
-    private boolean isCdma() {
-        return (mSignalStrength != null) && !mSignalStrength.isGsm();
-    }
-
-    private boolean isEvdo() {
-        return ( (mServiceState != null)
-                 && ((mServiceState.getRadioTechnology()
-                        == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
-                     || (mServiceState.getRadioTechnology()
-                        == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
-                     || (mServiceState.getRadioTechnology()
-                        == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
-    }
-
-    private boolean hasService() {
-        if (mServiceState != null) {
-            switch (mServiceState.getState()) {
-                case ServiceState.STATE_OUT_OF_SERVICE:
-                case ServiceState.STATE_POWER_OFF:
-                    return false;
-                default:
-                    return true;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    private final void updateSignalStrength() {
-        int iconLevel = -1;
-        int[] iconList;
-
-        // Display signal strength while in "emergency calls only" mode
-        if (!hasService() && !mServiceState.isEmergencyOnly()) {
-            //Slog.d(TAG, "updateSignalStrength: no service");
-            if (Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
-                mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_flightmode;
-            } else {
-                mPhoneData.iconId = com.android.internal.R.drawable.stat_sys_signal_null;
-            }
-            mService.updateIcon(mPhoneIcon, mPhoneData, null);
-            return;
-        }
-
-        if (!isCdma()) {
-            int asu = mSignalStrength.getGsmSignalStrength();
-
-            // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-            // asu = 0 (-113dB or less) is very weak
-            // signal, its better to show 0 bars to the user in such cases.
-            // asu = 99 is a special case, where the signal strength is unknown.
-            if (asu <= 2 || asu == 99) iconLevel = 0;
-            else if (asu >= 12) iconLevel = 4;
-            else if (asu >= 8)  iconLevel = 3;
-            else if (asu >= 5)  iconLevel = 2;
-            else iconLevel = 1;
-
-            // Though mPhone is a Manager, this call is not an IPC
-            if (mPhone.isNetworkRoaming()) {
-                iconList = sSignalImages_r;
-            } else {
-                iconList = sSignalImages;
-            }
-        } else {
-            iconList = this.sSignalImages;
-
-            // If 3G(EV) and 1x network are available than 3G should be
-            // displayed, displayed RSSI should be from the EV side.
-            // If a voice call is made then RSSI should switch to 1x.
-            if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
-                iconLevel = getEvdoLevel();
-                if (false) {
-                    Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel());
-                }
-            } else {
-                iconLevel = getCdmaLevel();
-            }
-        }
-        mPhoneData.iconId = iconList[iconLevel];
-        mService.updateIcon(mPhoneIcon, mPhoneData, null);
-    }
-
-    private int getCdmaLevel() {
-        final int cdmaDbm = mSignalStrength.getCdmaDbm();
-        final int cdmaEcio = mSignalStrength.getCdmaEcio();
-        int levelDbm = 0;
-        int levelEcio = 0;
-
-        if (cdmaDbm >= -75) levelDbm = 4;
-        else if (cdmaDbm >= -85) levelDbm = 3;
-        else if (cdmaDbm >= -95) levelDbm = 2;
-        else if (cdmaDbm >= -100) levelDbm = 1;
-        else levelDbm = 0;
-
-        // Ec/Io are in dB*10
-        if (cdmaEcio >= -90) levelEcio = 4;
-        else if (cdmaEcio >= -110) levelEcio = 3;
-        else if (cdmaEcio >= -130) levelEcio = 2;
-        else if (cdmaEcio >= -150) levelEcio = 1;
-        else levelEcio = 0;
-
-        return (levelDbm < levelEcio) ? levelDbm : levelEcio;
-    }
-
-    private int getEvdoLevel() {
-        int evdoDbm = mSignalStrength.getEvdoDbm();
-        int evdoSnr = mSignalStrength.getEvdoSnr();
-        int levelEvdoDbm = 0;
-        int levelEvdoSnr = 0;
-
-        if (evdoDbm >= -65) levelEvdoDbm = 4;
-        else if (evdoDbm >= -75) levelEvdoDbm = 3;
-        else if (evdoDbm >= -90) levelEvdoDbm = 2;
-        else if (evdoDbm >= -105) levelEvdoDbm = 1;
-        else levelEvdoDbm = 0;
-
-        if (evdoSnr >= 7) levelEvdoSnr = 4;
-        else if (evdoSnr >= 5) levelEvdoSnr = 3;
-        else if (evdoSnr >= 3) levelEvdoSnr = 2;
-        else if (evdoSnr >= 1) levelEvdoSnr = 1;
-        else levelEvdoSnr = 0;
-
-        return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
-    }
-
-    private final void updateDataNetType(int net) {
-        switch (net) {
-        case TelephonyManager.NETWORK_TYPE_EDGE:
-            mDataIconList = sDataNetType_e;
-            break;
-        case TelephonyManager.NETWORK_TYPE_UMTS:
-            mDataIconList = sDataNetType_3g;
-            break;
-        case TelephonyManager.NETWORK_TYPE_HSDPA:
-        case TelephonyManager.NETWORK_TYPE_HSUPA:
-        case TelephonyManager.NETWORK_TYPE_HSPA:
-            if (mHspaDataDistinguishable) {
-                mDataIconList = sDataNetType_h;
-            } else {
-                mDataIconList = sDataNetType_3g;
-            }
-            break;
-        case TelephonyManager.NETWORK_TYPE_CDMA:
-            // display 1xRTT for IS95A/B
-            mDataIconList = this.sDataNetType_1x;
-            break;
-        case TelephonyManager.NETWORK_TYPE_1xRTT:
-            mDataIconList = this.sDataNetType_1x;
-            break;
-        case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
-        case TelephonyManager.NETWORK_TYPE_EVDO_A:
-        case TelephonyManager.NETWORK_TYPE_EVDO_B:
-            mDataIconList = sDataNetType_3g;
-            break;
-        default:
-            mDataIconList = sDataNetType_g;
-        break;
-        }
-    }
-
-    private final void updateDataIcon() {
-        int iconId;
-        boolean visible = true;
-
-        if (!isCdma()) {
-            // GSM case, we have to check also the sim state
-            if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
-                if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
-                    switch (mDataActivity) {
-                        case TelephonyManager.DATA_ACTIVITY_IN:
-                            iconId = mDataIconList[1];
-                            break;
-                        case TelephonyManager.DATA_ACTIVITY_OUT:
-                            iconId = mDataIconList[2];
-                            break;
-                        case TelephonyManager.DATA_ACTIVITY_INOUT:
-                            iconId = mDataIconList[3];
-                            break;
-                        default:
-                            iconId = mDataIconList[0];
-                            break;
-                    }
-                    mDataData.iconId = iconId;
-                    mService.updateIcon(mDataIcon, mDataData, null);
-                } else {
-                    visible = false;
-                }
-            } else {
-                mDataData.iconId = com.android.internal.R.drawable.stat_sys_no_sim;
-                mService.updateIcon(mDataIcon, mDataData, null);
-            }
-        } else {
-            // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
-            if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
-                switch (mDataActivity) {
-                    case TelephonyManager.DATA_ACTIVITY_IN:
-                        iconId = mDataIconList[1];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_OUT:
-                        iconId = mDataIconList[2];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_INOUT:
-                        iconId = mDataIconList[3];
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_DORMANT:
-                    default:
-                        iconId = mDataIconList[0];
-                        break;
-                }
-                mDataData.iconId = iconId;
-                mService.updateIcon(mDataIcon, mDataData, null);
-            } else {
-                visible = false;
-            }
-        }
-
-        long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-
-        if (mDataIconVisible != visible) {
-            mService.setIconVisibility(mDataIcon, visible);
-            mDataIconVisible = visible;
-        }
-    }
-
-    private final void updateVolume() {
-        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        final int ringerMode = audioManager.getRingerMode();
-        final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
-                ringerMode == AudioManager.RINGER_MODE_VIBRATE;
-        final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
-                ? com.android.internal.R.drawable.stat_sys_ringer_vibrate
-                : com.android.internal.R.drawable.stat_sys_ringer_silent;
-
-        if (visible) {
-            mVolumeData.iconId = iconId;
-            mService.updateIcon(mVolumeIcon, mVolumeData, null);
-        }
-        if (visible != mVolumeVisible) {
-            mService.setIconVisibility(mVolumeIcon, visible);
-            mVolumeVisible = visible;
-        }
-    }
-
-    private final void updateBluetooth(Intent intent) {
-        int iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth;
-        String action = intent.getAction();
-        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-            mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
-        } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
-            mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
-                    BluetoothHeadset.STATE_ERROR);
-        } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
-            BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
-            if (a2dp.getConnectedSinks().size() != 0) {
-                mBluetoothA2dpConnected = true;
-            } else {
-                mBluetoothA2dpConnected = false;
-            }
-        } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
-            mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
-                    BluetoothPbap.STATE_DISCONNECTED);
-        } else {
-            return;
-        }
-
-        if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected ||
-                mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) {
-            iconId = com.android.internal.R.drawable.stat_sys_data_bluetooth_connected;
-        }
-
-        mBluetoothData.iconId = iconId;
-        mService.updateIcon(mBluetoothIcon, mBluetoothData, null);
-        mService.setIconVisibility(mBluetoothIcon, mBluetoothEnabled);
-    }
-
-    private final void updateWifi(Intent intent) {
-        final String action = intent.getAction();
-        if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-
-            final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                    WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
-            if (!enabled) {
-                // If disabled, hide the icon. (We show icon when connected.)
-                mService.setIconVisibility(mWifiIcon, false);
-            }
-
-        } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
-            final boolean enabled = intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED,
-                                                           false);
-            if (!enabled) {
-                mService.setIconVisibility(mWifiIcon, false);
-            }
-        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-
-            final NetworkInfo networkInfo = (NetworkInfo)
-                    intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-
-            int iconId;
-            if (networkInfo != null && networkInfo.isConnected()) {
-                mIsWifiConnected = true;
-                if (mLastWifiSignalLevel == -1) {
-                    iconId = sWifiSignalImages[0];
-                } else {
-                    iconId = sWifiSignalImages[mLastWifiSignalLevel];
-                }
-
-                // Show the icon since wi-fi is connected
-                mService.setIconVisibility(mWifiIcon, true);
-
-            } else {
-                mLastWifiSignalLevel = -1;
-                mIsWifiConnected = false;
-                iconId = sWifiSignalImages[0];
-
-                // Hide the icon since we're not connected
-                mService.setIconVisibility(mWifiIcon, false);
-            }
-
-            mWifiData.iconId = iconId;
-            mService.updateIcon(mWifiIcon, mWifiData, null);
-        } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-            final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
-            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
-                                                                  sWifiSignalImages.length);
-            if (newSignalLevel != mLastWifiSignalLevel) {
-                mLastWifiSignalLevel = newSignalLevel;
-                if (mIsWifiConnected) {
-                    mWifiData.iconId = sWifiSignalImages[newSignalLevel];
-                } else {
-                    mWifiData.iconId = sWifiTemporarilyNotConnectedImage;
-                }
-                mService.updateIcon(mWifiIcon, mWifiData, null);
-            }
-        }
-    }
-
-    private final void updateGps(Intent intent) {
-        final String action = intent.getAction();
-        final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false);
-
-        if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
-            // GPS is getting fixes
-            mService.updateIcon(mGpsIcon, mGpsFixIconData, null);
-            mService.setIconVisibility(mGpsIcon, true);
-        } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
-            // GPS is off
-            mService.setIconVisibility(mGpsIcon, false);
-        } else {
-            // GPS is on, but not receiving fixes
-            mService.updateIcon(mGpsIcon, mGpsEnabledIconData, null);
-            mService.setIconVisibility(mGpsIcon, true);
-        }
-    }
-
-    private final void updateTTY(Intent intent) {
-        final String action = intent.getAction();
-        final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
-
-        if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
-
-        if (enabled) {
-            // TTY is on
-            if (false) Slog.v(TAG, "updateTTY: set TTY on");
-            mService.updateIcon(mTTYModeIcon, mTTYModeEnableIconData, null);
-            mService.setIconVisibility(mTTYModeIcon, true);
-        } else {
-            // TTY is off
-            if (false) Slog.v(TAG, "updateTTY: set TTY off");
-            mService.setIconVisibility(mTTYModeIcon, false);
-        }
-    }
-
-    private final void updateCdmaRoamingIcon(ServiceState state) {
-        if (!hasService()) {
-            mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
-            return;
-        }
-
-        if (!isCdma()) {
-            mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
-            return;
-        }
-
-        int[] iconList = sRoamingIndicatorImages_cdma;
-        int iconIndex = state.getCdmaEriIconIndex();
-        int iconMode = state.getCdmaEriIconMode();
-
-        if (iconIndex == -1) {
-            Slog.e(TAG, "getCdmaEriIconIndex returned null, skipping ERI icon update");
-            return;
-        }
-
-        if (iconMode == -1) {
-            Slog.e(TAG, "getCdmeEriIconMode returned null, skipping ERI icon update");
-            return;
-        }
-
-        if (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) {
-            if (false) Slog.v(TAG, "Cdma ROAMING_INDICATOR_OFF, removing ERI icon");
-            mService.setIconVisibility(mCdmaRoamingIndicatorIcon, false);
-            return;
-        }
-
-        switch (iconMode) {
-            case EriInfo.ROAMING_ICON_MODE_NORMAL:
-                mCdmaRoamingIndicatorIconData.iconId = iconList[iconIndex];
-                mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null);
-                mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true);
-                break;
-            case EriInfo.ROAMING_ICON_MODE_FLASH:
-                mCdmaRoamingIndicatorIconData.iconId =
-                        com.android.internal.R.drawable.stat_sys_roaming_cdma_flash;
-                mService.updateIcon(mCdmaRoamingIndicatorIcon, mCdmaRoamingIndicatorIconData, null);
-                mService.setIconVisibility(mCdmaRoamingIndicatorIcon, true);
-                break;
-
-        }
-        mService.updateIcon(mPhoneIcon, mPhoneData, null);
-    }
-
-
-    private class StatusBarHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case EVENT_BATTERY_CLOSE:
-                if (msg.arg1 == mBatteryViewSequence) {
-                    closeLastBatteryView();
-                }
-                break;
-            }
-        }
-    }
-}
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
deleted file mode 100644
index 93c8d34..0000000
--- a/services/java/com/android/server/status/StatusBarService.java
+++ /dev/null
@@ -1,1881 +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 com.android.server.status;
-
-import com.android.internal.R;
-import com.android.internal.util.CharSequences;
-
-import android.app.ActivityManagerNative;
-import android.app.Dialog;
-import android.app.IStatusBar;
-import android.app.PendingIntent;
-import android.app.StatusBarManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Telephony;
-import android.util.Slog;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.LinearLayout;
-import android.widget.RemoteViews;
-import android.widget.ScrollView;
-import android.widget.TextView;
-import android.widget.FrameLayout;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
-
-
-/**
- * The public (ok, semi-public) service for the status bar.
- * <p>
- * This interesting thing to note about this class is that most of the methods that
- * are called from other classes just post a message, and everything else is batched
- * and coalesced into a series of calls to methods that all start with "perform."
- * There are two reasons for this.  The first is that some of the methods (activate/deactivate)
- * are on IStatusBar, so they're called from the thread pool and they need to make their
- * way onto the UI thread.  The second is that the message queue is stopped while animations
- * are happening in order to make for smoother transitions.
- * <p>
- * Each icon is either an icon or an icon and a notification.  They're treated mostly
- * separately throughout the code, although they both use the same key, which is assigned
- * when they are created.
- */
-public class StatusBarService extends IStatusBar.Stub
-{
-    static final String TAG = "StatusBar";
-    static final boolean SPEW = false;
-
-    static final int EXPANDED_LEAVE_ALONE = -10000;
-    static final int EXPANDED_FULL_OPEN = -10001;
-
-    private static final int MSG_ANIMATE = 1000;
-    private static final int MSG_ANIMATE_REVEAL = 1001;
-
-    private static final int OP_ADD_ICON = 1;
-    private static final int OP_UPDATE_ICON = 2;
-    private static final int OP_REMOVE_ICON = 3;
-    private static final int OP_SET_VISIBLE = 4;
-    private static final int OP_EXPAND = 5;
-    private static final int OP_TOGGLE = 6;
-    private static final int OP_DISABLE = 7;
-    private class PendingOp {
-        IBinder key;
-        int code;
-        IconData iconData;
-        NotificationData notificationData;
-        boolean visible;
-        int integer;
-    }
-
-    private class DisableRecord implements IBinder.DeathRecipient {
-        String pkg;
-        int what;
-        IBinder token;
-
-        public void binderDied() {
-            Slog.i(TAG, "binder died for pkg=" + pkg);
-            disable(0, token, pkg);
-            token.unlinkToDeath(this, 0);
-        }
-    }
-
-    public interface NotificationCallbacks {
-        void onSetDisabled(int status);
-        void onClearAll();
-        void onNotificationClick(String pkg, String tag, int id);
-        void onPanelRevealed();
-    }
-
-    private class ExpandedDialog extends Dialog {
-        ExpandedDialog(Context context) {
-            super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
-        }
-
-        @Override
-        public boolean dispatchKeyEvent(KeyEvent event) {
-            boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
-            switch (event.getKeyCode()) {
-            case KeyEvent.KEYCODE_BACK:
-                if (!down) {
-                    StatusBarService.this.deactivate();
-                }
-                return true;
-            }
-            return super.dispatchKeyEvent(event);
-        }
-    }
-    
-    final Context mContext;
-    final Display mDisplay;
-    StatusBarView mStatusBarView;
-    int mPixelFormat;
-    H mHandler = new H();
-    Object mQueueLock = new Object();
-    ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>();
-    NotificationCallbacks mNotificationCallbacks;
-    
-    // All accesses to mIconMap and mNotificationData are syncronized on those objects,
-    // but this is only so dump() can work correctly.  Modifying these outside of the UI
-    // thread will not work, there are places in the code that unlock and reaquire between
-    // reads and require them to not be modified.
-
-    // icons
-    HashMap<IBinder,StatusBarIcon> mIconMap = new HashMap<IBinder,StatusBarIcon>();
-    ArrayList<StatusBarIcon> mIconList = new ArrayList<StatusBarIcon>();
-    String[] mRightIconSlots;
-    StatusBarIcon[] mRightIcons;
-    LinearLayout mIcons;
-    IconMerger mNotificationIcons;
-    LinearLayout mStatusIcons;
-    StatusBarIcon mMoreIcon;
-    private UninstallReceiver mUninstallReceiver;
-
-    // expanded notifications
-    NotificationViewList mNotificationData = new NotificationViewList();
-    Dialog mExpandedDialog;
-    ExpandedView mExpandedView;
-    WindowManager.LayoutParams mExpandedParams;
-    ScrollView mScrollView;
-    View mNotificationLinearLayout;
-    TextView mOngoingTitle;
-    LinearLayout mOngoingItems;
-    TextView mLatestTitle;
-    LinearLayout mLatestItems;
-    TextView mNoNotificationsTitle;
-    TextView mSpnLabel;
-    TextView mPlmnLabel;
-    TextView mClearButton;
-    View mExpandedContents;
-    CloseDragHandle mCloseView;
-    int[] mPositionTmp = new int[2];
-    boolean mExpanded;
-    boolean mExpandedVisible;
-
-    // the date view
-    DateView mDateView;
-
-    // the tracker view
-    TrackingView mTrackingView;
-    WindowManager.LayoutParams mTrackingParams;
-    int mTrackingPosition; // the position of the top of the tracking view.
-
-    // ticker
-    private Ticker mTicker;
-    private View mTickerView;
-    private boolean mTicking;
-    
-    // Tracking finger for opening/closing.
-    int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
-    boolean mTracking;
-    VelocityTracker mVelocityTracker;
-    
-    static final int ANIM_FRAME_DURATION = (1000/60);
-    
-    boolean mAnimating;
-    long mCurAnimationTime;
-    float mDisplayHeight;
-    float mAnimY;
-    float mAnimVel;
-    float mAnimAccel;
-    long mAnimLastTime;
-    boolean mAnimatingReveal = false;
-    int mViewDelta;
-    int[] mAbsPos = new int[2];
-    
-    // for disabling the status bar
-    ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
-    int mDisabled = 0;
-
-    /**
-     * Construct the service, add the status bar view to the window manager
-     */
-    public StatusBarService(Context context) {
-        mContext = context;
-        mDisplay = ((WindowManager)context.getSystemService(
-                Context.WINDOW_SERVICE)).getDefaultDisplay();
-        makeStatusBarView(context);
-        mUninstallReceiver = new UninstallReceiver();
-    }
-
-    public void setNotificationCallbacks(NotificationCallbacks listener) {
-        mNotificationCallbacks = listener;
-    }
-
-    // ================================================================================
-    // Constructing the view
-    // ================================================================================
-    private void makeStatusBarView(Context context) {
-        Resources res = context.getResources();
-        mRightIconSlots = res.getStringArray(com.android.internal.R.array.status_bar_icon_order);
-        mRightIcons = new StatusBarIcon[mRightIconSlots.length];
-
-        ExpandedView expanded = (ExpandedView)View.inflate(context,
-                com.android.internal.R.layout.status_bar_expanded, null);
-        expanded.mService = this;
-        StatusBarView sb = (StatusBarView)View.inflate(context,
-                com.android.internal.R.layout.status_bar, null);
-        sb.mService = this;
-
-        // figure out which pixel-format to use for the status bar.
-        mPixelFormat = PixelFormat.TRANSLUCENT;
-        Drawable bg = sb.getBackground();
-        if (bg != null) {
-            mPixelFormat = bg.getOpacity();
-        }
-
-        mStatusBarView = sb;
-        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
-        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
-        mNotificationIcons.service = this;
-        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
-        mTickerView = sb.findViewById(R.id.ticker);
-        mDateView = (DateView)sb.findViewById(R.id.date);
-
-        mExpandedDialog = new ExpandedDialog(context);
-        mExpandedView = expanded;
-        mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);
-        mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle);
-        mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems);
-        mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle);
-        mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems);
-        mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
-        mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button);
-        mClearButton.setOnClickListener(mClearButtonListener);
-        mSpnLabel = (TextView)expanded.findViewById(R.id.spnLabel);
-        mPlmnLabel = (TextView)expanded.findViewById(R.id.plmnLabel);
-        mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
-        mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
-
-        mOngoingTitle.setVisibility(View.GONE);
-        mLatestTitle.setVisibility(View.GONE);
-        
-        mTicker = new MyTicker(context, sb);
-
-        TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
-        tickerView.mTicker = mTicker;
-
-        mTrackingView = (TrackingView)View.inflate(context,
-                com.android.internal.R.layout.status_bar_tracking, null);
-        mTrackingView.mService = this;
-        mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close);
-        mCloseView.mService = this;
-
-        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
-
-        // add the more icon for the notifications
-        IconData moreData = IconData.makeIcon(null, context.getPackageName(),
-                R.drawable.stat_notify_more, 0, 42);
-        mMoreIcon = new StatusBarIcon(context, moreData, mNotificationIcons);
-        mMoreIcon.view.setId(R.drawable.stat_notify_more);
-        mNotificationIcons.moreIcon = mMoreIcon;
-        mNotificationIcons.addView(mMoreIcon.view);
-
-        // set the inital view visibility
-        setAreThereNotifications();
-        mDateView.setVisibility(View.INVISIBLE);
-
-        // before we register for broadcasts
-        mPlmnLabel.setText(R.string.lockscreen_carrier_default);
-        mPlmnLabel.setVisibility(View.VISIBLE);
-        mSpnLabel.setText("");
-        mSpnLabel.setVisibility(View.GONE);
-
-        // receive broadcasts
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
-        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
-        context.registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    public void systemReady() {
-        final StatusBarView view = mStatusBarView;
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                view.getContext().getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.status_bar_height),
-                WindowManager.LayoutParams.TYPE_STATUS_BAR,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
-                WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
-                mPixelFormat);
-        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
-        lp.setTitle("StatusBar");
-        lp.windowAnimations = R.style.Animation_StatusBar;
-
-        WindowManagerImpl.getDefault().addView(view, lp);
-    }
-    
-    // ================================================================================
-    // From IStatusBar
-    // ================================================================================
-    public void activate() {
-        enforceExpandStatusBar();
-        addPendingOp(OP_EXPAND, null, true);
-    }
-
-    public void deactivate() {
-        enforceExpandStatusBar();
-        addPendingOp(OP_EXPAND, null, false);
-    }
-
-    public void toggle() {
-        enforceExpandStatusBar();
-        addPendingOp(OP_TOGGLE, null, false);
-    }
-
-    public void disable(int what, IBinder token, String pkg) {
-        enforceStatusBar();
-        synchronized (mNotificationCallbacks) {
-            // This is a little gross, but I think it's safe as long as nobody else
-            // synchronizes on mNotificationCallbacks.  It's important that the the callback
-            // and the pending op get done in the correct order and not interleaved with
-            // other calls, otherwise they'll get out of sync.
-            int net;
-            synchronized (mDisableRecords) {
-                manageDisableListLocked(what, token, pkg);
-                net = gatherDisableActionsLocked();
-                mNotificationCallbacks.onSetDisabled(net);
-            }
-            addPendingOp(OP_DISABLE, net);
-        }
-    }
-
-    public IBinder addIcon(String slot, String iconPackage, int iconId, int iconLevel) {
-        enforceStatusBar();
-        return addIcon(IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null);
-    }
-
-    public void updateIcon(IBinder key,
-            String slot, String iconPackage, int iconId, int iconLevel) {
-        enforceStatusBar();
-        updateIcon(key, IconData.makeIcon(slot, iconPackage, iconId, iconLevel, 0), null);
-    }
-
-    public void removeIcon(IBinder key) {
-        enforceStatusBar();
-        addPendingOp(OP_REMOVE_ICON, key, null, null, -1);
-    }
-
-    private void enforceStatusBar() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.STATUS_BAR,
-                "StatusBarService");
-    }
-
-    private void enforceExpandStatusBar() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.EXPAND_STATUS_BAR,
-                "StatusBarService");
-    }
-
-    // ================================================================================
-    // Can be called from any thread
-    // ================================================================================
-    public IBinder addIcon(IconData data, NotificationData n) {
-        int slot;
-        // assert early-on if they using a slot that doesn't exist.
-        if (data != null && n == null) {
-            slot = getRightIconIndex(data.slot);
-            if (slot < 0) {
-                throw new SecurityException("invalid status bar icon slot: "
-                        + (data.slot != null ? "'" + data.slot + "'" : "null"));
-            }
-        } else {
-            slot = -1;
-        }
-        IBinder key = new Binder();
-        addPendingOp(OP_ADD_ICON, key, data, n, -1);
-        return key;
-    }
-
-    public void updateIcon(IBinder key, IconData data, NotificationData n) {
-        addPendingOp(OP_UPDATE_ICON, key, data, n, -1);
-    }
-
-    public void setIconVisibility(IBinder key, boolean visible) {
-        addPendingOp(OP_SET_VISIBLE, key, visible);
-    }
-
-    private void addPendingOp(int code, IBinder key, IconData data, NotificationData n, int i) {
-        synchronized (mQueueLock) {
-            PendingOp op = new PendingOp();
-            op.key = key;
-            op.code = code;
-            op.iconData = data == null ? null : data.clone();
-            op.notificationData = n;
-            op.integer = i;
-            mQueue.add(op);
-            if (mQueue.size() == 1) {
-                mHandler.sendEmptyMessage(2);
-            }
-        }
-    }
-
-    private void addPendingOp(int code, IBinder key, boolean visible) {
-        synchronized (mQueueLock) {
-            PendingOp op = new PendingOp();
-            op.key = key;
-            op.code = code;
-            op.visible = visible;
-            mQueue.add(op);
-            if (mQueue.size() == 1) {
-                mHandler.sendEmptyMessage(1);
-            }
-        }
-    }
-
-    private void addPendingOp(int code, int integer) {
-        synchronized (mQueueLock) {
-            PendingOp op = new PendingOp();
-            op.code = code;
-            op.integer = integer;
-            mQueue.add(op);
-            if (mQueue.size() == 1) {
-                mHandler.sendEmptyMessage(1);
-            }
-        }
-    }
-
-    // lock on mDisableRecords
-    void manageDisableListLocked(int what, IBinder token, String pkg) {
-        if (SPEW) {
-            Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what)
-                    + " pkg=" + pkg);
-        }
-        // update the list
-        synchronized (mDisableRecords) {
-            final int N = mDisableRecords.size();
-            DisableRecord tok = null;
-            int i;
-            for (i=0; i<N; i++) {
-                DisableRecord t = mDisableRecords.get(i);
-                if (t.token == token) {
-                    tok = t;
-                    break;
-                }
-            }
-            if (what == 0 || !token.isBinderAlive()) {
-                if (tok != null) {
-                    mDisableRecords.remove(i);
-                    tok.token.unlinkToDeath(tok, 0);
-                }
-            } else {
-                if (tok == null) {
-                    tok = new DisableRecord();
-                    try {
-                        token.linkToDeath(tok, 0);
-                    }
-                    catch (RemoteException ex) {
-                        return; // give up
-                    }
-                    mDisableRecords.add(tok);
-                }
-                tok.what = what;
-                tok.token = token;
-                tok.pkg = pkg;
-            }
-        }
-    }
-
-    // lock on mDisableRecords
-    int gatherDisableActionsLocked() {
-        final int N = mDisableRecords.size();
-        // gather the new net flags
-        int net = 0;
-        for (int i=0; i<N; i++) {
-            net |= mDisableRecords.get(i).what;
-        }
-        return net;
-    }
-
-    private int getRightIconIndex(String slot) {
-        final int N = mRightIconSlots.length;
-        for (int i=0; i<N; i++) {
-            if (mRightIconSlots[i].equals(slot)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    // ================================================================================
-    // Always called from UI thread
-    // ================================================================================
-    /**
-     * All changes to the status bar and notifications funnel through here and are batched.
-     */
-    private class H extends Handler {
-        public void handleMessage(Message m) {
-            if (m.what == MSG_ANIMATE) {
-                doAnimation();
-                return;
-            }
-            if (m.what == MSG_ANIMATE_REVEAL) {
-                doRevealAnimation();
-                return;
-            }
-
-            ArrayList<PendingOp> queue;
-            synchronized (mQueueLock) {
-                queue = mQueue;
-                mQueue = new ArrayList<PendingOp>();
-            }
-
-            boolean wasExpanded = mExpanded;
-
-            // for each one in the queue, find all of the ones with the same key
-            // and collapse that down into a final op and/or call to setVisibility, etc
-            boolean expand = wasExpanded;
-            boolean doExpand = false;
-            boolean doDisable = false;
-            int disableWhat = 0;
-            int N = queue.size();
-            while (N > 0) {
-                PendingOp op = queue.get(0);
-                boolean doOp = false;
-                boolean visible = false;
-                boolean doVisibility = false;
-                if (op.code == OP_SET_VISIBLE) {
-                    doVisibility = true;
-                    visible = op.visible;
-                }
-                else if (op.code == OP_EXPAND) {
-                    doExpand = true;
-                    expand = op.visible;
-                }
-                else if (op.code == OP_TOGGLE) {
-                    doExpand = true;
-                    expand = !expand;
-                }
-                else {
-                    doOp = true;
-                }
-
-                if (alwaysHandle(op.code)) {
-                    // coalesce these
-                    for (int i=1; i<N; i++) {
-                        PendingOp o = queue.get(i);
-                        if (!alwaysHandle(o.code) && o.key == op.key) {
-                            if (o.code == OP_SET_VISIBLE) {
-                                visible = o.visible;
-                                doVisibility = true;
-                            }
-                            else if (o.code == OP_EXPAND) {
-                                expand = o.visible;
-                                doExpand = true;
-                            }
-                            else {
-                                op.code = o.code;
-                                op.iconData = o.iconData;
-                                op.notificationData = o.notificationData;
-                            }
-                            queue.remove(i);
-                            i--;
-                            N--;
-                        }
-                    }
-                }
-
-                queue.remove(0);
-                N--;
-
-                if (doOp) {
-                    switch (op.code) {
-                        case OP_ADD_ICON:
-                        case OP_UPDATE_ICON:
-                            performAddUpdateIcon(op.key, op.iconData, op.notificationData);
-                            break;
-                        case OP_REMOVE_ICON:
-                            performRemoveIcon(op.key);
-                            break;
-                        case OP_DISABLE:
-                            doDisable = true;
-                            disableWhat = op.integer;
-                            break;
-                    }
-                }
-                if (doVisibility && op.code != OP_REMOVE_ICON) {
-                    performSetIconVisibility(op.key, visible);
-                }
-            }
-
-            if (queue.size() != 0) {
-                throw new RuntimeException("Assertion failed: queue.size=" + queue.size());
-            }
-            if (doExpand) {
-                // this is last so that we capture all of the pending changes before doing it
-                if (expand) {
-                    animateExpand();
-                } else {
-                    animateCollapse();
-                }
-            }
-            if (doDisable) {
-                performDisableActions(disableWhat);
-            }
-        }
-    }
-
-    private boolean alwaysHandle(int code) {
-        return code == OP_DISABLE;
-    }
-
-    /* private */ void performAddUpdateIcon(IBinder key, IconData data, NotificationData n)
-                        throws StatusBarException {
-        if (SPEW) {
-            Slog.d(TAG, "performAddUpdateIcon icon=" + data + " notification=" + n + " key=" + key);
-        }
-        // notification
-        if (n != null) {
-            StatusBarNotification notification = getNotification(key);
-            NotificationData oldData = null;
-            if (notification == null) {
-                // add
-                notification = new StatusBarNotification();
-                notification.key = key;
-                notification.data = n;
-                synchronized (mNotificationData) {
-                    mNotificationData.add(notification);
-                }
-                addNotificationView(notification);
-                setAreThereNotifications();
-            } else {
-                // update
-                oldData = notification.data;
-                notification.data = n;
-                updateNotificationView(notification, oldData);
-            }
-            // Show the ticker if one is requested, and the text is different
-            // than the currently displayed ticker.  Also don't do this
-            // until status bar window is attached to the window manager,
-            // because...  well, what's the point otherwise?  And trying to
-            // run a ticker without being attached will crash!
-            if (n.tickerText != null && mStatusBarView.getWindowToken() != null
-                    && (oldData == null
-                        || oldData.tickerText == null
-                        || !CharSequences.equals(oldData.tickerText, n.tickerText))) {
-                if (0 == (mDisabled & 
-                    (StatusBarManager.DISABLE_NOTIFICATION_ICONS | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
-                    mTicker.addEntry(n, StatusBarIcon.getIcon(mContext, data), n.tickerText);
-                }
-            }
-            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
-        }
-
-        // icon
-        synchronized (mIconMap) {
-            StatusBarIcon icon = mIconMap.get(key);
-            if (icon == null) {
-                // add
-                LinearLayout v = n == null ? mStatusIcons : mNotificationIcons;
-
-                icon = new StatusBarIcon(mContext, data, v);
-                mIconMap.put(key, icon);
-                mIconList.add(icon);
-
-                if (n == null) {
-                    int slotIndex = getRightIconIndex(data.slot);
-                    StatusBarIcon[] rightIcons = mRightIcons;
-                    if (rightIcons[slotIndex] == null) {
-                        int pos = 0;
-                        for (int i=mRightIcons.length-1; i>slotIndex; i--) {
-                            StatusBarIcon ic = rightIcons[i];
-                            if (ic != null) {
-                                pos++;
-                            }
-                        }
-                        rightIcons[slotIndex] = icon;
-                        mStatusIcons.addView(icon.view, pos);
-                    } else {
-                        Slog.e(TAG, "duplicate icon in slot " + slotIndex + "/" + data.slot);
-                        mIconMap.remove(key);
-                        mIconList.remove(icon);
-                        return ;
-                    }
-                } else {
-                    int iconIndex = mNotificationData.getIconIndex(n);
-                    mNotificationIcons.addView(icon.view, iconIndex);
-                }
-            } else {
-                if (n == null) {
-                    // right hand side icons -- these don't reorder
-                    icon.update(mContext, data);
-                } else {
-                    // remove old
-                    ViewGroup parent = (ViewGroup)icon.view.getParent();
-                    parent.removeView(icon.view);
-                    // add new
-                    icon.update(mContext, data);
-                    int iconIndex = mNotificationData.getIconIndex(n);
-                    mNotificationIcons.addView(icon.view, iconIndex);
-                }
-            }
-        }
-    }
-
-    /* private */ void performSetIconVisibility(IBinder key, boolean visible) {
-        synchronized (mIconMap) {
-            if (SPEW) {
-                Slog.d(TAG, "performSetIconVisibility key=" + key + " visible=" + visible);
-            }
-            StatusBarIcon icon = mIconMap.get(key);
-            icon.view.setVisibility(visible ? View.VISIBLE : View.GONE);
-        }
-    }
-    
-    /* private */ void performRemoveIcon(IBinder key) {
-        synchronized (this) {
-            if (SPEW) {
-                Slog.d(TAG, "performRemoveIcon key=" + key);
-            }
-            StatusBarIcon icon = mIconMap.remove(key);
-            mIconList.remove(icon);
-            if (icon != null) {
-                ViewGroup parent = (ViewGroup)icon.view.getParent();
-                parent.removeView(icon.view);
-                int slotIndex = getRightIconIndex(icon.mData.slot);
-                if (slotIndex >= 0) {
-                    mRightIcons[slotIndex] = null;
-                }
-            }
-            StatusBarNotification notification = getNotification(key);
-            if (notification != null) {
-                removeNotificationView(notification);
-                synchronized (mNotificationData) {
-                    mNotificationData.remove(notification);
-                }
-                setAreThereNotifications();
-            }
-        }
-    }
-
-    int getIconNumberForView(View v) {
-        synchronized (mIconMap) {
-            StatusBarIcon icon = null;
-            final int N = mIconList.size();
-            for (int i=0; i<N; i++) {
-                StatusBarIcon ic = mIconList.get(i);
-                if (ic.view == v) {
-                    icon = ic;
-                    break;
-                }
-            }
-            if (icon != null) {
-                return icon.getNumber();
-            } else {
-                return -1;
-            }
-        }
-    }
-
-
-    StatusBarNotification getNotification(IBinder key) {
-        synchronized (mNotificationData) {
-            return mNotificationData.get(key);
-        }
-    }
-
-    View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
-        public void onFocusChange(View v, boolean hasFocus) {
-            // Because 'v' is a ViewGroup, all its children will be (un)selected
-            // too, which allows marqueeing to work.
-            v.setSelected(hasFocus);
-        }
-    };
-    
-    View makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
-        NotificationData n = notification.data;
-        RemoteViews remoteViews = n.contentView;
-        if (remoteViews == null) {
-            return null;
-        }
-
-        // create the row view
-        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        View row = inflater.inflate(com.android.internal.R.layout.status_bar_latest_event, parent, false);
-
-        // bind the click event to the content area
-        ViewGroup content = (ViewGroup)row.findViewById(com.android.internal.R.id.content);
-        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-        content.setOnFocusChangeListener(mFocusChangeListener);
-        PendingIntent contentIntent = n.contentIntent;
-        if (contentIntent != null) {
-            content.setOnClickListener(new Launcher(contentIntent, n.pkg, n.tag, n.id));
-        }
-
-        View child = null;
-        Exception exception = null;
-        try {
-            child = remoteViews.apply(mContext, content);
-        }
-        catch (RuntimeException e) {
-            exception = e;
-        }
-        if (child == null) {
-            Slog.e(TAG, "couldn't inflate view for package " + n.pkg, exception);
-            return null;
-        }
-        content.addView(child);
-
-        row.setDrawingCacheEnabled(true);
-
-        notification.view = row;
-        notification.contentView = child;
-
-        return row;
-    }
-
-    void addNotificationView(StatusBarNotification notification) {
-        if (notification.view != null) {
-            throw new RuntimeException("Assertion failed: notification.view="
-                    + notification.view);
-        }
-
-        LinearLayout parent = notification.data.ongoingEvent ? mOngoingItems : mLatestItems;
-
-        View child = makeNotificationView(notification, parent);
-        if (child == null) {
-            return ;
-        }
-
-        int index = mNotificationData.getExpandedIndex(notification);
-        parent.addView(child, index);
-    }
-
-    /**
-     * Remove the old one and put the new one in its place.
-     * @param notification the notification
-     */
-    void updateNotificationView(StatusBarNotification notification, NotificationData oldData) {
-        NotificationData n = notification.data;
-        if (oldData != null && n != null
-                && n.when == oldData.when
-                && n.ongoingEvent == oldData.ongoingEvent
-                && n.contentView != null && oldData.contentView != null
-                && n.contentView.getPackage() != null
-                && oldData.contentView.getPackage() != null
-                && oldData.contentView.getPackage().equals(n.contentView.getPackage())
-                && oldData.contentView.getLayoutId() == n.contentView.getLayoutId()
-                && notification.view != null) {
-            mNotificationData.update(notification);
-            try {
-                n.contentView.reapply(mContext, notification.contentView);
-
-                // update the contentIntent
-                ViewGroup content = (ViewGroup)notification.view.findViewById(
-                        com.android.internal.R.id.content);
-                PendingIntent contentIntent = n.contentIntent;
-                if (contentIntent != null) {
-                    content.setOnClickListener(new Launcher(contentIntent, n.pkg, n.tag, n.id));
-                }
-            }
-            catch (RuntimeException e) {
-                // It failed to add cleanly.  Log, and remove the view from the panel.
-                Slog.w(TAG, "couldn't reapply views for package " + n.contentView.getPackage(), e);
-                removeNotificationView(notification);
-            }
-        } else {
-            mNotificationData.update(notification);
-            removeNotificationView(notification);
-            addNotificationView(notification);
-        }
-        setAreThereNotifications();
-    }
-
-    void removeNotificationView(StatusBarNotification notification) {
-        View v = notification.view;
-        if (v != null) {
-            ViewGroup parent = (ViewGroup)v.getParent();
-            parent.removeView(v);
-            notification.view = null;
-        }
-    }
-
-    private void setAreThereNotifications() {
-        boolean ongoing = mOngoingItems.getChildCount() != 0;
-        boolean latest = mLatestItems.getChildCount() != 0;
-
-        if (mNotificationData.hasClearableItems()) {
-            mClearButton.setVisibility(View.VISIBLE);
-        } else {
-            mClearButton.setVisibility(View.INVISIBLE);
-        }
-
-        mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
-        mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
-
-        if (ongoing || latest) {
-            mNoNotificationsTitle.setVisibility(View.GONE);
-        } else {
-            mNoNotificationsTitle.setVisibility(View.VISIBLE);
-        }
-    }
-
-    private void makeExpandedVisible() {
-        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
-        if (mExpandedVisible) {
-            return;
-        }
-        mExpandedVisible = true;
-        panelSlightlyVisible(true);
-        
-        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
-        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-        mExpandedView.requestFocus(View.FOCUS_FORWARD);
-        mTrackingView.setVisibility(View.VISIBLE);
-        
-        if (!mTicking) {
-            setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
-        }
-    }
-    
-    void animateExpand() {
-        if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
-            return ;
-        }
-        if (mExpanded) {
-            return;
-        }
-
-        prepareTracking(0, true);
-        performFling(0, 2000.0f, true);
-    }
-    
-    void animateCollapse() {
-        if (SPEW) {
-            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
-                    + " mExpandedVisible=" + mExpandedVisible
-                    + " mExpanded=" + mExpanded
-                    + " mAnimating=" + mAnimating
-                    + " mAnimY=" + mAnimY
-                    + " mAnimVel=" + mAnimVel);
-        }
-        
-        if (!mExpandedVisible) {
-            return;
-        }
-
-        int y;
-        if (mAnimating) {
-            y = (int)mAnimY;
-        } else {
-            y = mDisplay.getHeight()-1;
-        }
-        // Let the fling think that we're open so it goes in the right direction
-        // and doesn't try to re-open the windowshade.
-        mExpanded = true;
-        prepareTracking(y, false);
-        performFling(y, -2000.0f, true);
-    }
-    
-    void performExpand() {
-        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
-            return ;
-        }
-        if (mExpanded) {
-            return;
-        }
-
-        // It seems strange to sometimes not expand...
-        if (false) {
-            synchronized (mNotificationData) {
-                if (mNotificationData.size() == 0) {
-                    return;
-                }
-            }
-        }
-        
-        mExpanded = true;
-        makeExpandedVisible();
-        updateExpandedViewPos(EXPANDED_FULL_OPEN);
-
-        if (false) postStartTracing();
-    }
-
-    void performCollapse() {
-        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
-                + " mExpandedVisible=" + mExpandedVisible);
-        
-        if (!mExpandedVisible) {
-            return;
-        }
-        mExpandedVisible = false;
-        panelSlightlyVisible(false);
-        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-        mTrackingView.setVisibility(View.GONE);
-
-        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
-            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
-        }
-        setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
-        
-        if (!mExpanded) {
-            return;
-        }
-        mExpanded = false;
-    }
-
-    void doAnimation() {
-        if (mAnimating) {
-            if (SPEW) Slog.d(TAG, "doAnimation");
-            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
-            incrementAnim();
-            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
-            if (mAnimY >= mDisplay.getHeight()-1) {
-                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
-                mAnimating = false;
-                updateExpandedViewPos(EXPANDED_FULL_OPEN);
-                performExpand();
-            }
-            else if (mAnimY < mStatusBarView.getHeight()) {
-                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
-                mAnimating = false;
-                updateExpandedViewPos(0);
-                performCollapse();
-            }
-            else {
-                updateExpandedViewPos((int)mAnimY);
-                mCurAnimationTime += ANIM_FRAME_DURATION;
-                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
-            }
-        }
-    }
-
-    void stopTracking() {
-        mTracking = false;
-        mVelocityTracker.recycle();
-        mVelocityTracker = null;
-    }
-
-    void incrementAnim() {
-        long now = SystemClock.uptimeMillis();
-        float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s
-        final float y = mAnimY;
-        final float v = mAnimVel;                                   // px/s
-        final float a = mAnimAccel;                                 // px/s/s
-        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
-        mAnimVel = v + (a*t);                                       // px/s
-        mAnimLastTime = now;                                        // ms
-        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
-        //        + " mAnimAccel=" + mAnimAccel);
-    }
-
-    void doRevealAnimation() {
-        final int h = mCloseView.getHeight() + mStatusBarView.getHeight();
-        if (mAnimatingReveal && mAnimating && mAnimY < h) {
-            incrementAnim();
-            if (mAnimY >= h) {
-                mAnimY = h;
-                updateExpandedViewPos((int)mAnimY);
-            } else {
-                updateExpandedViewPos((int)mAnimY);
-                mCurAnimationTime += ANIM_FRAME_DURATION;
-                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
-                        mCurAnimationTime);
-            }
-        }
-    }
-    
-    void prepareTracking(int y, boolean opening) {
-        mTracking = true;
-        mVelocityTracker = VelocityTracker.obtain();
-        if (opening) {
-            mAnimAccel = 2000.0f;
-            mAnimVel = 200;
-            mAnimY = mStatusBarView.getHeight();
-            updateExpandedViewPos((int)mAnimY);
-            mAnimating = true;
-            mAnimatingReveal = true;
-            mHandler.removeMessages(MSG_ANIMATE);
-            mHandler.removeMessages(MSG_ANIMATE_REVEAL);
-            long now = SystemClock.uptimeMillis();
-            mAnimLastTime = now;
-            mCurAnimationTime = now + ANIM_FRAME_DURATION;
-            mAnimating = true;
-            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
-                    mCurAnimationTime);
-            makeExpandedVisible();
-        } else {
-            // it's open, close it?
-            if (mAnimating) {
-                mAnimating = false;
-                mHandler.removeMessages(MSG_ANIMATE);
-            }
-            updateExpandedViewPos(y + mViewDelta);
-        }
-    }
-    
-    void performFling(int y, float vel, boolean always) {
-        mAnimatingReveal = false;
-        mDisplayHeight = mDisplay.getHeight();
-
-        mAnimY = y;
-        mAnimVel = vel;
-
-        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
-
-        if (mExpanded) {
-            if (!always && (
-                    vel > 200.0f
-                    || (y > (mDisplayHeight-25) && vel > -200.0f))) {
-                // We are expanded, but they didn't move sufficiently to cause
-                // us to retract.  Animate back to the expanded position.
-                mAnimAccel = 2000.0f;
-                if (vel < 0) {
-                    mAnimVel = 0;
-                }
-            }
-            else {
-                // We are expanded and are now going to animate away.
-                mAnimAccel = -2000.0f;
-                if (vel > 0) {
-                    mAnimVel = 0;
-                }
-            }
-        } else {
-            if (always || (
-                    vel > 200.0f
-                    || (y > (mDisplayHeight/2) && vel > -200.0f))) {
-                // We are collapsed, and they moved enough to allow us to
-                // expand.  Animate in the notifications.
-                mAnimAccel = 2000.0f;
-                if (vel < 0) {
-                    mAnimVel = 0;
-                }
-            }
-            else {
-                // We are collapsed, but they didn't move sufficiently to cause
-                // us to retract.  Animate back to the collapsed position.
-                mAnimAccel = -2000.0f;
-                if (vel > 0) {
-                    mAnimVel = 0;
-                }
-            }
-        }
-        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
-        //        + " mAnimAccel=" + mAnimAccel);
-
-        long now = SystemClock.uptimeMillis();
-        mAnimLastTime = now;
-        mCurAnimationTime = now + ANIM_FRAME_DURATION;
-        mAnimating = true;
-        mHandler.removeMessages(MSG_ANIMATE);
-        mHandler.removeMessages(MSG_ANIMATE_REVEAL);
-        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
-        stopTracking();
-    }
-    
-    boolean interceptTouchEvent(MotionEvent event) {
-        if (SPEW) {
-            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
-                + mDisabled);
-        }
-
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
-            return false;
-        }
-        
-        final int statusBarSize = mStatusBarView.getHeight();
-        final int hitSize = statusBarSize*2;
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            final int y = (int)event.getRawY();
-
-            if (!mExpanded) {
-                mViewDelta = statusBarSize - y;
-            } else {
-                mTrackingView.getLocationOnScreen(mAbsPos);
-                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
-            }
-            if ((!mExpanded && y < hitSize) ||
-                    (mExpanded && y > (mDisplay.getHeight()-hitSize))) {
-
-                // We drop events at the edge of the screen to make the windowshade come
-                // down by accident less, especially when pushing open a device with a keyboard
-                // that rotates (like g1 and droid)
-                int x = (int)event.getRawX();
-                final int edgeBorder = mEdgeBorder;
-                if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) {
-                    prepareTracking(y, !mExpanded);// opening if we're not already fully visible
-                    mVelocityTracker.addMovement(event);
-                }
-            }
-        } else if (mTracking) {
-            mVelocityTracker.addMovement(event);
-            final int minY = statusBarSize + mCloseView.getHeight();
-            if (event.getAction() == MotionEvent.ACTION_MOVE) {
-                int y = (int)event.getRawY();
-                if (mAnimatingReveal && y < minY) {
-                    // nothing
-                } else  {
-                    mAnimatingReveal = false;
-                    updateExpandedViewPos(y + mViewDelta);
-                }
-            } else if (event.getAction() == MotionEvent.ACTION_UP) {
-                mVelocityTracker.computeCurrentVelocity(1000);
-
-                float yVel = mVelocityTracker.getYVelocity();
-                boolean negative = yVel < 0;
-
-                float xVel = mVelocityTracker.getXVelocity();
-                if (xVel < 0) {
-                    xVel = -xVel;
-                }
-                if (xVel > 150.0f) {
-                    xVel = 150.0f; // limit how much we care about the x axis
-                }
-
-                float vel = (float)Math.hypot(yVel, xVel);
-                if (negative) {
-                    vel = -vel;
-                }
-                
-                performFling((int)event.getRawY(), vel, false);
-            }
-            
-        }
-        return false;
-    }
-
-    private class Launcher implements View.OnClickListener {
-        private PendingIntent mIntent;
-        private String mPkg;
-        private String mTag;
-        private int mId;
-
-        Launcher(PendingIntent intent, String pkg, String tag, int id) {
-            mIntent = intent;
-            mPkg = pkg;
-            mTag = tag;
-            mId = id;
-        }
-
-        public void onClick(View v) {
-            try {
-                // The intent we are sending is for the application, which
-                // won't have permission to immediately start an activity after
-                // the user switches to home.  We know it is safe to do at this
-                // point, so make sure new activity switches are now allowed.
-                ActivityManagerNative.getDefault().resumeAppSwitches();
-            } catch (RemoteException e) {
-            }
-            int[] pos = new int[2];
-            v.getLocationOnScreen(pos);
-            Intent overlay = new Intent();
-            overlay.setSourceBounds(
-                    new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
-            try {
-                mIntent.send(mContext, 0, overlay);
-                mNotificationCallbacks.onNotificationClick(mPkg, mTag, mId);
-            } catch (PendingIntent.CanceledException e) {
-                // the stack trace isn't very helpful here.  Just log the exception message.
-                Slog.w(TAG, "Sending contentIntent failed: " + e);
-            }
-            deactivate();
-        }
-    }
-
-    private class MyTicker extends Ticker {
-        MyTicker(Context context, StatusBarView sb) {
-            super(context, sb);
-        }
-        
-        @Override
-        void tickerStarting() {
-            mTicking = true;
-            mIcons.setVisibility(View.GONE);
-            mTickerView.setVisibility(View.VISIBLE);
-            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
-            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
-            if (mExpandedVisible) {
-                setDateViewVisibility(false, com.android.internal.R.anim.push_up_out);
-            }
-        }
-
-        @Override
-        void tickerDone() {
-            mIcons.setVisibility(View.VISIBLE);
-            mTickerView.setVisibility(View.GONE);
-            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
-            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
-                        mTickingDoneListener));
-            if (mExpandedVisible) {
-                setDateViewVisibility(true, com.android.internal.R.anim.push_down_in);
-            }
-        }
-
-        void tickerHalting() {
-            mIcons.setVisibility(View.VISIBLE);
-            mTickerView.setVisibility(View.GONE);
-            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
-            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
-                        mTickingDoneListener));
-            if (mExpandedVisible) {
-                setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
-            }
-        }
-    }
-
-    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
-        public void onAnimationEnd(Animation animation) {
-            mTicking = false;
-        }
-        public void onAnimationRepeat(Animation animation) {
-        }
-        public void onAnimationStart(Animation animation) {
-        }
-    };
-
-    private Animation loadAnim(int id, Animation.AnimationListener listener) {
-        Animation anim = AnimationUtils.loadAnimation(mContext, id);
-        if (listener != null) {
-            anim.setAnimationListener(listener);
-        }
-        return anim;
-    }
-
-    public String viewInfo(View v) {
-        return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
-                + " " + v.getWidth() + "x" + v.getHeight() + ")";
-    }
-
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump StatusBar from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-        
-        synchronized (mQueueLock) {
-            pw.println("Current Status Bar state:");
-            pw.println("  mExpanded=" + mExpanded
-                    + ", mExpandedVisible=" + mExpandedVisible);
-            pw.println("  mTicking=" + mTicking);
-            pw.println("  mTracking=" + mTracking);
-            pw.println("  mAnimating=" + mAnimating
-                    + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
-                    + ", mAnimAccel=" + mAnimAccel);
-            pw.println("  mCurAnimationTime=" + mCurAnimationTime
-                    + " mAnimLastTime=" + mAnimLastTime);
-            pw.println("  mDisplayHeight=" + mDisplayHeight
-                    + " mAnimatingReveal=" + mAnimatingReveal
-                    + " mViewDelta=" + mViewDelta);
-            pw.println("  mDisplayHeight=" + mDisplayHeight);
-            final int N = mQueue.size();
-            pw.println("  mQueue.size=" + N);
-            for (int i=0; i<N; i++) {
-                PendingOp op = mQueue.get(i);
-                pw.println("    [" + i + "] key=" + op.key + " code=" + op.code + " visible="
-                        + op.visible);
-                pw.println("           iconData=" + op.iconData);
-                pw.println("           notificationData=" + op.notificationData);
-            }
-            pw.println("  mExpandedParams: " + mExpandedParams);
-            pw.println("  mExpandedView: " + viewInfo(mExpandedView));
-            pw.println("  mExpandedDialog: " + mExpandedDialog);
-            pw.println("  mTrackingParams: " + mTrackingParams);
-            pw.println("  mTrackingView: " + viewInfo(mTrackingView));
-            pw.println("  mOngoingTitle: " + viewInfo(mOngoingTitle));
-            pw.println("  mOngoingItems: " + viewInfo(mOngoingItems));
-            pw.println("  mLatestTitle: " + viewInfo(mLatestTitle));
-            pw.println("  mLatestItems: " + viewInfo(mLatestItems));
-            pw.println("  mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
-            pw.println("  mCloseView: " + viewInfo(mCloseView));
-            pw.println("  mTickerView: " + viewInfo(mTickerView));
-            pw.println("  mScrollView: " + viewInfo(mScrollView)
-                    + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
-            pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));
-        }
-        synchronized (mIconMap) {
-            final int N = mIconMap.size();
-            pw.println("  mIconMap.size=" + N);
-            Set<IBinder> keys = mIconMap.keySet();
-            int i=0;
-            for (IBinder key: keys) {
-                StatusBarIcon icon = mIconMap.get(key);
-                pw.println("    [" + i + "] key=" + key);
-                pw.println("           data=" + icon.mData);
-                i++;
-            }
-        }
-        synchronized (mNotificationData) {
-            int N = mNotificationData.ongoingCount();
-            pw.println("  ongoingCount.size=" + N);
-            for (int i=0; i<N; i++) {
-                StatusBarNotification n = mNotificationData.getOngoing(i);
-                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
-                pw.println("           data=" + n.data);
-            }
-            N = mNotificationData.latestCount();
-            pw.println("  ongoingCount.size=" + N);
-            for (int i=0; i<N; i++) {
-                StatusBarNotification n = mNotificationData.getLatest(i);
-                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
-                pw.println("           data=" + n.data);
-            }
-        }
-        synchronized (mDisableRecords) {
-            final int N = mDisableRecords.size();
-            pw.println("  mDisableRecords.size=" + N
-                    + " mDisabled=0x" + Integer.toHexString(mDisabled));
-            for (int i=0; i<N; i++) {
-                DisableRecord tok = mDisableRecords.get(i);
-                pw.println("    [" + i + "] what=0x" + Integer.toHexString(tok.what)
-                                + " pkg=" + tok.pkg + " token=" + tok.token);
-            }
-        }
-        
-        if (false) {
-            pw.println("see the logcat for a dump of the views we have created.");
-            // must happen on ui thread
-            mHandler.post(new Runnable() {
-                    public void run() {
-                        mStatusBarView.getLocationOnScreen(mAbsPos);
-                        Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
-                                + ") " + mStatusBarView.getWidth() + "x"
-                                + mStatusBarView.getHeight());
-                        mStatusBarView.debug();
-
-                        mExpandedView.getLocationOnScreen(mAbsPos);
-                        Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
-                                + ") " + mExpandedView.getWidth() + "x"
-                                + mExpandedView.getHeight());
-                        mExpandedView.debug();
-
-                        mTrackingView.getLocationOnScreen(mAbsPos);
-                        Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
-                                + ") " + mTrackingView.getWidth() + "x"
-                                + mTrackingView.getHeight());
-                        mTrackingView.debug();
-                    }
-                });
-        }
-    }
-
-    void onBarViewAttached() {
-        WindowManager.LayoutParams lp;
-        int pixelFormat;
-        Drawable bg;
-
-        /// ---------- Tracking View --------------
-        pixelFormat = PixelFormat.RGBX_8888;
-        bg = mTrackingView.getBackground();
-        if (bg != null) {
-            pixelFormat = bg.getOpacity();
-        }
-
-        lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                pixelFormat);
-//        lp.token = mStatusBarView.getWindowToken();
-        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
-        lp.setTitle("TrackingView");
-        lp.y = mTrackingPosition;
-        mTrackingParams = lp;
-
-        WindowManagerImpl.getDefault().addView(mTrackingView, lp);
-    }
-
-    void onTrackingViewAttached() {
-        WindowManager.LayoutParams lp;
-        int pixelFormat;
-        Drawable bg;
-
-        /// ---------- Expanded View --------------
-        pixelFormat = PixelFormat.TRANSLUCENT;
-
-        final int disph = mDisplay.getHeight();
-        lp = mExpandedDialog.getWindow().getAttributes();
-        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
-        lp.height = getExpandedHeight();
-        lp.x = 0;
-        mTrackingPosition = lp.y = -disph; // sufficiently large negative
-        lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
-        lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_DITHER
-                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        lp.format = pixelFormat;
-        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
-        lp.setTitle("StatusBarExpanded");
-        mExpandedDialog.getWindow().setAttributes(lp);
-        mExpandedDialog.getWindow().setFormat(pixelFormat);
-        mExpandedParams = lp;
-
-        mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
-        mExpandedDialog.setContentView(mExpandedView,
-                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-                                           ViewGroup.LayoutParams.MATCH_PARENT));
-        mExpandedDialog.getWindow().setBackgroundDrawable(null);
-        mExpandedDialog.show();
-        FrameLayout hack = (FrameLayout)mExpandedView.getParent();
-    }
-
-    void setDateViewVisibility(boolean visible, int anim) {
-        mDateView.setUpdates(visible);
-        mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-        mDateView.startAnimation(loadAnim(anim, null));
-    }
-
-    void setNotificationIconVisibility(boolean visible, int anim) {
-        int old = mNotificationIcons.getVisibility();
-        int v = visible ? View.VISIBLE : View.INVISIBLE;
-        if (old != v) {
-            mNotificationIcons.setVisibility(v);
-            mNotificationIcons.startAnimation(loadAnim(anim, null));
-        }
-    }
-
-    void updateExpandedViewPos(int expandedPosition) {
-        if (SPEW) {
-            Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
-                    + " mTrackingParams.y=" + mTrackingParams.y
-                    + " mTrackingPosition=" + mTrackingPosition);
-        }
-
-        int h = mStatusBarView.getHeight();
-        int disph = mDisplay.getHeight();
-
-        // If the expanded view is not visible, make sure they're still off screen.
-        // Maybe the view was resized.
-        if (!mExpandedVisible) {
-            if (mTrackingView != null) {
-                mTrackingPosition = -disph;
-                if (mTrackingParams != null) {
-                    mTrackingParams.y = mTrackingPosition;
-                    WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
-                }
-            }
-            if (mExpandedParams != null) {
-                mExpandedParams.y = -disph;
-                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-            }
-            return;
-        }
-
-        // tracking view...
-        int pos;
-        if (expandedPosition == EXPANDED_FULL_OPEN) {
-            pos = h;
-        }
-        else if (expandedPosition == EXPANDED_LEAVE_ALONE) {
-            pos = mTrackingPosition;
-        }
-        else {
-            if (expandedPosition <= disph) {
-                pos = expandedPosition;
-            } else {
-                pos = disph;
-            }
-            pos -= disph-h;
-        }
-        mTrackingPosition = mTrackingParams.y = pos;
-        mTrackingParams.height = disph-h;
-        WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
-
-        if (mExpandedParams != null) {
-            mCloseView.getLocationInWindow(mPositionTmp);
-            final int closePos = mPositionTmp[1];
-
-            mExpandedContents.getLocationInWindow(mPositionTmp);
-            final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
-
-            mExpandedParams.y = pos + mTrackingView.getHeight()
-                    - (mTrackingParams.height-closePos) - contentsBottom;
-            int max = h;
-            if (mExpandedParams.y > max) {
-                mExpandedParams.y = max;
-            }
-            int min = mTrackingPosition;
-            if (mExpandedParams.y < min) {
-                mExpandedParams.y = min;
-            }
-
-            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
-            if (!visible) {
-                // if the contents aren't visible, move the expanded view way off screen
-                // because the window itself extends below the content view.
-                mExpandedParams.y = -disph;
-            }
-            panelSlightlyVisible(visible);
-            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-        }
-
-        if (SPEW) {
-            Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition
-                    + " mTrackingParams.y=" + mTrackingParams.y
-                    + " mTrackingPosition=" + mTrackingPosition
-                    + " mExpandedParams.y=" + mExpandedParams.y
-                    + " mExpandedParams.height=" + mExpandedParams.height);
-        }
-    }
-
-    int getExpandedHeight() {
-        return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();
-    }
-
-    void updateExpandedHeight() {
-        if (mExpandedView != null) {
-            mExpandedParams.height = getExpandedHeight();
-            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
-        }
-    }
-
-    /**
-     * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
-     * This was added last-minute and is inconsistent with the way the rest of the notifications
-     * are handled, because the notification isn't really cancelled.  The lights are just
-     * turned off.  If any other notifications happen, the lights will turn back on.  Steve says
-     * this is what he wants. (see bug 1131461)
-     */
-    private boolean mPanelSlightlyVisible;
-    void panelSlightlyVisible(boolean visible) {
-        if (mPanelSlightlyVisible != visible) {
-            mPanelSlightlyVisible = visible;
-            if (visible) {
-                // tell the notification manager to turn off the lights.
-                mNotificationCallbacks.onPanelRevealed();
-            }
-        }
-    }
-
-    void performDisableActions(int net) {
-        int old = mDisabled;
-        int diff = net ^ old;
-        mDisabled = net;
-
-        // act accordingly
-        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
-            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
-                Slog.d(TAG, "DISABLE_EXPAND: yes");
-                animateCollapse();
-            }
-        }
-        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
-                if (mTicking) {
-                    mNotificationIcons.setVisibility(View.INVISIBLE);
-                    mTicker.halt();
-                } else {
-                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
-                }
-            } else {
-                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
-                if (!mExpandedVisible) {
-                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
-                }
-            }
-        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-                mTicker.halt();
-            }
-        }
-    }
-
-    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
-        public void onClick(View v) {
-            mNotificationCallbacks.onClearAll();
-            addPendingOp(OP_EXPAND, null, false);
-        }
-    };
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
-                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
-                deactivate();
-            }
-            else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
-                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
-            }
-            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
-                updateResources();
-            }
-        }
-    };
-
-    void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
-        if (false) {
-            Slog.d(TAG, "updateNetworkName showSpn=" + showSpn + " spn=" + spn
-                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
-        }
-        boolean something = false;
-        if (showPlmn) {
-            mPlmnLabel.setVisibility(View.VISIBLE);
-            if (plmn != null) {
-                mPlmnLabel.setText(plmn);
-            } else {
-                mPlmnLabel.setText(R.string.lockscreen_carrier_default);
-            }
-        } else {
-            mPlmnLabel.setText("");
-            mPlmnLabel.setVisibility(View.GONE);
-        }
-        if (showSpn && spn != null) {
-            mSpnLabel.setText(spn);
-            mSpnLabel.setVisibility(View.VISIBLE);
-            something = true;
-        } else {
-            mSpnLabel.setText("");
-            mSpnLabel.setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * Reload some of our resources when the configuration changes.
-     * 
-     * We don't reload everything when the configuration changes -- we probably
-     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
-     * meantime, just update the things that we know change.
-     */
-    void updateResources() {
-        Resources res = mContext.getResources();
-
-        mClearButton.setText(mContext.getText(R.string.status_bar_clear_all_button));
-        mOngoingTitle.setText(mContext.getText(R.string.status_bar_ongoing_events_title));
-        mLatestTitle.setText(mContext.getText(R.string.status_bar_latest_events_title));
-        mNoNotificationsTitle.setText(mContext.getText(R.string.status_bar_no_notifications_title));
-
-        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
-
-        if (false) Slog.v(TAG, "updateResources");
-    }
-
-    //
-    // tracing
-    //
-
-    void postStartTracing() {
-        mHandler.postDelayed(mStartTracing, 3000);
-    }
-
-    void vibrate() {
-        android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
-                Context.VIBRATOR_SERVICE);
-        vib.vibrate(250);
-    }
-
-    Runnable mStartTracing = new Runnable() {
-        public void run() {
-            vibrate();
-            SystemClock.sleep(250);
-            Slog.d(TAG, "startTracing");
-            android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
-            mHandler.postDelayed(mStopTracing, 10000);
-        }
-    };
-
-    Runnable mStopTracing = new Runnable() {
-        public void run() {
-            android.os.Debug.stopMethodTracing();
-            Slog.d(TAG, "stopTracing");
-            vibrate();
-        }
-    };
-    
-    class UninstallReceiver extends BroadcastReceiver {
-        public UninstallReceiver() {
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
-            filter.addDataScheme("package");
-            mContext.registerReceiver(this, filter);
-            IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
-            mContext.registerReceiver(this, sdFilter);
-        }
-        
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String pkgList[] = null;
-            if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
-                pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
-            } else {
-                Uri data = intent.getData();
-                if (data != null) {
-                    String pkg = data.getSchemeSpecificPart();
-                    if (pkg != null) {
-                        pkgList = new String[]{pkg};
-                    }
-                }
-            }
-            ArrayList<StatusBarNotification> list = null;
-            if (pkgList != null) {
-                synchronized (StatusBarService.this) {
-                    for (String pkg : pkgList) {
-                        list = mNotificationData.notificationsForPackage(pkg);
-                    }
-                }
-            }
-            
-            if (list != null) {
-                final int N = list.size();
-                for (int i=0; i<N; i++) {
-                    removeIcon(list.get(i).key);
-                }
-            }
-        }
-    }
-}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index e7a09d1..3602fec 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -21,6 +21,7 @@
 import android.widget.ArrayAdapter;
 import android.view.View;
 import android.widget.ListView;
+import android.content.Context;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.app.Notification;
@@ -60,7 +61,7 @@
     private Test[] mTests = new Test[] {
         new Test("Off and sound") {
             public void run() {
-                PowerManager pm = (PowerManager)NotificationTestList.this.getSystemService("power");
+                PowerManager pm = (PowerManager)NotificationTestList.this.getSystemService(Context.POWER_SERVICE);
                 PowerManager.WakeLock wl = 
                             pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "sound");
                 wl.acquire();
@@ -121,6 +122,16 @@
             }
         },
 
+        new Test("Bad Icon") {
+            public void run() {
+                mNM.notify(1, new Notification(NotificationTestList.this,
+                            R.layout.chrono_notification, /* not a drawable! */
+                            null, System.currentTimeMillis()-(1000*60*60*24),
+                            "(453) 123-2328",
+                            "", null));
+            }
+        },
+
         new Test("Bad resource #2") {
             public void run()
             {
@@ -180,7 +191,7 @@
                                 R.drawable.icon4,
                                 null, System.currentTimeMillis(), "Stress - Latest",
                                 "Notify me!!!", null);
-                        n.flags |= Notification.FLAG_ONGOING_EVENT;
+                        //n.flags |= Notification.FLAG_ONGOING_EVENT;
                         mNM.notify(1, n);
                     }
                 }
@@ -599,7 +610,7 @@
             public void run()
             {
                 PowerManager.WakeLock wl
-                        = ((PowerManager)NotificationTestList.this.getSystemService("power"))
+                        = ((PowerManager)NotificationTestList.this.getSystemService(Context.POWER_SERVICE))
                             .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "crasher");
                 wl.acquire();
                 mHandler.postDelayed(new Runnable() {
@@ -622,9 +633,7 @@
 
     private PendingIntent makeIntent() {
         Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setComponent(new android.content.ComponentName(
-                    "com.android.contacts",
-                    "com.android.contacts.ContactsActivity"));
+        intent.addCategory(Intent.CATEGORY_HOME);
         return PendingIntent.getActivity(this, 0, intent, 0);
     }
 
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 06506fb..3532e30 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -134,13 +134,9 @@
                     }, 3000);
             }
         },
-        new Test("Expand in 3 sec.") {
+        new Test("Expand") {
             public void run() {
-                mHandler.postDelayed(new Runnable() {
-                        public void run() {
-                            mStatusBarManager.expand();
-                        }
-                    }, 3000);
+                mStatusBarManager.expand();
             }
         },
         new Test("Expand in 3 sec.") {
@@ -161,14 +157,5 @@
                     }, 3000);
             }
         },
-        new Test("Toggle in 3 sec.") {
-            public void run() {
-                mHandler.postDelayed(new Runnable() {
-                        public void run() {
-                            mStatusBarManager.toggle();
-                        }
-                    }, 3000);
-            }
-        },
     };
 }
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index a2f085a..755b93b 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -573,6 +573,7 @@
                         const String16& parentIdent,
                         const String16& itemIdent,
                         int32_t curFormat,
+                        bool isFormatted,
                         bool pseudolocalize,
                         const bool overwrite,
                         ResourceTable* outTable)
@@ -583,7 +584,7 @@
     String16 str;
     Vector<StringPool::entry_style_span> spans;
     err = parseStyledString(bundle, in->getPrintableSource().string(),
-                            block, item16, &str, &spans,
+                            block, item16, &str, &spans, isFormatted,
                             pseudolocalize);
     if (err != NO_ERROR) {
         return err;
@@ -616,6 +617,7 @@
                         const String16& curTag,
                         bool curIsStyled,
                         int32_t curFormat,
+                        bool isFormatted,
                         bool pseudolocalize,
                         const bool overwrite,
                         ResourceTable* outTable)
@@ -626,7 +628,7 @@
     Vector<StringPool::entry_style_span> spans;
     err = parseStyledString(bundle, in->getPrintableSource().string(), block,
                             curTag, &str, curIsStyled ? &spans : NULL,
-                            pseudolocalize);
+                            isFormatted, pseudolocalize);
 
     if (err < NO_ERROR) { 
         return err;
@@ -709,12 +711,18 @@
     // useful attribute names and special values
     const String16 name16("name");
     const String16 translatable16("translatable");
+    const String16 formatted16("formatted");
     const String16 false16("false");
 
     const String16 myPackage(assets->getPackage());
 
     bool hasErrors = false;
-    
+
+    bool fileIsTranslatable = true;
+    if (strstr(in->getPrintableSource().string(), "donottranslate") != NULL) {
+        fileIsTranslatable = false;
+    }
+
     DefaultKeyedVector<String16, uint32_t> nextPublicId(0);
 
     ResXMLTree::event_code_t code;
@@ -751,6 +759,7 @@
             bool curIsBagReplaceOnOverwrite = false;
             bool curIsStyled = false;
             bool curIsPseudolocalizable = false;
+            bool curIsFormatted = fileIsTranslatable;
             bool localHasErrors = false;
 
             if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
@@ -1136,6 +1145,7 @@
                 String8 locale(rawLocale);
                 String16 name;
                 String16 translatable;
+                String16 formatted;
 
                 size_t n = block.getAttributeCount();
                 for (size_t i = 0; i < n; i++) {
@@ -1145,11 +1155,14 @@
                         name.setTo(block.getAttributeStringValue(i, &length));
                     } else if (strcmp16(attr, translatable16.string()) == 0) {
                         translatable.setTo(block.getAttributeStringValue(i, &length));
+                    } else if (strcmp16(attr, formatted16.string()) == 0) {
+                        formatted.setTo(block.getAttributeStringValue(i, &length));
                     }
                 }
                 
                 if (name.size() > 0) {
                     if (translatable == false16) {
+                        curIsFormatted = false;
                         // Untranslatable strings must only exist in the default [empty] locale
                         if (locale.size() > 0) {
                             fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
@@ -1167,6 +1180,10 @@
                     } else {
                         outTable->addLocalization(name, locale);
                     }
+
+                    if (formatted == false16) {
+                        curIsFormatted = false;
+                    }
                 }
 
                 curTag = &string16;
@@ -1356,7 +1373,7 @@
                         block.getPosition(&parserPosition);
 
                         err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
-                                ident, parentIdent, itemIdent, curFormat, 
+                                ident, parentIdent, itemIdent, curFormat, curIsFormatted,
                                 false, overwrite, outTable);
                         if (err == NO_ERROR) {
                             if (curIsPseudolocalizable && localeIsDefined(curParams)
@@ -1365,8 +1382,8 @@
 #if 1
                                 block.setPosition(parserPosition);
                                 err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
-                                        curType, ident, parentIdent, itemIdent, curFormat, true,
-                                        overwrite, outTable);
+                                        curType, ident, parentIdent, itemIdent, curFormat,
+                                        curIsFormatted, true, overwrite, outTable);
 #endif
                             }
                         } 
@@ -1389,7 +1406,8 @@
                 block.getPosition(&parserPosition);
 
                 err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
-                        *curTag, curIsStyled, curFormat, false, overwrite, outTable);
+                        *curTag, curIsStyled, curFormat, curIsFormatted,
+                        false, overwrite, outTable);
 
                 if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
                     hasErrors = localHasErrors = true;
@@ -1400,7 +1418,8 @@
                         // pseudolocalize here
                         block.setPosition(parserPosition);
                         err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
-                                ident, *curTag, curIsStyled, curFormat, true, overwrite, outTable);
+                                ident, *curTag, curIsStyled, curFormat,
+                                curIsFormatted, true, overwrite, outTable);
                         if (err != NO_ERROR) {
                             hasErrors = localHasErrors = true;
                         }
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 4c59288..57ff47a 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -68,12 +68,118 @@
     return String16(namespaceUri, namespaceUri.size()-prefixSize, prefixSize);
 }
 
+status_t hasSubstitutionErrors(const char* fileName,
+                               ResXMLTree* inXml,
+                               String16 str16)
+{
+    const char16_t* str = str16.string();
+    const char16_t* p = str;
+    const char16_t* end = str + str16.size();
+
+    bool nonpositional = false;
+    int argCount = 0;
+
+    while (p < end) {
+        /*
+         * Look for the start of a Java-style substitution sequence.
+         */
+        if (*p == '%' && p + 1 < end) {
+            p++;
+
+            // A literal percent sign represented by %%
+            if (*p == '%') {
+                p++;
+                continue;
+            }
+
+            argCount++;
+
+            if (*p >= '0' && *p <= '9') {
+                do {
+                    p++;
+                } while (*p >= '0' && *p <= '9');
+                if (*p != '$') {
+                    // This must be a size specification instead of position.
+                    nonpositional = true;
+                }
+            } else if (*p == '<') {
+                // Reusing last argument; bad idea since it can be re-arranged.
+                nonpositional = true;
+                p++;
+
+                // Optionally '$' can be specified at the end.
+                if (p < end && *p == '$') {
+                    p++;
+                }
+            } else {
+                nonpositional = true;
+            }
+
+            // Ignore flags and widths
+            while (p < end && (*p == '-' ||
+                    *p == '#' ||
+                    *p == '+' ||
+                    *p == ' ' ||
+                    *p == ',' ||
+                    *p == '(' ||
+                    (*p >= '0' && *p <= '9'))) {
+                p++;
+            }
+
+            /*
+             * This is a shortcut to detect strings that are going to Time.format()
+             * instead of String.format()
+             *
+             * Comparison of String.format() and Time.format() args:
+             *
+             * String: ABC E GH  ST X abcdefgh  nost x
+             *   Time:    DEFGHKMS W Za  d   hkm  s w yz
+             *
+             * Therefore we know it's definitely Time if we have:
+             *     DFKMWZkmwyz
+             */
+            if (p < end) {
+                switch (*p) {
+                case 'D':
+                case 'F':
+                case 'K':
+                case 'M':
+                case 'W':
+                case 'Z':
+                case 'k':
+                case 'm':
+                case 'w':
+                case 'y':
+                case 'z':
+                    return NO_ERROR;
+                }
+            }
+        }
+
+        p++;
+    }
+
+    /*
+     * If we have more than one substitution in this string and any of them
+     * are not in positional form, give the user an error.
+     */
+    if (argCount > 1 && nonpositional) {
+        SourcePos(String8(fileName), inXml->getLineNumber()).error(
+                "Multiple substitutions specified in non-positional format; "
+                "did you mean to add the formatted=\"true\" attribute?\n");
+        return NOT_ENOUGH_DATA;
+    }
+
+    return NO_ERROR;
+}
+
 status_t parseStyledString(Bundle* bundle,
                            const char* fileName,
                            ResXMLTree* inXml,
                            const String16& endTag,
                            String16* outString,
                            Vector<StringPool::entry_style_span>* outSpans,
+                           bool isFormatted,
                            bool pseudolocalize)
 {
     Vector<StringPool::entry_style_span> spanStack;
@@ -101,7 +207,11 @@
                 std::string pseudo = pseudolocalize_string(orig);
                 curString.append(String16(String8(pseudo.c_str())));
             } else {
-                curString.append(text);
+                if (isFormatted && hasSubstitutionErrors(fileName, inXml, text) != NO_ERROR) {
+                    return UNKNOWN_ERROR;
+                } else {
+                    curString.append(text);
+                }
             }
         } else if (code == ResXMLTree::START_TAG) {
             const String16 element16(inXml->getElementName(&len));
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index e9a263b..05624b7 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -25,6 +25,7 @@
                            const String16& endTag,
                            String16* outString,
                            Vector<StringPool::entry_style_span>* outSpans,
+                           bool isFormatted,
                            bool isPseudolocalizable);
 
 void printXMLBlock(ResXMLTree* block);