PhoneStatusBar.java revision 29fc2c9705e1bb8ae098fca016032d2325031587
1808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato/*
2808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Copyright (C) 2010 The Android Open Source Project
3808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
4808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * you may not use this file except in compliance with the License.
6808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * You may obtain a copy of the License at
7808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
8808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
10808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Unless required by applicable law or agreed to in writing, software
11808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * See the License for the specific language governing permissions and
14808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * limitations under the License.
15808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato */
16808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.phone;
18808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
19808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Service;
20808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.ActivityManagerNative;
21808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Dialog;
22808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Notification;
23808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.PendingIntent;
24808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Service;
25808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.StatusBarManager;
26808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.BroadcastReceiver;
27808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
28808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
29808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.IntentFilter;
30808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.res.Resources;
31808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.PixelFormat;
32808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.Rect;
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.drawable.Drawable;
34808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.net.Uri;
35808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
36808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.RemoteException;
37808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.Handler;
38808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.Message;
39808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.SystemClock;
40935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onoratoimport android.text.TextUtils;
41808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.util.Slog;
42808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.util.Log;
43808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Display;
44808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
45808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.KeyEvent;
46808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.LayoutInflater;
47808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.MotionEvent;
48808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.VelocityTracker;
49808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
50808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.ViewGroup;
51808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Window;
52808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManager;
53808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManagerImpl;
54808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.Animation;
55808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.AnimationUtils;
56808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ImageView;
57808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.RemoteViews;
59808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ScrollView;
60808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.TextView;
61808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.FrameLayout;
62808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.io.FileDescriptor;
64808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.io.PrintWriter;
65808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.util.ArrayList;
66808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.util.HashMap;
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.util.Set;
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
69808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
70808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIconList;
71808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
72808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
73808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.R;
74fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.NotificationData;
75fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.StatusBar;
76fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.StatusBarIconView;
77fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.DateView;
78808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
79808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
80fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopublic class PhoneStatusBar extends StatusBar {
81fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    static final String TAG = "PhoneStatusBar";
82808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final boolean SPEW = false;
83808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
84808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public static final String ACTION_STATUSBAR_START
85808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            = "com.android.internal.policy.statusbar.START";
86808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
87808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_LEAVE_ALONE = -10000;
88808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_FULL_OPEN = -10001;
89808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
90808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_ANIMATE = 1000;
91808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_ANIMATE_REVEAL = 1001;
92808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_SHOW_INTRUDER = 1002;
93808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_HIDE_INTRUDER = 1003;
94808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
95808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // will likely move to a resource or other tunable param at some point
96808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int INTRUDER_ALERT_DECAY_MS = 10000;
97808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
98fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarPolicy mIconPolicy;
99808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mIconSize;
101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Display mDisplay;
102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
103fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarView mStatusBarView;
104808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mPixelFormat;
105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    H mHandler = new H();
106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Object mQueueLock = new Object();
107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
108808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // icons
109808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mIcons;
110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    IconMerger mNotificationIcons;
111808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mStatusIcons;
112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // expanded notifications
114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Dialog mExpandedDialog;
115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ExpandedView mExpandedView;
116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WindowManager.LayoutParams mExpandedParams;
117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ScrollView mScrollView;
118808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View mNotificationLinearLayout;
119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View mExpandedContents;
120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // top bar
121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TextView mNoNotificationsTitle;
122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TextView mClearButton;
123808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // drag bar
124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    CloseDragHandle mCloseView;
125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ongoing
126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    NotificationData mOngoing = new NotificationData();
127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TextView mOngoingTitle;
128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mOngoingItems;
129808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // latest
130808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    NotificationData mLatest = new NotificationData();
131808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TextView mLatestTitle;
132808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mLatestItems;
133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // position
134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mPositionTmp = new int[2];
135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpanded;
136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpandedVisible;
137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the date view
139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    DateView mDateView;
140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for immersive activities
142808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View mIntruderAlertView;
143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the tracker view
145808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TrackingView mTrackingView;
146808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WindowManager.LayoutParams mTrackingParams;
147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mTrackingPosition; // the position of the top of the tracking view.
148808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mPanelSlightlyVisible;
149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ticker
151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Ticker mTicker;
152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View mTickerView;
153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mTicking;
154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Tracking finger for opening/closing.
156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mTracking;
158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    VelocityTracker mVelocityTracker;
159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int ANIM_FRAME_DURATION = (1000/60);
161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimating;
163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mCurAnimationTime;
164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mDisplayHeight;
165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimY;
166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimVel;
167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimAccel;
168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mAnimLastTime;
169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimatingReveal = false;
170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mViewDelta;
171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mAbsPos = new int[2];
172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for disabling the status bar
174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mDisabled = 0;
175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class ExpandedDialog extends Dialog {
177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ExpandedDialog(Context context) {
178808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
180808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
181808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
182808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public boolean dispatchKeyEvent(KeyEvent event) {
183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (event.getKeyCode()) {
185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            case KeyEvent.KEYCODE_BACK:
186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!down) {
187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    animateCollapse();
188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                return true;
190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return super.dispatchKeyEvent(event);
192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
196f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
197f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
198f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                .getDefaultDisplay();
199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
200f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start();
201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        addIntruderView();
203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Lastly, call to the icon policy to install/update all the icons.
205fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mIconPolicy = new PhoneStatusBarPolicy(mContext);
206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Constructing the view
210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
212f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Resources res = context.getResources();
215808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
216808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
217808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
218808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ExpandedView expanded = (ExpandedView)View.inflate(context,
219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                R.layout.status_bar_expanded, null);
220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        expanded.mService = this;
221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView = View.inflate(context, R.layout.intruder_alert, null);
223808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(View.GONE);
224808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setClickable(true);
225808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
226fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
227fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                R.layout.status_bar, null);
228808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        sb.mService = this;
229808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
230808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // figure out which pixel-format to use for the status bar.
231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mPixelFormat = PixelFormat.TRANSLUCENT;
232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Drawable bg = sb.getBackground();
233808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (bg != null) {
234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPixelFormat = bg.getOpacity();
235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusBarView = sb;
238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTickerView = sb.findViewById(R.id.ticker);
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView = (DateView)sb.findViewById(R.id.date);
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog = new ExpandedDialog(context);
245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedView = expanded;
246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);
247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle);
248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems);
249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle);
250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems);
251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button);
253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mClearButton.setOnClickListener(mClearButtonListener);
254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mOngoingTitle.setVisibility(View.GONE);
258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mLatestTitle.setVisibility(View.GONE);
259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
260808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTicker = new MyTicker(context, sb);
261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        tickerView.mTicker = mTicker;
264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null);
266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.mService = this;
267808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close);
268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCloseView.mService = this;
269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
272808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // set the inital view visibility
273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
274808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.setVisibility(View.INVISIBLE);
275808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
276808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // receive broadcasts
277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        IntentFilter filter = new IntentFilter();
278808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
279808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        context.registerReceiver(mBroadcastReceiver, filter);
282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
283808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
284808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
285808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
286808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
287808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.TOP | Gravity.FILL_HORIZONTAL;
288808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
289808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
290808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void addIntruderView() {
291f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = mContext.getResources();
292808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int height= res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
293808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
295808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
296808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.WRAP_CONTENT,
29729fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato                WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
299808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
300808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
30246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
30346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                PixelFormat.TRANSLUCENT);
305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
306808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.y += height * 1.5; // FIXME
307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("IntruderAlert");
308808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar_IntruderAlert;
309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " icon=" + icon);
316f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        StatusBarIconView view = new StatusBarIconView(mContext, slot);
317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
320808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
321808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
323808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " old=" + old + " icon=" + icon);
325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.removeViewAt(viewIndex);
332808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView iconView = addNotificationViews(key, notification);
336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (iconView == null) return;
337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        boolean immersive = false;
339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
340808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
341808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
342808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
343808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
344808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (immersive) {
345808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((notification.notification.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
346808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "Presenting high-priority notification in immersive activity");
347379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler                // special new transient ticker mode
348808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 1. Populate mIntruderAlertView
349808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
350808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
351808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
352808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                alertIcon.setImageDrawable(StatusBarIconView.getIcon(
353808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    alertIcon.getContext(),
354808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    iconView.getStatusBarIcon()));
355808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                alertText.setText(notification.notification.tickerText);
356808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
357808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                button.setOnClickListener(
359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    new Launcher(notification.notification.contentIntent,
360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.pkg, notification.tag, notification.id));
361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 2. Animate mIntruderAlertView in
363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 3. Set alarm to age the notification off (TODO)
366808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.removeMessages(MSG_HIDE_INTRUDER);
367808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
368808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
369808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (notification.notification.fullScreenIntent != null) {
370808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // not immersive & a full-screen alert should be shown
371808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
372808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " sending fullScreenIntent");
373808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
374808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                notification.notification.fullScreenIntent.send();
375808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (PendingIntent.CanceledException e) {
376808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
377808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
378808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // usual case: status bar visible & not immersive
379808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
380808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // show the ticker
381808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            tick(notification);
382808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
383808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
384808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
385808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
386808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
387808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
388808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
389808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
390808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification);
391808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
392808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        NotificationData oldList;
393379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        NotificationData.Entry oldEntry = mOngoing.findByKey(key);
394379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (oldEntry != null) {
395808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            oldList = mOngoing;
396808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
397379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            oldEntry = mLatest.findByKey(key);
398379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler            if (oldEntry == null) {
399808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.w(TAG, "updateNotification for unknown key: " + key);
400808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                return;
401808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
402808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            oldList = mLatest;
403808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
404808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final StatusBarNotification oldNotification = oldEntry.notification;
405808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final RemoteViews oldContentView = oldNotification.notification.contentView;
406808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
407808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final RemoteViews contentView = notification.notification.contentView;
408808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
409808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) {
410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " expanded=" + oldEntry.expanded
413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " contentView=" + oldContentView);
414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "new notification: when=" + notification.notification.when
415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " contentView=" + contentView);
417808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
418808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
419808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
420808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // didn't change.
421808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (notification.notification.when == oldNotification.notification.when
422808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && notification.isOngoing() == oldNotification.isOngoing()
423808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldEntry.expanded != null
424808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView != null && oldContentView != null
425808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView.getPackage() != null
426808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage() != null
427808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage().equals(contentView.getPackage())
428808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getLayoutId() == contentView.getLayoutId()) {
429808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "reusing notification");
430808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            oldEntry.notification = notification;
431808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
432808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Reapply the RemoteViews
433f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
434808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // update the contentIntent
435808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final PendingIntent contentIntent = notification.notification.contentIntent;
436808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (contentIntent != null) {
437808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    oldEntry.content.setOnClickListener(new Launcher(contentIntent,
438808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                notification.pkg, notification.tag, notification.id));
439184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
440184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
441808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
442808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Update the icon.
443808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
444808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.notification.icon, notification.notification.iconLevel,
445808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.notification.number);
446808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!oldEntry.icon.set(ic)) {
447808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
448808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    return;
449808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
450808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
451808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            catch (RuntimeException e) {
452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // It failed to add cleanly.  Log, and remove the view from the panel.
453808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                removeNotificationViews(key);
455808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                addNotificationViews(key, notification);
456808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
457808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
458808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "not reusing notification");
459808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            removeNotificationViews(key);
460808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            addNotificationViews(key, notification);
461808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
462808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
463808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Restart the ticker if it's still running
464935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato        if (notification.notification.tickerText != null
465935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato                && !TextUtils.equals(notification.notification.tickerText,
466935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato                    oldEntry.notification.notification.tickerText)) {
467935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato            tick(notification);
468935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato        }
469808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
470808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
471808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
472808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
473808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
474808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
475808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
476808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "removeNotification key=" + key);
477808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarNotification old = removeNotificationViews(key);
478808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != null) {
480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Cancel the ticker if it's still running
481808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicker.removeEntry(old);
482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
483808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Recalculate the position of the sliding windows and the titles.
484808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setAreThereNotifications();
485808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
486808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
487808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
488808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
489808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private int chooseIconIndex(boolean isOngoing, int viewIndex) {
490808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int latestSize = mLatest.size();
491808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (isOngoing) {
492808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return latestSize + (mOngoing.size() - viewIndex);
493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return latestSize - viewIndex;
495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Notification n = notification.notification;
500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        RemoteViews remoteViews = n.contentView;
501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (remoteViews == null) {
502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // create the row view
506f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
507f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false);
509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // bind the click event to the content area
511808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
512808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        content.setOnFocusChangeListener(mFocusChangeListener);
514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        PendingIntent contentIntent = n.contentIntent;
515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (contentIntent != null) {
516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
517808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.tag, notification.id));
518184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
519184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
520808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        View expanded = null;
523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Exception exception = null;
524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
525f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
526808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        catch (RuntimeException e) {
528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            exception = e;
529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (expanded == null) {
531808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);
532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
533808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
534808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
535808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            content.addView(expanded);
536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            row.setDrawingCacheEnabled(true);
537808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
539808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return new View[] { row, content, expanded };
540808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
541808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
542808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
543808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        NotificationData list;
544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ViewGroup parent;
545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final boolean isOngoing = notification.isOngoing();
546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (isOngoing) {
547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            list = mOngoing;
548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            parent = mOngoingItems;
549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            list = mLatest;
551808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            parent = mLatestItems;
552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
553808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Construct the expanded view.
554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final View[] views = makeNotificationView(notification, parent);
555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (views == null) {
556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + notification);
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final View row = views[0];
561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final View content = views[1];
562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final View expanded = views[2];
563808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Construct the icon.
564f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                notification.pkg + "/0x" + Integer.toHexString(notification.id));
566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    notification.notification.iconLevel, notification.notification.number);
568808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!iconView.set(ic)) {
569808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            handleNotificationError(key, notification, "Coulding create icon: " + ic);
570808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Add the expanded view.
573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int viewIndex = list.add(key, notification, row, content, expanded, iconView);
574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        parent.addView(row, viewIndex);
575808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Add the icon.
576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
577066b5c5166c1f5342bd42aa0d68f784a5f4c1dd1Joe Onorato        mNotificationIcons.addView(iconView, iconIndex);
578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return iconView;
579808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
581808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    StatusBarNotification removeNotificationViews(IBinder key) {
582808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        NotificationData.Entry entry = mOngoing.remove(key);
583808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (entry == null) {
584808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            entry = mLatest.remove(key);
585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (entry == null) {
586808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.w(TAG, "removeNotification for unknown key: " + key);
587808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                return null;
588808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
589808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
590808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Remove the expanded view.
591808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ((ViewGroup)entry.row.getParent()).removeView(entry.row);
592808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Remove the icon.
593808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ((ViewGroup)entry.icon.getParent()).removeView(entry.icon);
594808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
595808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return entry.notification;
596808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
597808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
598808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void setAreThereNotifications() {
599808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        boolean ongoing = mOngoing.hasVisibleItems();
600808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        boolean latest = mLatest.hasVisibleItems();
601808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
602808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // (no ongoing notifications are clearable)
603808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mLatest.hasClearableItems()) {
604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mClearButton.setVisibility(View.VISIBLE);
605808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
606808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mClearButton.setVisibility(View.INVISIBLE);
607808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
608808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
609808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
610808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
611808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
612808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (ongoing || latest) {
613808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNoNotificationsTitle.setVisibility(View.GONE);
614808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
615808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNoNotificationsTitle.setVisibility(View.VISIBLE);
616808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
617808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
618808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
619808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
620808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
621808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * State is one or more of the DISABLE constants from StatusBarManager.
622808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
623808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
624808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int old = mDisabled;
625808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int diff = state ^ old;
626808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = state;
627808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
628808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
629808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
630808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_EXPAND: yes");
631808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
632808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
633808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
634808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
635808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
636808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
637808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
638808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
639808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
640808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
641808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
644808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
645808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
646808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
647808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
648808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
649808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
650808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");
651808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
652808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
653808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
654808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
655808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
656808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
657808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * All changes to the status bar and notifications funnel through here and are batched.
658808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
659808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class H extends Handler {
660808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void handleMessage(Message m) {
661808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (m.what) {
662808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE:
663808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doAnimation();
664808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
665808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE_REVEAL:
666808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doRevealAnimation();
667808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
668808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_SHOW_INTRUDER:
669808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(true);
670808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
671808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_HIDE_INTRUDER:
672808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(false);
673808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
674808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
675808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
676808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
677808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
678808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
679808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onFocusChange(View v, boolean hasFocus) {
680808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Because 'v' is a ViewGroup, all its children will be (un)selected
681808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // too, which allows marqueeing to work.
682808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            v.setSelected(hasFocus);
683808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
684808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
685808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
686808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void makeExpandedVisible() {
687808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
688808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedVisible) {
689808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
690808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
691808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = true;
692808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(true);
693808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
694808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
695808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
696808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
697808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
698808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedView.requestFocus(View.FOCUS_FORWARD);
699808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.setVisibility(View.VISIBLE);
700808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
701808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mTicking) {
702808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
703808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
704808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
705808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
706808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
707808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
708808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
709808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
710808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
711808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
712808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
713808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
714808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
715808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(0, true);
716808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        performFling(0, 2000.0f, true);
717808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
718808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
719808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
720808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
721808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
722808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedVisible=" + mExpandedVisible
723808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpanded=" + mExpanded
724808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimating=" + mAnimating
725808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimY=" + mAnimY
726808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimVel=" + mAnimVel);
727808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
728808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
729808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
730808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
731808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
732808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
733808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int y;
734808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
735808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            y = (int)mAnimY;
736808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
737808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            y = mDisplay.getHeight()-1;
738808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
739808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Let the fling think that we're open so it goes in the right direction
740808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // and doesn't try to re-open the windowshade.
741808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
742808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(y, false);
743808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        performFling(y, -2000.0f, true);
744808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
745808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
746808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performExpand() {
747808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);
748808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
749808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
750808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
751808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
752808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
753808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
754808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
755808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
756808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        makeExpandedVisible();
757808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_FULL_OPEN);
758808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
759808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) postStartTracing();
760808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
761808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
762808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performCollapse() {
763808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
764808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " mExpandedVisible=" + mExpandedVisible);
765808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
766808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
767808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
768808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
769808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = false;
770808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(false);
771808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
772808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
773808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
774808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.setVisibility(View.GONE);
775808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
776808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
777808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
778808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
779808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
780808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
781808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpanded) {
782808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
783808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
784808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = false;
785808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
786808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
787808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doAnimation() {
788808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
789808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation");
790808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
791808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
792808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
793808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimY >= mDisplay.getHeight()-1) {
794808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
795808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
796808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(EXPANDED_FULL_OPEN);
797808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performExpand();
798808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
799808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (mAnimY < mStatusBarView.getHeight()) {
800808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
801808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
802808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(0);
803808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performCollapse();
804808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
805808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
806808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
807808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
808808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
809808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
810808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
811808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
812808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
813808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void stopTracking() {
814808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = false;
815808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker.recycle();
816808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = null;
817808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
818808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
819808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void incrementAnim() {
820808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
821808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s
822808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float y = mAnimY;
823808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float v = mAnimVel;                                   // px/s
824808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float a = mAnimAccel;                                 // px/s/s
825808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
826808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = v + (a*t);                                       // px/s
827808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;                                        // ms
828808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
829808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
830808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
831808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
832808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doRevealAnimation() {
833808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int h = mCloseView.getHeight() + mStatusBarView.getHeight();
834808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimatingReveal && mAnimating && mAnimY < h) {
835808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
836808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimY >= h) {
837808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimY = h;
838808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
839808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
840808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
841808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
842808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
843808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mCurAnimationTime);
844808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
845808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
846808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
847808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
848808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void prepareTracking(int y, boolean opening) {
849808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = true;
850808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = VelocityTracker.obtain();
851808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (opening) {
852808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimAccel = 2000.0f;
853808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimVel = 200;
854808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimY = mStatusBarView.getHeight();
855808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos((int)mAnimY);
856808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
857808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimatingReveal = true;
858808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE);
859808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE_REVEAL);
860808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            long now = SystemClock.uptimeMillis();
861808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimLastTime = now;
862808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mCurAnimationTime = now + ANIM_FRAME_DURATION;
863808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
864808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
865808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mCurAnimationTime);
866808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            makeExpandedVisible();
867808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
868808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // it's open, close it?
869808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimating) {
870808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
871808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.removeMessages(MSG_ANIMATE);
872808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
873808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(y + mViewDelta);
874808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
875808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
876808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
877808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performFling(int y, float vel, boolean always) {
878808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimatingReveal = false;
879808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisplayHeight = mDisplay.getHeight();
880808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
881808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y;
882808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = vel;
883808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
884808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
885808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
886808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
887808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!always && (
888808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel > 200.0f
889808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    || (y > (mDisplayHeight-25) && vel > -200.0f))) {
890808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded, but they didn't move sufficiently to cause
891808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the expanded position.
892808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = 2000.0f;
893808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
894808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
895808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
896808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
897808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
898808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded and are now going to animate away.
899808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = -2000.0f;
900808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
901808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
902808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
903808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
904808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
905808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (always || (
906808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel > 200.0f
907808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    || (y > (mDisplayHeight/2) && vel > -200.0f))) {
908808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, and they moved enough to allow us to
909808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // expand.  Animate in the notifications.
910808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = 2000.0f;
911808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
912808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
913808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
914808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
915808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
916808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, but they didn't move sufficiently to cause
917808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the collapsed position.
918808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = -2000.0f;
919808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
920808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
921808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
922808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
923808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
924808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
925808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
926808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
927808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
928808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;
929808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCurAnimationTime = now + ANIM_FRAME_DURATION;
930808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimating = true;
931808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE);
932808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE_REVEAL);
933808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
934808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        stopTracking();
935808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
936808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
937808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean interceptTouchEvent(MotionEvent event) {
938808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
939808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
940808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + mDisabled);
941808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
942808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
943808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
944808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return false;
945808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
946808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
947808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int statusBarSize = mStatusBarView.getHeight();
948808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int hitSize = statusBarSize*2;
949808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (event.getAction() == MotionEvent.ACTION_DOWN) {
950808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int y = (int)event.getRawY();
951808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
952808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!mExpanded) {
953808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mViewDelta = statusBarSize - y;
954808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
955808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTrackingView.getLocationOnScreen(mAbsPos);
956808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
957808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
958808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((!mExpanded && y < hitSize) ||
959808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    (mExpanded && y > (mDisplay.getHeight()-hitSize))) {
960808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
961808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We drop events at the edge of the screen to make the windowshade come
962808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // down by accident less, especially when pushing open a device with a keyboard
963808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // that rotates (like g1 and droid)
964808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int x = (int)event.getRawX();
965808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final int edgeBorder = mEdgeBorder;
966808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) {
967808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    prepareTracking(y, !mExpanded);// opening if we're not already fully visible
968808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mVelocityTracker.addMovement(event);
969808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
970808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
971808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (mTracking) {
972808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mVelocityTracker.addMovement(event);
973808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int minY = statusBarSize + mCloseView.getHeight();
974808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (event.getAction() == MotionEvent.ACTION_MOVE) {
975808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int y = (int)event.getRawY();
976808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mAnimatingReveal && y < minY) {
977808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // nothing
978808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else  {
979808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimatingReveal = false;
980808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    updateExpandedViewPos(y + mViewDelta);
981808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
982808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else if (event.getAction() == MotionEvent.ACTION_UP) {
983808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mVelocityTracker.computeCurrentVelocity(1000);
984808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
985808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float yVel = mVelocityTracker.getYVelocity();
986808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                boolean negative = yVel < 0;
987808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
988808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float xVel = mVelocityTracker.getXVelocity();
989808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (xVel < 0) {
990808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    xVel = -xVel;
991808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
992808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (xVel > 150.0f) {
993808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    xVel = 150.0f; // limit how much we care about the x axis
994808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
995808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
996808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float vel = (float)Math.hypot(yVel, xVel);
997808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (negative) {
998808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel = -vel;
999808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1000808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1001808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performFling((int)event.getRawY(), vel, false);
1002808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1003808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1004808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1005808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return false;
1006808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1007808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
10089305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
10099305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato        if (!on) {
10109305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato            // All we do for "lights out" mode on a phone is hide the status bar,
10119305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato            // which the window manager does.  But we do need to hide the windowshade
10129305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato            // on our own.
10139305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato            animateCollapse();
10149305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato        }
10159305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
10169305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
1017e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    // Not supported
1018e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    public void setMenuKeyVisible(boolean visible) { }
101906487a58be22b100daf3f950b9a1d25c3ea42aa2satok    public void setIMEButtonVisible(boolean visible) { }
1020e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
1021808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class Launcher implements View.OnClickListener {
1022808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private PendingIntent mIntent;
1023808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mPkg;
1024808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mTag;
1025808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private int mId;
1026808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1027808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Launcher(PendingIntent intent, String pkg, String tag, int id) {
1028808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIntent = intent;
1029808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPkg = pkg;
1030808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTag = tag;
1031808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mId = id;
1032808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1033808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1034808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
1035808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1036808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // The intent we are sending is for the application, which
1037808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // won't have permission to immediately start an activity after
1038808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // the user switches to home.  We know it is safe to do at this
1039808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // point, so make sure new activity switches are now allowed.
1040808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ActivityManagerNative.getDefault().resumeAppSwitches();
1041808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException e) {
1042808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1043808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1044808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mIntent != null) {
1045808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int[] pos = new int[2];
1046808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                v.getLocationOnScreen(pos);
1047808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Intent overlay = new Intent();
1048808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                overlay.setSourceBounds(
1049808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
1050808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                try {
1051f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
1052808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } catch (PendingIntent.CanceledException e) {
1053808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // the stack trace isn't very helpful here.  Just log the exception message.
1054808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    Slog.w(TAG, "Sending contentIntent failed: " + e);
1055808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1056808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1057808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1058808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1059808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onNotificationClick(mPkg, mTag, mId);
1060808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1061808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // system process is dead if we're here.
1062808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1063808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1064808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // close the shade if it was open
1065808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            animateCollapse();
1066808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1067808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // If this click was on the intruder alert, hide that instead
1068808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
1069808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1070808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1071808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1072808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void tick(StatusBarNotification n) {
1073808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Show the ticker if one is requested. Also don't do this
1074808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // until status bar window is attached to the window manager,
1075808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // because...  well, what's the point otherwise?  And trying to
1076808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // run a ticker without being attached will crash!
1077808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) {
1078808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1079808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1080808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.addEntry(n);
1081808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1082808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1083808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1084808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1085808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1086808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
1087808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * about the failure.
1088808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
1089808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * WARNING: this will call back into us.  Don't hold any locks.
1090808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1091808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
1092808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        removeNotification(key);
1093808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
1094808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
1095808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
1096808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // The end is nigh.
1097808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1098808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1099808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class MyTicker extends Ticker {
1101dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        MyTicker(Context context, View sb) {
1102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            super(context, sb);
1103808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1104808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1106dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerStarting() {
1107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = true;
1108808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.GONE);
1109808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.VISIBLE);
1110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
1111808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
1112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(false, com.android.internal.R.anim.push_up_out);
1114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1118dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerDone() {
1119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
1122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1123808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(true, com.android.internal.R.anim.push_down_in);
1126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1129dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerHalting() {
1130808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1131808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1132808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
1133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
1134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
1137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1142808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationEnd(Animation animation) {
1143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = false;
1144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1145808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationRepeat(Animation animation) {
1146808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationStart(Animation animation) {
1148808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Animation loadAnim(int id, Animation.AnimationListener listener) {
1152f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        Animation anim = AnimationUtils.loadAnimation(mContext, id);
1153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (listener != null) {
1154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            anim.setAnimationListener(listener);
1155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return anim;
1157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public String viewInfo(View v) {
1160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " " + v.getWidth() + "x" + v.getHeight() + ")";
1162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1164f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        synchronized (mQueueLock) {
1166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("Current Status Bar state:");
1167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpanded=" + mExpanded
1168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mExpandedVisible=" + mExpandedVisible);
1169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTicking=" + mTicking);
1170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTracking=" + mTracking);
1171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mAnimating=" + mAnimating
1172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimAccel=" + mAnimAccel);
1174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCurAnimationTime=" + mCurAnimationTime
1175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimLastTime=" + mAnimLastTime);
1176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mDisplayHeight=" + mDisplayHeight
1177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimatingReveal=" + mAnimatingReveal
1178808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mViewDelta=" + mViewDelta);
1179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mDisplayHeight=" + mDisplayHeight);
1180808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedParams: " + mExpandedParams);
1181808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedView: " + viewInfo(mExpandedView));
1182808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedDialog: " + mExpandedDialog);
1183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTrackingParams: " + mTrackingParams);
1184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTrackingView: " + viewInfo(mTrackingView));
1185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mOngoingTitle: " + viewInfo(mOngoingTitle));
1186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mOngoingItems: " + viewInfo(mOngoingItems));
1187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mLatestTitle: " + viewInfo(mLatestTitle));
1188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mLatestItems: " + viewInfo(mLatestItems));
1189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
1190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCloseView: " + viewInfo(mCloseView));
1191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTickerView: " + viewInfo(mTickerView));
1192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mScrollView: " + viewInfo(mScrollView)
1193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
1194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));
1195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1196808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /*
1197808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        synchronized (mNotificationData) {
1198808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int N = mNotificationData.ongoingCount();
1199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  ongoingCount.size=" + N);
1200808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (int i=0; i<N; i++) {
1201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                StatusBarNotification n = mNotificationData.getOngoing(i);
1202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
1203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("           data=" + n.data);
1204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1205808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            N = mNotificationData.latestCount();
1206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  ongoingCount.size=" + N);
1207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (int i=0; i<N; i++) {
1208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                StatusBarNotification n = mNotificationData.getLatest(i);
1209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
1210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("           data=" + n.data);
1211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1212808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        */
1214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1215808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) {
1216808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("see the logcat for a dump of the views we have created.");
1217808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // must happen on ui thread
1218808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.post(new Runnable() {
1219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    public void run() {
1220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mStatusBarView.getLocationOnScreen(mAbsPos);
1221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mStatusBarView.getWidth() + "x"
1223808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mStatusBarView.getHeight());
1224808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mStatusBarView.debug();
1225808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1226808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mExpandedView.getLocationOnScreen(mAbsPos);
1227808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1228808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mExpandedView.getWidth() + "x"
1229808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mExpandedView.getHeight());
1230808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mExpandedView.debug();
1231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTrackingView.getLocationOnScreen(mAbsPos);
1233808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mTrackingView.getWidth() + "x"
1235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mTrackingView.getHeight());
1236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTrackingView.debug();
1237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    }
1238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                });
1239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void onBarViewAttached() {
1243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp;
1244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pixelFormat;
1245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Drawable bg;
1246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /// ---------- Tracking View --------------
1248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        pixelFormat = PixelFormat.RGBX_8888;
1249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        bg = mTrackingView.getBackground();
1250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (bg != null) {
1251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pixelFormat = bg.getOpacity();
1252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp = new WindowManager.LayoutParams(
1255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
125729fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato                WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
1258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1260808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
1261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pixelFormat);
1262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato//        lp.token = mStatusBarView.getWindowToken();
1263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
1264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("TrackingView");
1265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.y = mTrackingPosition;
1266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingParams = lp;
1267808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().addView(mTrackingView, lp);
1269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void onTrackingViewAttached() {
1272808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp;
1273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pixelFormat;
1274808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Drawable bg;
1275808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1276808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /// ---------- Expanded View --------------
1277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        pixelFormat = PixelFormat.TRANSLUCENT;
1278808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1279808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int disph = mDisplay.getHeight();
1280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp = mExpandedDialog.getWindow().getAttributes();
1281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
1282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.height = getExpandedHeight();
1283808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.x = 0;
1284808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingPosition = lp.y = -disph; // sufficiently large negative
128529fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato        lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
1286808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1287808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1288808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1289808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_DITHER
1290808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1291808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.format = pixelFormat;
1292808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
1293808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("StatusBarExpanded");
1294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(lp);
1295808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setFormat(pixelFormat);
1296808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams = lp;
1297808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
1299808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.setContentView(mExpandedView,
1300808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                           ViewGroup.LayoutParams.MATCH_PARENT));
1302808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setBackgroundDrawable(null);
1303808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.show();
1304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        FrameLayout hack = (FrameLayout)mExpandedView.getParent();
1305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1306808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void setDateViewVisibility(boolean visible, int anim) {
1308808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
1309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.startAnimation(loadAnim(anim, null));
1310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void setNotificationIconVisibility(boolean visible, int anim) {
1313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mNotificationIcons.getVisibility();
1314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int v = visible ? View.VISIBLE : View.INVISIBLE;
1315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != v) {
1316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.setVisibility(v);
1317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.startAnimation(loadAnim(anim, null));
1318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1320808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1321808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateExpandedViewPos(int expandedPosition) {
1322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1323808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
1324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingParams.y=" + mTrackingParams.y
1325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingPosition=" + mTrackingPosition);
1326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int h = mStatusBarView.getHeight();
1329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int disph = mDisplay.getHeight();
1330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // If the expanded view is not visible, make sure they're still off screen.
1332808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Maybe the view was resized.
1333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
1334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTrackingView != null) {
1335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTrackingPosition = -disph;
1336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTrackingParams != null) {
1337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTrackingParams.y = mTrackingPosition;
1338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
1339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1340808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1341808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedParams != null) {
1342808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = -disph;
1343808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1344808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1345808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1346808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1347808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1348808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // tracking view...
1349808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pos;
1350808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (expandedPosition == EXPANDED_FULL_OPEN) {
1351808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos = h;
1352808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1353808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else if (expandedPosition == EXPANDED_LEAVE_ALONE) {
1354808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos = mTrackingPosition;
1355808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1356808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else {
1357808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (expandedPosition <= disph) {
1358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pos = expandedPosition;
1359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pos = disph;
1361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos -= disph-h;
1363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingPosition = mTrackingParams.y = pos;
1365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingParams.height = disph-h;
1366808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
1367808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1368808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedParams != null) {
1369808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mCloseView.getLocationInWindow(mPositionTmp);
1370808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int closePos = mPositionTmp[1];
1371808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1372808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedContents.getLocationInWindow(mPositionTmp);
1373808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
1374808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1375808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedParams.y = pos + mTrackingView.getHeight()
1376808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    - (mTrackingParams.height-closePos) - contentsBottom;
1377808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int max = h;
1378808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedParams.y > max) {
1379808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = max;
1380808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1381808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int min = mTrackingPosition;
1382808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedParams.y < min) {
1383808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = min;
1384808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1385808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1386808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
1387808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!visible) {
1388808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // if the contents aren't visible, move the expanded view way off screen
1389808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // because the window itself extends below the content view.
1390808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = -disph;
1391808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1392808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1393808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1394808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // As long as this isn't just a repositioning that's not supposed to affect
1395808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // the user's perception of what's showing, call to say that the visibility
1396808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // has changed. (Otherwise, someone else will call to do that).
1397808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (expandedPosition != EXPANDED_LEAVE_ALONE) {
1398808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");
1399808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                visibilityChanged(visible);
1400808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1401808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1402808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1403808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1404808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition
1405808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingParams.y=" + mTrackingParams.y
1406808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingPosition=" + mTrackingPosition
1407808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedParams.y=" + mExpandedParams.y
1408808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedParams.height=" + mExpandedParams.height);
1409808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int getExpandedHeight() {
1413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();
1414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateExpandedHeight() {
1417808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedView != null) {
1418808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedParams.height = getExpandedHeight();
1419808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1420808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1421808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1422808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1423808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1424808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
1425808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * This was added last-minute and is inconsistent with the way the rest of the notifications
1426808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * are handled, because the notification isn't really cancelled.  The lights are just
1427808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * turned off.  If any other notifications happen, the lights will turn back on.  Steve says
1428808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * this is what he wants. (see bug 1131461)
1429808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1430808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void visibilityChanged(boolean visible) {
1431808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mPanelSlightlyVisible != visible) {
1432808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPanelSlightlyVisible = visible;
1433808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1434808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onPanelRevealed();
1435808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1436808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Won't fail unless the world has ended.
1437808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1438808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1439808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1440808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1441808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performDisableActions(int net) {
1442808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mDisabled;
1443808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int diff = net ^ old;
1444808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = net;
1445808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1446808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // act accordingly
1447808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1448808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
1449808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_EXPAND: yes");
1450808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
1451808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1453808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1455808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
1456808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
1457808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mNotificationIcons.setVisibility(View.INVISIBLE);
1458808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
1459808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
1460808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
1461808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1462808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1463808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
1464808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
1465808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1466808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1467808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1468808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1469808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1470808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
1471808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1472808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1473808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1474808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1475808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
1476808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
1477808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1478808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onClearAllNotifications();
1479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // system process is dead if we're here.
1481808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            animateCollapse();
1483808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1484808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1485808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1486808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1487808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onReceive(Context context, Intent intent) {
1488808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            String action = intent.getAction();
1489808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
1490808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
149188e517ec7178db457ad987e91c5430c6be6c0c85Joe Onorato                animateCollapse();
1492808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
1494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateResources();
1495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void setIntruderAlertVisibility(boolean vis) {
1500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
1501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Reload some of our resources when the configuration changes.
1505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
1506808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * We don't reload everything when the configuration changes -- we probably
1507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
1508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * meantime, just update the things that we know change.
1509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateResources() {
1511f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
1512f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
1513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1514f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mClearButton.setText(context.getText(R.string.status_bar_clear_all_button));
1515f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mOngoingTitle.setText(context.getText(R.string.status_bar_ongoing_events_title));
1516f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mLatestTitle.setText(context.getText(R.string.status_bar_latest_events_title));
1517f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNoNotificationsTitle.setText(context.getText(R.string.status_bar_no_notifications_title));
1518808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1519808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
1520808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) Slog.v(TAG, "updateResources");
1522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
1525808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // tracing
1526808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
1527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void postStartTracing() {
1529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.postDelayed(mStartTracing, 3000);
1530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1531808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void vibrate() {
1533f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
1534f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.VIBRATOR_SERVICE);
1535808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        vib.vibrate(250);
1536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1537808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStartTracing = new Runnable() {
1539808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
1540808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
1541808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            SystemClock.sleep(250);
1542808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "startTracing");
1543808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
1544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.postDelayed(mStopTracing, 10000);
1545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStopTracing = new Runnable() {
1549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
1550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.stopMethodTracing();
1551808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "stopTracing");
1552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
1553808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
1556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1557