TabletStatusBar.java revision 536c58fbe51a53d0e6e78c360c9f6069ae0fd465
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
17808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratopackage com.android.systemui.statusbar.tablet;
18808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
19f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onoratoimport java.io.FileDescriptor;
20f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onoratoimport java.io.PrintWriter;
21b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport java.util.ArrayList;
22b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport java.util.Map;
23b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport java.util.IdentityHashMap;
24f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
25b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.LayoutTransition;
26b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.ObjectAnimator;
27b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport android.animation.AnimatorSet;
28dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.ActivityManagerNative;
29dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.PendingIntent;
30ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.app.Notification;
31dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.StatusBarManager;
32808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
34808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.res.Resources;
359120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.graphics.PixelFormat;
36dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.graphics.Rect;
374daaeafd278d22ec9013d1cdaade562044ee907eJoe Onoratoimport android.graphics.drawable.Drawable;
384daaeafd278d22ec9013d1cdaade562044ee907eJoe Onoratoimport android.graphics.drawable.LayerDrawable;
399120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.os.Handler;
40808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
413eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.os.Message;
42dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.os.RemoteException;
43ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.text.TextUtils;
443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.util.Slog;
4555d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onoratoimport android.view.animation.Animation;
46ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandlerimport android.view.animation.AnimationUtils;
47808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.view.LayoutInflater;
49b62ac127824e9723534a197189eca58d30f15d3dJoe Onoratoimport android.view.MotionEvent;
508304da460f95c0883eca0d97fcdc4eb42c10f7c2Daniel Sandlerimport android.view.VelocityTracker;
51808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
52b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.view.ViewConfiguration;
539120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.ViewGroup;
549120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManager;
559120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManagerImpl;
56ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.FrameLayout;
573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.widget.ImageView;
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
59dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.RemoteViews;
60dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.ScrollView;
61dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.TextSwitcher;
629120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.widget.TextView;
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
64808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
65808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
66808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
67fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.R;
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.statusbar.*;
69fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.BatteryController;
70fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.NetworkController;
71013cfc1116e3382981aa0da903d97fc4fdb2c791Joe Onoratoimport com.android.systemui.recent.RecentApplicationsActivity;
72808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
73fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopublic class TabletStatusBar extends StatusBar {
74fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler    public static final boolean DEBUG = false;
75fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    public static final String TAG = "TabletStatusBar";
76808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
77b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
78b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
79b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
80b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
8144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_OPEN_RECENTS_PANEL = 1020;
8244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_CLOSE_RECENTS_PANEL = 1021;
83b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int MSG_HIDE_SHADOWS = 1030;
84b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int MSG_SHOW_SHADOWS = 1031;
85e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler    public static final int MSG_RESTORE_SHADOWS = 1032;
8644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
87d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler    private static final int MAX_IMAGE_LEVEL = 10000;
8844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private static final boolean USE_2D_RECENTS = true;
89d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
90b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int LIGHTS_ON_DELAY = 5000;
91b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
92808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mIconSize;
939120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
949120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    H mHandler = new H();
959120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
96dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // tracking all current notifications
97dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    private NotificationData mNotns = new NotificationData();
9844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
99b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    TabletStatusBarView mStatusBarView;
100fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationArea;
101fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationTrigger;
102dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    NotificationIconArea mNotificationIconArea;
103091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    View mNavigationArea;
104b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
105536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato    ImageView mBackButton;
106b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mHomeButton;
107e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    View mMenuButton;
108f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    View mRecentButton;
109dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
110cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    InputMethodButton mInputMethodSwitchButton;
111cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    InputMethodButton mInputMethodShortcutButton;
11206487a58be22b100daf3f950b9a1d25c3ea42aa2satok
113ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato    NotificationPanel mNotificationPanel;
1148a576713e255eb822558cef840d170d4477f47f0Joe Onorato    NotificationPeekPanel mNotificationPeekWindow;
115b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    ViewGroup mNotificationPeekRow;
116b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekIndex;
117b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
118b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
119b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekTapDuration;
120b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationFlingVelocity;
1213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1220f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    ViewGroup mPile;
1233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
124fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    BatteryController mBatteryController;
125fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    NetworkController mNetworkController;
1261e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
127ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    View mBarContents;
128b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
129b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    // lights out support
130b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mBackShadow, mHomeShadow, mRecentShadow, mMenuShadow, mNotificationShadow;
131b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    ShadowController mShadowController;
132ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1330f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    NotificationIconArea.IconLayout mIconLayout;
1340f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
135ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    TabletTicker mTicker;
136dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
137dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // for disabling the status bar
138dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    int mDisabled = 0;
139dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
14055d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato    boolean mNotificationsOn = true;
14144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private RecentAppsPanel mRecentsPanel;
14255d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
1439120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    protected void addPanelWindows() {
144f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
145f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
146f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
1479120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        final int barHeight= res.getDimensionPixelSize(
148755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                com.android.internal.R.dimen.status_bar_height);
1499120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
15044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Notification Panel
151f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationPanel = (NotificationPanel)View.inflate(context,
152755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_panel, null);
153d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler        mNotificationPanel.setVisibility(View.GONE);
154b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mNotificationPanel.setOnTouchListener(
155ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
156b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
157fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the battery and network icons
158fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
159fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addLabelView(
160fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.battery_text));
161ddbba42b812ab397a75db78aba6b48fecf0e31f6Joe Onorato        mNetworkController.addCombinedSignalIconView(
162fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network));
163fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addLabelView(
164fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.network_text));
165fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
16655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
167d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1689120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1694cddc98a4b63961e3528c5a70cd5c55a67a0c60aJoe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
170cf2b199e98de71dcac042484800c07366363a734Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1719120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
1729120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
17346e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
17446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
1759120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                PixelFormat.TRANSLUCENT);
176ea70e63c0dcd09ec5790f4dca6ddd76284a6a23dJoe Onorato        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
1779120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        lp.setTitle("NotificationPanel");
1789120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
1799120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
1809120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
181b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // Notification preview window
1828a576713e255eb822558cef840d170d4477f47f0Joe Onorato        mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
183755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_peek, null);
184b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
185b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setVisibility(View.GONE);
186b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setOnTouchListener(
1875e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow));
188b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight = new LayoutTransition();
189b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING,
190b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
191b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING,
192b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
193b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setDuration(500);
194b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
195b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft = new LayoutTransition();
196b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING,
197b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
198b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING,
199b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
200b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setDuration(500);
201b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
202b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // XXX: setIgnoreChildren?
203b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp = new WindowManager.LayoutParams(
204b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                512, // ViewGroup.LayoutParams.WRAP_CONTENT,
205b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ViewGroup.LayoutParams.WRAP_CONTENT,
206b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
207b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
20846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
20946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
210b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                PixelFormat.TRANSLUCENT);
211b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
212b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.setTitle("NotificationPeekWindow");
213b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
214b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
215b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
216b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
21744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Recents Panel
21844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (USE_2D_RECENTS) {
219755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato            mRecentsPanel = (RecentAppsPanel) View.inflate(context,
220755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                    R.layout.status_bar_recent_panel, null);
22144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setVisibility(View.GONE);
22244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
22344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    mRecentsPanel));
22444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
22544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
22644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp = new WindowManager.LayoutParams(
22744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
22844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
22944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
23044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
23146e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
23246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
23344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    PixelFormat.TRANSLUCENT);
23444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
23544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.setTitle("RecentsPanel");
236fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            lp.windowAnimations = R.style.Animation_RecentPanel;
23744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
23844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
23944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setBar(this);
24044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
2419120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
244f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
245f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start(); // will add the main bar view
246808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
249f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
250f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
251808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
254b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
255f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                context, R.layout.status_bar, null);
256808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusBarView = sb;
257808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
258b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        sb.setHandler(mHandler);
259b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
260ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        mBarContents = sb.findViewById(R.id.bar_contents);
261f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
262fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the whole right-hand side of the bar
263fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationArea = sb.findViewById(R.id.notificationArea);
264fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
26555d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // the button to open the notification area
266fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
267f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationTrigger.setOnClickListener(mOnClickListener);
26855d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // the more notifications icon
270808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
271808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // where the icons go
2733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
274b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
275b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
276b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ViewConfiguration vc = ViewConfiguration.get(context);
277b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekTapDuration = vc.getTapTimeout();
278b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationFlingVelocity = 300; // px/s
2793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
28052f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        mTicker = new TabletTicker(context);
281dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
282fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // The icons
283fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController = new BatteryController(mContext);
284fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
285fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController = new NetworkController(mContext);
286ddbba42b812ab397a75db78aba6b48fecf0e31f6Joe Onorato        mNetworkController.addCombinedSignalIconView((ImageView)sb.findViewById(R.id.network));
2871e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
288091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // The navigation buttons
289091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        mNavigationArea = sb.findViewById(R.id.navigationArea);
290536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton = (ImageView)mNavigationArea.findViewById(R.id.back);
291b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeButton = mNavigationArea.findViewById(R.id.home);
292e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        mMenuButton = mNavigationArea.findViewById(R.id.menu);
293b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
294b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        Slog.d(TAG, "rec=" + mRecentButton + ", listener=" + mOnClickListener);
295b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton.setOnClickListener(mOnClickListener);
296091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
29706487a58be22b100daf3f950b9a1d25c3ea42aa2satok        // The bar contents buttons
298cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton = (InputMethodButton) sb.findViewById(R.id.imeSwitchButton);
299cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodShortcutButton = (InputMethodButton) sb.findViewById(R.id.imeShortcutButton);
30006487a58be22b100daf3f950b9a1d25c3ea42aa2satok
301b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // "shadows" of the status bar features, for lights-out mode
302b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mBackShadow = sb.findViewById(R.id.back_shadow);
303b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mHomeShadow = sb.findViewById(R.id.home_shadow);
304b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mRecentShadow = sb.findViewById(R.id.recent_shadow);
305b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mMenuShadow = sb.findViewById(R.id.menu_shadow);
306b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mNotificationShadow = sb.findViewById(R.id.notification_shadow);
307b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
308b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController = new ShadowController(false);
309b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController.add(mBackButton, mBackShadow);
310b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController.add(mHomeButton, mHomeShadow);
311b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController.add(mRecentButton, mRecentShadow);
312b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController.add(mMenuButton, mMenuShadow);
313b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        mShadowController.add(mNotificationArea, mNotificationShadow);
314b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
3155dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        // set the initial view visibility
3165dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
317271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
3185dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
319dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Add the windows
320dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        addPanelWindows();
321dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
322dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
323dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile.removeAllViews();
32444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
325dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        ScrollView scroller = (ScrollView)mPile.getParent();
326dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        scroller.setFillViewport(true);
327dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
331808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
332808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
333808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
334808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3359120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    private class H extends Handler {
3369120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        public void handleMessage(Message m) {
3379120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            switch (m.what) {
338b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_OPEN_NOTIFICATION_PEEK:
339b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
340b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (m.arg1 >= 0) {
341b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int N = mNotns.size();
342b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (mNotificationPeekIndex < N) {
343b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
344b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0);
345b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
346b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
347b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int peekIndex = m.arg1;
348b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (peekIndex < N) {
349b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            Slog.d(TAG, "loading peek: " + peekIndex);
350b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
351b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry copy = new NotificationData.Entry(
352b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.key,
353b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.notification,
354b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.icon);
355b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            inflateViews(copy, mNotificationPeekRow);
356b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
357b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0x20FFFFFF);
358b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
359b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                          mNotificationPeekRow.setLayoutTransition(
360b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                              peekIndex < mNotificationPeekIndex
361b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  ? mNotificationPeekScrubLeft
362b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  : mNotificationPeekScrubRight);
363b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
364b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.removeAllViews();
365b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.addView(copy.row);
366b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
367b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekWindow.setVisibility(View.VISIBLE);
368b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPanel.setVisibility(View.GONE);
369b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
370b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekIndex = peekIndex;
371b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
372b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
373b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
374b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_CLOSE_NOTIFICATION_PEEK:
375b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notification peek window");
376b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekWindow.setVisibility(View.GONE);
377b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekRow.removeAllViews();
378b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    final int N = mNotns.size();
379b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mNotificationPeekIndex < N) {
380b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
381b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        entry.icon.setBackgroundColor(0);
382b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
383b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
3849120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_OPEN_NOTIFICATION_PANEL:
3859120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notifications panel");
386091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    if (mNotificationPanel.getVisibility() == View.GONE) {
387b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mNotificationPeekWindow.setVisibility(View.GONE);
388091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                        mNotificationPanel.setVisibility(View.VISIBLE);
389b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        // synchronize with current shadow state
390b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        mShadowController.hideElement(mNotificationArea);
39150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mTicker.halt();
392091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
3939120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
3949120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_CLOSE_NOTIFICATION_PANEL:
3959120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
396091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    if (mNotificationPanel.getVisibility() == View.VISIBLE) {
397091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                        mNotificationPanel.setVisibility(View.GONE);
398b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        // synchronize with current shadow state
399b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        mShadowController.showElement(mNotificationArea);
400091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
4019120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
40244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_OPEN_RECENTS_PANEL:
40344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "opening recents panel");
40444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE);
40544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    break;
40644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_CLOSE_RECENTS_PANEL:
40744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "closing recents panel");
40844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE);
4099120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
410b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                case MSG_HIDE_SHADOWS:
411e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
412b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    mShadowController.hideAllShadows();
41306e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
414b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                case MSG_SHOW_SHADOWS:
415e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
41606e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    animateCollapse();
417b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    mShadowController.showAllShadows();
41806e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
419e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                case MSG_RESTORE_SHADOWS:
420e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "quickly re-showing shadows if appropriate");
421e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    mShadowController.refresh();
422e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    break;
4239120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            }
4249120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        }
4259120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
426271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
427271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler    public void refreshNotificationTrigger() {
428fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        /*
429cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler        if (mNotificationTrigger == null) return;
430cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler
431271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        int resId;
432271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        boolean panel = (mNotificationPanel != null
433271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                && mNotificationPanel.getVisibility() == View.VISIBLE);
434271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        if (!mNotificationsOn) {
435271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = R.drawable.ic_sysbar_noti_dnd;
436271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else if (mNotns.size() > 0) {
437271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_avail_open : R.drawable.ic_sysbar_noti_avail;
438271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else {
439271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_none_open : R.drawable.ic_sysbar_noti_none;
440271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        }
441fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        //mNotificationTrigger.setImageResource(resId);
442fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        */
4431e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler    }
4449120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
445808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
4461e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
447808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
448808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
449808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
450808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
4511e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
453808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
4551e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
456808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
457808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
458808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
4593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
4603eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        addNotificationViews(key, notification);
461fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler
46250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
463cf2b199e98de71dcac042484800c07366363a734Joe Onorato        if (false && immersive) {
464fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // TODO: immersive mode popups for tablet
465fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else if (notification.notification.fullScreenIntent != null) {
466fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // not immersive & a full-screen alert should be shown
467fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
468fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                    + " sending fullScreenIntent");
469fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            try {
470fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                notification.notification.fullScreenIntent.send();
471fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            } catch (PendingIntent.CanceledException e) {
472fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            }
473fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else {
47450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            tick(key, notification);
475fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        }
4765dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
4775dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
478808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
479808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
480808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
4813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
48244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
4830f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        final NotificationData.Entry oldEntry = mNotns.findByKey(key);
484379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (oldEntry == null) {
4853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
4863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return;
4873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
4883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarNotification oldNotification = oldEntry.notification;
4903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews oldContentView = oldNotification.notification.contentView;
4913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews contentView = notification.notification.contentView;
4933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (false) {
4953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
4963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
4973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " expanded=" + oldEntry.expanded
4983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + oldContentView);
4993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "new notification: when=" + notification.notification.when
5003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + contentView);
5023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
5053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // didn't change.
5063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (notification.notification.when == oldNotification.notification.when
5073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && notification.isOngoing() == oldNotification.isOngoing()
5083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldEntry.expanded != null
5093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView != null
5103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView != null
5113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView.getPackage() != null
5123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage() != null
5133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage().equals(contentView.getPackage())
5143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId()) {
5153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
5163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            oldEntry.notification = notification;
5173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
5183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Reapply the RemoteViews
519f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
5203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // update the contentIntent
5213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final PendingIntent contentIntent = notification.notification.contentIntent;
5223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (contentIntent != null) {
5233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
5243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                                notification.pkg, notification.tag, notification.id));
525184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
526184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
5273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
5283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Update the icon.
5293eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
5303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.icon, notification.notification.iconLevel,
5313eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.number);
5323eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (!oldEntry.icon.set(ic)) {
5333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
5343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    return;
5353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
5363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
5373eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            catch (RuntimeException e) {
5383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // It failed to add cleanly.  Log, and remove the view from the panel.
5393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
5403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                removeNotificationViews(key);
5413eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                addNotificationViews(key, notification);
5423eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
5433eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
5443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
5453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            removeNotificationViews(key);
5463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            addNotificationViews(key, notification);
5473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
54850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // fullScreenIntent doesn't happen on updates.  You need to clear & repost a new
54950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // notification.
55050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
55150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (false && immersive) {
55250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // TODO: immersive mode
55350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } else {
55450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            tick(key, notification);
55550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
5565dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
5575dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
5613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO");
5623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        removeNotificationViews(key);
56350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mTicker.remove(key);
5645dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
565808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
566808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
567808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
568091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int old = mDisabled;
569091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int diff = state ^ old;
570dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mDisabled = state;
571dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
572091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // act accordingly
573dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
574dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
575dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_EXPAND: yes");
576dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                animateCollapse();
577dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
578dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
579dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
580dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
581dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
582b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
583b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                mShadowController.hideElement(mNotificationArea);
584091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                mTicker.halt();
585dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
586dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
587b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
588b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                mShadowController.showElement(mNotificationArea);
589dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
590dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
591091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
592ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                mTicker.halt();
593dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
594dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
595091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
596091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
597091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: yes");
598fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.GONE);
599dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
600091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: no");
601fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.VISIBLE);
602dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
603dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
604dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
605dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
606ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private boolean hasTicker(Notification n) {
60746439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
608ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
609ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
61050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private void tick(IBinder key, StatusBarNotification n) {
61155d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // Don't show the ticker when the windowshade is open.
61255d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        if (mNotificationPanel.getVisibility() == View.VISIBLE) {
61355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato            return;
61455d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        }
615dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Show the ticker if one is requested. Also don't do this
616dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // until status bar window is attached to the window manager,
617dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // because...  well, what's the point otherwise?  And trying to
618dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // run a ticker without being attached will crash!
619ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
620dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
621dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
62250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                mTicker.add(key, n);
623dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
624dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
625dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
626dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
627808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
628b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
629b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
630808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
631808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
632808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
633b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
634b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
63544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
63644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
6379120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
6389120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
639fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    // called by StatusBar
64006e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler    @Override
6419305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
642b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.removeMessages(MSG_SHOW_SHADOWS);
643b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.removeMessages(MSG_HIDE_SHADOWS);
644b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.sendEmptyMessage(on ? MSG_HIDE_SHADOWS : MSG_SHOW_SHADOWS);
6459305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
6469305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
647e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    public void setMenuKeyVisible(boolean visible) {
648e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        if (DEBUG) {
649e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
650e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        }
651b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
652e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    }
653e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
654cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    public void setIMEButtonVisible(IBinder token, boolean visible) {
65506487a58be22b100daf3f950b9a1d25c3ea42aa2satok        if (DEBUG) {
65606487a58be22b100daf3f950b9a1d25c3ea42aa2satok            Slog.d(TAG, (visible?"showing":"hiding") + " the IME button");
65706487a58be22b100daf3f950b9a1d25c3ea42aa2satok        }
658cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton.setIMEButtonVisible(token, visible);
659cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodShortcutButton.setIMEButtonVisible(token, visible);
660536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton.setImageResource(
661536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato                visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back);
66206487a58be22b100daf3f950b9a1d25c3ea42aa2satok    }
66306487a58be22b100daf3f950b9a1d25c3ea42aa2satok
66450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private boolean isImmersive() {
66550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        try {
66650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return ActivityManagerNative.getDefault().isTopActivityImmersive();
66750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
66850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } catch (RemoteException ex) {
66950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // the end is nigh
67050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return false;
67150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
67250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    }
67350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
6745dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    private void setAreThereNotifications() {
6755dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        final boolean hasClearable = mNotns.hasClearableItems();
6765dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6775dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        //Slog.d(TAG, "setAreThereNotifications hasClerable=" + hasClearable);
6785dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6795dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        /*
6805dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
6815dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
6825dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6835dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        if (ongoing || latest) {
6845dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato            mNoNotificationsTitle.setVisibility(View.GONE);
6855dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        } else {
6865dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato            mNoNotificationsTitle.setVisibility(View.VISIBLE);
6875dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        }
6885dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        */
6895dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    }
6905dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
691f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    /**
692f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     * Cancel this notification and tell the status bar service about the failure. Hold no locks.
693f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     */
694f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
695f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        removeNotification(key);
696f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        try {
697f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
698f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        } catch (RemoteException ex) {
699f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            // The end is nigh.
700f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
701f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
702f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
703f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
704f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        public void onClick(View v) {
705fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            if (v == mNotificationTrigger) {
706f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickNotificationTrigger();
707f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            } else if (v == mRecentButton) {
708f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickRecentButton();
709f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            }
710f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
711f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    };
712f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
713f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickNotificationTrigger() {
714b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
715091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
716271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            if (!mNotificationsOn) {
717271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mNotificationsOn = true;
718cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler                mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
719271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                refreshNotificationTrigger();
720271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            } else {
72144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mNotificationPanel.getVisibility() == View.GONE)
722271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    ? MSG_OPEN_NOTIFICATION_PANEL
723271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    : MSG_CLOSE_NOTIFICATION_PANEL;
724271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.removeMessages(msg);
725271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.sendEmptyMessage(msg);
726271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            }
727091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
7289120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
7299120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
730f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickRecentButton() {
731b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
73244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (mRecentsPanel == null) {
73344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            Intent intent = new Intent();
73444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setClass(mContext, RecentApplicationsActivity.class);
73544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
73644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
73744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mContext.startActivity(intent);
73844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        } else {
73944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
74044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mRecentsPanel.getVisibility() == View.GONE)
74144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ? MSG_OPEN_RECENTS_PANEL
74244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    : MSG_CLOSE_RECENTS_PANEL;
74344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.removeMessages(msg);
74444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.sendEmptyMessage(msg);
74544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            }
74644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
7473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
7483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7493eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private class NotificationClicker implements View.OnClickListener {
7503eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private PendingIntent mIntent;
7513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mPkg;
7523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mTag;
7533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private int mId;
7543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7553eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
7563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mIntent = intent;
7573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mPkg = pkg;
7583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mTag = tag;
7593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mId = id;
7603eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
7613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public void onClick(View v) {
7633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
7643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // The intent we are sending is for the application, which
7653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // won't have permission to immediately start an activity after
7663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // the user switches to home.  We know it is safe to do at this
7673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // point, so make sure new activity switches are now allowed.
7683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                ActivityManagerNative.getDefault().resumeAppSwitches();
7693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException e) {
7703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (mIntent != null) {
7733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                int[] pos = new int[2];
7743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                v.getLocationOnScreen(pos);
7753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Intent overlay = new Intent();
7763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                overlay.setSourceBounds(
7773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
7783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                try {
779f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
7803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                } catch (PendingIntent.CanceledException e) {
7813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    // the stack trace isn't very helpful here.  Just log the exception message.
7823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    Slog.w(TAG, "Sending contentIntent failed: " + e);
7833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
7843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
7873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                mBarService.onNotificationClick(mPkg, mTag, mId);
7883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException ex) {
7893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // system process is dead if we're here.
7903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // close the shade if it was open
7933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            animateCollapse();
7943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // If this click was on the intruder alert, hide that instead
7963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
7973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
7983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
7993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
8010f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        NotificationData.Entry entry = mNotns.remove(key);
8023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (entry == null) {
8033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
8043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
8053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
8063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the expanded view.
8073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
8083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
8093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the icon.
8100f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        ViewGroup iconParent = (ViewGroup)entry.icon.getParent();
8110f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        if (iconParent != null) iconParent.removeView(entry.icon);
8120f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        refreshIcons();
8133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return entry.notification;
8153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
8163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
817b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private class NotificationIconTouchListener implements View.OnTouchListener {
818b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        VelocityTracker mVT;
819b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
820b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public NotificationIconTouchListener() {
821b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
822b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
823b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public boolean onTouch(View v, MotionEvent event) {
824b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
825b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean panelShowing = mNotificationPanel.getVisibility() != View.GONE;
826b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (panelShowing) return false;
827b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
828b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            switch (event.getAction()) {
829b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_DOWN:
830b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = VelocityTracker.obtain();
831b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
832b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // fall through
833b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_OUTSIDE:
834b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_MOVE:
835b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // peek and switch icons if necessary
836b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    int numIcons = mIconLayout.getChildCount();
8375e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                    int peekIndex = (int)((float)event.getX() * numIcons / mIconLayout.getWidth());
838b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peekIndex > numIcons - 1) peekIndex = numIcons - 1;
839b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    else if (peekIndex < 0) peekIndex = 0;
840b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
841b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (!peeking || mNotificationPeekIndex != peekIndex) {
842b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + peekIndex);
843b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
844b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        peekMsg.arg1 = peekIndex;
845b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
846b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
847b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
848b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // no delay if we're scrubbing left-right
8495e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendMessage(peekMsg);
850b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
851b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
852b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // check for fling
853b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mVT != null) {
854b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.addMovement(event);
855b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.computeCurrentVelocity(1000);
856b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // require a little more oomph once we're already in peekaboo mode
857b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (!panelShowing && (
858b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                               (peeking && mVT.getYVelocity() < -mNotificationFlingVelocity*3)
859b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            || (mVT.getYVelocity() < -mNotificationFlingVelocity))) {
860b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
861b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
862b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
863b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
864b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
865b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
866b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
867b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_UP:
868b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_CANCEL:
869b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
870b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peeking) {
8715e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK, 5000);
872b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
873b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT.recycle();
874b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = null;
875b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
876b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
877b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            return false;
878b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
879b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
880b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
8813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
882dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
883dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
884dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
8853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the icon.
886f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
8873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                notification.pkg + "/0x" + Integer.toHexString(notification.id));
8883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
8893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
8913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.icon,
8923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.iconLevel,
8933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.number);
8943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (!iconView.set(ic)) {
8953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
8963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
8973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
8983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the expanded view.
8993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
900dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (!inflateViews(entry, mPile)) {
9013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
9023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + notification);
9033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
9043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
905b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Add the icon.
907dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mNotns.add(entry);
9080f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        refreshIcons();
9090f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
9103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return iconView;
9113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
9123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9130f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    private void refreshIcons() {
9140f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // XXX: need to implement a new limited linear layout class
9150f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // to avoid removing & readding everything
916dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
917b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final int ICON_LIMIT = 4;
918b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final LinearLayout.LayoutParams params
919b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            = new LinearLayout.LayoutParams(mIconSize, mIconSize);
920b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9210f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        int N = mNotns.size();
922dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
923dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
924b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
925dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
926dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
927b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
928b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
929b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<ICON_LIMIT; i++) {
9300f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler            if (i>=N) break;
931b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(mNotns.get(N-i-1).icon);
9320f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        }
933dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
934b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
935b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mIconLayout.getChildCount(); i++) {
936b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mIconLayout.getChildAt(i);
937b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
938b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
939b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
940b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
941b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
942b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
943b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mIconLayout.removeView(remove);
944dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
945271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
946b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
947b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
948b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
949b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mIconLayout.addView(toShow.get(i), i, params);
950b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
951b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
952b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
953b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        loadNotificationPanel();
954271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
9550f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    }
9560f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
957b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private void loadNotificationPanel() {
958b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        int N = mNotns.size();
959b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
960b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
961b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
962b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<N; i++) {
963b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View row = mNotns.get(N-i-1).row;
964b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(row);
965b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
966b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
967b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
968b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
969b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mPile.getChildAt(i);
970b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
971b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
972b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
973b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
974b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
975b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
976b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mPile.removeView(remove);
977b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
978b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
979b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
980b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
981b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
982b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mPile.addView(toShow.get(i));
983b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
984b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
985b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
986b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9874daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    void workAroundBadLayerDrawableOpacity(View v) {
9884daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        LayerDrawable d = (LayerDrawable)v.getBackground();
9894daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(null);
9904daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        d.setOpacity(PixelFormat.TRANSLUCENT);
9914daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(d);
9924daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    }
9934daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato
9943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
9953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        StatusBarNotification sbn = entry.notification;
9963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        RemoteViews remoteViews = sbn.notification.contentView;
9973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (remoteViews == null) {
9983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
9993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // create the row view
1002f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
1003f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
1004755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
10054daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        workAroundBadLayerDrawableOpacity(row);
10060f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        View vetoButton = row.findViewById(R.id.veto);
1007a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        if (entry.notification.isClearable()) {
1008a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _pkg = sbn.pkg;
1009a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _tag = sbn.tag;
1010a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final int _id = sbn.id;
101144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            vetoButton.setOnClickListener(new View.OnClickListener() {
1012a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                    public void onClick(View v) {
1013a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        try {
1014a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            mBarService.onNotificationClear(_pkg, _tag, _id);
1015a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        } catch (RemoteException ex) {
1016a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            // system process is dead if we're here.
1017a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        }
10180f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler                    }
1019a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                });
1020a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        } else {
1021a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            vetoButton.setVisibility(View.INVISIBLE);
1022a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        }
10233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1024561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        // the large icon
1025561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
1026561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        if (sbn.notification.largeIcon != null) {
1027561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setImageBitmap(sbn.notification.largeIcon);
1028561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        } else {
1029561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.getLayoutParams().width = 0;
1030561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setVisibility(View.INVISIBLE);
1031561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        }
1032561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato
10333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // bind the click event to the content area
10343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
10353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // XXX: update to allow controls within notification views
10363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
10373eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//        content.setOnFocusChangeListener(mFocusChangeListener);
10383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        PendingIntent contentIntent = sbn.notification.contentIntent;
10393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (contentIntent != null) {
10403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent,
10413eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        sbn.pkg, sbn.tag, sbn.id));
1042184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
1043184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
10443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        View expanded = null;
10473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        Exception exception = null;
10483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        try {
1049f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
10503eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        catch (RuntimeException e) {
10523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            exception = e;
10533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (expanded == null) {
105546439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
10563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
10573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
10583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
10593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.addView(expanded);
10603eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            row.setDrawingCacheEnabled(true);
10613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.row = row;
10643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.content = content;
10653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.expanded = expanded;
10663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return true;
10683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
1069ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1070b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public class ShadowController {
1071b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        boolean mShowShadows;
1072b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mShadowsForElements = new IdentityHashMap<View, View>(7);
1073b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mElementsForShadows = new IdentityHashMap<View, View>(7);
1074b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        LayoutTransition mElementTransition, mShadowTransition;
1075b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1076b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        View mTouchTarget;
1077f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1078b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        ShadowController(boolean showShadows) {
1079b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = showShadows;
1080b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mTouchTarget = null;
1081b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1082b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition = new LayoutTransition();
1083b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            AnimatorSet s = new AnimatorSet();
1084b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 48, 0))
1085b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 0.5f, 1f))
1086b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f))
1087b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1088b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.APPEARING, //s);
1089b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                   ObjectAnimator.ofInt(null, "top", 48, 0));
1090b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.APPEARING, 100);
1091b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setStartDelay(LayoutTransition.APPEARING, 0);
1092b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1093b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s = new AnimatorSet();
1094b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 0, 48))
1095b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 1f, 0.5f))
1096b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 1f, 0.5f))
1097b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1098b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.DISAPPEARING, //s);
1099b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofInt(null, "top", 0, 48));
1100b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.DISAPPEARING, 400);
1101b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1102b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition = new LayoutTransition();
1103b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.APPEARING,
1104b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
1105b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.APPEARING, 200);
1106b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setStartDelay(LayoutTransition.APPEARING, 100);
1107b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.DISAPPEARING,
1108b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
1109b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.DISAPPEARING, 100);
1110b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1111b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup bar = (ViewGroup) TabletStatusBar.this.mBarContents;
1112b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            bar.setLayoutTransition(mElementTransition);
1113b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup nav = (ViewGroup) TabletStatusBar.this.mNavigationArea;
1114b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            nav.setLayoutTransition(mElementTransition);
1115b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup shadowGroup = (ViewGroup) bar.findViewById(R.id.shadows);
1116b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadowGroup.setLayoutTransition(mShadowTransition);
1117b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1118b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1119b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void add(View element, View shadow) {
1120b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadow.setOnTouchListener(makeTouchListener());
1121b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowsForElements.put(element, shadow);
1122b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementsForShadows.put(shadow, element);
1123f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1124f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1125b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public boolean getShadowState() {
1126b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return mShowShadows;
1127f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1128f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1129b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public View.OnTouchListener makeTouchListener() {
1130b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return new View.OnTouchListener() {
1131b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
1132b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    final int action = ev.getAction();
1133b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1134b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);
1135b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1136b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    // currently redirecting events?
1137b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget == null) {
1138b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        mTouchTarget = mElementsForShadows.get(v);
1139b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1140b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1141b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
1142b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        boolean last = false;
1143b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        switch (action) {
1144b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_CANCEL:
1145b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_UP:
1146e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1147b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                if (mShowShadows) {
1148e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                    mHandler.sendEmptyMessageDelayed(MSG_RESTORE_SHADOWS,
1149b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                            v == mNotificationShadow ? 5000 : 500);
1150b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                }
1151b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                last = true;
1152b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1153b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_DOWN:
1154e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1155b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                                setElementShadow(mTouchTarget, false);
1156b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1157b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        }
1158b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        mTouchTarget.dispatchTouchEvent(ev);
1159b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        if (last) mTouchTarget = null;
1160b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        return true;
1161b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1162b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1163b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    return false;
1164b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1165b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            };
1166b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1167b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1168e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        public void refresh() {
1169b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            for (View element : mShadowsForElements.keySet()) {
1170b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                setElementShadow(element, mShowShadows);
1171b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1172e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        }
1173e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler
1174b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void showAllShadows() {
1175b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = true;
1176e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1177ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        }
1178ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1179b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void hideAllShadows() {
1180b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = false;
1181e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1182b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1183b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1184b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
1185b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // disabled (and should not be shadowed or re-shown)
1186b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void setElementShadow(View button, boolean shade) {
1187b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1188b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            if (shadow != null) {
1189b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                if (button.getVisibility() != View.GONE) {
1190b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
1191b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
1192b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1193b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            }
1194b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1195b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1196b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Hide both element and shadow, using default layout animations.
1197b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void hideElement(View button) {
1198b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "hiding: " + button);
1199b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1200b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1201b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(View.GONE);
1202b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1203b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(View.GONE);
1204b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1205b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1206b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Honoring the current shadow state.
1207b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void showElement(View button) {
1208b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "showing: " + button);
1209b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1210b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1211b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(mShowShadows ? View.VISIBLE : View.INVISIBLE);
1212b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1213b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(mShowShadows ? View.INVISIBLE : View.VISIBLE);
1214b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1215ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    }
1216b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1217b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public class TouchOutsideListener implements View.OnTouchListener {
1218b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        private int mMsg;
1219ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        private StatusBarPanel mPanel;
1220b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1221ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        public TouchOutsideListener(int msg, StatusBarPanel panel) {
1222b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            mMsg = msg;
1223ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            mPanel = panel;
1224b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1225b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1226b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        public boolean onTouch(View v, MotionEvent ev) {
1227ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            final int action = ev.getAction();
1228ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            if (action == MotionEvent.ACTION_OUTSIDE
1229ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                    || (action == MotionEvent.ACTION_DOWN
1230ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                        && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
1231b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.removeMessages(mMsg);
1232b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.sendEmptyMessage(mMsg);
1233b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                return true;
1234b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            }
1235b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            return false;
1236b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1237b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    }
1238091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
1239f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1240f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.print("mDisabled=0x");
1241f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.println(Integer.toHexString(mDisabled));
1242f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
1243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
1244d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1245d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1246