TabletStatusBar.java revision e03d1bcfc42188e574a8e401154c77d5714eea41
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;
22f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
23b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.LayoutTransition;
24b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.ObjectAnimator;
25dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.ActivityManagerNative;
26dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.PendingIntent;
27ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.app.Notification;
28dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.StatusBarManager;
29808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
30808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
31808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.res.Resources;
329120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.graphics.PixelFormat;
33dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.graphics.Rect;
349120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.os.Handler;
35808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.os.Message;
37dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.os.RemoteException;
38ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.text.TextUtils;
393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.util.Slog;
4055d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onoratoimport android.view.animation.Animation;
41ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandlerimport android.view.animation.AnimationUtils;
42808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
433eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.view.LayoutInflater;
44b62ac127824e9723534a197189eca58d30f15d3dJoe Onoratoimport android.view.MotionEvent;
458304da460f95c0883eca0d97fcdc4eb42c10f7c2Daniel Sandlerimport android.view.VelocityTracker;
46808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
47b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.view.ViewConfiguration;
489120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.ViewGroup;
499120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManager;
509120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManagerImpl;
51ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.FrameLayout;
523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.widget.ImageView;
53808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
54dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.RemoteViews;
55dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.ScrollView;
56dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.TextSwitcher;
579120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.widget.TextView;
58808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
59808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
60808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
61808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
62fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.R;
63808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.statusbar.*;
64fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.BatteryController;
65fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.NetworkController;
66013cfc1116e3382981aa0da903d97fc4fdb2c791Joe Onoratoimport com.android.systemui.recent.RecentApplicationsActivity;
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
68fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopublic class TabletStatusBar extends StatusBar {
69fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler    public static final boolean DEBUG = false;
70fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    public static final String TAG = "TabletStatusBar";
71808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
72b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
73b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
74b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
75b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
7644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_OPEN_RECENTS_PANEL = 1020;
7744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_CLOSE_RECENTS_PANEL = 1021;
78b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int MSG_HIDE_SHADOWS = 1030;
79b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int MSG_SHOW_SHADOWS = 1031;
80e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler    public static final int MSG_RESTORE_SHADOWS = 1032;
8144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
82d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler    private static final int MAX_IMAGE_LEVEL = 10000;
8344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private static final boolean USE_2D_RECENTS = true;
84d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
85b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int LIGHTS_ON_DELAY = 5000;
86b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
87808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    int mIconSize;
889120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
899120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    H mHandler = new H();
909120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
91dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // tracking all current notifications
92dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    private NotificationData mNotns = new NotificationData();
9344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
94b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    TabletStatusBarView mStatusBarView;
95fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationArea;
96fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationTrigger;
97dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    NotificationIconArea mNotificationIconArea;
98091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    View mNavigationArea;
99b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
100b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mBackButton;
101b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mHomeButton;
102e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    View mMenuButton;
103f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    View mRecentButton;
104dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
10506487a58be22b100daf3f950b9a1d25c3ea42aa2satok    InputMethodButton mInputMethodButton;
10606487a58be22b100daf3f950b9a1d25c3ea42aa2satok
107ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato    NotificationPanel mNotificationPanel;
1088a576713e255eb822558cef840d170d4477f47f0Joe Onorato    NotificationPeekPanel mNotificationPeekWindow;
109b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    ViewGroup mNotificationPeekRow;
110b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekIndex;
111b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
112b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
113b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekTapDuration;
114b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationFlingVelocity;
1153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1160f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    ViewGroup mPile;
1173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
118fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    BatteryController mBatteryController;
119fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    NetworkController mNetworkController;
1201e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
121ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    View mBarContents;
122b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
123b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    // lights out support
124b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mBackShadow, mHomeShadow, mRecentShadow, mMenuShadow, mNotificationShadow;
125b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    ShadowController mShadowController;
126ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1270f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    NotificationIconArea.IconLayout mIconLayout;
1280f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
129ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    TabletTicker mTicker;
130ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    View mTickerView;
131dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    boolean mTicking;
132dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
133dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // for disabling the status bar
134dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    int mDisabled = 0;
135dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
13655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato    boolean mNotificationsOn = true;
13744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private RecentAppsPanel mRecentsPanel;
13855d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
1399120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    protected void addPanelWindows() {
140f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
141f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
142f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
1439120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        final int barHeight= res.getDimensionPixelSize(
1449120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            com.android.internal.R.dimen.status_bar_height);
1459120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
14644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Notification Panel
147f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationPanel = (NotificationPanel)View.inflate(context,
148ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                R.layout.sysbar_panel_notifications, null);
149d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler        mNotificationPanel.setVisibility(View.GONE);
150b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mNotificationPanel.setOnTouchListener(
151ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
152b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
153fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the battery and network icons
154fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
155fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addLabelView(
156fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.battery_text));
157fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addCombinedDataIconView(
158fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network));
159fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addLabelView(
160fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.network_text));
161fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
16255d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
163d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1649120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1659120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                ViewGroup.LayoutParams.WRAP_CONTENT,
166cf2b199e98de71dcac042484800c07366363a734Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1679120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
1689120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
16946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
17046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
1719120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                PixelFormat.TRANSLUCENT);
172ea70e63c0dcd09ec5790f4dca6ddd76284a6a23dJoe Onorato        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
1739120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        lp.setTitle("NotificationPanel");
1749120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
1759120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
1769120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
177b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // Notification preview window
1788a576713e255eb822558cef840d170d4477f47f0Joe Onorato        mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
179b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                R.layout.sysbar_panel_notification_peek, null);
180b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
181b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setVisibility(View.GONE);
182b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setOnTouchListener(
183b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPeekWindow));
184b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight = new LayoutTransition();
185b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING,
186b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
187b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING,
188b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
189b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setDuration(500);
190b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
191b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft = new LayoutTransition();
192b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING,
193b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
194b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING,
195b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
196b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setDuration(500);
197b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
198b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // XXX: setIgnoreChildren?
199b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp = new WindowManager.LayoutParams(
200b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                512, // ViewGroup.LayoutParams.WRAP_CONTENT,
201b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ViewGroup.LayoutParams.WRAP_CONTENT,
202b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
203b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
20446e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
20546e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
206b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                PixelFormat.TRANSLUCENT);
207b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
208b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.setTitle("NotificationPeekWindow");
209b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
210b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
211b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
212b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
21344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Recents Panel
21444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (USE_2D_RECENTS) {
21544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel = (RecentAppsPanel) View.inflate(context, R.layout.sysbar_panel_recent,
21644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    null);
21744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setVisibility(View.GONE);
21844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
21944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    mRecentsPanel));
22044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
22144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
22244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp = new WindowManager.LayoutParams(
22344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
22444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
22544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
22644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
22746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
22846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
22944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    PixelFormat.TRANSLUCENT);
23044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
23144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.setTitle("RecentsPanel");
232fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            lp.windowAnimations = R.style.Animation_RecentPanel;
23344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
23444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
23544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setBar(this);
23644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
2379120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
238808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
239808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
240f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
241f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start(); // will add the main bar view
242808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
243808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
244808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
245f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
246f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Resources res = context.getResources();
247808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
248808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
249808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
250b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
251f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                context, R.layout.status_bar, null);
252808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusBarView = sb;
253808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
254b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        sb.setHandler(mHandler);
255b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
256ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        mBarContents = sb.findViewById(R.id.bar_contents);
257f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
258b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // "shadows" of the status bar features, for lights-out mode
259b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mBackShadow = sb.findViewById(R.id.back_shadow);
260b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeShadow = sb.findViewById(R.id.home_shadow);
261b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentShadow = sb.findViewById(R.id.recent_shadow);
262b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuShadow = sb.findViewById(R.id.menu_shadow);
263b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mNotificationShadow = sb.findViewById(R.id.notification_shadow);
264f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
265b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mShadowController = new ShadowController(false);
266b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
267b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mBackShadow.setOnTouchListener(mShadowController.makeTouchListener());
268b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeShadow.setOnTouchListener(mShadowController.makeTouchListener());
269b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentShadow.setOnTouchListener(mShadowController.makeTouchListener());
270b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuShadow.setOnTouchListener(mShadowController.makeTouchListener());
271b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mNotificationShadow.setOnTouchListener(mShadowController.makeTouchListener());
272ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
273fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the whole right-hand side of the bar
274fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationArea = sb.findViewById(R.id.notificationArea);
275fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
27655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // the button to open the notification area
277fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
278f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationTrigger.setOnClickListener(mOnClickListener);
27955d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
280808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // the more notifications icon
281808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
282808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // where the icons go
2843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
285b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
286b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
287b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ViewConfiguration vc = ViewConfiguration.get(context);
288b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekTapDuration = vc.getTapTimeout();
289b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationFlingVelocity = 300; // px/s
2903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
291f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mTicker = new TabletTicker(context, (FrameLayout)sb.findViewById(R.id.ticker));
292dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
293fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // The icons
294fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController = new BatteryController(mContext);
295fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
296fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController = new NetworkController(mContext);
297fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addCombinedDataIconView((ImageView)sb.findViewById(R.id.network));
2981e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
299091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // The navigation buttons
300091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        mNavigationArea = sb.findViewById(R.id.navigationArea);
301b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mBackButton = mNavigationArea.findViewById(R.id.back);
302b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeButton = mNavigationArea.findViewById(R.id.home);
303e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        mMenuButton = mNavigationArea.findViewById(R.id.menu);
304b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
305b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        Slog.d(TAG, "rec=" + mRecentButton + ", listener=" + mOnClickListener);
306b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton.setOnClickListener(mOnClickListener);
307091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
30806487a58be22b100daf3f950b9a1d25c3ea42aa2satok        // The bar contents buttons
309b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mInputMethodButton = (InputMethodButton) sb.findViewById(R.id.imeButton);
31006487a58be22b100daf3f950b9a1d25c3ea42aa2satok
3115dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        // set the initial view visibility
3125dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
313271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
3145dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
315dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Add the windows
316dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        addPanelWindows();
317dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
318dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
319dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile.removeAllViews();
32044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
321dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        ScrollView scroller = (ScrollView)mPile.getParent();
322dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        scroller.setFillViewport(true);
323dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
324808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
325808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
326808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
327808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
328808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
329808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
330808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3319120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    private class H extends Handler {
3329120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        public void handleMessage(Message m) {
3339120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            switch (m.what) {
334b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_OPEN_NOTIFICATION_PEEK:
335b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
336b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (m.arg1 >= 0) {
337b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int N = mNotns.size();
338b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (mNotificationPeekIndex < N) {
339b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
340b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0);
341b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
342b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
343b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int peekIndex = m.arg1;
344b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (peekIndex < N) {
345b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            Slog.d(TAG, "loading peek: " + peekIndex);
346b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
347b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry copy = new NotificationData.Entry(
348b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.key,
349b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.notification,
350b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.icon);
351b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            inflateViews(copy, mNotificationPeekRow);
352b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
353b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0x20FFFFFF);
354b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
355b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                          mNotificationPeekRow.setLayoutTransition(
356b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                              peekIndex < mNotificationPeekIndex
357b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  ? mNotificationPeekScrubLeft
358b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  : mNotificationPeekScrubRight);
359b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
360b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.removeAllViews();
361b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.addView(copy.row);
362b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
363b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekWindow.setVisibility(View.VISIBLE);
364b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPanel.setVisibility(View.GONE);
365b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
366b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekIndex = peekIndex;
367b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
368b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
369b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
370b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_CLOSE_NOTIFICATION_PEEK:
371b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notification peek window");
372b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekWindow.setVisibility(View.GONE);
373b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekRow.removeAllViews();
374b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    final int N = mNotns.size();
375b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mNotificationPeekIndex < N) {
376b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
377b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        entry.icon.setBackgroundColor(0);
378b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
379b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
3809120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_OPEN_NOTIFICATION_PANEL:
3819120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notifications panel");
382091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    if (mNotificationPanel.getVisibility() == View.GONE) {
383b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mNotificationPeekWindow.setVisibility(View.GONE);
384b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
385091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                        mNotificationPanel.setVisibility(View.VISIBLE);
386b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
387b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        // XXX: need to synchronize with shadows here
388fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                        mNotificationArea.setVisibility(View.GONE);
389091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
3909120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
3919120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_CLOSE_NOTIFICATION_PANEL:
3929120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
393091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    if (mNotificationPanel.getVisibility() == View.VISIBLE) {
394091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                        mNotificationPanel.setVisibility(View.GONE);
395b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
396b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        // XXX: need to synchronize with shadows here
397fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                        mNotificationArea.setVisibility(View.VISIBLE);
398091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
3999120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
40044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_OPEN_RECENTS_PANEL:
40144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "opening recents panel");
40244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE);
40344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    break;
40444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_CLOSE_RECENTS_PANEL:
40544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "closing recents panel");
40644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE);
4079120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
408b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                case MSG_HIDE_SHADOWS:
409e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
410b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    mShadowController.hideAllShadows();
41106e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
412b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                case MSG_SHOW_SHADOWS:
413e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
41406e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    animateCollapse();
415b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    mShadowController.showAllShadows();
41606e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
417e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                case MSG_RESTORE_SHADOWS:
418e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "quickly re-showing shadows if appropriate");
419e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    mShadowController.refresh();
420e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    break;
4219120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            }
4229120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        }
4239120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
424271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
425271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler    public void refreshNotificationTrigger() {
426fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        /*
427cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler        if (mNotificationTrigger == null) return;
428cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler
429271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        int resId;
430271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        boolean panel = (mNotificationPanel != null
431271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                && mNotificationPanel.getVisibility() == View.VISIBLE);
432271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        if (!mNotificationsOn) {
433271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = R.drawable.ic_sysbar_noti_dnd;
434271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else if (mNotns.size() > 0) {
435271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_avail_open : R.drawable.ic_sysbar_noti_avail;
436271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else {
437271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_none_open : R.drawable.ic_sysbar_noti_none;
438271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        }
439fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        //mNotificationTrigger.setImageResource(resId);
440fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        */
4411e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler    }
4429120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
443808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
4441e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
445808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
446808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
447808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
448808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
4491e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
450808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
451808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
452808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
4531e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
454808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
455808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
456808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
4573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
4583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        addNotificationViews(key, notification);
459fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler
460fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        boolean immersive = false;
461fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        try {
462fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
463fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
464fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } catch (RemoteException ex) {
465fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        }
466cf2b199e98de71dcac042484800c07366363a734Joe Onorato        if (false && immersive) {
467fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // TODO: immersive mode popups for tablet
468fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else if (notification.notification.fullScreenIntent != null) {
469fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // not immersive & a full-screen alert should be shown
470fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
471fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                    + " sending fullScreenIntent");
472fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            try {
473fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                notification.notification.fullScreenIntent.send();
474fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            } catch (PendingIntent.CanceledException e) {
475fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            }
476fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else {
477ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato            tick(notification);
478fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        }
4795dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
4805dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
481808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
482808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
483808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
4843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
48544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
4860f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        final NotificationData.Entry oldEntry = mNotns.findByKey(key);
487379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (oldEntry == null) {
4883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
4893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return;
4903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
4913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarNotification oldNotification = oldEntry.notification;
4933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews oldContentView = oldNotification.notification.contentView;
4943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews contentView = notification.notification.contentView;
4963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
4973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (false) {
4983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
4993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " expanded=" + oldEntry.expanded
5013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + oldContentView);
5023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "new notification: when=" + notification.notification.when
5033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + contentView);
5053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
5083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // didn't change.
5093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (notification.notification.when == oldNotification.notification.when
5103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && notification.isOngoing() == oldNotification.isOngoing()
5113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldEntry.expanded != null
5123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView != null
5133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView != null
5143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView.getPackage() != null
5153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage() != null
5163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage().equals(contentView.getPackage())
5173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId()) {
5183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
5193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            oldEntry.notification = notification;
5203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
5213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Reapply the RemoteViews
522f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
5233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // update the contentIntent
5243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final PendingIntent contentIntent = notification.notification.contentIntent;
5253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (contentIntent != null) {
5263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
5273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                                notification.pkg, notification.tag, notification.id));
528184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
529184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
5303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
5313eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Update the icon.
5323eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
5333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.icon, notification.notification.iconLevel,
5343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.number);
5353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (!oldEntry.icon.set(ic)) {
5363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
5373eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    return;
5383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
5393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
5403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            catch (RuntimeException e) {
5413eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // It failed to add cleanly.  Log, and remove the view from the panel.
5423eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
5433eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                removeNotificationViews(key);
5443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                addNotificationViews(key, notification);
5453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
5463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
5473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
5483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            removeNotificationViews(key);
5493eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            addNotificationViews(key, notification);
5503eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
551ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        // TODO: ticker; immersive mode
5525dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
5535dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
554808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
555808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
556808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
5573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO");
5583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        removeNotificationViews(key);
5595dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
561808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
562808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
563091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int old = mDisabled;
564091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int diff = state ^ old;
565dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mDisabled = state;
566dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
567091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // act accordingly
568dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
569dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
570dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_EXPAND: yes");
571dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                animateCollapse();
572dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
573dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
574dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
575dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
576dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
577fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNotificationIconArea.setVisibility(View.GONE);
578091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                mTicker.halt();
579dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
580dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
581fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNotificationIconArea.setVisibility(View.VISIBLE);
582dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
583dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
584091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
585ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                mTicker.halt();
586dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
587dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
588091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
589091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
590091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: yes");
591fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.GONE);
592dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
593091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: no");
594fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.VISIBLE);
595dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
596dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
597dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
598dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
599ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private boolean hasTicker(Notification n) {
600ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        return !TextUtils.isEmpty(n.tickerText)
601ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                || !TextUtils.isEmpty(n.tickerTitle)
602ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                || !TextUtils.isEmpty(n.tickerSubtitle);
603ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
604ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
605dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    private void tick(StatusBarNotification n) {
60655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // Don't show the ticker when the windowshade is open.
60755d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        if (mNotificationPanel.getVisibility() == View.VISIBLE) {
60855d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato            return;
60955d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        }
610dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Show the ticker if one is requested. Also don't do this
611dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // until status bar window is attached to the window manager,
612dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // because...  well, what's the point otherwise?  And trying to
613dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // run a ticker without being attached will crash!
614ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
615dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
616dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
617ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                mTicker.add(n);
618dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
619dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
620dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
621dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
622808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
623b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
624b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
625808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
626808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
627808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
628b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
629b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
63044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
63144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
6329120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
6339120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
634fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    // called by StatusBar
63506e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler    @Override
6369305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
637b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.removeMessages(MSG_SHOW_SHADOWS);
638b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.removeMessages(MSG_HIDE_SHADOWS);
639b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHandler.sendEmptyMessage(on ? MSG_HIDE_SHADOWS : MSG_SHOW_SHADOWS);
6409305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
6419305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
642e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    public void setMenuKeyVisible(boolean visible) {
643e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        if (DEBUG) {
644e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
645e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        }
646b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
647e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    }
648e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
64906487a58be22b100daf3f950b9a1d25c3ea42aa2satok    public void setIMEButtonVisible(boolean visible) {
65006487a58be22b100daf3f950b9a1d25c3ea42aa2satok        if (DEBUG) {
65106487a58be22b100daf3f950b9a1d25c3ea42aa2satok            Slog.d(TAG, (visible?"showing":"hiding") + " the IME button");
65206487a58be22b100daf3f950b9a1d25c3ea42aa2satok        }
65306487a58be22b100daf3f950b9a1d25c3ea42aa2satok        mInputMethodButton.setIMEButtonVisible(visible);
65406487a58be22b100daf3f950b9a1d25c3ea42aa2satok    }
65506487a58be22b100daf3f950b9a1d25c3ea42aa2satok
6565dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    private void setAreThereNotifications() {
6575dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        final boolean hasClearable = mNotns.hasClearableItems();
6585dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6595dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        //Slog.d(TAG, "setAreThereNotifications hasClerable=" + hasClearable);
6605dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6615dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        /*
6625dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
6635dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
6645dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6655dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        if (ongoing || latest) {
6665dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato            mNoNotificationsTitle.setVisibility(View.GONE);
6675dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        } else {
6685dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato            mNoNotificationsTitle.setVisibility(View.VISIBLE);
6695dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        }
6705dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        */
6715dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    }
6725dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
673f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    /**
674f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     * Cancel this notification and tell the status bar service about the failure. Hold no locks.
675f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     */
676f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
677f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        removeNotification(key);
678f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        try {
679f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
680f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        } catch (RemoteException ex) {
681f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            // The end is nigh.
682f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
683f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
684f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
685f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
686f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        public void onClick(View v) {
687fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            if (v == mNotificationTrigger) {
688f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickNotificationTrigger();
689f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            } else if (v == mRecentButton) {
690f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickRecentButton();
691f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            }
692f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
693f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    };
694f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
695f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickNotificationTrigger() {
696b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
697091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
698271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            if (!mNotificationsOn) {
699271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mNotificationsOn = true;
700cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler                mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
701271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                refreshNotificationTrigger();
702271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            } else {
70344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mNotificationPanel.getVisibility() == View.GONE)
704271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    ? MSG_OPEN_NOTIFICATION_PANEL
705271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    : MSG_CLOSE_NOTIFICATION_PANEL;
706271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.removeMessages(msg);
707271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.sendEmptyMessage(msg);
708271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            }
709091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
7109120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
7119120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
712f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickRecentButton() {
713b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
71444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (mRecentsPanel == null) {
71544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            Intent intent = new Intent();
71644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setClass(mContext, RecentApplicationsActivity.class);
71744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
71844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
71944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mContext.startActivity(intent);
72044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        } else {
72144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
72244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mRecentsPanel.getVisibility() == View.GONE)
72344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ? MSG_OPEN_RECENTS_PANEL
72444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    : MSG_CLOSE_RECENTS_PANEL;
72544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.removeMessages(msg);
72644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.sendEmptyMessage(msg);
72744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            }
72844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
7293eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
7303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7313eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private class NotificationClicker implements View.OnClickListener {
7323eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private PendingIntent mIntent;
7333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mPkg;
7343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mTag;
7353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private int mId;
7363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7373eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
7383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mIntent = intent;
7393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mPkg = pkg;
7403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mTag = tag;
7413eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mId = id;
7423eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
7433eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public void onClick(View v) {
7453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
7463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // The intent we are sending is for the application, which
7473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // won't have permission to immediately start an activity after
7483eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // the user switches to home.  We know it is safe to do at this
7493eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // point, so make sure new activity switches are now allowed.
7503eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                ActivityManagerNative.getDefault().resumeAppSwitches();
7513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException e) {
7523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (mIntent != null) {
7553eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                int[] pos = new int[2];
7563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                v.getLocationOnScreen(pos);
7573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Intent overlay = new Intent();
7583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                overlay.setSourceBounds(
7593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
7603eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                try {
761f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
7623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                } catch (PendingIntent.CanceledException e) {
7633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    // the stack trace isn't very helpful here.  Just log the exception message.
7643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    Slog.w(TAG, "Sending contentIntent failed: " + e);
7653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
7663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
7693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                mBarService.onNotificationClick(mPkg, mTag, mId);
7703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException ex) {
7713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // system process is dead if we're here.
7723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
7733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // close the shade if it was open
7753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            animateCollapse();
7763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // If this click was on the intruder alert, hide that instead
7783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
7793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
7803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
7813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
7830f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        NotificationData.Entry entry = mNotns.remove(key);
7843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (entry == null) {
7853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
7863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
7873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
7883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the expanded view.
7893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
7903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
7913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the icon.
7920f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        ViewGroup iconParent = (ViewGroup)entry.icon.getParent();
7930f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        if (iconParent != null) iconParent.removeView(entry.icon);
7940f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        refreshIcons();
7953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
7963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return entry.notification;
7973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
7983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
799b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private class NotificationIconTouchListener implements View.OnTouchListener {
800b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        VelocityTracker mVT;
801b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
802b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public NotificationIconTouchListener() {
803b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
804b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
805b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public boolean onTouch(View v, MotionEvent event) {
806b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
807b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean panelShowing = mNotificationPanel.getVisibility() != View.GONE;
808b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (panelShowing) return false;
809b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
810b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            switch (event.getAction()) {
811b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_DOWN:
812b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = VelocityTracker.obtain();
813b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
814b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // fall through
815b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_OUTSIDE:
816b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_MOVE:
817b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // peek and switch icons if necessary
818b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    int numIcons = mIconLayout.getChildCount();
819b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    int peekIndex =
820b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            (int)((float)event.getX() * numIcons / mIconLayout.getWidth());
821b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peekIndex > numIcons - 1) peekIndex = numIcons - 1;
822b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    else if (peekIndex < 0) peekIndex = 0;
823b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
824b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (!peeking || mNotificationPeekIndex != peekIndex) {
825b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + peekIndex);
826b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
827b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        peekMsg.arg1 = peekIndex;
828b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
829b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
830b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
831b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // no delay if we're scrubbing left-right
832b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.sendMessageDelayed(peekMsg,
833b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                peeking ? 0 : mNotificationPeekTapDuration);
834b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
835b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
836b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // check for fling
837b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mVT != null) {
838b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.addMovement(event);
839b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.computeCurrentVelocity(1000);
840b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // require a little more oomph once we're already in peekaboo mode
841b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (!panelShowing && (
842b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                               (peeking && mVT.getYVelocity() < -mNotificationFlingVelocity*3)
843b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            || (mVT.getYVelocity() < -mNotificationFlingVelocity))) {
844b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
845b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
846b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
847b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
848b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
849b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
850b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
851b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_UP:
852b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_CANCEL:
853b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
854b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peeking) {
855b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK, 250);
856b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
857b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT.recycle();
858b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = null;
859b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
860b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
861b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            return false;
862b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
863b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
864b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
8653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
866dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
867dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
868dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
8693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the icon.
870f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
8713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                notification.pkg + "/0x" + Integer.toHexString(notification.id));
8723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
8733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
8753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.icon,
8763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.iconLevel,
8773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.number);
8783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (!iconView.set(ic)) {
8793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
8803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
8813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
8823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the expanded view.
8833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
884dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (!inflateViews(entry, mPile)) {
8853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
8863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + notification);
8873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
8883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
889b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
8903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Add the icon.
891dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mNotns.add(entry);
8920f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        refreshIcons();
8930f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
8943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return iconView;
8953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
8963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8970f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    private void refreshIcons() {
8980f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // XXX: need to implement a new limited linear layout class
8990f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // to avoid removing & readding everything
900dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
901b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final int ICON_LIMIT = 4;
902b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final LinearLayout.LayoutParams params
903b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            = new LinearLayout.LayoutParams(mIconSize, mIconSize);
904b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9050f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        int N = mNotns.size();
906dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
907dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
908b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
909dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
910dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
911b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
912b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
913b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<ICON_LIMIT; i++) {
9140f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler            if (i>=N) break;
915b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(mNotns.get(N-i-1).icon);
9160f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        }
917dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
918b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
919b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mIconLayout.getChildCount(); i++) {
920b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mIconLayout.getChildAt(i);
921b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
922b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
923b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
924b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
925b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
926b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
927b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mIconLayout.removeView(remove);
928dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
929271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
930b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
931b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
932b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
933b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mIconLayout.addView(toShow.get(i), i, params);
934b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
935b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
936b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
937b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        loadNotificationPanel();
938271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
9390f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    }
9400f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
941b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private void loadNotificationPanel() {
942b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        int N = mNotns.size();
943b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
944b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
945b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
946b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<N; i++) {
947b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View row = mNotns.get(N-i-1).row;
948b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(row);
949b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
950b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
951b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
952b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
953b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mPile.getChildAt(i);
954b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
955b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
956b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
957b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
958b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
959b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
960b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mPile.removeView(remove);
961b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
962b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
963b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
964b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
965b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
966b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mPile.addView(toShow.get(i));
967b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
968b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
969b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
970b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
9723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        StatusBarNotification sbn = entry.notification;
9733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        RemoteViews remoteViews = sbn.notification.contentView;
9743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (remoteViews == null) {
9753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
9763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
9773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // create the row view
979f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
980f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
9813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false);
9820f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        View vetoButton = row.findViewById(R.id.veto);
983a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        if (entry.notification.isClearable()) {
984a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _pkg = sbn.pkg;
985a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _tag = sbn.tag;
986a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final int _id = sbn.id;
98744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            vetoButton.setOnClickListener(new View.OnClickListener() {
988a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                    public void onClick(View v) {
989a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        try {
990a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            mBarService.onNotificationClear(_pkg, _tag, _id);
991a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        } catch (RemoteException ex) {
992a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            // system process is dead if we're here.
993a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        }
994a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato    //                    animateCollapse();
9950f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler                    }
996a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                });
997a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        } else {
998a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            vetoButton.setVisibility(View.INVISIBLE);
999a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        }
10003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // bind the click event to the content area
10023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
10033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // XXX: update to allow controls within notification views
10043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
10053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//        content.setOnFocusChangeListener(mFocusChangeListener);
10063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        PendingIntent contentIntent = sbn.notification.contentIntent;
10073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (contentIntent != null) {
10083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent,
10093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        sbn.pkg, sbn.tag, sbn.id));
1010184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
1011184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
10123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        View expanded = null;
10153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        Exception exception = null;
10163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        try {
1017f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
10183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        catch (RuntimeException e) {
10203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            exception = e;
10213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (expanded == null) {
10233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
10243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
10253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
10263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
10273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.addView(expanded);
10283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            row.setDrawingCacheEnabled(true);
10293eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10313eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.row = row;
10323eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.content = content;
10333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.expanded = expanded;
10343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return true;
10363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
1037ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1038b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public class ShadowController {
1039b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        boolean mShowShadows;
1040b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        View mTouchTarget;
1041f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1042b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        ShadowController(boolean showShadows) {
1043b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = showShadows;
1044b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mTouchTarget = null;
1045f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1046f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1047b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public boolean getShadowState() {
1048b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return mShowShadows;
1049f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1050f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1051b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public View.OnTouchListener makeTouchListener() {
1052b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return new View.OnTouchListener() {
1053b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
1054b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    final int action = ev.getAction();
1055b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1056b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);
1057b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1058b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    // currently redirecting events?
1059b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget == null) {
1060b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        if (v == mBackShadow) {
1061b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            mTouchTarget = mBackButton;
1062b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        } else if (v == mHomeShadow) {
1063b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            mTouchTarget = mHomeButton;
1064b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        } else if (v == mMenuShadow) {
1065b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            mTouchTarget = mMenuButton;
1066b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        } else if (v == mRecentShadow) {
1067b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            mTouchTarget = mRecentButton;
1068b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        } else if (v == mNotificationShadow) {
1069b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            mTouchTarget = mNotificationArea;
1070b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        }
1071b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1072b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1073b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
1074b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        boolean last = false;
1075b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        switch (action) {
1076b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_CANCEL:
1077b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_UP:
1078e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1079b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                if (mShowShadows) {
1080e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                    mHandler.sendEmptyMessageDelayed(MSG_RESTORE_SHADOWS,
1081b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                            v == mNotificationShadow ? 5000 : 500);
1082b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                }
1083b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                last = true;
1084b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1085b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_DOWN:
1086e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1087b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                setShadowForButton(mTouchTarget, false);
1088b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1089b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        }
1090b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        mTouchTarget.dispatchTouchEvent(ev);
1091b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        if (last) mTouchTarget = null;
1092b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        return true;
1093b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1094b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1095b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    return false;
1096b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1097b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            };
1098b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1099b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1100e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        public void refresh() {
1101e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            setShadowForButton(mBackButton, mShowShadows);
1102e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            setShadowForButton(mHomeButton, mShowShadows);
1103e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            setShadowForButton(mRecentButton, mShowShadows);
1104e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            setShadowForButton(mMenuButton, mShowShadows);
1105e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            setShadowForButton(mNotificationArea, mShowShadows);
1106e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        }
1107e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler
1108b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void showAllShadows() {
1109b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = true;
1110e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1111ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        }
1112ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1113b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void hideAllShadows() {
1114b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = false;
1115e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1116b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1117b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1118b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
1119b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // disabled (and should not be shadowed or re-shown)
1120b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void setShadowForButton(View button, boolean shade) {
1121b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            View shadow = null;
1122b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            if (button == mBackButton) {
1123b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                shadow = mBackShadow;
1124b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            } else if (button == mHomeButton) {
1125b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                shadow = mHomeShadow;
1126b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            } else if (button == mMenuButton) {
1127b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                shadow = mMenuShadow;
1128b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            } else if (button == mRecentButton) {
1129b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                shadow = mRecentShadow;
1130b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            } else if (button == mNotificationArea) {
1131b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                shadow = mNotificationShadow;
1132b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            }
1133b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            if (shadow != null) {
1134b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                if (button.getVisibility() != View.GONE) {
1135b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
1136b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
1137b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1138b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            }
1139b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1140ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    }
1141b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1142b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public class TouchOutsideListener implements View.OnTouchListener {
1143b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        private int mMsg;
1144ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        private StatusBarPanel mPanel;
1145b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1146ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        public TouchOutsideListener(int msg, StatusBarPanel panel) {
1147b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            mMsg = msg;
1148ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            mPanel = panel;
1149b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1150b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1151b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        public boolean onTouch(View v, MotionEvent ev) {
1152ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            final int action = ev.getAction();
1153ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            if (action == MotionEvent.ACTION_OUTSIDE
1154ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                    || (action == MotionEvent.ACTION_DOWN
1155ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                        && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
1156b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.removeMessages(mMsg);
1157b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.sendEmptyMessage(mMsg);
1158b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                return true;
1159b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            }
1160b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            return false;
1161b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1162b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    }
1163091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
1164091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    private void setViewVisibility(View v, int vis, int anim) {
1165091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if (v.getVisibility() != vis) {
11665dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato            //Slog.d(TAG, "setViewVisibility vis=" + (vis == View.VISIBLE) + " v=" + v);
1167f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            v.setAnimation(AnimationUtils.loadAnimation(mContext, anim));
1168091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            v.setVisibility(vis);
1169091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
1170091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    }
1171f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
1172f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
1173f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1174f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.print("mDisabled=0x");
1175f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.println(Integer.toHexString(mDisabled));
1176f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
1177808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
1178d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1179d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1180