PhoneStatusBar.java revision 6cf602cd1de4fd1b6a8a5028ef10df0ffc57bacb
1808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato/*
2808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Copyright (C) 2010 The Android Open Source Project
3808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
4808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * you may not use this file except in compliance with the License.
6808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * You may obtain a copy of the License at
7808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
8808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
10808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Unless required by applicable law or agreed to in writing, software
11808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * See the License for the specific language governing permissions and
14808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * limitations under the License.
15808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato */
16808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
17fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopackage com.android.systemui.statusbar.phone;
18808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
19808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.ActivityManagerNative;
20808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Dialog;
21808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.Notification;
22808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.PendingIntent;
23808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.app.StatusBarManager;
24808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.BroadcastReceiver;
25808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
26808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
27808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.IntentFilter;
28808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.res.Resources;
293b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurkaimport android.content.res.Configuration;
30808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.PixelFormat;
311dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackbornimport android.graphics.Point;
32808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.Rect;
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.graphics.drawable.Drawable;
347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandlerimport android.graphics.drawable.LayerDrawable;
35808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.net.Uri;
363b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurkaimport android.os.Bundle;
37808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
38808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.RemoteException;
39808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.Handler;
40808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.Message;
411d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandlerimport android.os.ServiceManager;
42808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.SystemClock;
43935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onoratoimport android.text.TextUtils;
44808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.util.Slog;
45808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.util.Log;
46808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Display;
47808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
481d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandlerimport android.view.IWindowManager;
49808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.KeyEvent;
50808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.LayoutInflater;
51808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.MotionEvent;
528956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandlerimport android.view.Surface;
53808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.VelocityTracker;
54808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
55808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.ViewGroup;
56f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Millerimport android.view.ViewGroup.LayoutParams;
57808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Window;
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManager;
59808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.WindowManagerImpl;
60808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.Animation;
61808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.animation.AnimationUtils;
62808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ImageView;
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
64808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.RemoteViews;
65808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.ScrollView;
66808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.TextView;
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.io.FileDescriptor;
69808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.io.PrintWriter;
70808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport java.util.ArrayList;
71808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
72808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
73808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
74808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
75808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.R;
763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurkaimport com.android.systemui.recent.RecentsPanelView;
77fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.NotificationData;
78fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.StatusBar;
79fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.StatusBarIconView;
80fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.DateView;
812b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.BatteryController;
822b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.LocationController;
832b69735e014872ca2183b4a39a8381daa337e146Daniel Sandlerimport com.android.systemui.statusbar.policy.NetworkController;
84808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
85fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopublic class PhoneStatusBar extends StatusBar {
86fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    static final String TAG = "PhoneStatusBar";
87808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final boolean SPEW = false;
883b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public static final boolean DEBUG = false;
89808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
9096e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler    // additional instrumentation for testing purposes; intended to be left on during development
9196e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler    public static final boolean CHATTY = DEBUG || true;
9296e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
93808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public static final String ACTION_STATUSBAR_START
94808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            = "com.android.internal.policy.statusbar.START";
95808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
96808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_LEAVE_ALONE = -10000;
97808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int EXPANDED_FULL_OPEN = -10001;
98808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
99808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_ANIMATE = 1000;
100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_ANIMATE_REVEAL = 1001;
101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_SHOW_INTRUDER = 1002;
102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int MSG_HIDE_INTRUDER = 1003;
1033b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    private static final int MSG_OPEN_RECENTS_PANEL = 1020;
1043b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    private static final int MSG_CLOSE_RECENTS_PANEL = 1021;
105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // will likely move to a resource or other tunable param at some point
107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private static final int INTRUDER_ALERT_DECAY_MS = 10000;
108808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
109fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarPolicy mIconPolicy;
110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1112b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    // These are no longer handled by the policy, because we need custom strategies for them
1122b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    BatteryController mBatteryController;
1132b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    LocationController mLocationController;
1142b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler    NetworkController mNetworkController;
1152b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler
1167c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mNaturalBarHeight = -1;
1177c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mIconSize = -1;
1187c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    int mIconHPadding = -1;
119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Display mDisplay;
120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1211d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    IWindowManager mWindowManager;
1221d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
123fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    PhoneStatusBarView mStatusBarView;
124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mPixelFormat;
125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    H mHandler = new H();
126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Object mQueueLock = new Object();
127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // icons
129808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mIcons;
130808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    IconMerger mNotificationIcons;
131808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    LinearLayout mStatusIcons;
132808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // expanded notifications
134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Dialog mExpandedDialog;
135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ExpandedView mExpandedView;
136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WindowManager.LayoutParams mExpandedParams;
137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    ScrollView mScrollView;
138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View mNotificationLinearLayout;
139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View mExpandedContents;
140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // top bar
141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TextView mNoNotificationsTitle;
1421347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler    View mClearButton;
143808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // drag bar
144808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    CloseDragHandle mCloseView;
1457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
1467c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    // all notifications
1477c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    NotificationData mNotificationData = new NotificationData();
1487c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    ViewGroup mPile;
1497c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // position
151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mPositionTmp = new int[2];
152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpanded;
153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mExpandedVisible;
154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
155808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the date view
156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    DateView mDateView;
157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for immersive activities
159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View mIntruderAlertView;
160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1618956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    // on-screen navigation buttons
1620129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler    private NavigationBarView mNavigationBarView = null;
1638956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // the tracker view
165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    TrackingView mTrackingView;
166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    WindowManager.LayoutParams mTrackingParams;
167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mTrackingPosition; // the position of the top of the tracking view.
168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mPanelSlightlyVisible;
169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ticker
171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Ticker mTicker;
172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View mTickerView;
173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private boolean mTicking;
174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1753b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    // Recent applications
1763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    private RecentsPanelView mRecentsPanel;
1773b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
178808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Tracking finger for opening/closing.
179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore
180808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mTracking;
181808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    VelocityTracker mVelocityTracker;
182808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    static final int ANIM_FRAME_DURATION = (1000/60);
184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimating;
186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mCurAnimationTime;
187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimY;
188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimVel;
189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    float mAnimAccel;
190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    long mAnimLastTime;
191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean mAnimatingReveal = false;
192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mViewDelta;
193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int[] mAbsPos = new int[2];
194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // for disabling the status bar
196808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mDisabled = 0;
197808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
19860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    // tracking calls to View.setSystemUiVisibility()
19960ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
20060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
2011dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    final Point mDisplaySize = new Point();
2021dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class ExpandedDialog extends Dialog {
204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ExpandedDialog(Context context) {
205808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public boolean dispatchKeyEvent(KeyEvent event) {
210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
211808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (event.getKeyCode()) {
212808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            case KeyEvent.KEYCODE_BACK:
213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!down) {
214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    animateCollapse();
215808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
216808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                return true;
217808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
218808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return super.dispatchKeyEvent(event);
219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
223f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
224f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
225f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                .getDefaultDisplay();
226808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2271d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        mWindowManager = IWindowManager.Stub.asInterface(
2281d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler                ServiceManager.getService(Context.WINDOW_SERVICE));
2291d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
230f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start();
231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2328956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        addNavigationBar();
2338956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
2348956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        //addIntruderView();
235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Lastly, call to the icon policy to install/update all the icons.
237fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mIconPolicy = new PhoneStatusBarPolicy(mContext);
238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // Constructing the view
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // ================================================================================
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
244f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Resources res = context.getResources();
247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2481dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mDisplay.getSize(mDisplaySize);
2497c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadDimens();
250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2511dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
2521dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ExpandedView expanded = (ExpandedView)View.inflate(context,
254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                R.layout.status_bar_expanded, null);
255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        expanded.mService = this;
256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView = View.inflate(context, R.layout.intruder_alert, null);
258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(View.GONE);
259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setClickable(true);
260808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
26160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
26260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                R.layout.status_bar, null);
26360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        sb.mService = this;
26460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        mStatusBarView = sb;
26560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
2660129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        try {
2678c4706252228755ed181d19532b7e0cfec270ba4Adam Powell            boolean showNav = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
2680129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler            if (showNav) {
2690129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler                mNavigationBarView =
2700129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler                    (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
27160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
27260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                sb.setOnSystemUiVisibilityChangeListener(
27360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                    new View.OnSystemUiVisibilityChangeListener() {
27460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                        @Override
27560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                        public void onSystemUiVisibilityChange(int visibility) {
27660ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                            if (DEBUG) {
27760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                                Slog.d(TAG, "systemUi: " + visibility);
27860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                            }
27960ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                            boolean hide = (0 != (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION));
28060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                            mNavigationBarView.setHidden(hide);
28160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                        }
28260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                    });
2830129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler            }
2840129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        } catch (Resources.NotFoundException ex) {
2850129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler            // no nav bar for you
2860129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        }
2878956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
288808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // figure out which pixel-format to use for the status bar.
289808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mPixelFormat = PixelFormat.TRANSLUCENT;
290808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Drawable bg = sb.getBackground();
291808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (bg != null) {
292808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPixelFormat = bg.getOpacity();
293808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
295808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
296808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
297808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIcons = (LinearLayout)sb.findViewById(R.id.icons);
298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTickerView = sb.findViewById(R.id.ticker);
299808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView = (DateView)sb.findViewById(R.id.date);
300808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog = new ExpandedDialog(context);
302808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedView = expanded;
303808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);
3047c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mPile = (ViewGroup)expanded.findViewById(R.id.latestItems);
305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
3061347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        mClearButton = expanded.findViewById(R.id.clear_all_button);
307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mClearButton.setOnClickListener(mClearButtonListener);
308808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTicker = new MyTicker(context, sb);
312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);
314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        tickerView.mTicker = mTicker;
315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null);
317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.mService = this;
318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close);
319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCloseView.mService = this;
320808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
321808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
323808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // set the inital view visibility
324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.setVisibility(View.INVISIBLE);
326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3272b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        // Other icons
3282b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mLocationController = new LocationController(mContext); // will post a notification
3292b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mBatteryController = new BatteryController(mContext);
3302b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
3312b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mNetworkController = new NetworkController(mContext);
3322b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        final ImageView comboRSSI =
3332b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler                (ImageView)sb.findViewById(R.id.network_signal);
3342b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        if (comboRSSI != null) {
3352b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler            mNetworkController.addCombinedSignalIconView(comboRSSI);
3362b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        }
3372b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        final ImageView mobileRSSI =
3382b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler                (ImageView)sb.findViewById(R.id.mobile_signal);
3392b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        if (mobileRSSI != null) {
3402b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler            mNetworkController.addPhoneSignalIconView(mobileRSSI);
3412b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        }
3422b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        final ImageView wifiRSSI =
3432b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler                (ImageView)sb.findViewById(R.id.wifi_signal);
3442b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        if (wifiRSSI != null) {
3452b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler            mNetworkController.addWifiIconView(wifiRSSI);
3462b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        }
3472b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mNetworkController.addDataTypeIconView(
3482b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler                (ImageView)sb.findViewById(R.id.network_type));
3492b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mNetworkController.addDataDirectionOverlayIconView(
3502b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler                (ImageView)sb.findViewById(R.id.network_direction));
3512b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler        mNetworkController.setStackedMode(true);
3522b69735e014872ca2183b4a39a8381daa337e146Daniel Sandler
3533b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        // Recents Panel
35417dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller        updateRecentsPanel();
3553b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
356808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // receive broadcasts
357808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        IntentFilter filter = new IntentFilter();
358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        filter.addAction(Intent.ACTION_SCREEN_OFF);
361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        context.registerReceiver(mBroadcastReceiver, filter);
362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
366f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller    protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
3673b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        boolean translucent = false;
3683b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
369f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller                layoutParams.width,
370f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller                layoutParams.height,
3713b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
3723b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
3733b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
3743b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
3753b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
3763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                (translucent ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
3773b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
3783b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.setTitle("RecentsPanel");
3793b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.windowAnimations = R.style.Animation_RecentPanel;
3803b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
3813b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
3823b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        return lp;
3833b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
3843b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
38517dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller    protected void updateRecentsPanel() {
3863b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        // Recents Panel
3873b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        boolean visible = false;
3883b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        if (mRecentsPanel != null) {
3893b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            visible = mRecentsPanel.getVisibility() == View.VISIBLE;
3903b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            WindowManagerImpl.getDefault().removeView(mRecentsPanel);
3913b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
392f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller
393f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller        // Provide RecentsPanelView with a temporary parent to allow layout params to work.
394f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller        LinearLayout tmpRoot = new LinearLayout(mContext);
395f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller        mRecentsPanel = (RecentsPanelView) LayoutInflater.from(mContext).inflate(
396f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller                R.layout.status_bar_recent_panel, tmpRoot, false);
3973b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
3983b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
3993b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                mRecentsPanel));
4003b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        mRecentsPanel.setVisibility(View.GONE);
401f2a16b27afd1ede5880d05eb9e19090c7e3e820eJim Miller        WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
4023b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
4033b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
4043b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        mRecentsPanel.setBar(this);
4053b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        if (visible) {
4063b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            // need to set visibility to View.GONE earlier since that
4073b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            // triggers refreshing application list
4083b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mRecentsPanel.setVisibility(View.VISIBLE);
4093b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mRecentsPanel.show(true, false);
4103b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
4113b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
4123b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
4133b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.TOP | Gravity.FILL_HORIZONTAL;
416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
417808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
418dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    public int getStatusBarHeight() {
419f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = mContext.getResources();
420dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato        return res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
421dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    }
422dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato
4235c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
4245c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        public void onClick(View v) {
4255c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler            toggleRecentApps();
4265c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
4275c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    };
4285c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4298956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    // For small-screen devices (read: phones) that lack hardware navigation buttons
4308956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private void addNavigationBar() {
4310129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        if (mNavigationBarView == null) return;
43217dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller
4338956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        mNavigationBarView.reorient();
43417dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller
4355c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
4365c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4378956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManagerImpl.getDefault().addView(
4388956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                mNavigationBarView, getNavigationBarLayoutParams());
4398956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4408956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4418956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private void repositionNavigationBar() {
4420129b31ff493bb0aa10b778cbeacbec5964644f8Daniel Sandler        if (mNavigationBarView == null) return;
44317dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller
4448956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        mNavigationBarView.reorient();
4455c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4465c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
4475c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
4488956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManagerImpl.getDefault().updateViewLayout(
4498956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                mNavigationBarView, getNavigationBarLayoutParams());
4508956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4518956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4528956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    private WindowManager.LayoutParams getNavigationBarLayoutParams() {
4538956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        final int rotation = mDisplay.getRotation();
4548956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        final boolean sideways =
4558956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler            (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
4568956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4578956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        final Resources res = mContext.getResources();
4588956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        final int size = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
4598956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4608956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
4618956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                sideways ? size : ViewGroup.LayoutParams.MATCH_PARENT,
4628956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                sideways ? ViewGroup.LayoutParams.MATCH_PARENT : size,
4638956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
4648956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    0
4658956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
4668956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
4678956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
4688956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
46998db5fabdad86dca379740d8050697950b9f026cJeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
47098db5fabdad86dca379740d8050697950b9f026cJeff Brown                    | WindowManager.LayoutParams.FLAG_SLIPPERY,
4718956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                PixelFormat.TRANSLUCENT);
4728956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4738956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        lp.setTitle("NavigationBar");
4748956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        switch (rotation) {
4758956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler            case Surface.ROTATION_90:
4768956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                // device has been turned 90deg counter-clockwise
4778956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                lp.gravity = Gravity.RIGHT | Gravity.FILL_VERTICAL;
4788956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                break;
4798956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler            case Surface.ROTATION_270:
4808956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                // device has been turned 90deg clockwise
481f86f898f8afe73d81b34543dcb2c30d8bf7da563Daniel Sandler                lp.gravity = (NavigationBarView.NAVBAR_ALWAYS_AT_RIGHT ? Gravity.RIGHT
482f86f898f8afe73d81b34543dcb2c30d8bf7da563Daniel Sandler                                                                       : Gravity.LEFT)
483f86f898f8afe73d81b34543dcb2c30d8bf7da563Daniel Sandler                             | Gravity.FILL_VERTICAL;
4848956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                break;
4858956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler            default:
4868956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
4878956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                break;
4888956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        }
4898956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        lp.windowAnimations = 0;
4908956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
4918956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler        return lp;
4928956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler    }
4938956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler
494dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato    private void addIntruderView() {
495dc10030581d6eec1c96acd62ed511f91d25d73a1Joe Onorato        final int height = getStatusBarHeight();
496808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.WRAP_CONTENT,
50029fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato                WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
50546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
50646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                PixelFormat.TRANSLUCENT);
508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.y += height * 1.5; // FIXME
510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("IntruderAlert");
51159aed3885e7bf34b4d7c021db4243484fa267526Dianne Hackborn        lp.packageName = mContext.getPackageName();
51259aed3885e7bf34b4d7c021db4243484fa267526Dianne Hackborn        lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
517808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
518808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
519808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " icon=" + icon);
5206179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov        StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
525808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
526808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " old=" + old + " icon=" + icon);
529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        view.set(icon);
531808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
533808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
534808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
535808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusIcons.removeViewAt(viewIndex);
536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
537808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
539808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarIconView iconView = addNotificationViews(key, notification);
540808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (iconView == null) return;
541808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
542808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        boolean immersive = false;
543808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (immersive) {
549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((notification.notification.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "Presenting high-priority notification in immersive activity");
551379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler                // special new transient ticker mode
552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 1. Populate mIntruderAlertView
553808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                alertIcon.setImageDrawable(StatusBarIconView.getIcon(
557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    alertIcon.getContext(),
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    iconView.getStatusBarIcon()));
559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                alertText.setText(notification.notification.tickerText);
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                button.setOnClickListener(
5637c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    new NotificationClicker(notification.notification.contentIntent,
564808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.pkg, notification.tag, notification.id));
565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 2. Animate mIntruderAlertView in
567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
568808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
569808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // 3. Set alarm to age the notification off (TODO)
570808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.removeMessages(MSG_HIDE_INTRUDER);
571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (notification.notification.fullScreenIntent != null) {
574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // not immersive & a full-screen alert should be shown
575808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " sending fullScreenIntent");
577808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                notification.notification.fullScreenIntent.send();
579808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (PendingIntent.CanceledException e) {
580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
581808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
582808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // usual case: status bar visible & not immersive
583808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
584808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // show the ticker
585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            tick(notification);
586808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
587808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
588808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
589808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
590808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
591808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
592808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
593808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
5947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
595808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
5967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
5977c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (oldEntry == null) {
5987c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
5997c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return;
600808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
6017c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
602808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final StatusBarNotification oldNotification = oldEntry.notification;
603808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final RemoteViews oldContentView = oldNotification.notification.contentView;
604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
605808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final RemoteViews contentView = notification.notification.contentView;
606808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
6077c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
60820cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        if (DEBUG) {
609808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
610808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
611808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " expanded=" + oldEntry.expanded
61220cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                    + " contentView=" + oldContentView
61320cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                    + " rowParent=" + oldEntry.row.getParent());
614808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "new notification: when=" + notification.notification.when
615808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " ongoing=" + oldNotification.isOngoing()
616808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " contentView=" + contentView);
617808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
618808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
61920cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler
620808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
621808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // didn't change.
62220cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        boolean contentsUnchanged = oldEntry.expanded != null
623808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView != null && oldContentView != null
624808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && contentView.getPackage() != null
625808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage() != null
626808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                && oldContentView.getPackage().equals(contentView.getPackage())
62720cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId();
62820cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
62920cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler        boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
63020cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                && notification.priority == oldNotification.priority;
63120cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler                // priority now encompasses isOngoing()
6327c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        boolean isFirstAnyway = rowParent.indexOfChild(oldEntry.row) == 0;
6337c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (contentsUnchanged && (orderUnchanged || isFirstAnyway)) {
63420cdb151c9f1a956eee9eebe77459e14029ad131Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
635808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            oldEntry.notification = notification;
636808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
637808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Reapply the RemoteViews
638f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
639808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // update the contentIntent
640808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final PendingIntent contentIntent = notification.notification.contentIntent;
641808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (contentIntent != null) {
6427c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                notification.pkg, notification.tag, notification.id));
644184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
645184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
646808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
647808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Update the icon.
648808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
649808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.notification.icon, notification.notification.iconLevel,
6507c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        notification.notification.number,
6517c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        notification.notification.tickerText);
652808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!oldEntry.icon.set(ic)) {
653808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
654808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    return;
655808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
656d5b858639cc32d27c003d7165969ec47288b3bfaDaniel Sandler                // Update the large icon
657d5b858639cc32d27c003d7165969ec47288b3bfaDaniel Sandler                if (notification.notification.largeIcon != null) {
658d5b858639cc32d27c003d7165969ec47288b3bfaDaniel Sandler                    oldEntry.largeIcon.setImageBitmap(notification.notification.largeIcon);
659d5b858639cc32d27c003d7165969ec47288b3bfaDaniel Sandler                } else {
6607c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    oldEntry.largeIcon.getLayoutParams().width = 0;
6617c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    oldEntry.largeIcon.setVisibility(View.INVISIBLE);
662d5b858639cc32d27c003d7165969ec47288b3bfaDaniel Sandler                }
663808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
664808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            catch (RuntimeException e) {
665808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // It failed to add cleanly.  Log, and remove the view from the panel.
666808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
667808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                removeNotificationViews(key);
668808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                addNotificationViews(key, notification);
669808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
670808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
671808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "not reusing notification");
672808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            removeNotificationViews(key);
673808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            addNotificationViews(key, notification);
674808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
675808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
676808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Restart the ticker if it's still running
677935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato        if (notification.notification.tickerText != null
678935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato                && !TextUtils.equals(notification.notification.tickerText,
679935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato                    oldEntry.notification.notification.tickerText)) {
680935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato            tick(notification);
681935865923fdad9f47061ff0aedfe92d0b912d5d6Joe Onorato        }
682808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
683808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Recalculate the position of the sliding windows and the titles.
684808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setAreThereNotifications();
685808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
686808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
687808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
688808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
689808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "removeNotification key=" + key);
690808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        StatusBarNotification old = removeNotificationViews(key);
691808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
692808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != null) {
693808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Cancel the ticker if it's still running
694808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicker.removeEntry(old);
695808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
696808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Recalculate the position of the sliding windows and the titles.
697808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setAreThereNotifications();
698808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
699808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
700808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
701808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
7023b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    @Override
7033b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    protected void onConfigurationChanged(Configuration newConfig) {
70417dfec7111fcc53a4f6ae6e92b4a7f85a278fe71Jim Miller        updateRecentsPanel();
7053b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
7063b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
7073b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
708808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
709808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Notification n = notification.notification;
710808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        RemoteViews remoteViews = n.contentView;
711808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (remoteViews == null) {
712808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
713808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
714808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
715808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // create the row view
716f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
717f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
718755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
719808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
720b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        // wire up the veto button
721b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        View vetoButton = row.findViewById(R.id.veto);
722b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        if (notification.isClearable()) {
723b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            final String _pkg = notification.pkg;
724b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            final String _tag = notification.tag;
725b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            final int _id = notification.id;
726b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            vetoButton.setOnClickListener(new View.OnClickListener() {
727b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                    public void onClick(View v) {
728b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                        try {
729b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                            mBarService.onNotificationClear(_pkg, _tag, _id);
730b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                        } catch (RemoteException ex) {
731b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                            // system process is dead if we're here.
732b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                        }
733b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                    }
734b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                });
735b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        } else {
736b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            if ((notification.notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) {
737b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                vetoButton.setVisibility(View.INVISIBLE);
738b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            } else {
739b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler                vetoButton.setVisibility(View.GONE);
740b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            }
741b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        }
742b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
743b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        // the large icon
744b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
745b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        if (notification.notification.largeIcon != null) {
746b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            largeIcon.setImageBitmap(notification.notification.largeIcon);
747b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        } else {
748b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            largeIcon.getLayoutParams().width = 0;
749b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler            largeIcon.setVisibility(View.INVISIBLE);
750b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler        }
751b48e74b10c3ef14d6c30381d8893abaddd50f2b2Daniel Sandler
752808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // bind the click event to the content area
753808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
754808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
755808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        content.setOnFocusChangeListener(mFocusChangeListener);
756808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        PendingIntent contentIntent = n.contentIntent;
757808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (contentIntent != null) {
7587c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent, notification.pkg,
759808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        notification.tag, notification.id));
760184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
761184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
762808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
763808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
764808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        View expanded = null;
765808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Exception exception = null;
766808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
767f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
768808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
769808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        catch (RuntimeException e) {
770808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            exception = e;
771808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
772808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (expanded == null) {
773808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);
774808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
775808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
776808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
777808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            content.addView(expanded);
778808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            row.setDrawingCacheEnabled(true);
779808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
780808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
781808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return new View[] { row, content, expanded };
782808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
783808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
784808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
7857c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
7867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
787808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
788808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Construct the icon.
789f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
7906179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                notification.pkg + "/0x" + Integer.toHexString(notification.id),
7916179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                notification.notification);
7927c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
7937c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
7947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
7957c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.icon,
7967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.iconLevel,
7977c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    notification.notification.number,
7986179ea3196e9306d3f14361fe9ef14191b1edba6Svetoslav Ganov                    notification.notification.tickerText);
799808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!iconView.set(ic)) {
8007c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            handleNotificationError(key, notification, "Couldn't create icon: " + ic);
8017c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return null;
8027c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8037c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Construct the expanded view.
8047c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
8057c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (!inflateViews(entry, mPile)) {
8067c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
8077c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    + notification);
808808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return null;
809808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
8107c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8117c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Add the expanded view and icon.
8127c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int pos = mNotificationData.add(entry);
8137c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
8147c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "addNotificationViews: added at " + pos);
8157c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8167c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
8177c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
818808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return iconView;
819808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
820808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
8217c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void loadNotificationShade() {
8227c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int N = mNotificationData.size();
8237c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8247c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
8257c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<N; i++) {
8277c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View row = mNotificationData.get(N-i-1).row;
8287c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            toShow.add(row);
8297c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8307c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8317c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
8327c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
8337c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View child = mPile.getChildAt(i);
8347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (!toShow.contains(child)) {
8357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                toRemove.add(child);
836808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
837808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
838808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
8397c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (View remove : toRemove) {
8407c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mPile.removeView(remove);
8417c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8427c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8437c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
8447c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View v = toShow.get(i);
8457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (v.getParent() == null) {
8467c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                mPile.addView(v, 0); // the notification shade has newest at the top
8477c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
8487c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
849808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
850808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
8517c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void reloadAllNotificationIcons() {
8527c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (mNotificationIcons == null) return;
8537c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mNotificationIcons.removeAllViews();
8547c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
8557c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
8567c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8577c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void updateNotificationIcons() {
8587c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadNotificationShade();
8597c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8607c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final LinearLayout.LayoutParams params
8617c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
862808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
8637c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int N = mNotificationData.size();
8647c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8657c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (DEBUG) {
8667c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
8677c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8687c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8697c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
8707c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8717c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<N; i++) {
8727c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            toShow.add(mNotificationData.get(N-i-1).icon);
8737c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8747c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8757c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
8767c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
8777c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View child = mNotificationIcons.getChildAt(i);
8787c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (!toShow.contains(child)) {
8797c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                toRemove.add(child);
8807c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
8817c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8827c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8837c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (View remove : toRemove) {
8847c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mNotificationIcons.removeView(remove);
8857c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8877c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
8887c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            View v = toShow.get(i);
8897c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if (v.getParent() == null) {
8907c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                mNotificationIcons.addView(v, i, params);
8917c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
8927c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
8937c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
8947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
8957c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    void workAroundBadLayerDrawableOpacity(View v) {
8967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        LayerDrawable d = (LayerDrawable)v.getBackground();
8977c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (d == null) return;
8987c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        v.setBackgroundDrawable(null);
8997c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        d.setOpacity(PixelFormat.TRANSLUCENT);
9007c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        v.setBackgroundDrawable(d);
9017c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
9027c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9037c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
9047c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        StatusBarNotification sbn = entry.notification;
9057c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        RemoteViews remoteViews = sbn.notification.contentView;
9067c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (remoteViews == null) {
9077c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return false;
9087c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9097c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9107c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // create the row view
9117c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
9127c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                Context.LAYOUT_INFLATER_SERVICE);
9137c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
9147c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        workAroundBadLayerDrawableOpacity(row);
9157c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        View vetoButton = row.findViewById(R.id.veto);
9167c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (entry.notification.isClearable()) {
9177c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            final String _pkg = sbn.pkg;
9187c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            final String _tag = sbn.tag;
9197c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            final int _id = sbn.id;
9207c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            vetoButton.setOnClickListener(new View.OnClickListener() {
9217c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    public void onClick(View v) {
9227c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        try {
9237c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                            mBarService.onNotificationClear(_pkg, _tag, _id);
9247c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        } catch (RemoteException ex) {
9257c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                            // system process is dead if we're here.
9267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        }
9277c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                    }
9287c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                });
929808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
9307c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            if ((sbn.notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) {
9317c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                vetoButton.setVisibility(View.INVISIBLE);
9327c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                vetoButton.setContentDescription("VETO");
9337c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            } else {
9347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                vetoButton.setVisibility(View.GONE);
9357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            }
936808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
9377c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        vetoButton.setContentDescription(mContext.getString(
9387c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                R.string.accessibility_remove_notification));
939808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
9407c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // the large icon
9417c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
9427c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (sbn.notification.largeIcon != null) {
9437c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            largeIcon.setImageBitmap(sbn.notification.largeIcon);
9447c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            largeIcon.setContentDescription(sbn.notification.tickerText);
9457c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        } else {
9467c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            largeIcon.getLayoutParams().width = 0;
9477c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            largeIcon.setVisibility(View.INVISIBLE);
9487c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9497c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        largeIcon.setContentDescription(sbn.notification.tickerText);
950808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
9517c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // bind the click event to the content area
9527c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
9537c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // XXX: update to allow controls within notification views
9547c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
9557c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler//        content.setOnFocusChangeListener(mFocusChangeListener);
9567c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        PendingIntent contentIntent = sbn.notification.contentIntent;
9577c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (contentIntent != null) {
9587c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent,
9597c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                        sbn.pkg, sbn.tag, sbn.id));
960808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
9617c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            content.setOnClickListener(null);
9627c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9637c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9647c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        View expanded = null;
9657c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        Exception exception = null;
9667c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        try {
9677c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            expanded = remoteViews.apply(mContext, content);
968808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
9697c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        catch (RuntimeException e) {
9707c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            exception = e;
9717c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9727c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (expanded == null) {
9737c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
9747c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
9757c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return false;
9767c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        } else {
9777c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            content.addView(expanded);
9787c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            row.setDrawingCacheEnabled(true);
9797c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9807c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9817c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        entry.row = row;
9827c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        entry.content = content;
9837c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        entry.expanded = expanded;
9847c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        entry.largeIcon = largeIcon;
9857c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        return true;
9877c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
9887c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
9897c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
9907c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationData.Entry entry = mNotificationData.remove(key);
9917c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (entry == null) {
9927c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
9937c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            return null;
9947c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
9957c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        // Remove the expanded view.
9967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
9977c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
9987c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        updateNotificationIcons();
9997c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
10007c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        return entry.notification;
10017c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
10027c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
10037c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private void setAreThereNotifications() {
10047c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mClearButton.setVisibility(mNotificationData.hasClearableItems()
10057c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                ? View.VISIBLE
10067c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                : View.INVISIBLE);
10077c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
10087c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mNoNotificationsTitle.setVisibility(mNotificationData.size() > 0
10097c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                ? View.GONE
10107c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                : View.VISIBLE);
1011808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1012808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1013808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1014808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1015808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * State is one or more of the DISABLE constants from StatusBarManager.
1016808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1017808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
1018808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int old = mDisabled;
1019808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int diff = state ^ old;
1020808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = state;
1021808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1022808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1023808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
1024808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_EXPAND: yes");
1025808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
1026808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1027808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1028808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1029808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1030808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
1031808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
1032808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
1033808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
1034808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
1035808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1036808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1037808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
1038808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
1039808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1040808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1041808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1042808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1043808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1044808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");
1045808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
1046808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1047808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1048808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1049808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1050808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1051808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * All changes to the status bar and notifications funnel through here and are batched.
1052808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1053808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class H extends Handler {
1054808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void handleMessage(Message m) {
1055808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            switch (m.what) {
1056808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE:
1057808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doAnimation();
1058808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
1059808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_ANIMATE_REVEAL:
1060808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    doRevealAnimation();
1061808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
1062808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_SHOW_INTRUDER:
1063808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(true);
1064808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
1065808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                case MSG_HIDE_INTRUDER:
1066808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setIntruderAlertVisibility(false);
1067808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    break;
10683b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                case MSG_OPEN_RECENTS_PANEL:
10693b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (DEBUG) Slog.d(TAG, "opening recents panel");
10703b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (mRecentsPanel != null) {
10713b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        disable(StatusBarManager.DISABLE_BACK);
10723b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        mRecentsPanel.setVisibility(View.VISIBLE);
10733b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        mRecentsPanel.show(true, true);
10743b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    }
10753b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    break;
10763b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                case MSG_CLOSE_RECENTS_PANEL:
10773b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (DEBUG) Slog.d(TAG, "closing recents panel");
10783b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (mRecentsPanel != null && mRecentsPanel.isShowing()) {
10793b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        disable(StatusBarManager.DISABLE_NONE);
10803b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        mRecentsPanel.show(false, true);
10813b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    }
10823b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    break;
1083808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1084808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1085808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1086808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1087808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {
1088808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onFocusChange(View v, boolean hasFocus) {
1089808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // Because 'v' is a ViewGroup, all its children will be (un)selected
1090808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // too, which allows marqueeing to work.
1091808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            v.setSelected(hasFocus);
1092808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1093808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1094808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1095808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void makeExpandedVisible() {
1096808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
1097808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedVisible) {
1098808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1099808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1100808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = true;
1101808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(true);
1102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1103808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
1104808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1105808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
1106808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1107808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedView.requestFocus(View.FOCUS_FORWARD);
1108808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.setVisibility(View.VISIBLE);
1109808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1110808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mTicking) {
1111808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
1112808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1113808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1114808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1115808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
1116808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);
1117808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1118808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
1119808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1120808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1121808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1122808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1123808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1124808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(0, true);
1125808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        performFling(0, 2000.0f, true);
1126808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1127808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1128808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
11293b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        animateCollapse(false);
11303b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
11313b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
11323b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public void animateCollapse(boolean excludeRecents) {
1133808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1134808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
1135808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedVisible=" + mExpandedVisible
1136808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpanded=" + mExpanded
1137808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimating=" + mAnimating
1138808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimY=" + mAnimY
1139808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimVel=" + mAnimVel);
1140808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1141808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
11423b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        if (!excludeRecents) {
11433b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
11443b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
11453b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
11463b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
1147808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
1148808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1149808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1150808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1151808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int y;
1152808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
1153808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            y = (int)mAnimY;
1154808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
11551dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            y = mDisplaySize.y-1;
1156808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1157808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Let the fling think that we're open so it goes in the right direction
1158808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // and doesn't try to re-open the windowshade.
1159808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
1160808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        prepareTracking(y, false);
1161808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        performFling(y, -2000.0f, true);
1162808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1163808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1164808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performExpand() {
1165808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);
1166808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1167808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return ;
1168808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1169808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1170808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1171808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1172808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1173808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = true;
1174808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        makeExpandedVisible();
1175808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        updateExpandedViewPos(EXPANDED_FULL_OPEN);
1176808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) postStartTracing();
1178808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1179808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1180808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performCollapse() {
1181808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
1182808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " mExpandedVisible=" + mExpandedVisible);
1183808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1184808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
1185808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1186808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1187808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedVisible = false;
1188808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        visibilityChanged(false);
1189808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1190808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
1191808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1192808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingView.setVisibility(View.GONE);
1193808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1194808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
1195808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1196808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1197808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
1198808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1199808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpanded) {
1200808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1201808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1202808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpanded = false;
1203808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1204808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1205808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doAnimation() {
1206808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimating) {
1207808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation");
1208808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
1209808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
1210808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
12111dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            if (mAnimY >= mDisplaySize.y-1) {
1212808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
1213808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1214808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(EXPANDED_FULL_OPEN);
1215808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performExpand();
1216808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1217808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (mAnimY < mStatusBarView.getHeight()) {
1218808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
1219808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1220808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos(0);
1221808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performCollapse();
1222808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1223808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1224808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1225808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
1226808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
1227808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1228808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1229808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1230808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1231808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void stopTracking() {
1232808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = false;
1233808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker.recycle();
1234808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = null;
1235808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1236808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1237808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void incrementAnim() {
1238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
1239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s
1240808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float y = mAnimY;
1241808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float v = mAnimVel;                                   // px/s
1242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final float a = mAnimAccel;                                 // px/s/s
1243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
1244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = v + (a*t);                                       // px/s
1245808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;                                        // ms
1246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
1247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
1248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1250808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void doRevealAnimation() {
1251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int h = mCloseView.getHeight() + mStatusBarView.getHeight();
1252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mAnimatingReveal && mAnimating && mAnimY < h) {
1253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            incrementAnim();
1254808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimY >= h) {
1255808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimY = h;
1256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1258808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateExpandedViewPos((int)mAnimY);
1259808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mCurAnimationTime += ANIM_FRAME_DURATION;
1260808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
1261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mCurAnimationTime);
1262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1263808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void prepareTracking(int y, boolean opening) {
126796e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        if (CHATTY) {
126896e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
126996e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        }
127096e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
1271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTracking = true;
1272808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mVelocityTracker = VelocityTracker.obtain();
1273808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (opening) {
1274808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimAccel = 2000.0f;
1275808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimVel = 200;
1276808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimY = mStatusBarView.getHeight();
1277808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos((int)mAnimY);
1278808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
1279808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimatingReveal = true;
1280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE);
1281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.removeMessages(MSG_ANIMATE_REVEAL);
1282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            long now = SystemClock.uptimeMillis();
1283808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimLastTime = now;
1284808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mCurAnimationTime = now + ANIM_FRAME_DURATION;
1285808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mAnimating = true;
1286808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),
1287808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mCurAnimationTime);
1288808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            makeExpandedVisible();
1289808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
1290808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // it's open, close it?
1291808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mAnimating) {
1292808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimating = false;
1293808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mHandler.removeMessages(MSG_ANIMATE);
1294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1295808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            updateExpandedViewPos(y + mViewDelta);
1296808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1297808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1299808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performFling(int y, float vel, boolean always) {
130096e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        if (CHATTY) {
130196e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel);
130296e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        }
130396e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler
1304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimatingReveal = false;
1305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1306808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimY = y;
1307808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimVel = vel;
1308808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1309808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
1310808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1311808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpanded) {
1312808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!always && (
1313808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel > 200.0f
13141dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                    || (y > (mDisplaySize.y-25) && vel > -200.0f))) {
1315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded, but they didn't move sufficiently to cause
1316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the expanded position.
1317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = 2000.0f;
1318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
1319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1320808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1321808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1322808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1323808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are expanded and are now going to animate away.
1324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = -2000.0f;
1325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
1326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else {
1330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (always || (
1331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel > 200.0f
13321dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                    || (y > (mDisplaySize.y/2) && vel > -200.0f))) {
1333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, and they moved enough to allow us to
1334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // expand.  Animate in the notifications.
1335808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = 2000.0f;
1336808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel < 0) {
1337808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1338808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1339808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1340808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else {
1341808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We are collapsed, but they didn't move sufficiently to cause
1342808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // us to retract.  Animate back to the collapsed position.
1343808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mAnimAccel = -2000.0f;
1344808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (vel > 0) {
1345808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimVel = 0;
1346808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1347808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1348808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1349808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
1350808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        //        + " mAnimAccel=" + mAnimAccel);
1351808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1352808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        long now = SystemClock.uptimeMillis();
1353808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimLastTime = now;
1354808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mCurAnimationTime = now + ANIM_FRAME_DURATION;
1355808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mAnimating = true;
1356808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE);
1357808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.removeMessages(MSG_ANIMATE_REVEAL);
1358808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);
1359808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        stopTracking();
1360808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1361808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    boolean interceptTouchEvent(MotionEvent event) {
1363808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1364808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
1365808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + mDisabled);
136696e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler        } else if (CHATTY) {
136796e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            if (event.getAction() == MotionEvent.ACTION_DOWN) {
136896e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler                Slog.d(TAG, String.format(
13696cf602cd1de4fd1b6a8a5028ef10df0ffc57bacbDaniel Sandler                            "panel: ACTION_DOWN at (%f, %f) mDisabled=0x%08x",
137096e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler                            event.getRawX(), event.getRawY(), mDisabled));
137196e61c3c86b2aff3d298d8757ba51eb568c30543Daniel Sandler            }
1372808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1373808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1374808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1375808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return false;
1376808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1377808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1378808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int statusBarSize = mStatusBarView.getHeight();
1379808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        final int hitSize = statusBarSize*2;
1380808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (event.getAction() == MotionEvent.ACTION_DOWN) {
1381808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int y = (int)event.getRawY();
1382808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1383808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!mExpanded) {
1384808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mViewDelta = statusBarSize - y;
1385808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1386808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTrackingView.getLocationOnScreen(mAbsPos);
1387808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
1388808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1389808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((!mExpanded && y < hitSize) ||
13901dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                    (mExpanded && y > (mDisplaySize.y-hitSize))) {
1391808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1392808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // We drop events at the edge of the screen to make the windowshade come
1393808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // down by accident less, especially when pushing open a device with a keyboard
1394808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // that rotates (like g1 and droid)
1395808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int x = (int)event.getRawX();
1396808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                final int edgeBorder = mEdgeBorder;
13971dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                if (x >= edgeBorder && x < mDisplaySize.x - edgeBorder) {
1398808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    prepareTracking(y, !mExpanded);// opening if we're not already fully visible
1399808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mVelocityTracker.addMovement(event);
1400808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1401808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1402808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if (mTracking) {
1403808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mVelocityTracker.addMovement(event);
1404808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            final int minY = statusBarSize + mCloseView.getHeight();
1405808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (event.getAction() == MotionEvent.ACTION_MOVE) {
1406808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int y = (int)event.getRawY();
1407808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mAnimatingReveal && y < minY) {
1408808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // nothing
1409808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else  {
1410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mAnimatingReveal = false;
1411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    updateExpandedViewPos(y + mViewDelta);
1412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else if (event.getAction() == MotionEvent.ACTION_UP) {
1414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mVelocityTracker.computeCurrentVelocity(1000);
1415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float yVel = mVelocityTracker.getYVelocity();
1417808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                boolean negative = yVel < 0;
1418808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1419808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float xVel = mVelocityTracker.getXVelocity();
1420808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (xVel < 0) {
1421808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    xVel = -xVel;
1422808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1423808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (xVel > 150.0f) {
1424808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    xVel = 150.0f; // limit how much we care about the x axis
1425808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1426808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1427808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                float vel = (float)Math.hypot(yVel, xVel);
1428808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (negative) {
1429808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    vel = -vel;
1430808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1431808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1432808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                performFling((int)event.getRawY(), vel, false);
1433808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1434808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1435808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1436808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return false;
1437808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1438808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
143960ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    @Override // CommandQueue
144060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    public void setSystemUiVisibility(int vis) {
144160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        if (vis != mSystemUiVisibility) {
144260ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            mSystemUiVisibility = vis;
144360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
144460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            if (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
144560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler                animateCollapse();
144660ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            }
144760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
144860ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            notifyUiVisibilityChanged();
144960ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        }
145060ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    }
145160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler
14529305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
145360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        Log.v(TAG, "setLightsOn(" + on + ")");
145460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        if (on) {
145560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            setSystemUiVisibility(mSystemUiVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
145660ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler        } else {
145760ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            setSystemUiVisibility(mSystemUiVisibility | View.SYSTEM_UI_FLAG_LOW_PROFILE);
14589305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato        }
14591d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    }
14601d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
146160ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    private void notifyUiVisibilityChanged() {
14621d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        try {
146360ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler            mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
14641d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        } catch (RemoteException ex) {
14651d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler        }
14669305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
14679305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
14685c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    public void topAppWindowChanged(boolean showMenu) {
14695c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (DEBUG) {
14705c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler            Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
14715c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
14725c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (mNavigationBarView != null) {
14735c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler            mNavigationBarView.getMenuButton().setVisibility(showMenu
14745c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler                ? View.VISIBLE : View.INVISIBLE);
14755c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        }
14765c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
14775c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        // See above re: lights-out policy for legacy apps.
14785c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler        if (showMenu) setLightsOn(true);
14795c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler    }
14805c8da949804ed4b55dcebae63796714e0028b488Daniel Sandler
1481e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    // Not supported
1482857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { }
14832992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown    @Override
14842992ea782fa61780d8e0de7a36a2a84622f8694bJeff Brown    public void setHardKeyboardStatus(boolean available, boolean enabled) { }
1485e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
14867c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
14877c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        return new NotificationClicker(intent, pkg, tag, id);
14887c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
14897c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
14907c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    private class NotificationClicker implements View.OnClickListener {
1491808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private PendingIntent mIntent;
1492808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mPkg;
1493808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private String mTag;
1494808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        private int mId;
1495808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
14967c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
1497808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIntent = intent;
1498808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPkg = pkg;
1499808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTag = tag;
1500808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mId = id;
1501808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1502808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1503808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
1504808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1505808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // The intent we are sending is for the application, which
1506808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // won't have permission to immediately start an activity after
1507808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // the user switches to home.  We know it is safe to do at this
1508808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // point, so make sure new activity switches are now allowed.
1509808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ActivityManagerNative.getDefault().resumeAppSwitches();
1510808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException e) {
1511808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1512808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mIntent != null) {
1514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                int[] pos = new int[2];
1515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                v.getLocationOnScreen(pos);
1516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Intent overlay = new Intent();
1517808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                overlay.setSourceBounds(
1518808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
1519808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                try {
1520f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
1521808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } catch (PendingIntent.CanceledException e) {
1522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    // the stack trace isn't very helpful here.  Just log the exception message.
1523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    Slog.w(TAG, "Sending contentIntent failed: " + e);
1524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1525808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1526808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onNotificationClick(mPkg, mTag, mId);
1529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // system process is dead if we're here.
1531808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1533808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // close the shade if it was open
1534808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            animateCollapse();
1535808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // If this click was on the intruder alert, hide that instead
1537808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
1538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1539808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1540808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1541808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void tick(StatusBarNotification n) {
1542808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Show the ticker if one is requested. Also don't do this
1543808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // until status bar window is attached to the window manager,
1544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // because...  well, what's the point otherwise?  And trying to
1545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // run a ticker without being attached will crash!
1546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) {
1547808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
1548808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
1549808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.addEntry(n);
1550808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1551808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1552808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1553808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
1556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * about the failure.
1557808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
1558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * WARNING: this will call back into us.  Don't hold any locks.
1559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
1561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        removeNotification(key);
1562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        try {
1563808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
1564808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } catch (RemoteException ex) {
1565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // The end is nigh.
1566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1568808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1569808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private class MyTicker extends Ticker {
1570dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        MyTicker(Context context, View sb) {
1571808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            super(context, sb);
1572808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1573808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1574808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1575dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerStarting() {
1576808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = true;
1577808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.GONE);
1578808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.VISIBLE);
1579808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
1580808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
1581808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1582808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(false, com.android.internal.R.anim.push_up_out);
1583808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1584808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1585808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1586808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        @Override
1587dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerDone() {
1588808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1589808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1590808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
1591808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
1592808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1593808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1594808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(true, com.android.internal.R.anim.push_down_in);
1595808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1596808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1597808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1598dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        public void tickerHalting() {
1599808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.setVisibility(View.VISIBLE);
1600808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.setVisibility(View.GONE);
1601808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
1602808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
1603808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTickingDoneListener));
1604808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedVisible) {
1605808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                setDateViewVisibility(true, com.android.internal.R.anim.fade_in);
1606808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1607808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1608808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1609808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1610808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
1611808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationEnd(Animation animation) {
1612808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mTicking = false;
1613808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1614808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationRepeat(Animation animation) {
1615808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1616808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onAnimationStart(Animation animation) {
1617808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1618808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1619808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1620808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private Animation loadAnim(int id, Animation.AnimationListener listener) {
1621f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        Animation anim = AnimationUtils.loadAnimation(mContext, id);
1622808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (listener != null) {
1623808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            anim.setAnimationListener(listener);
1624808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1625808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return anim;
1626808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1627808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1628808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public String viewInfo(View v) {
1629808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
1630808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                + " " + v.getWidth() + "x" + v.getHeight() + ")";
1631808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1632808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1633f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1634808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        synchronized (mQueueLock) {
1635808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("Current Status Bar state:");
1636808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpanded=" + mExpanded
1637808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mExpandedVisible=" + mExpandedVisible);
1638808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTicking=" + mTicking);
1639808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTracking=" + mTracking);
1640808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mAnimating=" + mAnimating
1641808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
1642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + ", mAnimAccel=" + mAnimAccel);
1643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCurAnimationTime=" + mCurAnimationTime
1644808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mAnimLastTime=" + mAnimLastTime);
16451dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            pw.println("  mAnimatingReveal=" + mAnimatingReveal
1646808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mViewDelta=" + mViewDelta);
16471dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            pw.println("  mDisplaySize=" + mDisplaySize);
1648808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedParams: " + mExpandedParams);
1649808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedView: " + viewInfo(mExpandedView));
1650808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mExpandedDialog: " + mExpandedDialog);
1651808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTrackingParams: " + mTrackingParams);
1652808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTrackingView: " + viewInfo(mTrackingView));
16537c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            pw.println("  mPile: " + viewInfo(mPile));
1654808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
1655808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mCloseView: " + viewInfo(mCloseView));
1656808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mTickerView: " + viewInfo(mTickerView));
1657808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  mScrollView: " + viewInfo(mScrollView)
1658808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
1659808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));
1660808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1661808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /*
1662808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        synchronized (mNotificationData) {
1663808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int N = mNotificationData.ongoingCount();
1664808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  ongoingCount.size=" + N);
1665808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (int i=0; i<N; i++) {
1666808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                StatusBarNotification n = mNotificationData.getOngoing(i);
1667808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
1668808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("           data=" + n.data);
1669808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1670808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            N = mNotificationData.latestCount();
1671808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("  ongoingCount.size=" + N);
1672808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            for (int i=0; i<N; i++) {
1673808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                StatusBarNotification n = mNotificationData.getLatest(i);
1674808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
1675808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pw.println("           data=" + n.data);
1676808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1677808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1678808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        */
1679808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1680808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) {
1681808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pw.println("see the logcat for a dump of the views we have created.");
1682808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // must happen on ui thread
1683808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.post(new Runnable() {
1684808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    public void run() {
1685808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mStatusBarView.getLocationOnScreen(mAbsPos);
1686808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1687808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mStatusBarView.getWidth() + "x"
1688808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mStatusBarView.getHeight());
1689808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mStatusBarView.debug();
1690808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1691808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mExpandedView.getLocationOnScreen(mAbsPos);
1692808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1693808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mExpandedView.getWidth() + "x"
1694808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mExpandedView.getHeight());
1695808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mExpandedView.debug();
1696808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1697808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTrackingView.getLocationOnScreen(mAbsPos);
1698808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
1699808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + ") " + mTrackingView.getWidth() + "x"
1700808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                + mTrackingView.getHeight());
1701808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                        mTrackingView.debug();
1702808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    }
1703808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                });
1704808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1705808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1706808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1707808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void onBarViewAttached() {
1708808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp;
1709808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pixelFormat;
1710808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        Drawable bg;
1711808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1712808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /// ---------- Tracking View --------------
1713808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        pixelFormat = PixelFormat.RGBX_8888;
1714808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        bg = mTrackingView.getBackground();
1715808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (bg != null) {
1716808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pixelFormat = bg.getOpacity();
1717808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1718808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1719808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp = new WindowManager.LayoutParams(
1720808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1721808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
172229fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato                WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
1723808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1724808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1725808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
1726808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pixelFormat);
1727808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato//        lp.token = mStatusBarView.getWindowToken();
1728808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
1729808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("TrackingView");
1730808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.y = mTrackingPosition;
1731808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingParams = lp;
1732808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1733808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().addView(mTrackingView, lp);
1734808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1735808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1736808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void onTrackingViewAttached() {
1737808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManager.LayoutParams lp;
1738808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pixelFormat;
1739808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1740808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        /// ---------- Expanded View --------------
1741808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        pixelFormat = PixelFormat.TRANSLUCENT;
1742808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1743808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp = mExpandedDialog.getWindow().getAttributes();
1744808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.x = 0;
17451dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mTrackingPosition = lp.y = mDisplaySize.y; // sufficiently large negative
174629fc2c9705e1bb8ae098fca016032d2325031587Joe Onorato        lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
1747808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1748808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1749808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1750808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_DITHER
1751808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
1752808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.format = pixelFormat;
1753808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
1754808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        lp.setTitle("StatusBarExpanded");
1755808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedParams = lp;
17561dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        updateExpandedSize();
17571dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mExpandedDialog.getWindow().setFormat(pixelFormat);
1758808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1759808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
1760808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.setContentView(mExpandedView,
1761808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1762808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                                           ViewGroup.LayoutParams.MATCH_PARENT));
1763808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.getWindow().setBackgroundDrawable(null);
1764808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mExpandedDialog.show();
1765808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1766808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1767808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void setDateViewVisibility(boolean visible, int anim) {
1768808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
1769808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDateView.startAnimation(loadAnim(anim, null));
1770808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1771808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1772808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void setNotificationIconVisibility(boolean visible, int anim) {
1773808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mNotificationIcons.getVisibility();
1774808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int v = visible ? View.VISIBLE : View.INVISIBLE;
1775808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (old != v) {
1776808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.setVisibility(v);
1777808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mNotificationIcons.startAnimation(loadAnim(anim, null));
1778808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1779808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1780808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
17811dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateExpandedInvisiblePosition() {
17821dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        if (mTrackingView != null) {
17831dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            mTrackingPosition = -mDisplaySize.y;
17841dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            if (mTrackingParams != null) {
17851dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mTrackingParams.y = mTrackingPosition;
17861dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
17871dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            }
17881dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        }
17891dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        if (mExpandedParams != null) {
17901dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            mExpandedParams.y = -mDisplaySize.y;
17911dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
17921dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        }
17931dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    }
17941dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
1795808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateExpandedViewPos(int expandedPosition) {
1796808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1797808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition
1798808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingParams.y=" + mTrackingParams.y
1799808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingPosition=" + mTrackingPosition);
1800808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1801808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1802808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int h = mStatusBarView.getHeight();
18031dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        int disph = mDisplaySize.y;
1804808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1805808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // If the expanded view is not visible, make sure they're still off screen.
1806808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // Maybe the view was resized.
1807808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (!mExpandedVisible) {
18081dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            updateExpandedInvisiblePosition();
1809808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            return;
1810808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1811808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1812808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // tracking view...
1813808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int pos;
1814808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (expandedPosition == EXPANDED_FULL_OPEN) {
1815808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos = h;
1816808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1817808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else if (expandedPosition == EXPANDED_LEAVE_ALONE) {
1818808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos = mTrackingPosition;
1819808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1820808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        else {
1821808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (expandedPosition <= disph) {
1822808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pos = expandedPosition;
1823808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1824808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                pos = disph;
1825808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1826808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            pos -= disph-h;
1827808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1828808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingPosition = mTrackingParams.y = pos;
1829808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mTrackingParams.height = disph-h;
1830808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);
1831808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1832808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mExpandedParams != null) {
18331dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            if (mCloseView.getWindowVisibility() == View.VISIBLE) {
18341dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mCloseView.getLocationInWindow(mPositionTmp);
18351dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                final int closePos = mPositionTmp[1];
1836808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18371dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mExpandedContents.getLocationInWindow(mPositionTmp);
18381dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight();
1839808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18401dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mExpandedParams.y = pos + mTrackingView.getHeight()
18411dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                        - (mTrackingParams.height-closePos) - contentsBottom;
18421dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            } else {
18431dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                // If the tracking view is not yet visible, then we can't have
18441dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                // a good value of the close view location.  We need to wait for
18451dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                // it to be visible to do a layout.
18461dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mExpandedParams.y = -mDisplaySize.y;
18471dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            }
1848808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int max = h;
1849808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedParams.y > max) {
1850808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = max;
1851808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1852808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            int min = mTrackingPosition;
1853808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mExpandedParams.y < min) {
1854808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = min;
1855808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1856808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1857808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h;
1858808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (!visible) {
1859808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // if the contents aren't visible, move the expanded view way off screen
1860808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // because the window itself extends below the content view.
1861808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mExpandedParams.y = -disph;
1862808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1863808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mExpandedDialog.getWindow().setAttributes(mExpandedParams);
1864808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1865808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // As long as this isn't just a repositioning that's not supposed to affect
1866808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // the user's perception of what's showing, call to say that the visibility
1867808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            // has changed. (Otherwise, someone else will call to do that).
1868808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (expandedPosition != EXPANDED_LEAVE_ALONE) {
1869808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");
1870808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                visibilityChanged(visible);
1871808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1872808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1873808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1874808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (SPEW) {
1875808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition
1876808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingParams.y=" + mTrackingParams.y
1877808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mTrackingPosition=" + mTrackingPosition
1878808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedParams.y=" + mExpandedParams.y
1879808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    + " mExpandedParams.height=" + mExpandedParams.height);
1880808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1881808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1882808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18831dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    int getExpandedHeight(int disph) {
18841dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        return disph - mStatusBarView.getHeight() - mCloseView.getHeight();
1885808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1886808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
18871dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateDisplaySize() {
18881dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        mDisplay.getSize(mDisplaySize);
18891dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn        updateExpandedSize();
18901dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    }
18911dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn
18921dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn    void updateExpandedSize() {
1893f48fd822e055da272f9e821db56db98591a35cfeDaniel Sandler        if (mExpandedDialog != null && mExpandedParams != null && mDisplaySize != null) {
18941dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            mExpandedParams.width = mDisplaySize.x;
18951dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            mExpandedParams.height = getExpandedHeight(mDisplaySize.y);
18961dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            if (!mExpandedVisible) {
18971dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                updateExpandedInvisiblePosition();
18981dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            } else {
18991dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn                mExpandedDialog.getWindow().setAttributes(mExpandedParams);
19001dacf2772d0099ae74f42f81d162a3d0e180ffb7Dianne Hackborn            }
1901808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1902808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1903808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
190460ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    // The user is not allowed to get stuck without navigation UI. Upon the slightest user
190560ee25643e0a7b8841063a4e97b0f18c51807e91Daniel Sandler    // interaction we bring the navigation back.
19061d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    public void userActivity() {
1907f3f2011285e2f5079db2229461e2d9a448cb61ecDaniel Sandler        if (mNavigationBarView != null) {
1908f3f2011285e2f5079db2229461e2d9a448cb61ecDaniel Sandler            mNavigationBarView.setHidden(false);
1909f3f2011285e2f5079db2229461e2d9a448cb61ecDaniel Sandler        }
19101d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler    }
19111d4d30aebd2c22627131819cabfe95f97def2c83Daniel Sandler
19123b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public void toggleRecentApps() {
19133b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        int msg = (mRecentsPanel.getVisibility() == View.GONE)
19143b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                ? MSG_OPEN_RECENTS_PANEL : MSG_CLOSE_RECENTS_PANEL;
19153b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        mHandler.removeMessages(msg);
19163b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        mHandler.sendEmptyMessage(msg);
19173b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
19183b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
1919808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
1920808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
1921808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * This was added last-minute and is inconsistent with the way the rest of the notifications
1922808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * are handled, because the notification isn't really cancelled.  The lights are just
1923808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * turned off.  If any other notifications happen, the lights will turn back on.  Steve says
1924808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * this is what he wants. (see bug 1131461)
1925808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
1926808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void visibilityChanged(boolean visible) {
1927808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (mPanelSlightlyVisible != visible) {
1928808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mPanelSlightlyVisible = visible;
1929808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1930808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onPanelRevealed();
1931808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1932808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // Won't fail unless the world has ended.
1933808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1934808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1935808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1936808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1937808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void performDisableActions(int net) {
1938808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int old = mDisabled;
1939808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        int diff = net ^ old;
1940808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mDisabled = net;
1941808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1942808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // act accordingly
1943808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
1944808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
1945808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_EXPAND: yes");
1946808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                animateCollapse();
1947808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1948808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1949808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1950808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
1951808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
1952808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (mTicking) {
1953808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mNotificationIcons.setVisibility(View.INVISIBLE);
1954808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    mTicker.halt();
1955808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                } else {
1956808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
1957808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1958808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } else {
1959808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
1960808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                if (!mExpandedVisible) {
1961808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
1962808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                }
1963808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1964808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1965808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
1966808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mTicker.halt();
1967808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1968808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1969808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
1970808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1971808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
1972808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onClick(View v) {
1973808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            try {
1974808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                mBarService.onClearAllNotifications();
1975808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            } catch (RemoteException ex) {
1976808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                // system process is dead if we're here.
1977808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1978808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            animateCollapse();
1979808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
1980808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
1981808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
1982808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1983808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void onReceive(Context context, Intent intent) {
1984808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            String action = intent.getAction();
1985808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
1986808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
19873b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                boolean excludeRecents = false;
19883b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
1989edbdd3a024ca35c331036823dde1f484d3333b31Daniel Sandler                    String reason = intent.getStringExtra("reason");
19903b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    if (reason != null) {
19913b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                        excludeRecents = reason.equals("recentapps");
19923b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    }
19933b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                }
19943b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                animateCollapse(excludeRecents);
1995808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
1996808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
19978956dbbc5f292d8b79072ae73b25f2114c8c7479Daniel Sandler                repositionNavigationBar();
1998808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato                updateResources();
1999808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            }
2000808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2001808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2002808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2003808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    private void setIntruderAlertVisibility(boolean vis) {
2004808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
2005808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2006808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2007808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    /**
2008808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * Reload some of our resources when the configuration changes.
2009808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     *
2010808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * We don't reload everything when the configuration changes -- we probably
2011808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * should, but getting that smooth is tough.  Someday we'll fix that.  In the
2012808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     * meantime, just update the things that we know change.
2013808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato     */
2014808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void updateResources() {
2015f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
2016f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
2017808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
20181347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        if (mClearButton instanceof TextView) {
20191347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler            ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button));
20201347c30824ce3544dff03c93ffad9af7f0327e41Daniel Sandler        }
2021f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNoNotificationsTitle.setText(context.getText(R.string.status_bar_no_notifications_title));
2022808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
20237c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        loadDimens();
20247c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    }
20257c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20267c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler    protected void loadDimens() {
20277c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        final Resources res = mContext.getResources();
20287c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20297c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        mNaturalBarHeight = res.getDimensionPixelSize(
20307c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler                com.android.internal.R.dimen.status_bar_height);
20317c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20327c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int newIconSize = res.getDimensionPixelSize(
20337c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            com.android.internal.R.dimen.status_bar_icon_size);
20347c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        int newIconHPadding = res.getDimensionPixelSize(
20357c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            R.dimen.status_bar_icon_padding);
20367c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
20377c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
20387c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
20397c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mIconHPadding = newIconHPadding;
20407c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            mIconSize = newIconSize;
20417c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler            //reloadAllNotificationIcons(); // reload the tray
20427c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler        }
20437c3e39de22c68e69c4924b339132f8e3bf3f96afDaniel Sandler
2044808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
2045808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2046808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        if (false) Slog.v(TAG, "updateResources");
2047808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2048808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2049808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
2050808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    // tracing
2051808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    //
2052808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2053808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void postStartTracing() {
2054808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mHandler.postDelayed(mStartTracing, 3000);
2055808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2056808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2057808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    void vibrate() {
2058f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
2059f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.VIBRATOR_SERVICE);
2060808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        vib.vibrate(250);
2061808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
2062808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2063808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStartTracing = new Runnable() {
2064808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
2065808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
2066808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            SystemClock.sleep(250);
2067808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "startTracing");
2068808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
2069808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            mHandler.postDelayed(mStopTracing, 10000);
2070808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2071808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
2072808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2073808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    Runnable mStopTracing = new Runnable() {
2074808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        public void run() {
2075808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            android.os.Debug.stopMethodTracing();
2076808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            Slog.d(TAG, "stopTracing");
2077808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            vibrate();
2078808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        }
2079808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    };
20803b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
20813b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    public class TouchOutsideListener implements View.OnTouchListener {
20823b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        private int mMsg;
20833b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        private RecentsPanelView mPanel;
20843b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
20853b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        public TouchOutsideListener(int msg, RecentsPanelView panel) {
20863b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mMsg = msg;
20873b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            mPanel = panel;
20883b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
20893b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka
20903b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        public boolean onTouch(View v, MotionEvent ev) {
20913b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            final int action = ev.getAction();
20923b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            if (action == MotionEvent.ACTION_OUTSIDE
20933b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                || (action == MotionEvent.ACTION_DOWN
20943b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                    && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
20953b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                mHandler.removeMessages(mMsg);
20963b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                mHandler.sendEmptyMessage(mMsg);
20973b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka                return true;
20983b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            }
20993b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka            return false;
21003b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka        }
21013b1fc47d004f6b29af8f40d181baa3460b1e3b15Michael Jurka    }
2102808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
2103808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2104