TabletTicker.java revision bec7d63c9cad875bb127786d61ee34b4d609db59
1ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato/*
2ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * Copyright (C) 2010 The Android Open Source Project
3ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato *
4ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * you may not use this file except in compliance with the License.
6ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * You may obtain a copy of the License at
7ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato *
8ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato *
10ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * Unless required by applicable law or agreed to in writing, software
11ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * See the License for the specific language governing permissions and
14ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato * limitations under the License.
15ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato */
16ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
17ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratopackage com.android.systemui.statusbar.tablet;
18ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
192026e8d4681437fb056409bc95bc2f126582e4a8Joe Onoratoimport java.util.Arrays;
202026e8d4681437fb056409bc95bc2f126582e4a8Joe Onorato
21c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandlerimport android.animation.LayoutTransition;
22ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.app.Notification;
23c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandlerimport android.app.PendingIntent;
24ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.content.Context;
2552f80cd36f406725e85a1825741a45c69de3d898Joe Onoratoimport android.content.res.Resources;
26ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.graphics.Bitmap;
2752f80cd36f406725e85a1825741a45c69de3d898Joe Onoratoimport android.graphics.PixelFormat;
282026e8d4681437fb056409bc95bc2f126582e4a8Joe Onoratoimport android.graphics.drawable.Drawable;
29ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.os.Handler;
3050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onoratoimport android.os.IBinder;
31ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.os.Message;
32ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.util.Slog;
33ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.view.Gravity;
34ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.view.LayoutInflater;
35ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.view.View;
36ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.view.ViewGroup;
3752f80cd36f406725e85a1825741a45c69de3d898Joe Onoratoimport android.view.WindowManager;
3852f80cd36f406725e85a1825741a45c69de3d898Joe Onoratoimport android.view.WindowManagerImpl;
39ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.FrameLayout;
40ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.ImageView;
416aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandlerimport android.widget.FrameLayout;
42ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.TextView;
43ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
442026e8d4681437fb056409bc95bc2f126582e4a8Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
45ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
46ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
47ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport com.android.systemui.R;
482026e8d4681437fb056409bc95bc2f126582e4a8Joe Onoratoimport com.android.systemui.statusbar.StatusBarIconView;
49ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
50c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandlerpublic class TabletTicker
51c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        extends Handler
52c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        implements LayoutTransition.TransitionListener {
53c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
54ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private static final String TAG = "StatusBar.TabletTicker";
55ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
56e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler    private static final boolean CLICKABLE_TICKER = true;
57c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
5850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    // 3 is enough to let us see most cases, but not get so far behind that it's too annoying.
5950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private static final int QUEUE_LENGTH = 3;
6050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
61ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private static final int MSG_ADVANCE = 1;
62ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
636c1af93c17cf1ebf17ecbee12cbed27db5a26a0bJoe Onorato    private static final int ADVANCE_DELAY = 5000; // 5 seconds
64ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
65ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private Context mContext;
66ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
6752f80cd36f406725e85a1825741a45c69de3d898Joe Onorato    private ViewGroup mWindow;
6850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private IBinder mCurrentKey;
69ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private StatusBarNotification mCurrentNotification;
70ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private View mCurrentView;
71ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
7250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private IBinder[] mKeys = new IBinder[QUEUE_LENGTH];
7350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private StatusBarNotification[] mQueue = new StatusBarNotification[QUEUE_LENGTH];
74ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private int mQueuePos;
75ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
76c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    private TabletStatusBar mBar;
77c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
78c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    private LayoutTransition mLayoutTransition;
79c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    private boolean mWindowShouldClose;
80c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
81c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    public TabletTicker(TabletStatusBar bar) {
82c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mBar = bar;
83c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mContext = bar.getContext();
84ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
85ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
8650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    public void add(IBinder key, StatusBarNotification notification) {
87ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (false) {
8850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            Slog.d(TAG, "add 1 mCurrentNotification=" + mCurrentNotification
89ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                    + " mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
90ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
9150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
9250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // If it's already in here, remove whatever's in there and put the new one at the end.
9350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        remove(key, false);
9450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
9550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mKeys[mQueuePos] = key;
96ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        mQueue[mQueuePos] = notification;
97ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
9850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // If nothing is running now, start the next one.
9950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (mQueuePos == 0 && mCurrentNotification == null) {
100ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            sendEmptyMessage(MSG_ADVANCE);
101ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
102ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
10350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (mQueuePos < QUEUE_LENGTH - 1) {
104ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            mQueuePos++;
105ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
106ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
107ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
10850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    public void remove(IBinder key) {
10950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        remove(key, true);
11050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    }
11150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
11250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    public void remove(IBinder key, boolean advance) {
11350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (mCurrentKey == key) {
11450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // Showing now
11550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            if (advance) {
11650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                removeMessages(MSG_ADVANCE);
11750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                sendEmptyMessage(MSG_ADVANCE);
11850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            }
11950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } else {
12050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // In the queue
12150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            for (int i=0; i<QUEUE_LENGTH; i++) {
12250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                if (mKeys[i] == key) {
12350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    for (; i<QUEUE_LENGTH-1; i++) {
12450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mKeys[i] = mKeys[i+1];
12550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mQueue[i] = mQueue[i+1];
12650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    }
12750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    mKeys[QUEUE_LENGTH-1] = null;
12850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    mQueue[QUEUE_LENGTH-1] = null;
12950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    if (mQueuePos > 0) {
13050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mQueuePos--;
13150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    }
13250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                    break;
13350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                }
13450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            }
13550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
13650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    }
13750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
138091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    public void halt() {
139091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        removeMessages(MSG_ADVANCE);
140af5e4da2a5766198f533f1ff9e2072d2cd5c63d4Joe Onorato        if (mCurrentView != null || mQueuePos != 0) {
14150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            for (int i=0; i<QUEUE_LENGTH; i++) {
14250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                mKeys[i] = null;
143091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                mQueue[i] = null;
144091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            }
145091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            mQueuePos = 0;
146091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            sendEmptyMessage(MSG_ADVANCE);
147091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
148091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    }
149091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
150ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    public void handleMessage(Message msg) {
151ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        switch (msg.what) {
152ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            case MSG_ADVANCE:
153ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                advance();
154ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                break;
155ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
156ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
157ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
158ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private void advance() {
159ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        // Out with the old...
160ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (mCurrentView != null) {
161bec7d63c9cad875bb127786d61ee34b4d609db59Daniel Sandler            if (mWindow != null) {
162bec7d63c9cad875bb127786d61ee34b4d609db59Daniel Sandler                mWindow.removeView(mCurrentView);
163bec7d63c9cad875bb127786d61ee34b4d609db59Daniel Sandler            }
164ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            mCurrentView = null;
16550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            mCurrentKey = null;
166ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            mCurrentNotification = null;
167ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
168ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
169ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        // In with the new...
17050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        dequeue();
17150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        while (mCurrentNotification != null) {
17250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            mCurrentView = makeTickerView(mCurrentNotification);
17346439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            if (mCurrentView != null) {
17452f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                if (mWindow == null) {
17552f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                    mWindow = makeWindow();
17652f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                    WindowManagerImpl.getDefault().addView(mWindow, mWindow.getLayoutParams());
17752f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                }
1786aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler
17952f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                mWindow.addView(mCurrentView);
18046439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
18146439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                break;
18246439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            }
18350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            dequeue();
184ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
18552f80cd36f406725e85a1825741a45c69de3d898Joe Onorato
18652f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        // if there's nothing left, close the window
187c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mWindowShouldClose = (mCurrentView == null && mWindow != null);
188ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
189ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
19050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private void dequeue() {
19150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mCurrentKey = mKeys[0];
19250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mCurrentNotification = mQueue[0];
193ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (false) {
194ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            Slog.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
195ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
196ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        final int N = mQueuePos;
197ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        for (int i=0; i<N; i++) {
19850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            mKeys[i] = mKeys[i+1];
199ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            mQueue[i] = mQueue[i+1];
200ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
20150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mKeys[N] = null;
202ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        mQueue[N] = null;
203ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (mQueuePos > 0) {
204ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            mQueuePos--;
205ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
206ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
207ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
20852f80cd36f406725e85a1825741a45c69de3d898Joe Onorato    private ViewGroup makeWindow() {
20952f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        final Resources res = mContext.getResources();
21052f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        final FrameLayout view = new FrameLayout(mContext);
21152f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
212a032c90189d9ac28b65af4fe5f8b34f182441335Joe Onorato        final int height = res.getDimensionPixelSize(
213a032c90189d9ac28b65af4fe5f8b34f182441335Joe Onorato                android.R.dimen.notification_large_icon_height);
214ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        int windowFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
2156c1af93c17cf1ebf17ecbee12cbed27db5a26a0bJoe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
216ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
217ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        if (CLICKABLE_TICKER) {
218ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato            windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
219ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        } else {
220ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato            windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
221ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        }
222ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
223ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, windowFlags,
22452f80cd36f406725e85a1825741a45c69de3d898Joe Onorato                PixelFormat.TRANSLUCENT);
22552f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
226c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler//        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
227c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
228c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mLayoutTransition = new LayoutTransition();
229c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mLayoutTransition.addTransitionListener(this);
230c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        view.setLayoutTransition(mLayoutTransition);
23152f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        lp.setTitle("NotificationTicker");
23252f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        view.setLayoutParams(lp);
23352f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        return view;
23452f80cd36f406725e85a1825741a45c69de3d898Joe Onorato    }
23552f80cd36f406725e85a1825741a45c69de3d898Joe Onorato
236c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    public void startTransition(LayoutTransition transition, ViewGroup container,
237c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            View view, int transitionType) {}
238c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
239c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    public void endTransition(LayoutTransition transition, ViewGroup container,
240c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            View view, int transitionType) {
241c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        if (mWindowShouldClose) {
242c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            WindowManagerImpl.getDefault().removeView(mWindow);
243c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            mWindow = null;
244c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            mWindowShouldClose = false;
245b8027d87d87fbf24a6091ef183e519157876df41Daniel Sandler            mBar.doneTicking();
246c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        }
247c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    }
248c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
249ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private View makeTickerView(StatusBarNotification notification) {
250ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        final Notification n = notification.notification;
251ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
252ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
253ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
254ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
255ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        ViewGroup group;
25646439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        int layoutId;
257561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        int iconId;
258561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        if (n.largeIcon != null) {
259561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            iconId = R.id.right_icon;
260561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        } else {
261561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            iconId = R.id.left_icon;
262561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        }
26346439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        if (n.tickerView != null) {
264755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato            group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_panel, null, false);
2656aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler            ViewGroup content = (FrameLayout) group.findViewById(R.id.ticker_expanded);
26646439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            View expanded = null;
26746439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            Exception exception = null;
26846439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            try {
2696aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler                expanded = n.tickerView.apply(mContext, content);
270ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            }
27146439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            catch (RuntimeException e) {
27246439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                exception = e;
273ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            }
27446439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            if (expanded == null) {
27546439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                final String ident = notification.pkg
27646439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                        + "/0x" + Integer.toHexString(notification.id);
27746439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
27846439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato                return null;
27946439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            }
2806aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
2816aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler                    ViewGroup.LayoutParams.MATCH_PARENT,
2826aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler                    ViewGroup.LayoutParams.MATCH_PARENT);
2836aa2d3a166b7b2fe5362931297953d08c17a0fb6Daniel Sandler            content.addView(expanded, lp);
28446439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        } else if (n.tickerText != null) {
285755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato            group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_compat, mWindow, false);
2862026e8d4681437fb056409bc95bc2f126582e4a8Joe Onorato            final Drawable icon = StatusBarIconView.getIcon(mContext,
2872026e8d4681437fb056409bc95bc2f126582e4a8Joe Onorato                    new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0));
288561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            ImageView iv = (ImageView)group.findViewById(iconId);
2892026e8d4681437fb056409bc95bc2f126582e4a8Joe Onorato            iv.setImageDrawable(icon);
290561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            iv.setVisibility(View.VISIBLE);
291ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            TextView tv = (TextView)group.findViewById(R.id.text);
292ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            tv.setText(n.tickerText);
29346439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        } else {
29446439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            throw new RuntimeException("tickerView==null && tickerText==null");
295ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        }
296561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        ImageView largeIcon = (ImageView)group.findViewById(R.id.large_icon);
297561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        if (n.largeIcon != null) {
298561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setImageBitmap(n.largeIcon);
299561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setVisibility(View.VISIBLE);
300561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        }
301c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
302c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        if (CLICKABLE_TICKER) {
303c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            PendingIntent contentIntent = notification.notification.contentIntent;
304c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            if (contentIntent != null) {
305e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                // create the usual notification clicker, but chain it together with a halt() call
306e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                // to abort the ticker too
307e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                final View.OnClickListener clicker = mBar.makeClicker(contentIntent,
308e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                                            notification.pkg, notification.tag, notification.id);
309e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                group.setOnClickListener(new View.OnClickListener() {
310e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                    public void onClick(View v) {
311e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                        halt();
312e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                        clicker.onClick(v);
313e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                    }
314e2c251b564a46a8f7352094ba8a61d46dc6b676fDaniel Sandler                });
315c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            } else {
316c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler                group.setOnClickListener(null);
317c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler            }
318c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        }
319c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
320ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        return group;
321ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
322ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato}
323ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
324