notification panel animations

Change-Id: I3ca06a35be480df6e8741270c10eb1b23b1d4835
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png b/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png
new file mode 100755
index 0000000..7d17a54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_glow_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png
new file mode 100644
index 0000000..d960c78
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_bottom.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png
new file mode 100755
index 0000000..3e46370
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_left.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png
new file mode 100755
index 0000000..afc91b9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_item_glow_top.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png
new file mode 100755
index 0000000..7086def
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
new file mode 100755
index 0000000..e9589d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 1d98458..2272e34 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -17,161 +17,178 @@
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
 <com.android.systemui.statusbar.tablet.NotificationPanel
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:layout_height="match_parent"
     android:layout_width="match_parent"
-    android:animateLayoutChanges="true"
-    android:paddingTop="32dp"
-    android:paddingBottom="@dimen/status_bar_panel_bottom_offset"
     android:orientation="vertical"
     android:gravity="right"
+    android:paddingTop="32dp"
     >
 
-    <com.android.systemui.statusbar.tablet.NotificationTitleArea
-        android:id="@+id/title_area"
-        android:layout_height="160dp"
-        android:layout_width="384dp"
-        android:layout_marginLeft="24dp"
-        android:paddingTop="20dp"
-        android:orientation="vertical"
-        android:animateLayoutChanges="true"
-        >
-
-        <com.android.systemui.statusbar.tablet.HoloClock
-            android:id="@+id/clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_alignParentTop="true"
-            android:layout_marginRight="40dip"
-            android:layout_marginBottom="4dip"
-            >
-            <TextView android:id="@+id/time_bg"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="right"
-                android:singleLine="true"
-                android:textSize="90dip"
-                android:textColor="#999999" />
-            <TextView android:id="@+id/time_fg"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="right"
-                android:singleLine="true"
-                android:textSize="90dip"
-                android:textColor="#666666" />
-        </com.android.systemui.statusbar.tablet.HoloClock>
-
-        <com.android.systemui.statusbar.policy.DateView
-            android:id="@+id/date"
-            style="@style/StatusBarNotificationText"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_below="@id/clock"
-            android:layout_marginTop="4dp"
-            android:layout_marginRight="48dp"
-            android:gravity="right"
-            />
-
-        <ImageView
-            android:id="@+id/battery"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_below="@id/date"
-            android:layout_marginLeft="48dp"
-            android:layout_marginTop="18dp"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <TextView
-            android:id="@+id/battery_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="56dp"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/battery"
-            android:layout_alignBaseline="@id/battery"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
-
-        <ImageView
-            android:id="@+id/network_signal"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_toRightOf="@id/battery_text"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <ImageView
-            android:id="@+id/network_type"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_toRightOf="@id/battery_text"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_marginRight="8dp"
-            android:baseline="15dp"
-            />
-
-        <TextView
-            android:id="@+id/network_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/network_signal"
-            android:layout_alignBaseline="@id/battery"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
-
-        <ImageView
-            android:id="@+id/settings_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_alignParentRight="true"
-            android:paddingRight="16dp"
-            android:src="@drawable/ic_notification_open"
-            android:baseline="21dp"
-            />
-
-        <ImageView
-            android:id="@+id/notification_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_alignBaseline="@id/battery"
-            android:paddingRight="16dp"
-            android:visibility="invisible"
-            android:src="@drawable/status_bar_veto"
-            android:baseline="21dp"
-            />
-    </com.android.systemui.statusbar.tablet.NotificationTitleArea>
-
-    <FrameLayout
-        android:id="@+id/content_frame"
+    <LinearLayout
+        android:id="@+id/content_parent"
         android:layout_height="wrap_content"
-        android:layout_width="408dp"
+        android:layout_width="wrap_content"
+        android:animateLayoutChanges="true"
+        android:orientation="vertical"
         >
-        <ScrollView
-            android:id="@+id/notificationScroller"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
+
+        <com.android.systemui.statusbar.tablet.NotificationTitleArea
+            android:id="@+id/title_area"
+            android:layout_height="160dp"
+            android:layout_width="384dp"
+            android:layout_marginLeft="24dp"
+            android:paddingTop="20dp"
+            android:orientation="vertical"
+            android:animateLayoutChanges="true"
             >
-            <LinearLayout 
-                android:id="@+id/content"
-                android:layout_width="match_parent"
+
+            <com.android.systemui.statusbar.tablet.HoloClock
+                android:id="@+id/clock"
                 android:layout_height="wrap_content"
-                android:gravity="center_horizontal|bottom"
-                android:animateLayoutChanges="true"
-                android:animationCache="false"
-                android:orientation="vertical"
-                android:clickable="true"
-                android:focusable="true"
-                android:descendantFocusability="afterDescendants"
+                android:layout_width="match_parent"
+                android:layout_alignParentTop="true"
+                android:layout_marginRight="40dip"
+                android:layout_marginBottom="4dip"
                 >
-            </LinearLayout>
-        </ScrollView>
-    </FrameLayout>
+                <TextView android:id="@+id/time_bg"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="right"
+                    android:singleLine="true"
+                    android:textSize="90dip"
+                    android:textColor="#999999" />
+                <TextView android:id="@+id/time_fg"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="right"
+                    android:singleLine="true"
+                    android:textSize="90dip"
+                    android:textColor="#666666" />
+            </com.android.systemui.statusbar.tablet.HoloClock>
+
+            <com.android.systemui.statusbar.policy.DateView
+                android:id="@+id/date"
+                style="@style/StatusBarNotificationText"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_below="@id/clock"
+                android:layout_marginTop="4dp"
+                android:layout_marginRight="48dp"
+                android:gravity="right"
+                />
+
+            <ImageView
+                android:id="@+id/battery"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_below="@id/date"
+                android:layout_marginLeft="48dp"
+                android:layout_marginTop="18dp"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <TextView
+                android:id="@+id/battery_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_width="56dp"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@id/battery"
+                android:layout_alignBaseline="@id/battery"
+                android:singleLine="true"
+                android:text="@string/status_bar_settings_settings_button"
+                />
+
+            <ImageView
+                android:id="@+id/network_signal"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_toRightOf="@id/battery_text"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <ImageView
+                android:id="@+id/network_type"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:layout_toRightOf="@id/battery_text"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_marginRight="8dp"
+                android:baseline="15dp"
+                />
+
+            <TextView
+                android:id="@+id/network_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@id/network_signal"
+                android:layout_alignBaseline="@id/battery"
+                android:singleLine="true"
+                android:text="@string/status_bar_settings_settings_button"
+                />
+
+            <ImageView
+                android:id="@+id/settings_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignBaseline="@id/battery"
+                android:layout_alignParentRight="true"
+                android:paddingRight="16dp"
+                android:src="@drawable/ic_notification_open"
+                android:baseline="21dp"
+                />
+
+            <ImageView
+                android:id="@+id/notification_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignBaseline="@id/battery"
+                android:paddingRight="16dp"
+                android:visibility="invisible"
+                android:src="@drawable/status_bar_veto"
+                android:baseline="21dp"
+                />
+        </com.android.systemui.statusbar.tablet.NotificationTitleArea>
+
+        <LinearLayout
+            android:id="@+id/content_frame"
+            android:layout_height="wrap_content"
+            android:layout_width="408dp"
+            android:orientation="vertical"
+            >
+            <ScrollView
+                android:id="@+id/notificationScroller"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:layout_weight="1"
+                >
+                <com.android.systemui.statusbar.tablet.NotificationLinearLayout
+                    android:id="@+id/content"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_horizontal|bottom"
+                    android:animateLayoutChanges="true"
+                    android:animationCache="false"
+                    android:orientation="vertical"
+                    android:clickable="true"
+                    android:focusable="true"
+                    android:descendantFocusability="afterDescendants"
+                    systemui:insetLeft="16dp"
+                    >
+                </com.android.systemui.statusbar.tablet.NotificationLinearLayout>
+            </ScrollView>
+            <ImageView
+                android:layout_width="match_parent"
+                android:layout_height="@dimen/status_bar_panel_bottom_offset"
+                android:layout_marginLeft="16dp"
+                android:src="@drawable/notify_item_glow_bottom"
+                />
+        </LinearLayout>
+    </LinearLayout>
 </com.android.systemui.statusbar.tablet.NotificationPanel>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 87395c1..fb2f7d63 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -21,5 +21,8 @@
     <declare-styleable name="ToggleSlider">
         <attr name="text" format="string" />
     </declare-styleable>
+    <declare-styleable name="NotificationLinearLayout">
+        <attr name="insetLeft" format="dimension" />
+    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
new file mode 100644
index 0000000..9ecb2e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
@@ -0,0 +1,92 @@
+/*
+ * 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.tablet;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+public class NotificationLinearLayout extends LinearLayout {
+    private static final String TAG = "NotificationLinearLayout";
+
+    Drawable mItemGlow;
+    int mInsetLeft;
+    Rect mTmp = new Rect();
+
+    public NotificationLinearLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public NotificationLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final Resources res = context.getResources();
+
+        mItemGlow = res.getDrawable(R.drawable.notify_item_glow_bottom);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationLinearLayout,
+                defStyle, 0);
+        mInsetLeft = a.getDimensionPixelSize(R.styleable.NotificationLinearLayout_insetLeft, 0);
+        a.recycle();
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        setWillNotDraw(false);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        final Rect padding = mTmp;
+        final Drawable glow = mItemGlow;
+        glow.getPadding(padding);
+        final int glowHeight = glow.getIntrinsicHeight();
+        final int insetLeft = mInsetLeft;
+
+        final int N = getChildCount();
+        for (int i=0; i<N; i++) {
+            final View child = getChildAt(i);
+
+            final int childBottom = child.getBottom();
+
+            glow.setBounds(child.getLeft() - padding.left + insetLeft, childBottom,
+                    child.getRight() - padding.right, childBottom + glowHeight);
+            glow.draw(canvas);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index baf4a0f..82c1d17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -16,11 +16,20 @@
 
 package com.android.systemui.statusbar.tablet;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -32,12 +41,20 @@
         View.OnClickListener {
     static final String TAG = "NotificationPanel";
 
+    boolean mShowing;
     View mTitleArea;
     View mSettingsButton;
     View mNotificationButton;
     View mNotificationScroller;
-    FrameLayout mContentFrame;
+    ViewGroup mContentFrame;
+    Rect mContentArea;
     View mSettingsView;
+    ViewGroup mContentParent;
+
+    Choreographer mChoreo = new Choreographer();
+    int mStatusBarHeight;
+    Drawable mBgDrawable;
+    Drawable mGlowDrawable;
 
     public NotificationPanel(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -45,12 +62,22 @@
 
     public NotificationPanel(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+
+        final Resources res = context.getResources();
+
+        mStatusBarHeight = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mBgDrawable = res.getDrawable(R.drawable.notify_panel_bg_protect);
+        mGlowDrawable = res.getDrawable(R.drawable.notify_glow_back);
     }
 
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
 
+        setWillNotDraw(false);
+
+        mContentParent = (ViewGroup)findViewById(R.id.content_parent);
         mTitleArea = findViewById(R.id.title_area);
 
         mSettingsButton = (ImageView)findViewById(R.id.settings_button);
@@ -59,7 +86,31 @@
         mNotificationButton.setOnClickListener(this);
 
         mNotificationScroller = findViewById(R.id.notificationScroller);
-        mContentFrame = (FrameLayout)findViewById(R.id.content_frame);
+        mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
+    }
+
+    public void show(boolean show, boolean animate) {
+        if (animate) {
+            if (mShowing != show) {
+                mShowing = show;
+                if (show) {
+                    setVisibility(View.VISIBLE);
+                }
+                mChoreo.startAnimation(show);
+            }
+        } else {
+            mShowing = show;
+            setVisibility(show ? View.VISIBLE : View.GONE);
+            mChoreo.jumpTo(show);
+        }
+    }
+
+    /**
+     * Whether the panel is showing, or, if it's animating, whether it will be
+     * when the animation is done.
+     */
+    public boolean isShowing() {
+        return mShowing;
     }
 
     @Override
@@ -93,6 +144,34 @@
             final View c = getChildAt(i);
             c.layout(c.getLeft(), c.getTop() + shift, c.getRight(), c.getBottom() + shift);
         }
+
+        mChoreo.setPanelHeight(mContentParent.getHeight());
+    }
+
+    @Override
+    public void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mContentArea = null;
+        mBgDrawable.setBounds(0, 0, w, h-mStatusBarHeight);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        int saveCount;
+        final int w = getWidth();
+        final int h = getHeight();
+
+        super.onDraw(canvas);
+
+        // Background protection
+        mBgDrawable.draw(canvas);
+
+        // The panel glow (behind status bar)
+
+        saveCount = canvas.save();
+        canvas.clipRect(0, 0, w, h-mStatusBarHeight);
+        mGlowDrawable.draw(canvas);
+        canvas.restoreToCount(saveCount);
     }
 
     public void onClick(View v) {
@@ -119,11 +198,14 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        final int l = mContentFrame.getLeft();
-        final int r = mContentFrame.getRight();
-        final int t = mTitleArea.getTop();
-        final int b = mContentFrame.getBottom();
-        return x >= l && x < r && y >= t && y < b;
+        if (mContentArea == null) {
+            mContentArea = new Rect(mContentFrame.getLeft(),
+                    mTitleArea.getTop(),
+                    mContentFrame.getRight(),
+                    mContentFrame.getBottom());
+            offsetDescendantRectToMyCoords(mContentParent, mContentArea);
+        }
+        return mContentArea.contains(x, y);
     }
 
     void removeSettingsView() {
@@ -138,5 +220,102 @@
         mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
         mContentFrame.addView(mSettingsView);
     }
+
+    private class Choreographer implements Animator.AnimatorListener {
+        int mBgAlpha;
+        ValueAnimator mBgAnim;
+        int mPanelHeight;
+        int mPanelBottom;
+        ValueAnimator mPositionAnim;
+
+        // should group this into a multi-property animation
+        final int OPEN_DURATION = 200;
+
+        Choreographer() {
+        }
+
+        void createAnimation(boolean visible) {
+            mBgAnim = ObjectAnimator.ofInt(this, "bgAlpha", mBgAlpha, visible ? 255 : 0)
+                    .setDuration(OPEN_DURATION);
+            mBgAnim.addListener(this);
+
+            mPositionAnim = ObjectAnimator.ofInt(this, "panelBottom", mPanelBottom,
+                        visible ? mPanelHeight : 0)
+                    .setDuration(OPEN_DURATION);
+        }
+
+        void startAnimation(boolean visible) {
+            if (mBgAnim == null) {
+                createAnimation(visible);
+                mBgAnim.start();
+                mPositionAnim.start();
+            } else {
+                mBgAnim.reverse();
+                mPositionAnim.reverse();
+            }
+        }
+
+        void jumpTo(boolean visible) {
+            setBgAlpha(visible ? 255 : 0);
+            setPanelBottom(visible ? mPanelHeight : 0);
+        }
+
+        public void setBgAlpha(int alpha) {
+            mBgAlpha = alpha;
+            mBgDrawable.setAlpha((int)(alpha));
+            invalidate();
+        }
+
+        // 0 is closed, the height of the panel is open
+        public void setPanelBottom(int y) {
+            mPanelBottom = y;
+            int translationY = mPanelHeight - y;
+            mContentParent.setTranslationY(translationY);
+
+            final int glowXOffset = 100;
+            final int glowYOffset = 100;
+            int glowX = mContentParent.getLeft() - glowXOffset;
+            int glowY = mContentParent.getTop() - glowYOffset + translationY;
+            mGlowDrawable.setBounds(glowX, glowY, glowX + mGlowDrawable.getIntrinsicWidth(),
+                    glowY + mGlowDrawable.getIntrinsicHeight());
+
+            float alpha;
+            if (mPanelBottom > glowYOffset) {
+                alpha = 1;
+            } else {
+                alpha = ((float)mPanelBottom) / glowYOffset;
+            }
+            mContentParent.setAlpha(alpha);
+            mGlowDrawable.setAlpha((int)(255 * alpha));
+
+            if (false) {
+                Slog.d(TAG, "mPanelBottom=" + mPanelBottom + "translationY=" + translationY
+                        + " alpha=" + alpha + " glowY=" + glowY);
+            }
+        }
+
+        public void setPanelHeight(int h) {
+            mPanelHeight = h;
+            setPanelBottom(mPanelBottom);
+        }
+
+        public void onAnimationCancel(Animator animation) {
+            //Slog.d(TAG, "onAnimationCancel mBgAlpha=" + mBgAlpha);
+        }
+
+        public void onAnimationEnd(Animator animation) {
+            //Slog.d(TAG, "onAnimationEnd mBgAlpha=" + mBgAlpha);
+            if (mBgAlpha == 0) {
+                setVisibility(View.GONE);
+            }
+            mBgAnim = null;
+        }
+
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        public void onAnimationStart(Animator animation) {
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 8b80e50..7a7976a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -161,7 +161,7 @@
         // Notification Panel
         mNotificationPanel = (NotificationPanel)View.inflate(context,
                 R.layout.status_bar_notification_panel, null);
-        mNotificationPanel.setVisibility(View.GONE);
+        mNotificationPanel.show(false, false);
         mNotificationPanel.setOnTouchListener(
                 new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
 
@@ -186,10 +186,14 @@
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
         lp.setTitle("NotificationPanel");
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+        lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
 
         WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
 
@@ -391,7 +395,7 @@
                             mNotificationPeekRow.addView(copy.row);
 
                             mNotificationPeekWindow.setVisibility(View.VISIBLE);
-                            mNotificationPanel.setVisibility(View.GONE);
+                            mNotificationPanel.show(false, true);
 
                             mNotificationPeekIndex = peekIndex;
                             mNotificationPeekKey = entry.key;
@@ -413,9 +417,9 @@
                     break;
                 case MSG_OPEN_NOTIFICATION_PANEL:
                     if (DEBUG) Slog.d(TAG, "opening notifications panel");
-                    if (mNotificationPanel.getVisibility() == View.GONE) {
+                    if (!mNotificationPanel.isShowing()) {
                         mNotificationPeekWindow.setVisibility(View.GONE);
-                        mNotificationPanel.setVisibility(View.VISIBLE);
+                        mNotificationPanel.show(true, true);
                         // synchronize with current shadow state
                         mShadowController.hideElement(mNotificationArea);
                         mTicker.halt();
@@ -423,8 +427,8 @@
                     break;
                 case MSG_CLOSE_NOTIFICATION_PANEL:
                     if (DEBUG) Slog.d(TAG, "closing notifications panel");
-                    if (mNotificationPanel.getVisibility() == View.VISIBLE) {
-                        mNotificationPanel.setVisibility(View.GONE);
+                    if (mNotificationPanel.isShowing()) {
+                        mNotificationPanel.show(false, true);
                         // synchronize with current shadow state
                         mShadowController.showElement(mNotificationArea);
                     }
@@ -459,8 +463,7 @@
         if (mNotificationTrigger == null) return;
 
         int resId;
-        boolean panel = (mNotificationPanel != null 
-                && mNotificationPanel.getVisibility() == View.VISIBLE);
+        boolean panel = (mNotificationPanel != null && mNotificationPanel.isShowing();
         if (!mNotificationsOn) {
             resId = R.drawable.ic_sysbar_noti_dnd;
         } else if (mNotns.size() > 0) {
@@ -658,7 +661,7 @@
 
     private void tick(IBinder key, StatusBarNotification n) {
         // Don't show the ticker when the windowshade is open.
-        if (mNotificationPanel.getVisibility() == View.VISIBLE) {
+        if (mNotificationPanel.isShowing()) {
             return;
         }
         // Show the ticker if one is requested. Also don't do this
@@ -786,7 +789,7 @@
                 mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
                 refreshNotificationTrigger();
             } else {
-                int msg = (mNotificationPanel.getVisibility() == View.GONE)
+                int msg = !mNotificationPanel.isShowing()
                     ? MSG_OPEN_NOTIFICATION_PANEL
                     : MSG_CLOSE_NOTIFICATION_PANEL;
                 mHandler.removeMessages(msg);
@@ -895,7 +898,7 @@
 
         public boolean onTouch(View v, MotionEvent event) {
             boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
-            boolean panelShowing = mNotificationPanel.getVisibility() != View.GONE;
+            boolean panelShowing = mNotificationPanel.isShowing();
             if (panelShowing) return false;
 
             switch (event.getAction()) {