Merge "Fix PANU - Bluetooth tethering - JNI calls."
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index cb06c89..636f547 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -153,8 +153,9 @@
      * we cache all of the current animations in this map for possible cancellation on
      * another layout event.
      */
-    private HashMap<View, Animator> currentChangingAnimations = new HashMap<View, Animator>();
-    private HashMap<View, Animator> currentVisibilityAnimations = new HashMap<View, Animator>();
+    private final HashMap<View, Animator> currentChangingAnimations = new HashMap<View, Animator>();
+    private final HashMap<View, Animator> currentVisibilityAnimations =
+            new HashMap<View, Animator>();
 
     /**
      * This hashmap is used to track the listeners that have been added to the children of
@@ -165,7 +166,7 @@
      * the process of setting up and running all appropriate animations is done, we need to
      * remove these listeners and clear out the map.
      */
-    private HashMap<View, View.OnLayoutChangeListener> layoutChangeListenerMap =
+    private final HashMap<View, View.OnLayoutChangeListener> layoutChangeListenerMap =
             new HashMap<View, View.OnLayoutChangeListener>();
 
     /**
@@ -599,12 +600,14 @@
                 // Remove the animation from the cache when it ends
                 anim.addListener(new AnimatorListenerAdapter() {
                     private boolean canceled = false;
+                    @Override
                     public void onAnimationCancel(Animator animator) {
                         // we remove canceled animations immediately, not here
                         canceled = true;
                         child.removeOnLayoutChangeListener(listener);
                         layoutChangeListenerMap.remove(child);
                     }
+                    @Override
                     public void onAnimationEnd(Animator animator) {
                         if (!canceled) {
                             currentChangingAnimations.remove(child);
@@ -662,7 +665,8 @@
         }
         if (mListeners != null) {
             anim.addListener(new AnimatorListenerAdapter() {
-                public void onAnimationEnd() {
+                @Override
+                public void onAnimationEnd(Animator anim) {
                     currentVisibilityAnimations.remove(child);
                     for (TransitionListener listener : mListeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index ec57de3..0eaf08e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -31,6 +31,7 @@
             android:id="@+id/bar_contents"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:animateLayoutChanges="true"
             >
 
             <!-- notification icons & panel access -->
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 06c058b..3201f8b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -154,6 +154,8 @@
     boolean mNotificationsOn = true;
     private RecentAppsPanel mRecentsPanel;
 
+    public Context getContext() { return mContext; }
+
     protected void addPanelWindows() {
         final Context context = mContext;
 
@@ -322,7 +324,7 @@
         mNotificationPeekTapDuration = vc.getTapTimeout();
         mNotificationFlingVelocity = 300; // px/s
 
-        mTicker = new TabletTicker(context);
+        mTicker = new TabletTicker(this);
 
         // The icons
         mBatteryController = new BatteryController(mContext);
@@ -714,10 +716,17 @@
             if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
                             | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
                 mTicker.add(key, n);
+
+                mNotificationArea.setVisibility(View.GONE);
             }
         }
     }
 
+    // called by TabletTicker when it's done with all queued ticks
+    public void doneTicking() {
+        mNotificationArea.setVisibility(View.VISIBLE);
+    }
+
     public void animateExpand() {
         mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
         mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
@@ -844,6 +853,10 @@
         }
     }
 
+    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
+        return new NotificationClicker(intent, pkg, tag, id);
+    }
+
     private class NotificationClicker implements View.OnClickListener {
         private PendingIntent mIntent;
         private String mPkg;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index b3aed03..32f1e98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -18,7 +18,9 @@
 
 import java.util.Arrays;
 
+import android.animation.LayoutTransition;
 import android.app.Notification;
+import android.app.PendingIntent;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -45,9 +47,14 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
 
-public class TabletTicker extends Handler {
+public class TabletTicker
+        extends Handler
+        implements LayoutTransition.TransitionListener {
+
     private static final String TAG = "StatusBar.TabletTicker";
 
+    private static final boolean CLICKABLE_TICKER = true;
+
     // 3 is enough to let us see most cases, but not get so far behind that it's too annoying.
     private static final int QUEUE_LENGTH = 3;
 
@@ -66,8 +73,14 @@
     private StatusBarNotification[] mQueue = new StatusBarNotification[QUEUE_LENGTH];
     private int mQueuePos;
 
-    public TabletTicker(Context context) {
-        mContext = context;
+    private TabletStatusBar mBar;
+
+    private LayoutTransition mLayoutTransition;
+    private boolean mWindowShouldClose;
+
+    public TabletTicker(TabletStatusBar bar) {
+        mBar = bar;
+        mContext = bar.getContext();
     }
 
     public void add(IBinder key, StatusBarNotification notification) {
@@ -170,11 +183,7 @@
         }
 
         // if there's nothing left, close the window
-        // TODO: Do this when the animation is done instead
-        if (mCurrentView == null && mWindow != null) {
-            WindowManagerImpl.getDefault().removeView(mWindow);
-            mWindow = null;
-        }
+        mWindowShouldClose = (mCurrentView == null && mWindow != null);
     }
 
     private void dequeue() {
@@ -208,11 +217,29 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
+//        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
+
+        mLayoutTransition = new LayoutTransition();
+        mLayoutTransition.addTransitionListener(this);
+        view.setLayoutTransition(mLayoutTransition);
         lp.setTitle("NotificationTicker");
         view.setLayoutParams(lp);
         return view;
     }
 
+    public void startTransition(LayoutTransition transition, ViewGroup container,
+            View view, int transitionType) {}
+
+    public void endTransition(LayoutTransition transition, ViewGroup container,
+            View view, int transitionType) {
+        if (mWindowShouldClose) {
+            WindowManagerImpl.getDefault().removeView(mWindow);
+            mWindow = null;
+            mWindowShouldClose = false;
+            mBar.doneTicking();
+        }
+    }
+
     private View makeTickerView(StatusBarNotification notification) {
         final Notification n = notification.notification;
 
@@ -266,6 +293,17 @@
             largeIcon.setImageBitmap(n.largeIcon);
             largeIcon.setVisibility(View.VISIBLE);
         }
+
+        if (CLICKABLE_TICKER) {
+            PendingIntent contentIntent = notification.notification.contentIntent;
+            if (contentIntent != null) {
+                group.setOnClickListener(mBar.makeClicker(contentIntent,
+                            notification.pkg, notification.tag, notification.id));
+            } else {
+                group.setOnClickListener(null);
+            }
+        }
+
         return group;
     }
 }