PhoneStatusBar.java revision 6a858c347f4d4e5db4c8f00d5e285967631b71ca
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
190761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandlerimport android.animation.ObjectAnimator;
20fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackbornimport android.app.ActivityManager;
21808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.ActivityManagerNative;
22808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Dialog;
2392d331883ada42e49001853e266cda2d9c8631b8Daniel Sandlerimport android.app.KeyguardManager;
24808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Notification;
25808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.PendingIntent;
26808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.StatusBarManager;
27808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.BroadcastReceiver;
28808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
29808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
30808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.IntentFilter;
313b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurkaimport android.content.res.Configuration;
327f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport android.content.res.Resources;
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.PixelFormat;
34808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.Rect;
357f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport android.inputmethodservice.InputMethodService;
36808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
37808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.Message;
387f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport android.os.RemoteException;
391d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandlerimport android.os.ServiceManager;
40808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.SystemClock;
41d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandlerimport android.provider.Settings;
42935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onoratoimport android.text.TextUtils;
4336412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandlerimport android.util.DisplayMetrics;
44808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.util.Log;
457f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport android.util.Slog;
46808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Display;
47808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
481d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandlerimport android.view.IWindowManager;
49808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.KeyEvent;
50808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.MotionEvent;
51808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.VelocityTracker;
52808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
53808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.ViewGroup;
54f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Millerimport android.view.ViewGroup.LayoutParams;
55808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Window;
56808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManager;
57808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManagerImpl;
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.Animation;
59808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.AnimationUtils;
60808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ImageView;
61808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
62808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.RemoteViews;
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ScrollView;
64808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.TextView;
65808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
66808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.R;
69ab48b681401628a191a4a90d4906fa88edde95baMichael Jurkaimport com.android.systemui.recent.RecentTasksLoader;
70c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandlerimport com.android.systemui.statusbar.BaseStatusBar;
717f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport com.android.systemui.statusbar.NotificationData;
722e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertsonimport com.android.systemui.statusbar.SignalClusterView;
737f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport com.android.systemui.statusbar.StatusBarIconView;
742b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.BatteryController;
757f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurkaimport com.android.systemui.statusbar.policy.DateView;
766a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandlerimport com.android.systemui.statusbar.policy.IntruderAlertView;
772b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.LocationController;
782b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.NetworkController;
798ba33c965f940070060585e45e1c833519bb45c9Daniel Sandlerimport com.android.systemui.statusbar.policy.NotificationRowLayout;
80808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
816a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandlerimport java.io.FileDescriptor;
826a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandlerimport java.io.PrintWriter;
836a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandlerimport java.util.ArrayList;
846a858c347f4d4e5db4c8f00d5e285967631b71caDaniel Sandler
85c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandlerpublic class PhoneStatusBar extends BaseStatusBar {
86fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    static final String TAG = "PhoneStatusBar";
873b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public static final boolean DEBUG = false;
88c1ebee40b60472553e9678b063b32f4e80b180e8Daniel Sandler    public static final boolean SPEW = DEBUG;
897579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler    public static final boolean DUMPTRUCK = true; // extra dumpsys info
90808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
9196e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler    // additional instrumentation for testing purposes; intended to be left on during development
927c35174a6f0fd6a01b6d63418bf4355f16b8ae64Daniel Sandler    public static final boolean CHATTY = DEBUG;
9396e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
94808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public static final String ACTION_STATUSBAR_START
95808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            = "com.android.internal.policy.statusbar.START";
96808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
97fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    private static final boolean ENABLE_INTRUDERS = true;
98fc6fda3950338ce737f096548a079342317cfd7fDaniel Sandler
99808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_LEAVE_ALONE = -10000;
100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_FULL_OPEN = -10001;
101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1028ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    private static final int MSG_ANIMATE = 100;
1038ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    private static final int MSG_ANIMATE_REVEAL = 101;
1048ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
1058ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_SHOW_INTRUDER = 1002;
107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_HIDE_INTRUDER = 1003;
1087f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    // 1020-1030 reserved for BaseStatusBar
109808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // will likely move to a resource or other tunable param at some point
111fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1138cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler    private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
1148cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler
115dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    // fling gesture tuning parameters, scaled to display density
116dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mSelfExpandVelocityPx; // classic value: 2000px/s
117dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
118dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mFlingExpandMinVelocityPx; // classic value: 200px/s
119dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
120dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
121dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
122dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
123dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
124dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mExpandAccelPx; // classic value: 2000px/s/s
125dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler    private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
126dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
127fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarPolicy mIconPolicy;
128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1292b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    // These are no longer handled by the policy, because we need custom strategies for them
1302b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    BatteryController mBatteryController;
1312b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    LocationController mLocationController;
1322b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    NetworkController mNetworkController;
1335e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller
1347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mNaturalBarHeight = -1;
1357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mIconSize = -1;
1367c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mIconHPadding = -1;
137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Display mDisplay;
138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1391d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    IWindowManager mWindowManager;
1401d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
141fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarView mStatusBarView;
142808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mPixelFormat;
143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Object mQueueLock = new Object();
144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
145808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // icons
146808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mIcons;
147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    IconMerger mNotificationIcons;
14805e2414ef5a3a8fecbabc1f220c9925539d51f7aDaniel Sandler    View mMoreIcon;
149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mStatusIcons;
150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // expanded notifications
152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Dialog mExpandedDialog;
153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WindowManager.LayoutParams mExpandedParams;
154c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    View mExpandedWindowView;
155079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler    View mNotificationPanel; // the sliding/resizing panel within the notification window
156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ScrollView mScrollView;
157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View mExpandedContents;
158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // top bar
1591347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler    View mClearButton;
160d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler    View mSettingsButton;
161d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler
162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // drag bar
163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    CloseDragHandle mCloseView;
1645e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller
1657c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    // all notifications
1667c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    NotificationData mNotificationData = new NotificationData();
1678ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    NotificationRowLayout mPile;
1687c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // position
170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mPositionTmp = new int[2];
171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpanded;
172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpandedVisible;
173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the date view
175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    DateView mDateView;
176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for immersive activities
178fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    private IntruderAlertView mIntruderAlertView;
179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1808956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    // on-screen navigation buttons
1810129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler    private NavigationBarView mNavigationBarView = null;
1828956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the tracker view
184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mTrackingPosition; // the position of the top of the tracking view.
185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mPanelSlightlyVisible;
186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ticker
188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Ticker mTicker;
189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View mTickerView;
190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mTicking;
191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Tracking finger for opening/closing.
193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mTracking;
195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    VelocityTracker mVelocityTracker;
196808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
197808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int ANIM_FRAME_DURATION = (1000/60);
198808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimating;
200808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mCurAnimationTime;
201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimY;
202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimVel;
203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimAccel;
204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mAnimLastTime;
205808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimatingReveal = false;
206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mViewDelta;
207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mAbsPos = new int[2];
2082f2022afa1eb85018368398bd150e9575fc099c9Chet Haase    Runnable mPostCollapseCleanup = null;
2092f2022afa1eb85018368398bd150e9575fc099c9Chet Haase
210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for disabling the status bar
212808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mDisabled = 0;
213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
21460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    // tracking calls to View.setSystemUiVisibility()
21560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
21660ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
21736412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler    DisplayMetrics mDisplayMetrics = new DisplayMetrics();
2181dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
219328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    private int mNavigationIconHints = 0;
220328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
2212561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    // TODO(dsandler): codify this stuff in NotificationManager's header somewhere
2222561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    private int mDisplayMinScore             = Notification.PRIORITY_LOW * 10;
2232561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    private int mIntruderMinScore            = Notification.PRIORITY_HIGH * 10;
2242561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    private int mIntruderInImmersiveMinScore = Notification.PRIORITY_HIGH * 10 + 5;
2252561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
226808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class ExpandedDialog extends Dialog {
227808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ExpandedDialog(Context context) {
22836412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            super(context, com.android.internal.R.style.Theme_Translucent_NoTitleBar);
229808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
230808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public boolean dispatchKeyEvent(KeyEvent event) {
233808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (event.getKeyCode()) {
235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            case KeyEvent.KEYCODE_BACK:
236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!down) {
237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    animateCollapse();
238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                return true;
240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return super.dispatchKeyEvent(event);
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
246f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
247f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
248f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                .getDefaultDisplay();
249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2501d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        mWindowManager = IWindowManager.Stub.asInterface(
2511d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler                ServiceManager.getService(Context.WINDOW_SERVICE));
2521d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
253c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        super.start(); // calls createAndAddWindows()
254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2558956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        addNavigationBar();
2568956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
257fc6fda3950338ce737f096548a079342317cfd7fDaniel Sandler        if (ENABLE_INTRUDERS) addIntruderView();
258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Lastly, call to the icon policy to install/update all the icons.
260fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mIconPolicy = new PhoneStatusBarPolicy(mContext);
261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Constructing the view
265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
267f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Resources res = context.getResources();
270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2716e8db88b4b31a6e0211561f25ee1a422e4797ba1Daniel Sandler        updateDisplaySize(); // populates mDisplayMetrics
2727c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadDimens();
273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2741dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
2751dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
276c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        final View expanded = mExpandedWindowView = View.inflate(context,
277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                R.layout.status_bar_expanded, null);
278cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        if (DEBUG) {
279cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler            expanded.setBackgroundColor(0x6000FF80);
280cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        }
281c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mNotificationPanel = expanded.findViewById(R.id.notification_panel);
282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
283fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
284808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(View.GONE);
285fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        mIntruderAlertView.setBar(this);
286808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
28760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
28860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                R.layout.status_bar, null);
28960ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        sb.mService = this;
29060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        mStatusBarView = sb;
29160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
2920129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        try {
2930c4ccff36930ff4f0292b94ad51e164c9fa060a3Daniel Sandler            boolean showNav = mWindowManager.hasNavigationBar();
2940129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler            if (showNav) {
2955e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                mNavigationBarView =
2960129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler                    (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
29760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
2986da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler                mNavigationBarView.setDisabledFlags(mDisabled);
2990129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler            }
3000c4ccff36930ff4f0292b94ad51e164c9fa060a3Daniel Sandler        } catch (RemoteException ex) {
3010c4ccff36930ff4f0292b94ad51e164c9fa060a3Daniel Sandler            // no window manager? good luck with that
3020129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        }
3038956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // figure out which pixel-format to use for the status bar.
305f733c2aaa652f3ead60c8b2bc982dc9bdbc7df8eDaniel Sandler        mPixelFormat = PixelFormat.OPAQUE;
306808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
30805e2414ef5a3a8fecbabc1f220c9925539d51f7aDaniel Sandler        mMoreIcon = sb.findViewById(R.id.moreIcon);
30905e2414ef5a3a8fecbabc1f220c9925539d51f7aDaniel Sandler        mNotificationIcons.setOverflowIndicator(mMoreIcon);
310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTickerView = sb.findViewById(R.id.ticker);
312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog = new ExpandedDialog(context);
3148ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        mPile = (NotificationRowLayout)expanded.findViewById(R.id.latestItems);
3150761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
316d714148bd2752c63a46f51b12cea288fb1f10528Daniel Sandler
3171347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        mClearButton = expanded.findViewById(R.id.clear_all_button);
318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mClearButton.setOnClickListener(mClearButtonListener);
3190761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        mClearButton.setAlpha(0f);
3208ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        mClearButton.setEnabled(false);
321d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler        mDateView = (DateView)expanded.findViewById(R.id.date);
322d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler        mSettingsButton = expanded.findViewById(R.id.settings_button);
323d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler        mSettingsButton.setOnClickListener(mSettingsButtonListener);
324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
325079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTicker = new MyTicker(context, sb);
328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        tickerView.mTicker = mTicker;
331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
332c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mCloseView = (CloseDragHandle)mExpandedWindowView.findViewById(R.id.close);
333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCloseView.mService = this;
334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // set the inital view visibility
338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3402b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        // Other icons
3412b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mLocationController = new LocationController(mContext); // will post a notification
3422b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mBatteryController = new BatteryController(mContext);
3432b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
3442b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mNetworkController = new NetworkController(mContext);
3455e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller        final SignalClusterView signalCluster =
3462e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson                (SignalClusterView)sb.findViewById(R.id.signal_cluster);
3472e347429dfcd03b0827c7506ba6305ab0d1f4951Christian Robertson        mNetworkController.addSignalCluster(signalCluster);
34828f89d40ee7bab93cf7b783f92dbb18bdc43e473Daniel Sandler        signalCluster.setNetworkController(mNetworkController);
3495e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller//        final ImageView wimaxRSSI =
350633eabe56d3126fa92eb56636019e5792e20a5daDaniel Sandler//                (ImageView)sb.findViewById(R.id.wimax_signal);
351633eabe56d3126fa92eb56636019e5792e20a5daDaniel Sandler//        if (wimaxRSSI != null) {
352633eabe56d3126fa92eb56636019e5792e20a5daDaniel Sandler//            mNetworkController.addWimaxIconView(wimaxRSSI);
353633eabe56d3126fa92eb56636019e5792e20a5daDaniel Sandler//        }
3543b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        // Recents Panel
355ab48b681401628a191a4a90d4906fa88edde95baMichael Jurka        mRecentTasksLoader = new RecentTasksLoader(context);
35617dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller        updateRecentsPanel();
3573b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // receive broadcasts
359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        IntentFilter filter = new IntentFilter();
360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        context.registerReceiver(mBroadcastReceiver, filter);
364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
366808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
367808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3687f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    @Override
369f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller    protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
3703cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka        boolean opaque = false;
3713b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
372f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller                layoutParams.width,
373f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller                layoutParams.height,
3743b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
3753b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
3763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
377fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
3783cd0a593937c0724d77db1e2e3995255cfae61acMichael Jurka                (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
379fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn        if (ActivityManager.isHighEndGfx(mDisplay)) {
380fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
381f16fc51d96be53a844877674b98cb70e60b45278Michael Jurka        } else {
382f16fc51d96be53a844877674b98cb70e60b45278Michael Jurka            lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
383f16fc51d96be53a844877674b98cb70e60b45278Michael Jurka            lp.dimAmount = 0.7f;
384fc8fa638617efb5695a1f89ea75375faebbe2a40Dianne Hackborn        }
3853b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
3863b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.setTitle("RecentsPanel");
38799a9655b9333c3bff6e462b12baa56a5fcd4cb20Michael Jurka        lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
3883b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
3893b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
3903b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        return lp;
3913b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
3923b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
3937f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    @Override
39417dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller    protected void updateRecentsPanel() {
3957f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka        super.updateRecentsPanel();
3964eaa983f253d0215d4de777edd8616318610ea22Michael Jurka        // Make .03 alpha the minimum so you always see the item a bit-- slightly below
3974eaa983f253d0215d4de777edd8616318610ea22Michael Jurka        // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
3984eaa983f253d0215d4de777edd8616318610ea22Michael Jurka        // a bit jarring
3994eaa983f253d0215d4de777edd8616318610ea22Michael Jurka        mRecentsPanel.setMinSwipeAlpha(0.03f);
4003b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
4013b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
402808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
403808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.TOP | Gravity.FILL_HORIZONTAL;
404808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
405808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
406dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    public int getStatusBarHeight() {
407f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = mContext.getResources();
408dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato        return res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
409dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    }
410dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato
4115c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
4125c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        public void onClick(View v) {
4135c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler            toggleRecentApps();
4145c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
4155c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    };
416fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    private StatusBarNotification mCurrentlyIntrudingNotification;
4175c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
418412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka    private void prepareNavigationBarView() {
419412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka        mNavigationBarView.reorient();
420412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka
421412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
422412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka        mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
423412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka    }
424412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka
4258956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    // For small-screen devices (read: phones) that lack hardware navigation buttons
4268956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private void addNavigationBar() {
4270129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        if (mNavigationBarView == null) return;
42817dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller
429412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka        prepareNavigationBarView();
4305c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4318956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManagerImpl.getDefault().addView(
4328956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                mNavigationBarView, getNavigationBarLayoutParams());
4338956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4348956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4358956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private void repositionNavigationBar() {
4360129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        if (mNavigationBarView == null) return;
43717dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller
438412cba8aa10231cdf515d9400a754e8a16a8eb3dMichael Jurka        prepareNavigationBarView();
4395c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4408956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManagerImpl.getDefault().updateViewLayout(
4418956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                mNavigationBarView, getNavigationBarLayoutParams());
4428956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4438956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4448956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private WindowManager.LayoutParams getNavigationBarLayoutParams() {
4458956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
4461f903c3b577d20f7db7e3d5875cafe577d0d845fDianne Hackborn                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
4478956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
4488956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    0
4498956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
4508956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
451df89e65bf0fcc651d20b208c8d8d0b848fb43418Dianne Hackborn                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
45298db5fabdad86dca379740d8050697950b9f026cJeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
45398db5fabdad86dca379740d8050697950b9f026cJeff Brown                    | WindowManager.LayoutParams.FLAG_SLIPPERY,
454a388449e632fadb75a0eae67f77ff618b3a39a01Daniel Sandler                PixelFormat.OPAQUE);
455c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler        // this will allow the navbar to run in an overlay on devices that support this
456c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler        if (ActivityManager.isHighEndGfx(mDisplay)) {
457c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
458c638c1eb1bbed67d7d8f0d43f39137d766366f54Daniel Sandler        }
4598956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4608956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        lp.setTitle("NavigationBar");
4618956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        lp.windowAnimations = 0;
4628956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4638956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        return lp;
4648956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4658956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
466dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    private void addIntruderView() {
467dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato        final int height = getStatusBarHeight();
468808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
469808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
470808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
471808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.WRAP_CONTENT,
472fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
473808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
474808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
475808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
476808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
47746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
47846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                PixelFormat.TRANSLUCENT);
480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
481fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        //lp.y += height * 1.5; // FIXME
482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("IntruderAlert");
48359aed3885e7bf34b4d7c021db4243484fa267526Dianne Hackborn        lp.packageName = mContext.getPackageName();
48459aed3885e7bf34b4d7c021db4243484fa267526Dianne Hackborn        lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
485808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
486808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
487808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
488808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
489808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
490808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
491808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " icon=" + icon);
4926179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov        StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " old=" + old + " icon=" + icon);
501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
506808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.removeViewAt(viewIndex);
508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
5112561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        /* if (DEBUG) */ Slog.d(TAG, "addNotification score=" + notification.score);
512808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView iconView = addNotificationViews(key, notification);
513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (iconView == null) return;
514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        boolean immersive = false;
516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
517808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
5188355e932a033398625eef676ac93aec0cb084efeDaniel Sandler            if (DEBUG) {
5198355e932a033398625eef676ac93aec0cb084efeDaniel Sandler                Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
5208355e932a033398625eef676ac93aec0cb084efeDaniel Sandler            }
521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
523fc6fda3950338ce737f096548a079342317cfd7fDaniel Sandler        if (ENABLE_INTRUDERS && (
524fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                   // TODO(dsandler): Only if the screen is on
525fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                notification.notification.intruderView != null)) {
526fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler//                   notification.notification.fullScreenIntent != null
527fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler//                || (notification.score >= mIntruderInImmersiveMinScore)
528fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler//                || (!immersive && (notification.score > mIntruderMinScore)))) {
5292561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            Slog.d(TAG, "Presenting high-priority notification");
5302561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            // special new transient ticker mode
5312561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            // 1. Populate mIntruderAlertView
532fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
533fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (notification.notification.intruderView == null) {
534fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
535fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                return;
536fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            }
5372561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
538fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            // bind the click event to the content area
539fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            PendingIntent contentIntent = notification.notification.contentIntent;
540fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            final View.OnClickListener listener = (contentIntent != null)
541fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    ? new NotificationClicker(contentIntent,
542fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                            notification.pkg, notification.tag, notification.id)
543fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    : null;
5442561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
545fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
5462561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
547fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            mCurrentlyIntrudingNotification = notification;
548fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
5492561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            // 2. Animate mIntruderAlertView in
5502561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
5512561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
5522561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            // 3. Set alarm to age the notification off (TODO)
5532561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            mHandler.removeMessages(MSG_HIDE_INTRUDER);
554fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (INTRUDER_ALERT_DECAY_MS > 0) {
555fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
556fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            }
557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (notification.notification.fullScreenIntent != null) {
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // not immersive & a full-screen alert should be shown
5598355e932a033398625eef676ac93aec0cb084efeDaniel Sandler            Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                notification.notification.fullScreenIntent.send();
562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (PendingIntent.CanceledException e) {
563808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
564808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // usual case: status bar visible & not immersive
566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
567fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            // show the ticker if there isn't an intruder too
568fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (mCurrentlyIntrudingNotification == null) {
569fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                tick(notification);
570fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            }
571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
575808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
577808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
5797c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
5817c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
5827c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (oldEntry == null) {
5837c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
5847c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return;
585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
5867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
587808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final StatusBarNotification oldNotification = oldEntry.notification;
588808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
58984920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler        // XXX: modify when we do something more intelligent with the two content views
59084920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler        final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null)
59184920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler                ? oldNotification.notification.bigContentView
59284920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler                : oldNotification.notification.contentView;
59384920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler        final RemoteViews contentView = (notification.notification.bigContentView != null)
59484920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler                ? notification.notification.bigContentView
59584920cc56e4cd4e843845d8d542ba47f3ffb4f36Daniel Sandler                : notification.notification.contentView;
5967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
59720cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        if (DEBUG) {
598808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
599808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
600808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " expanded=" + oldEntry.expanded
60120cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                    + " contentView=" + oldContentView
60220cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                    + " rowParent=" + oldEntry.row.getParent());
603808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "new notification: when=" + notification.notification.when
604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
605808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " contentView=" + contentView);
606808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
607808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
60820cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler
609808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
610808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // didn't change.
61120cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        boolean contentsUnchanged = oldEntry.expanded != null
612808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView != null && oldContentView != null
613808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView.getPackage() != null
614808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage() != null
615808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage().equals(contentView.getPackage())
61620cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId();
61720cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
61820cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
6192561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                && notification.score == oldNotification.score;
6202561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                // score now encompasses/supersedes isOngoing()
621c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung
622c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung        boolean updateTicker = notification.notification.tickerText != null
623c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung                && !TextUtils.equals(notification.notification.tickerText,
624c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung                        oldEntry.notification.notification.tickerText);
6257c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
6267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
62720cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
628808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            oldEntry.notification = notification;
629808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
630808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Reapply the RemoteViews
631f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
632808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // update the contentIntent
633808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final PendingIntent contentIntent = notification.notification.contentIntent;
634808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (contentIntent != null) {
635847fd751a9c9eb3cb02da1dca95d3d4b215c0b76Jeff Sharkey                    final View.OnClickListener listener = new NotificationClicker(contentIntent,
636847fd751a9c9eb3cb02da1dca95d3d4b215c0b76Jeff Sharkey                            notification.pkg, notification.tag, notification.id);
637847fd751a9c9eb3cb02da1dca95d3d4b215c0b76Jeff Sharkey                    oldEntry.content.setOnClickListener(listener);
638184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
639184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
640808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
641808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Update the icon.
642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.notification.icon, notification.notification.iconLevel,
6447c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        notification.notification.number,
6457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        notification.notification.tickerText);
646808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!oldEntry.icon.set(ic)) {
647808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
648808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    return;
649808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
650808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
651808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            catch (RuntimeException e) {
652808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // It failed to add cleanly.  Log, and remove the view from the panel.
653808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
654808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                removeNotificationViews(key);
655808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                addNotificationViews(key, notification);
656808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
657808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
658808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "not reusing notification");
659808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            removeNotificationViews(key);
660808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            addNotificationViews(key, notification);
661808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
662808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
663c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung        // Update the veto button accordingly (and as a result, whether this row is
664c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung        // swipe-dismissable)
665c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung        updateNotificationVetoButton(oldEntry.row, notification);
666c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung
667808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Restart the ticker if it's still running
668c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung        if (updateTicker) {
669c57ccf01fe24ce508404c99b449e9097e6d8b270Winson Chung            mTicker.halt();
670935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato            tick(notification);
671935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato        }
672808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
673808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
674808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
675808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
676fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
677fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        // See if we need to update the intruder.
678fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        if (oldNotification == mCurrentlyIntrudingNotification) {
679fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
680fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            // XXX: this is a hack for Alarms. The real implementation will need to *update*
681fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            // the intruder.
682fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
683fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                if (DEBUG) Slog.d(TAG, "no longer intrudes!");
684fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
685fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            }
686fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        }
687808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
688808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
689808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
690808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarNotification old = removeNotificationViews(key);
691fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
692808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
693808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != null) {
694808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Cancel the ticker if it's still running
695808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicker.removeEntry(old);
696808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
697808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Recalculate the position of the sliding windows and the titles.
698808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
699fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
700fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            if (old == mCurrentlyIntrudingNotification) {
701fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
702fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            }
7038cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler
7048cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler            if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) {
7058cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler                animateCollapse();
7068cc36e572876f3bb9197f0109db3042466e5f917Daniel Sandler            }
707808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
7080761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler
7090761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        setAreThereNotifications();
710808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
711808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7123b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    @Override
7133b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    protected void onConfigurationChanged(Configuration newConfig) {
71417dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller        updateRecentsPanel();
7153b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
7163b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
7173b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
718808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
7197c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
7207c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
721808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
722808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Construct the icon.
723f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
7246179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                notification.pkg + "/0x" + Integer.toHexString(notification.id),
7256179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                notification.notification);
7267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
7277c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7287c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
7297c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.icon,
7307c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.iconLevel,
7317c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.number,
7326179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                    notification.notification.tickerText);
733808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!iconView.set(ic)) {
7347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            handleNotificationError(key, notification, "Couldn't create icon: " + ic);
7357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return null;
7367c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
7377c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Construct the expanded view.
7387c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
7397c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (!inflateViews(entry, mPile)) {
7407c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
7417c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    + notification);
742808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
743808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
7447c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Add the expanded view and icon.
7467c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int pos = mNotificationData.add(entry);
7477c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
7487c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "addNotificationViews: added at " + pos);
7497c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
7507c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
7517c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
752808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return iconView;
753808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
754808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7557c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void loadNotificationShade() {
7567c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int N = mNotificationData.size();
7577c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7587c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
7597c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7607c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<N; i++) {
7617c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View row = mNotificationData.get(N-i-1).row;
7627c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            toShow.add(row);
7637c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
7647c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7657c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
7667c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
7677c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View child = mPile.getChildAt(i);
7687c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (!toShow.contains(child)) {
7697c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                toRemove.add(child);
770808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
771808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
772808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7737c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (View remove : toRemove) {
7747c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mPile.removeView(remove);
7757c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
7767c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7777c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
7787c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View v = toShow.get(i);
7797c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (v.getParent() == null) {
7802561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                mPile.addView(v, i);
7817c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
7827c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
783808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
784808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7857c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void reloadAllNotificationIcons() {
7867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (mNotificationIcons == null) return;
7877c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mNotificationIcons.removeAllViews();
7887c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
7897c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
7907c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7917c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void updateNotificationIcons() {
7927c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadNotificationShade();
7937c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final LinearLayout.LayoutParams params
7957c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
796808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7977c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int N = mNotificationData.size();
7987c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7997c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
8007c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
8017c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8027c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8037c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
8047c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8057c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<N; i++) {
8067c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            toShow.add(mNotificationData.get(N-i-1).icon);
8077c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8087c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8097c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
8107c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
8117c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View child = mNotificationIcons.getChildAt(i);
8127c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (!toShow.contains(child)) {
8137c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                toRemove.add(child);
8147c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
8157c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8167c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8177c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (View remove : toRemove) {
8187c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mNotificationIcons.removeView(remove);
8197c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8207c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8217c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
8227c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View v = toShow.get(i);
8237c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (v.getParent() == null) {
8247c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                mNotificationIcons.addView(v, i, params);
8257c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
8267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8277c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
8287c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8297c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
8307c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationData.Entry entry = mNotificationData.remove(key);
8317c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (entry == null) {
8327c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
8337c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return null;
8347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Remove the expanded view.
8367c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
8377c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
8387c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
8397c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8407c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        return entry.notification;
8417c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
8427c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8437c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void setAreThereNotifications() {
8440761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        final boolean any = mNotificationData.size() > 0;
8457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8460761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        final boolean clearable = any && mNotificationData.hasClearableItems();
8470761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler
8480761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        if (DEBUG) {
8490761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler            Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
8500761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler                    + " any=" + any + " clearable=" + clearable);
8510761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        }
8520761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler
8530761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        if (mClearButton.isShown()) {
8540761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler            if (clearable != (mClearButton.getAlpha() == 1.0f)) {
8550761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler                ObjectAnimator.ofFloat(mClearButton, "alpha",
8560761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler                        clearable ? 1.0f : 0.0f)
8570761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler                    .setDuration(250)
8580761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler                    .start();
8590761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler            }
8600761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        } else {
8610761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler            mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
8620761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler        }
8638ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        mClearButton.setEnabled(clearable);
8640761e4cd95b6968dd4b1659a766ef504d13f6d50Daniel Sandler
865808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
866808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
867f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey    public void showClock(boolean show) {
868c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        if (mStatusBarView == null) return;
869f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey        View clock = mStatusBarView.findViewById(R.id.clock);
870f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey        if (clock != null) {
871f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey            clock.setVisibility(show ? View.VISIBLE : View.GONE);
872f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey        }
873f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey    }
874808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
875808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
876808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * State is one or more of the DISABLE constants from StatusBarManager.
877808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
878808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
879808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int old = mDisabled;
880808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int diff = state ^ old;
881808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = state;
882808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
883e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler        if (DEBUG) {
884e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler            Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
885e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler                old, state, diff));
886e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler        }
887e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler
8886da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        StringBuilder flagdbg = new StringBuilder();
8896da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append("disable: < ");
8906da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
8916da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
8926da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
8936da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
8946da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
8956da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
8966da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
8976da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
8986da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
8996da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
9006da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
9016da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
902dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
903dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
904dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
905dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
9066da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
9076da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(((diff  & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
9086da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        flagdbg.append(">");
9096da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler        Slog.d(TAG, flagdbg.toString());
9106da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler
911f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
912f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey            boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
913f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey            showClock(show);
914f52c70b2ccf711f507723bc74a68ca8c3a12c57aJeff Sharkey        }
915808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
916808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
917808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
918808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
919808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
920e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler
9215e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller        if ((diff & (StatusBarManager.DISABLE_HOME
9225e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                        | StatusBarManager.DISABLE_RECENT
923dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler                        | StatusBarManager.DISABLE_BACK)) != 0) {
924dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler            // the nav bar will take care of these
925d9283b903125c875f973bf6f724f23e595bce756Daniel Sandler            if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
9266da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler
927dba935659024a9ca83cb6bd3f1a9970e277f7658Daniel Sandler            if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
9286da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler                // close recents if it's visible
9296da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler                mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
9306da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler                mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
9316da2b76ea496129da5370bfafd667ee94907a356Daniel Sandler            }
932e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler        }
933e21f288358df2c1cea57c0a359dcf647baeb970dDaniel Sandler
934808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
935808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
936808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
937808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
938808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
939808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
940808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
941808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
942808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
943808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
944808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
945808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
946808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
947808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
948808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
949808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
950808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
951808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
952808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
9537f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    @Override
954ecc395a51053c433e359a6cfd6c23a193ee546c0Michael Jurka    protected BaseStatusBar.H createHandler() {
9557f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka        return new PhoneStatusBar.H();
9567f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    }
9577f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka
958808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
959808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * All changes to the status bar and notifications funnel through here and are batched.
960808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
9617f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka    private class H extends BaseStatusBar.H {
962808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void handleMessage(Message m) {
9637f2668c8469934ce83a5647977f6e74ab782cf07Michael Jurka            super.handleMessage(m);
964808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (m.what) {
965808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE:
966808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doAnimation();
967808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
968808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE_REVEAL:
969808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doRevealAnimation();
970808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
9718ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                case MSG_OPEN_NOTIFICATION_PANEL:
9728ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    animateExpand();
9738ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    break;
9748ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                case MSG_CLOSE_NOTIFICATION_PANEL:
9758ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    animateCollapse();
9768ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    break;
977808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_SHOW_INTRUDER:
978808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(true);
979808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
980808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_HIDE_INTRUDER:
981808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(false);
982fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    mCurrentlyIntrudingNotification = null;
983808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
984808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
985808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
986808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
987808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
988808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
989808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onFocusChange(View v, boolean hasFocus) {
990808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Because 'v' is a ViewGroup, all its children will be (un)selected
991808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // too, which allows marqueeing to work.
992808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            v.setSelected(hasFocus);
993808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
994808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
995808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
996808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void makeExpandedVisible() {
997808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
998808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedVisible) {
999808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1000808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1001c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedDialog.show(); // XXX HAX
1002808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = true;
1003808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(true);
1004808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1005808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
1006808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1007808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
100836412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        if (DEBUG) {
100936412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            Slog.d(TAG, "makeExpandedVisible: expanded params = " + mExpandedParams);
101036412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        }
1011808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1012c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedWindowView.requestFocus(View.FOCUS_FORWARD);
1013c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedWindowView.setVisibility(View.VISIBLE);
1014808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1015808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1016808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
1017808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
1018808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1019808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
1020808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1021808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1022808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1023808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1024808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1025808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(0, true);
1026dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        performFling(0, mSelfExpandVelocityPx, true);
1027808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1028808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1029808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
10303b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        animateCollapse(false);
10313b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
10323b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
10333b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public void animateCollapse(boolean excludeRecents) {
10348ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        animateCollapse(excludeRecents, 1.0f);
10358ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    }
10365e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller
10378ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler    public void animateCollapse(boolean excludeRecents, float velocityMultiplier) {
1038808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1039808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
1040808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedVisible=" + mExpandedVisible
1041808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpanded=" + mExpanded
1042808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimating=" + mAnimating
1043808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimY=" + mAnimY
1044808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimVel=" + mAnimVel);
1045808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1046808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
10473b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        if (!excludeRecents) {
10483b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
10493b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
10503b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
10513b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
1052808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
1053808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1054808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1055808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1056808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int y;
1057808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
1058808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            y = (int)mAnimY;
1059808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
106036412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            y = mDisplayMetrics.heightPixels-1;
1061808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1062808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Let the fling think that we're open so it goes in the right direction
1063808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // and doesn't try to re-open the windowshade.
1064808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
1065808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(y, false);
10668ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        performFling(y, -mSelfCollapseVelocityPx*velocityMultiplier, true);
1067808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1068808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1069808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performExpand() {
1070808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);
1071808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1072808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
1073808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1074808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1075808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1076808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1077808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1078808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
1079808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        makeExpandedVisible();
1080808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_FULL_OPEN);
1081808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1082808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) postStartTracing();
1083808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1084808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1085808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performCollapse() {
1086808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
1087808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " mExpandedVisible=" + mExpandedVisible);
1088808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1089808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
1090808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1091808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1092808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = false;
1093808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(false);
1094808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1095808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
1096808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1097c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedDialog.hide(); // XXX HAX
1098c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedWindowView.setVisibility(View.GONE);
1099808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1103808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1104808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpanded) {
1105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = false;
11082f2022afa1eb85018368398bd150e9575fc099c9Chet Haase        if (mPostCollapseCleanup != null) {
11092f2022afa1eb85018368398bd150e9575fc099c9Chet Haase            mPostCollapseCleanup.run();
11102f2022afa1eb85018368398bd150e9575fc099c9Chet Haase            mPostCollapseCleanup = null;
11112f2022afa1eb85018368398bd150e9575fc099c9Chet Haase        }
1112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doAnimation() {
1115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
1116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation");
1117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
1118808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
1119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
112036412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            if (mAnimY >= mDisplayMetrics.heightPixels-1) {
1121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
1122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1123808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(EXPANDED_FULL_OPEN);
1124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performExpand();
1125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (mAnimY < mStatusBarView.getHeight()) {
1127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
1128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1129808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(0);
1130808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performCollapse();
1131808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1132808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
1135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
1136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void stopTracking() {
1141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = false;
1142079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        mPile.setLayerType(View.LAYER_TYPE_NONE, null);
1143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker.recycle();
1144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = null;
1145808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1146808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void incrementAnim() {
1148808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
1149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s
1150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float y = mAnimY;
1151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float v = mAnimVel;                                   // px/s
1152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float a = mAnimAccel;                                 // px/s/s
1153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
1154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = v + (a*t);                                       // px/s
1155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;                                        // ms
1156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
1157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
1158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doRevealAnimation() {
1161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int h = mCloseView.getHeight() + mStatusBarView.getHeight();
1162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimatingReveal && mAnimating && mAnimY < h) {
1163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
1164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimY >= h) {
1165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimY = h;
1166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
1170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
1171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mCurAnimationTime);
1172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void prepareTracking(int y, boolean opening) {
117796e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        if (CHATTY) {
117896e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
117996e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        }
118096e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
1181cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        // there are some race conditions that cause this to be inaccurate; let's recalculate it any
1182cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        // time we're about to drag the panel
1183cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        updateExpandedSize();
1184cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler
1185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = true;
1186079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        mPile.setLayerType(View.LAYER_TYPE_HARDWARE, null);
1187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = VelocityTracker.obtain();
1188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (opening) {
1189dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler            mAnimAccel = mExpandAccelPx;
1190dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler            mAnimVel = mFlingExpandMinVelocityPx;
1191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimY = mStatusBarView.getHeight();
1192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos((int)mAnimY);
1193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
1194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimatingReveal = true;
1195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE);
1196808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE_REVEAL);
1197808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            long now = SystemClock.uptimeMillis();
1198808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimLastTime = now;
1199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mCurAnimationTime = now + ANIM_FRAME_DURATION;
1200808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
1201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
1202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mCurAnimationTime);
1203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            makeExpandedVisible();
1204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
1205808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // it's open, close it?
1206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimating) {
1207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.removeMessages(MSG_ANIMATE);
1209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(y + mViewDelta);
1211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1212808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performFling(int y, float vel, boolean always) {
121596e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        if (CHATTY) {
121696e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel);
121796e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        }
121896e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
1219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimatingReveal = false;
1220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y;
1222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = vel;
1223808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1224808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
1225808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1226808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1227808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!always && (
1228dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                    vel > mFlingCollapseMinVelocityPx
1229dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                    || (y > (mDisplayMetrics.heightPixels*(1f-mCollapseMinDisplayFraction)) &&
1230dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                        vel > -mFlingExpandMinVelocityPx))) {
1231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded, but they didn't move sufficiently to cause
1232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the expanded position.
1233dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                mAnimAccel = mExpandAccelPx;
1234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
1235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded and are now going to animate away.
1240dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                mAnimAccel = -mCollapseAccelPx;
1241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
1242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
1246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (always || (
1247dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                    vel > mFlingExpandMinVelocityPx
1248dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                    || (y > (mDisplayMetrics.heightPixels*(1f-mExpandMinDisplayFraction)) &&
1249dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                        vel > -mFlingCollapseMinVelocityPx))) {
1250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, and they moved enough to allow us to
1251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // expand.  Animate in the notifications.
1252dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                mAnimAccel = mExpandAccelPx;
1253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
1254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, but they didn't move sufficiently to cause
1259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the collapsed position.
1260dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                mAnimAccel = -mCollapseAccelPx;
1261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
1262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
1267808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
1268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
1270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;
1271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCurAnimationTime = now + ANIM_FRAME_DURATION;
1272808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimating = true;
1273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE);
1274808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE_REVEAL);
1275808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
1276808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        stopTracking();
1277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1278808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1279808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean interceptTouchEvent(MotionEvent event) {
1280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
1282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + mDisabled);
128396e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        } else if (CHATTY) {
1284fe172cc861448cf1115195cbad5b3300357c02f0Daniel Sandler            if (event.getAction() != MotionEvent.ACTION_MOVE) {
128596e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler                Slog.d(TAG, String.format(
1286fe172cc861448cf1115195cbad5b3300357c02f0Daniel Sandler                            "panel: %s at (%f, %f) mDisabled=0x%08x",
1287fe172cc861448cf1115195cbad5b3300357c02f0Daniel Sandler                            MotionEvent.actionToString(event.getAction()),
128896e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler                            event.getRawX(), event.getRawY(), mDisabled));
128996e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            }
1290808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1291808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1292808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1293808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return false;
1294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1295808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
129668ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown        final int action = event.getAction();
1297808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int statusBarSize = mStatusBarView.getHeight();
1298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int hitSize = statusBarSize*2;
1299fe172cc861448cf1115195cbad5b3300357c02f0Daniel Sandler        final int y = (int)event.getRawY();
130068ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown        if (action == MotionEvent.ACTION_DOWN) {
1301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!mExpanded) {
1302808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mViewDelta = statusBarSize - y;
1303808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1304c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mCloseView.getLocationOnScreen(mAbsPos)...?
1305c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
1306808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((!mExpanded && y < hitSize) ||
130836412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler                    (mExpanded && y > (mDisplayMetrics.heightPixels-hitSize))) {
1309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We drop events at the edge of the screen to make the windowshade come
1311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // down by accident less, especially when pushing open a device with a keyboard
1312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // that rotates (like g1 and droid)
1313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int x = (int)event.getRawX();
1314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final int edgeBorder = mEdgeBorder;
131536412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler                if (x >= edgeBorder && x < mDisplayMetrics.widthPixels - edgeBorder) {
1316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    prepareTracking(y, !mExpanded);// opening if we're not already fully visible
1317911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown                    trackMovement(event);
1318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1320808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (mTracking) {
1321911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown            trackMovement(event);
1322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int minY = statusBarSize + mCloseView.getHeight();
132368ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown            if (action == MotionEvent.ACTION_MOVE) {
1324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mAnimatingReveal && y < minY) {
1325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // nothing
1326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else  {
1327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimatingReveal = false;
1328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    updateExpandedViewPos(y + mViewDelta);
1329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
133068ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown            } else if (action == MotionEvent.ACTION_UP
133168ebcdf3fd8b98fe35ec3e0b2e91fd254fcd807fJeff Brown                    || action == MotionEvent.ACTION_CANCEL) {
1332808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mVelocityTracker.computeCurrentVelocity(1000);
1333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float yVel = mVelocityTracker.getYVelocity();
1335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                boolean negative = yVel < 0;
1336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float xVel = mVelocityTracker.getXVelocity();
1338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (xVel < 0) {
1339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    xVel = -xVel;
1340808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1341dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                if (xVel > mFlingGestureMaxXVelocityPx) {
1342dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                    xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
1343808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1344808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1345808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float vel = (float)Math.hypot(yVel, xVel);
1346808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (negative) {
1347808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel = -vel;
1348808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1349808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1350dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                if (CHATTY) {
13515e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                    Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
13525e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                        mVelocityTracker.getXVelocity(),
1353dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                        mVelocityTracker.getYVelocity(),
1354dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                        xVel, yVel,
1355dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                        vel));
1356dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler                }
1357dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
1358fe172cc861448cf1115195cbad5b3300357c02f0Daniel Sandler                performFling(y + mViewDelta, vel, false);
1359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return false;
1363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1365911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown    private void trackMovement(MotionEvent event) {
1366911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        // Add movement to velocity tracker using raw screen X and Y coordinates instead
1367911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        // of window coordinates because the window frame may be moving at the same time.
1368911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        float deltaX = event.getRawX() - event.getX();
1369911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        float deltaY = event.getRawY() - event.getY();
1370911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        event.offsetLocation(deltaX, deltaY);
1371911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        mVelocityTracker.addMovement(event);
1372911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown        event.offsetLocation(-deltaX, -deltaY);
1373911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown    }
1374911fe30d5841d0622f3925a9fbc66d499965b111Jeff Brown
137560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    @Override // CommandQueue
1376328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    public void setNavigationIconHints(int hints) {
1377328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        if (hints == mNavigationIconHints) return;
1378328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
1379328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        mNavigationIconHints = hints;
1380328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
1381328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        if (mNavigationBarView != null) {
1382328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler            mNavigationBarView.setNavigationIconHints(hints);
1383328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        }
1384328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    }
1385328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
1386328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    @Override // CommandQueue
13873a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public void setSystemUiVisibility(int vis, int mask) {
13883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int oldVal = mSystemUiVisibility;
13893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int newVal = (oldVal&~mask) | (vis&mask);
13903a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int diff = newVal ^ oldVal;
1391e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler
1392e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler        if (diff != 0) {
13933a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mSystemUiVisibility = newVal;
139460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
1395e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler            if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
1396e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler                final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE));
1397e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler                if (lightsOut) {
1398e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler                    animateCollapse();
1399e137a1ea997036248c86e8fc0a94711020721f19Daniel Sandler                }
140069314e72941c86734c12476d1e61459811159b74Daniel Sandler                if (mNavigationBarView != null) {
140169314e72941c86734c12476d1e61459811159b74Daniel Sandler                    mNavigationBarView.setLowProfile(lightsOut);
140269314e72941c86734c12476d1e61459811159b74Daniel Sandler                }
140360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            }
140460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
140560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            notifyUiVisibilityChanged();
140660ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        }
140760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    }
140860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
14099305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
141060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        Log.v(TAG, "setLightsOn(" + on + ")");
141160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        if (on) {
14123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
141360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        } else {
14143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
14159305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato        }
14161d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    }
14171d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
141860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    private void notifyUiVisibilityChanged() {
14191d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        try {
142060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
14211d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        } catch (RemoteException ex) {
14221d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        }
14239305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
14249305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
14255c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    public void topAppWindowChanged(boolean showMenu) {
14265c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (DEBUG) {
14275c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler            Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
14285c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
14295c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (mNavigationBarView != null) {
1430f1ebcee22442e0bc2aa86582d352b5ee78257db3Daniel Sandler            mNavigationBarView.setMenuVisibility(showMenu);
14315c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
14325c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
14335c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        // See above re: lights-out policy for legacy apps.
14345c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (showMenu) setLightsOn(true);
14355c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    }
14365c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
1437328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    @Override
1438328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
1439328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
1440328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler            || ((vis & InputMethodService.IME_VISIBLE) != 0);
1441328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
1442328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler        mCommandQueue.setNavigationIconHints(
1443328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1444328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
1445328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler    }
1446328310c6fac6066d338926bb43d359862cae36d2Daniel Sandler
14472992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown    @Override
14482992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown    public void setHardKeyboardStatus(boolean available, boolean enabled) { }
1449e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
14507c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private class NotificationClicker implements View.OnClickListener {
1451808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private PendingIntent mIntent;
1452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mPkg;
1453808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mTag;
1454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private int mId;
1455808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
14567c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
1457808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIntent = intent;
1458808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPkg = pkg;
1459808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTag = tag;
1460808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mId = id;
1461808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1462808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1463808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
1464808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1465808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // The intent we are sending is for the application, which
1466808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // won't have permission to immediately start an activity after
1467808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // the user switches to home.  We know it is safe to do at this
1468808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // point, so make sure new activity switches are now allowed.
1469808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ActivityManagerNative.getDefault().resumeAppSwitches();
147090c52de28691ca0bbbf7c039ef20f85ce46882ccDianne Hackborn                // Also, notifications can be launched from the lock screen,
147190c52de28691ca0bbbf7c039ef20f85ce46882ccDianne Hackborn                // so dismiss the lock screen when the activity starts.
147290c52de28691ca0bbbf7c039ef20f85ce46882ccDianne Hackborn                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
1473808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException e) {
1474808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1475808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1476808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mIntent != null) {
1477808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int[] pos = new int[2];
1478808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                v.getLocationOnScreen(pos);
1479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Intent overlay = new Intent();
1480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                overlay.setSourceBounds(
1481808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
1482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                try {
1483f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
1484808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } catch (PendingIntent.CanceledException e) {
1485808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // the stack trace isn't very helpful here.  Just log the exception message.
1486808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    Slog.w(TAG, "Sending contentIntent failed: " + e);
1487808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
148892d331883ada42e49001853e266cda2d9c8631b8Daniel Sandler
148992d331883ada42e49001853e266cda2d9c8631b8Daniel Sandler                KeyguardManager kgm =
149092d331883ada42e49001853e266cda2d9c8631b8Daniel Sandler                    (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
149192d331883ada42e49001853e266cda2d9c8631b8Daniel Sandler                if (kgm != null) kgm.exitKeyguardSecurely(null);
1492808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onNotificationClick(mPkg, mTag, mId);
1496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // system process is dead if we're here.
1498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // close the shade if it was open
1501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            animateCollapse();
1502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // If this click was on the intruder alert, hide that instead
1504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
1505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1506808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void tick(StatusBarNotification n) {
1509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Show the ticker if one is requested. Also don't do this
1510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // until status bar window is attached to the window manager,
1511808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // because...  well, what's the point otherwise?  And trying to
1512808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // run a ticker without being attached will crash!
1513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) {
1514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.addEntry(n);
1517808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1518808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1519808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1520808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
1523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * about the failure.
1524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
1525808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * WARNING: this will call back into us.  Don't hold any locks.
1526808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
1528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        removeNotification(key);
1529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
1530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
1531808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
1532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // The end is nigh.
1533808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1534808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1535808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class MyTicker extends Ticker {
1537dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        MyTicker(Context context, View sb) {
1538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            super(context, sb);
1539808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1540808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1541808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1542dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerStarting() {
1543808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = true;
1544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.GONE);
1545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.VISIBLE);
1546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
1547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
1548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1551dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerDone() {
1552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1553808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
1555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1559dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerHalting() {
1560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
1563808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
1564808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1568808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1569808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationEnd(Animation animation) {
1570808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = false;
1571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationRepeat(Animation animation) {
1573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationStart(Animation animation) {
1575808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1577808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Animation loadAnim(int id, Animation.AnimationListener listener) {
1579f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        Animation anim = AnimationUtils.loadAnimation(mContext, id);
1580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (listener != null) {
1581808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            anim.setAnimationListener(listener);
1582808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1583808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return anim;
1584808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1586488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler    public static String viewInfo(View v) {
1587488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler        return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1588488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler                + ") " + v.getWidth() + "x" + v.getHeight() + "]";
1589808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1590808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1591f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1592808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        synchronized (mQueueLock) {
1593808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("Current Status Bar state:");
1594808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpanded=" + mExpanded
1595808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mExpandedVisible=" + mExpandedVisible);
1596808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTicking=" + mTicking);
1597808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTracking=" + mTracking);
1598808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mAnimating=" + mAnimating
1599808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1600808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimAccel=" + mAnimAccel);
1601808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCurAnimationTime=" + mCurAnimationTime
1602808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimLastTime=" + mAnimLastTime);
16031dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            pw.println("  mAnimatingReveal=" + mAnimatingReveal
1604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mViewDelta=" + mViewDelta);
160536412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            pw.println("  mDisplayMetrics=" + mDisplayMetrics);
1606808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedParams: " + mExpandedParams);
1607c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler            pw.println("  mExpandedView: " + viewInfo(mExpandedWindowView));
1608808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedDialog: " + mExpandedDialog);
16097c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            pw.println("  mPile: " + viewInfo(mPile));
1610808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCloseView: " + viewInfo(mCloseView));
1611808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTickerView: " + viewInfo(mTickerView));
1612808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mScrollView: " + viewInfo(mScrollView)
1613808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
1614808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
16157579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler
1616488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler        pw.print("  mNavigationBarView=");
1617488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler        if (mNavigationBarView == null) {
1618488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler            pw.println("null");
1619488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler        } else {
1620488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler            mNavigationBarView.dump(fd, pw, args);
1621488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler        }
1622488529506f2b767aec0c6e122e7227a9ebe067a2Daniel Sandler
16237579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler        if (DUMPTRUCK) {
16247579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler            synchronized (mNotificationData) {
16257579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                int N = mNotificationData.size();
16267579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                pw.println("  notification icons: " + N);
16277579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                for (int i=0; i<N; i++) {
16287579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                    NotificationData.Entry e = mNotificationData.get(i);
16297579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                    pw.println("    [" + i + "] key=" + e.key + " icon=" + e.icon);
16307579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                    StatusBarNotification n = e.notification;
16312561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                    pw.println("         pkg=" + n.pkg + " id=" + n.id + " score=" + n.score);
16327579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                    pw.println("         notification=" + n.notification);
16337579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                    pw.println("         tickerText=\"" + n.notification.tickerText + "\"");
16347579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                }
1635808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
16367579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler
16377579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler            int N = mStatusIcons.getChildCount();
16387579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler            pw.println("  system icons: " + N);
1639808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (int i=0; i<N; i++) {
16407579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
16417579bca7a02477353700d3b716f172b4fab267c0Daniel Sandler                pw.println("    [" + i + "] icon=" + ic);
1642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
16435e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller
164489d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler            if (false) {
164589d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                pw.println("see the logcat for a dump of the views we have created.");
164689d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                // must happen on ui thread
164789d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                mHandler.post(new Runnable() {
164889d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                        public void run() {
164989d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                            mStatusBarView.getLocationOnScreen(mAbsPos);
165089d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                            Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
165189d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                                    + ") " + mStatusBarView.getWidth() + "x"
165289d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                                    + mStatusBarView.getHeight());
165389d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                            mStatusBarView.debug();
165489d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler
1655c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                            mExpandedWindowView.getLocationOnScreen(mAbsPos);
165689d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                            Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1657c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                                    + ") " + mExpandedWindowView.getWidth() + "x"
1658c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                                    + mExpandedWindowView.getHeight());
1659c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                            mExpandedWindowView.debug();
166089d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                        }
166189d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler                    });
166289d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler            }
1663808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
166489d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler
166589d97131bd7fd7494c3469dfdf6351a84bae62bfDaniel Sandler        mNetworkController.dump(fd, pw, args);
1666808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1667808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1668c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    @Override
1669c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    public void createAndAddWindows() {
1670c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        addStatusBarWindow();
1671c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        addExpandedWindow();
1672c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    }
1673c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler
1674c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    private void addStatusBarWindow() {
1675c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // Put up the view
1676c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        final int height = getStatusBarHeight();
16776e8db88b4b31a6e0211561f25ee1a422e4797ba1Daniel Sandler
1678c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1679c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                ViewGroup.LayoutParams.MATCH_PARENT,
1680c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                height,
1681c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR,
1682c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
1683c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
1684c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
1685c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                // We use a pixel format of RGB565 for the status bar to save memory bandwidth and
1686c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                // to ensure that the layer can be handled by HWComposer.  On some devices the
1687c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                // HWComposer is unable to handle SW-rendered RGBX_8888 layers.
1688c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                PixelFormat.RGB_565);
1689c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler
1690c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
1691c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
1692c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // for the status bar, we prevent the GPU from having to wake up just to do these small
1693c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // updates, which should help keep power consumption down.
1694808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1695c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        lp.gravity = getStatusBarGravity();
1696c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        lp.setTitle("StatusBar");
1697c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        lp.packageName = mContext.getPackageName();
1698c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        WindowManagerImpl.getDefault().addView(makeStatusBarView(), lp);
1699808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1700c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler
1701c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler    void addExpandedWindow() {
1702808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp;
1703808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pixelFormat;
1704808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1705808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /// ---------- Expanded View --------------
1706808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        pixelFormat = PixelFormat.TRANSLUCENT;
1707808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1708808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp = mExpandedDialog.getWindow().getAttributes();
1709808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.x = 0;
1710c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        lp.y = 0;
171129fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato        lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
171236412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        lp.flags = 0
171336412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1714808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1715808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1716808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_DITHER
1717808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1718b69f7015e7233d1c22d474f7f6850d4d93b2b790Daniel Sandler        if (ActivityManager.isHighEndGfx(mDisplay)) {
1719b69f7015e7233d1c22d474f7f6850d4d93b2b790Daniel Sandler            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
1720b69f7015e7233d1c22d474f7f6850d4d93b2b790Daniel Sandler        }
1721808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.format = pixelFormat;
1722808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
1723808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("StatusBarExpanded");
1724808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams = lp;
17251dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        updateExpandedSize();
17261dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mExpandedDialog.getWindow().setFormat(pixelFormat);
1727808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1728808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
1729c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedDialog.setContentView(mExpandedWindowView,
1730808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1731808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                           ViewGroup.LayoutParams.MATCH_PARENT));
1732808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setBackgroundDrawable(null);
1733c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        //mExpandedDialog.show();
1734808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1735808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1736808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void setNotificationIconVisibility(boolean visible, int anim) {
1737808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mNotificationIcons.getVisibility();
1738808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int v = visible ? View.VISIBLE : View.INVISIBLE;
1739808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != v) {
1740808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.setVisibility(v);
1741808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.startAnimation(loadAnim(anim, null));
1742808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1743808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1744808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
17451dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateExpandedInvisiblePosition() {
1746c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mTrackingPosition = -mDisplayMetrics.heightPixels;
17471dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    }
17481dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
1749808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateExpandedViewPos(int expandedPosition) {
1750808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1751808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
1752c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler                    //+ " mTrackingParams.y=" + ((mTrackingParams == null) ? "?" : mTrackingParams.y)
1753808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingPosition=" + mTrackingPosition);
1754808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1755808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1756079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        int panelh = 0;
1757079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        final int disph = mDisplayMetrics.heightPixels;
1758808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1759808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // If the expanded view is not visible, make sure they're still off screen.
1760808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Maybe the view was resized.
1761808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
17621dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            updateExpandedInvisiblePosition();
1763808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1764808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1765808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1766808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // tracking view...
1767808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pos;
1768808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (expandedPosition == EXPANDED_FULL_OPEN) {
1769079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler            panelh = disph;
1770808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1771808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else if (expandedPosition == EXPANDED_LEAVE_ALONE) {
1772079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler            panelh = mTrackingPosition;
1773808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1774808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else {
1775808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (expandedPosition <= disph) {
1776079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler                panelh = expandedPosition;
1777808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1778079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler                panelh = disph;
1779808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1780808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1781079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler
1782079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        // catch orientation changes and other peculiar cases
1783079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        if (panelh > disph || (panelh < disph && !mTracking && !mAnimating))
1784079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler            panelh = disph;
1785079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler
1786079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        mTrackingPosition = panelh;
1787c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // XXX: this is all very WIP
1788079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        //mNotificationPanel.setY(panelh);
1789079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        final View cropView = mNotificationPanel;
1790079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        ViewGroup.LayoutParams lp = cropView.getLayoutParams();
1791079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        lp.height = panelh;
1792079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        cropView.setLayoutParams(lp);
1793c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        // woo, special effects
1794079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        final float frac = (float)panelh / disph;
1795079b33d215a49bc38b488489b0cc13d7273cdc66Daniel Sandler        final int color = ((int)(0xB0 * frac * frac)) << 24;
1796c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        mExpandedWindowView.setBackgroundColor(color);
1797c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler
1798c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//        Slog.d(TAG, String.format("updateExpanded: pos=%d frac=%.2f col=0x%08x", pos, frac, color));
1799c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler
1800c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//        if (mExpandedParams != null) {
1801c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            if (mCloseView.getWindowVisibility() == View.VISIBLE) {
1802c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mCloseView.getLocationInWindow(mPositionTmp);
1803c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                final int closePos = mPositionTmp[1];
1804c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1805c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedContents.getLocationInWindow(mPositionTmp);
1806c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
1807c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1808c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedParams.y = pos + mTrackingView.getHeight()
1809c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                        - (mTrackingParams.height-closePos) - contentsBottom;
1810c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1811c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                if (SPEW) {
1812c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                    Slog.d(PhoneStatusBar.TAG,
1813c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                            "pos=" + pos +
1814c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                            " trackingHeight=" + mTrackingView.getHeight() +
1815c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                            " (trackingParams.height - closePos)=" +
1816c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                                (mTrackingParams.height - closePos) +
1817c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                            " contentsBottom=" + contentsBottom);
1818c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                }
1819c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1820c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            } else {
1821c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                // If the tracking view is not yet visible, then we can't have
1822c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                // a good value of the close view location.  We need to wait for
1823c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                // it to be visible to do a layout.
1824c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedParams.y = -mDisplayMetrics.heightPixels;
1825c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            }
1826c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            int max = h;
1827c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            if (mExpandedParams.y > max) {
1828c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedParams.y = max;
1829c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            }
1830c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            int min = mTrackingPosition;
1831c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            if (mExpandedParams.y < min) {
1832c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedParams.y = min;
1833c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            }
1834c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1835c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
1836c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            if (!visible) {
1837c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                // if the contents aren't visible, move the expanded view way off screen
1838c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                // because the window itself extends below the content view.
1839c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                mExpandedParams.y = -disph;
1840c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            }
1841c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1842c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1843c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            // As long as this isn't just a repositioning that's not supposed to affect
1844c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            // the user's perception of what's showing, call to say that the visibility
1845c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            // has changed. (Otherwise, someone else will call to do that).
1846c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            if (expandedPosition != EXPANDED_LEAVE_ALONE) {
1847c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");
1848c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                visibilityChanged(visible);
1849c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            }
1850c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//        }
1851c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//
1852c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//        if (SPEW) {
1853c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//            Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition
1854c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                    + " mTrackingParams.y=" + mTrackingParams.y
1855c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                    + " mTrackingPosition=" + mTrackingPosition
1856c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                    + " mExpandedParams.y=" + mExpandedParams.y
1857c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//                    + " mExpandedParams.height=" + mExpandedParams.height);
1858c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler//        }
1859808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1860808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18611dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    int getExpandedHeight(int disph) {
1862cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        if (DEBUG) {
1863cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler            Slog.d(TAG, "getExpandedHeight(" + disph + "): sbView="
1864cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler                    + mStatusBarView.getHeight() + " closeView=" + mCloseView.getHeight());
1865cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        }
1866c6d29fc0f552db7cfee6491530cf89f59c242bd4Daniel Sandler        return disph; // - mStatusBarView.getHeight();
1867808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1868808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18691dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateDisplaySize() {
187036412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        mDisplay.getMetrics(mDisplayMetrics);
187136412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        if (DEBUG) {
187236412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            Slog.d(TAG, "updateDisplaySize: " + mDisplayMetrics);
187336412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        }
18741dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        updateExpandedSize();
18751dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    }
18761dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
18771dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateExpandedSize() {
1878cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        if (DEBUG) {
1879cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler            Slog.d(TAG, "updateExpandedSize()");
1880cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler        }
188136412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler        if (mExpandedDialog != null && mExpandedParams != null && mDisplayMetrics != null) {
188236412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            mExpandedParams.width = mDisplayMetrics.widthPixels;
188336412a7e7c4929bdac1221b7ced9e73d0d204691Daniel Sandler            mExpandedParams.height = getExpandedHeight(mDisplayMetrics.heightPixels);
18841dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            if (!mExpandedVisible) {
18851dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                updateExpandedInvisiblePosition();
18861dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            } else {
18871dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
18881dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            }
1889cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler            if (DEBUG) {
18905e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                Slog.d(TAG, "updateExpandedSize: height=" + mExpandedParams.height + " " +
1891cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler                    (mExpandedVisible ? "VISIBLE":"INVISIBLE"));
1892cf336e10c03a802bd96df164c49b069cb7ad6819Daniel Sandler            }
1893808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1894808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1895808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1896808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performDisableActions(int net) {
1897808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mDisabled;
1898808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int diff = net ^ old;
1899808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = net;
1900808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1901808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // act accordingly
1902808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1903808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
1904808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_EXPAND: yes");
1905808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
1906808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1907808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1908808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1909808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1910808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
1911808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
1912808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mNotificationIcons.setVisibility(View.INVISIBLE);
1913808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
1914808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
1915808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
1916808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1917808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1918808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
1919808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
1920808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1921808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1922808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1923808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1924808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1925808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
1926808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1927808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1928808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1929808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1930808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
19318ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        final int mini(int a, int b) {
19328ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler            return (b>a?a:b);
19338ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler        }
1934808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
19358ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler            synchronized (mNotificationData) {
19362f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                // animate-swipe all dismissable notifications, then animate the shade closed
19372f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                int numChildren = mPile.getChildCount();
19388ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler
19392f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                int scrollTop = mScrollView.getScrollY();
19402f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                int scrollBottom = scrollTop + mScrollView.getHeight();
19412f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                final ArrayList<View> snapshot = new ArrayList<View>(numChildren);
19422f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                for (int i=0; i<numChildren; i++) {
19438ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    final View child = mPile.getChildAt(i);
19442f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                    if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop &&
19452f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            child.getTop() < scrollBottom) {
19462f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        snapshot.add(child);
19472f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                    }
19488ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                }
194993a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                if (snapshot.isEmpty()) {
195093a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                    animateCollapse(false);
195193a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                    return;
195293a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                }
19538ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                new Thread(new Runnable() {
19548ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    @Override
19558ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    public void run() {
19562f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // Decrease the delay for every row we animate to give the sense of
19572f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // accelerating the swipes
19582f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        final int ROW_DELAY_DECREMENT = 10;
19592f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        int currentDelay = 140;
19602f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        int totalDelay = 0;
19612f2022afa1eb85018368398bd150e9575fc099c9Chet Haase
19622f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // Set the shade-animating state to avoid doing other work during
19632f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // all of these animations. In particular, avoid layout and
19642f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // redrawing when collapsing the shade.
19652f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        mPile.setViewRemoval(false);
19662f2022afa1eb85018368398bd150e9575fc099c9Chet Haase
19672f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        mPostCollapseCleanup = new Runnable() {
196893a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                            @Override
19698ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                            public void run() {
19708ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                                try {
19712f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                                    mPile.setViewRemoval(true);
19728ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                                    mBarService.onClearAllNotifications();
19732f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                                } catch (Exception ex) { }
19748ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                            }
19752f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        };
19768ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler
19772f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        View sampleView = snapshot.get(0);
19782f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        int width = sampleView.getWidth();
197993a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                        final int velocity = width * 8; // 1000/8 = 125 ms duration
198093a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                        for (final View _v : snapshot) {
19812f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            mHandler.postDelayed(new Runnable() {
19828ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                                @Override
19838ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                                public void run() {
19842f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                                    mPile.dismissRowAnimated(_v, velocity);
19858ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                                }
19862f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            }, totalDelay);
19872f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT);
19882f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            totalDelay += currentDelay;
19898ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                        }
19902f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // Delay the collapse animation until after all swipe animations have
19912f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // finished. Provide some buffer because there may be some extra delay
19922f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // before actually starting each swipe animation. Ideally, we'd
19932f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // synchronize the end of those animations with the start of the collaps
19942f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        // exactly.
19952f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        mHandler.postDelayed(new Runnable() {
199693a035cce1a3a3c70cd6f0e0a5f98ac0e4138337Craig Mautner                            @Override
19972f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            public void run() {
19982f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                                animateCollapse(false);
19992f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                            }
20002f2022afa1eb85018368398bd150e9575fc099c9Chet Haase                        }, totalDelay + 225);
20018ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                    }
20028ba33c965f940070060585e45e1c833519bb45c9Daniel Sandler                }).start();
2003808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
2004808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2005808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2006808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2007d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler    private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
2008d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler        public void onClick(View v) {
20095e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller            try {
20105e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                // Dismiss the lock screen when Settings starts.
20115e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
20125e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller            } catch (RemoteException e) {
20135e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller            }
2014d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler            v.getContext().startActivity(new Intent(Settings.ACTION_SETTINGS)
2015d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
2016d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler            animateCollapse();
2017d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler        }
2018d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler    };
2019d309056d36759446c91ff5c1e17a217bfa4fdcfbDaniel Sandler
2020808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
2021808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onReceive(Context context, Intent intent) {
2022808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            String action = intent.getAction();
2023808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
2024808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
20253b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                boolean excludeRecents = false;
20263b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
2027edbdd3a024ca35c331036823dde1f484d3333b31Daniel Sandler                    String reason = intent.getStringExtra("reason");
20283b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (reason != null) {
20293b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        excludeRecents = reason.equals("recentapps");
20303b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    }
20313b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                }
20323b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                animateCollapse(excludeRecents);
2033808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
2034808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
20358956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                repositionNavigationBar();
2036808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateResources();
2037808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
2038808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2039808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2040808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2041808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void setIntruderAlertVisibility(boolean vis) {
2042fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        if (DEBUG) {
2043fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
2044fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        }
2045808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
2046808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2047808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2048fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    public void dismissIntruder() {
2049fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        if (mCurrentlyIntrudingNotification == null) return;
2050fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
2051fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        try {
2052fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            mBarService.onNotificationClear(
2053fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    mCurrentlyIntrudingNotification.pkg,
2054fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    mCurrentlyIntrudingNotification.tag,
2055fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler                    mCurrentlyIntrudingNotification.id);
2056fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        } catch (android.os.RemoteException ex) {
2057fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler            // oh well
2058fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler        }
2059fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler    }
2060fa7887bebf57f3dcb8283d73e69ba1daa115225fDaniel Sandler
2061808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
2062808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Reload some of our resources when the configuration changes.
2063808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
2064808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * We don't reload everything when the configuration changes -- we probably
2065808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
2066808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * meantime, just update the things that we know change.
2067808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
2068808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateResources() {
2069f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
2070f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
2071808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
20721347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        if (mClearButton instanceof TextView) {
20731347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler            ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
20741347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        }
20757c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadDimens();
20767c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
20775e6af448045f20f7a1b393960d200c25e9d976e8Jim Miller
20787c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    protected void loadDimens() {
20797c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final Resources res = mContext.getResources();
20807c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20817c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mNaturalBarHeight = res.getDimensionPixelSize(
20827c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                com.android.internal.R.dimen.status_bar_height);
20837c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20847c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int newIconSize = res.getDimensionPixelSize(
20857c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            com.android.internal.R.dimen.status_bar_icon_size);
20867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int newIconHPadding = res.getDimensionPixelSize(
20877c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            R.dimen.status_bar_icon_padding);
20887c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20897c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
20907c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
20917c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mIconHPadding = newIconHPadding;
20927c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mIconSize = newIconSize;
20937c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            //reloadAllNotificationIcons(); // reload the tray
20947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
20957c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
2096808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2097808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2098dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
2099dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
2100dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
2101dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
2102dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
2103dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
2104dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
2105dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
2106dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
2107dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
2108dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
2109dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler        mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
2110dc940eaa67db0108f8a8629826dbb3c5c7d779e9Daniel Sandler
2111808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) Slog.v(TAG, "updateResources");
2112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
2115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // tracing
2116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
2117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2118808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void postStartTracing() {
2119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.postDelayed(mStartTracing, 3000);
2120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void vibrate() {
2123f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2124f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.VIBRATOR_SERVICE);
2125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        vib.vibrate(250);
2126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
21282561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    public int getScoreThreshold() {
21292561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        return mDisplayMinScore;
21302561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    }
21312561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
21322561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    public void setScoreThreshold(int score) {
21332561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        // XXX HAX
21342561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        if (mDisplayMinScore != score) {
21352561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            this.mDisplayMinScore = score;
21362561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            applyScoreThreshold();
21372561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        }
21382561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    }
21392561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
21402561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    private void applyScoreThreshold() {
21412561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        int N = mNotificationData.size();
21422561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        for (int i=0; i<N; i++) {
21432561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            NotificationData.Entry entry = mNotificationData.get(i);
21442561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            int vis = (entry.notification.score < mDisplayMinScore)
21452561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                ? View.GONE
21462561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler                : View.VISIBLE;
21472561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            entry.row.setVisibility(vis);
21482561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler            entry.icon.setVisibility(vis);
21492561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler        }
21502561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler    }
21512561b0b10a55841a08e0e1d467e73e10b1bf256dDaniel Sandler
2152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStartTracing = new Runnable() {
2153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
2154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
2155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            SystemClock.sleep(250);
2156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "startTracing");
2157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.postDelayed(mStopTracing, 10000);
2159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStopTracing = new Runnable() {
2163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
2164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.stopMethodTracing();
2165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "stopTracing");
2166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
2167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
2170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2171