TabletStatusBar.java revision 0ad460b087abbd4b523a2e61ff27b0bf6fb5be92
1808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato/*
2808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Copyright (C) 2010 The Android Open Source Project
3808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
4808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * you may not use this file except in compliance with the License.
6808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * You may obtain a copy of the License at
7808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
8808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato *
10808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * Unless required by applicable law or agreed to in writing, software
11808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * See the License for the specific language governing permissions and
14808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato * limitations under the License.
15808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato */
16808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
17808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratopackage com.android.systemui.statusbar.tablet;
18808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
19f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onoratoimport java.io.FileDescriptor;
20f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onoratoimport java.io.PrintWriter;
21b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport java.util.ArrayList;
22b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport java.util.Map;
23b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport java.util.IdentityHashMap;
24f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
25b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.LayoutTransition;
26b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.animation.ObjectAnimator;
27b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandlerimport android.animation.AnimatorSet;
28dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.ActivityManagerNative;
29dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.PendingIntent;
30ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.app.Notification;
31dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.app.StatusBarManager;
32808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Context;
33808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.Intent;
340ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandlerimport android.content.res.Configuration;
35808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.content.res.Resources;
369120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.graphics.PixelFormat;
37dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.graphics.Rect;
384daaeafd278d22ec9013d1cdaade562044ee907eJoe Onoratoimport android.graphics.drawable.Drawable;
394daaeafd278d22ec9013d1cdaade562044ee907eJoe Onoratoimport android.graphics.drawable.LayerDrawable;
409120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.os.Handler;
41808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.os.IBinder;
423eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.os.Message;
43dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.os.RemoteException;
4410163c689a713a35f69aad420c35372946b8b32aDaniel Sandlerimport android.os.ServiceManager;
45ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.text.TextUtils;
463eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.util.Slog;
4755d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onoratoimport android.view.animation.Animation;
48ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandlerimport android.view.animation.AnimationUtils;
49808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.Gravity;
5010163c689a713a35f69aad420c35372946b8b32aDaniel Sandlerimport android.view.IWindowManager;
5110163c689a713a35f69aad420c35372946b8b32aDaniel Sandlerimport android.view.KeyEvent;
523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.view.LayoutInflater;
53b62ac127824e9723534a197189eca58d30f15d3dJoe Onoratoimport android.view.MotionEvent;
548304da460f95c0883eca0d97fcdc4eb42c10f7c2Daniel Sandlerimport android.view.VelocityTracker;
55808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.view.View;
56b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandlerimport android.view.ViewConfiguration;
579120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.ViewGroup;
589120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManager;
599120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.view.WindowManagerImpl;
60ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onoratoimport android.widget.FrameLayout;
613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandlerimport android.widget.ImageView;
62808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport android.widget.LinearLayout;
63dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.RemoteViews;
64dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.ScrollView;
65dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandlerimport android.widget.TextSwitcher;
669120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandlerimport android.widget.TextView;
67808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
68808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarIcon;
69808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.internal.statusbar.StatusBarNotification;
70808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
71fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.R;
72808182dc874e93582da38d013a4a790d6bc08fc9Joe Onoratoimport com.android.systemui.statusbar.*;
73fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.BatteryController;
74fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratoimport com.android.systemui.statusbar.policy.NetworkController;
75013cfc1116e3382981aa0da903d97fc4fdb2c791Joe Onoratoimport com.android.systemui.recent.RecentApplicationsActivity;
76808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
77fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onoratopublic class TabletStatusBar extends StatusBar {
78fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler    public static final boolean DEBUG = false;
79fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    public static final String TAG = "TabletStatusBar";
80808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    public static final int MAX_NOTIFICATION_ICONS = 5;
820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
83b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
84b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
85b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
86b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
8744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_OPEN_RECENTS_PANEL = 1020;
8844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    public static final int MSG_CLOSE_RECENTS_PANEL = 1021;
890ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    public static final int MSG_SHOW_CHROME = 1030;
900ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    public static final int MSG_HIDE_CHROME = 1031;
9144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
9210163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    // Fitts' Law assistance for LatinIME; TODO: replace with a more general approach
9310163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    private static final boolean FAKE_SPACE_BAR = true;
9410163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
95d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler    private static final int MAX_IMAGE_LEVEL = 10000;
9644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private static final boolean USE_2D_RECENTS = true;
97d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
98b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public static final int LIGHTS_ON_DELAY = 5000;
99b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1000ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    int mBarHeight = -1;
1010ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    int mIconSize = -1;
1020ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    int mIconHPadding = -1;
1039120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
1049120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    H mHandler = new H();
1059120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
10610163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    IWindowManager mWindowManager;
10710163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
108dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // tracking all current notifications
109dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    private NotificationData mNotns = new NotificationData();
11044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
111b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    TabletStatusBarView mStatusBarView;
112fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationArea;
113fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    View mNotificationTrigger;
114dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    NotificationIconArea mNotificationIconArea;
115091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato    View mNavigationArea;
116b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
117536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato    ImageView mBackButton;
118b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    View mHomeButton;
119e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    View mMenuButton;
120f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    View mRecentButton;
121dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
122cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    InputMethodButton mInputMethodSwitchButton;
12306487a58be22b100daf3f950b9a1d25c3ea42aa2satok
124ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato    NotificationPanel mNotificationPanel;
1258a576713e255eb822558cef840d170d4477f47f0Joe Onorato    NotificationPeekPanel mNotificationPeekWindow;
126b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    ViewGroup mNotificationPeekRow;
127b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekIndex;
128a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler    IBinder mNotificationPeekKey;
129b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
130b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
131b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekTapDuration;
132b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationFlingVelocity;
1333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1340f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    ViewGroup mPile;
1353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
136fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    BatteryController mBatteryController;
137fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    NetworkController mNetworkController;
1381e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
139ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    View mBarContents;
140b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1410ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    // hide system chrome ("lights out") support
1420ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    View mShadow;
143ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1440f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    NotificationIconArea.IconLayout mIconLayout;
1450f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
146ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    TabletTicker mTicker;
147dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
14810163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    View mFakeSpaceBar;
14910163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    KeyEvent mSpaceBarKeyEvent = null;
15010163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
151dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // for disabling the status bar
152dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    int mDisabled = 0;
153dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
15455d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato    boolean mNotificationsOn = true;
15544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private RecentAppsPanel mRecentsPanel;
15655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
1579120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    protected void addPanelWindows() {
158f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
159f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
16044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Notification Panel
161f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationPanel = (NotificationPanel)View.inflate(context,
162755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_panel, null);
1637c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        mNotificationPanel.show(false, false);
164b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mNotificationPanel.setOnTouchListener(
165ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
166b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
167fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the battery and network icons
168fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
169fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addLabelView(
170fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.battery_text));
171ddbba42b812ab397a75db78aba6b48fecf0e31f6Joe Onorato        mNetworkController.addCombinedSignalIconView(
17242f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network_signal));
17342f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addDataTypeIconView(
17442f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network_type));
175fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addLabelView(
176fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.network_text));
1773e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        mNetworkController.addLabelView(
1783e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler                (TextView)mBarContents.findViewById(R.id.network_text));
179fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
18055d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
181d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1829120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1834cddc98a4b63961e3528c5a70cd5c55a67a0c60aJoe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
184cf2b199e98de71dcac042484800c07366363a734Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1859120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
1869120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
18746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
1887c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
1897c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
1909120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                PixelFormat.TRANSLUCENT);
191ea70e63c0dcd09ec5790f4dca6ddd76284a6a23dJoe Onorato        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
1929120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        lp.setTitle("NotificationPanel");
1937c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
1947c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
1957c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
1969120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
1979120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
1989120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
199b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // Notification preview window
2008a576713e255eb822558cef840d170d4477f47f0Joe Onorato        mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
201755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_peek, null);
202b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
203b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setVisibility(View.GONE);
204b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setOnTouchListener(
2055e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow));
206b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight = new LayoutTransition();
207b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING,
208b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
209b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING,
210b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
211b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setDuration(500);
212b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
213b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft = new LayoutTransition();
214b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING,
215b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
216b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING,
217b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
218b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setDuration(500);
219b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
220b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // XXX: setIgnoreChildren?
221b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp = new WindowManager.LayoutParams(
222b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                512, // ViewGroup.LayoutParams.WRAP_CONTENT,
223b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ViewGroup.LayoutParams.WRAP_CONTENT,
224b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
225b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
22646e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
22746e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
228b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                PixelFormat.TRANSLUCENT);
229b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
230b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.setTitle("NotificationPeekWindow");
231b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
232b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
233b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
234b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
23544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Recents Panel
23644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (USE_2D_RECENTS) {
237755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato            mRecentsPanel = (RecentAppsPanel) View.inflate(context,
238755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                    R.layout.status_bar_recent_panel, null);
23944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setVisibility(View.GONE);
24044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
24144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    mRecentsPanel));
24244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
24344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
24444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp = new WindowManager.LayoutParams(
24544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
24644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
24744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
24844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
24946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
250169a211f6be5fc842dce6281aad16697c6cecfa9Jim Miller                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
251169a211f6be5fc842dce6281aad16697c6cecfa9Jim Miller                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
25244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    PixelFormat.TRANSLUCENT);
25344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
25444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.setTitle("RecentsPanel");
255fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            lp.windowAnimations = R.style.Animation_RecentPanel;
25644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
25744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
25844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setBar(this);
25944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
2609120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
261808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
262808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
263f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
264f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start(); // will add the main bar view
265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
266808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2670ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    @Override
2680ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    protected void onConfigurationChanged (Configuration newConfig) {
2690ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        loadDimens();
2700ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
2710ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2720ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    protected void loadDimens() {
2730ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final Resources res = mContext.getResources();
2740ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2750ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mBarHeight = res.getDimensionPixelSize(
2760ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            com.android.internal.R.dimen.status_bar_height);
2770ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2780ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        int newIconSize = res.getDimensionPixelSize(
2790ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            com.android.internal.R.dimen.status_bar_icon_size);
2800ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        int newIconHPadding = res.getDimensionPixelSize(
2810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            R.dimen.status_bar_icon_padding);
2820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2830ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
2840ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
2850ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            mIconHPadding = newIconHPadding;
2860ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            mIconSize = newIconSize;
2870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            reloadAllNotificationIcons(); // reload the tray
2880ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        }
2890ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
2900ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
291808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
292f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
29310163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
29410163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        mWindowManager = IWindowManager.Stub.asInterface(
29510163c689a713a35f69aad420c35372946b8b32aDaniel Sandler                ServiceManager.getService(Context.WINDOW_SERVICE));
296808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2970ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        loadDimens();
298808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
299b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
300f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                context, R.layout.status_bar, null);
301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusBarView = sb;
302808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
303b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        sb.setHandler(mHandler);
304b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
305ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        mBarContents = sb.findViewById(R.id.bar_contents);
306f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
307fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the whole right-hand side of the bar
308fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationArea = sb.findViewById(R.id.notificationArea);
309fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
31055d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // the button to open the notification area
311fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
312f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationTrigger.setOnClickListener(mOnClickListener);
31355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
314808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // the more notifications icon
315808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
316808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // where the icons go
3183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
319b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
320b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
321b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ViewConfiguration vc = ViewConfiguration.get(context);
322b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekTapDuration = vc.getTapTimeout();
323b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationFlingVelocity = 300; // px/s
3243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
32552f80cd36f406725e85a1825741a45c69de3d898Joe Onorato        mTicker = new TabletTicker(context);
326dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
327fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // The icons
328fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController = new BatteryController(mContext);
329fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
330fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController = new NetworkController(mContext);
33142f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addCombinedSignalIconView(
33242f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)sb.findViewById(R.id.network_signal));
33342f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addDataTypeIconView(
33442f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)sb.findViewById(R.id.network_type));
3351e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
336091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // The navigation buttons
337091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        mNavigationArea = sb.findViewById(R.id.navigationArea);
338536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton = (ImageView)mNavigationArea.findViewById(R.id.back);
339b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeButton = mNavigationArea.findViewById(R.id.home);
340e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        mMenuButton = mNavigationArea.findViewById(R.id.menu);
341b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
342b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton.setOnClickListener(mOnClickListener);
343091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
34406487a58be22b100daf3f950b9a1d25c3ea42aa2satok        // The bar contents buttons
345cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton = (InputMethodButton) sb.findViewById(R.id.imeSwitchButton);
34606487a58be22b100daf3f950b9a1d25c3ea42aa2satok
34710163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        // for redirecting errant bar taps to the IME
34810163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
34910163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
350b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // "shadows" of the status bar features, for lights-out mode
3510ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mShadow = sb.findViewById(R.id.bar_shadow);
3520ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mShadow.setOnTouchListener(
3530ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            new View.OnTouchListener() {
3540ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
3550ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
3560ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mShadow.setVisibility(View.GONE);
3570ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mBarContents.setVisibility(View.VISIBLE);
3580ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    }
3590ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    return false;
3600ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                }
3610ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            });
3620ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3630ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        // tuning parameters
3640ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SYSBAR_DURATION = 600;
3650ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SHADOW_DURATION = 1000;
3660ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SHADOW_DELAY    = 500;
3670ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3680ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_COMING_UP_SYSBAR_DURATION = 200;
3690ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler//        final int LIGHTS_COMING_UP_SYSBAR_DELAY    = 50;
3700ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_COMING_UP_SHADOW_DURATION = 0;
3710ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3720ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        LayoutTransition xition = new LayoutTransition();
3730ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.APPEARING,
3740ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f));
3750ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_COMING_UP_SYSBAR_DURATION);
3760ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.APPEARING, 0);
3770ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.DISAPPEARING,
3780ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
3790ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_GOING_OUT_SYSBAR_DURATION);
3800ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
3810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        ((ViewGroup)sb.findViewById(R.id.bar_contents_holder)).setLayoutTransition(xition);
3820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3830ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition = new LayoutTransition();
3840ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.APPEARING,
3850ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
3860ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DURATION);
3870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DELAY);
3880ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.DISAPPEARING,
3890ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
3900ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_COMING_UP_SHADOW_DURATION);
3910ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
3920ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        ((ViewGroup)sb.findViewById(R.id.bar_shadow_holder)).setLayoutTransition(xition);
393b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
3945dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        // set the initial view visibility
3955dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
396271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
3975dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
398dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Add the windows
399dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        addPanelWindows();
400dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
401dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
402dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile.removeAllViews();
40344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
404dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        ScrollView scroller = (ScrollView)mPile.getParent();
405dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        scroller.setFillViewport(true);
406dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
407808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
408808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
409808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
4149120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    private class H extends Handler {
4159120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        public void handleMessage(Message m) {
4169120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            switch (m.what) {
417b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_OPEN_NOTIFICATION_PEEK:
418b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
419b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (m.arg1 >= 0) {
420b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int N = mNotns.size();
421a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                        if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
422b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
423b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0);
424a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekIndex = -1;
425a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekKey = null;
426b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
427b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
428b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int peekIndex = m.arg1;
429b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (peekIndex < N) {
4300ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                            //Slog.d(TAG, "loading peek: " + peekIndex);
431b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
432b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry copy = new NotificationData.Entry(
433b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.key,
434b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.notification,
435b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.icon);
436b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            inflateViews(copy, mNotificationPeekRow);
437b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
438b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0x20FFFFFF);
439b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
440b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                          mNotificationPeekRow.setLayoutTransition(
441b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                              peekIndex < mNotificationPeekIndex
442b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  ? mNotificationPeekScrubLeft
443b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  : mNotificationPeekScrubRight);
444b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
445b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.removeAllViews();
446b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.addView(copy.row);
447b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
448b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekWindow.setVisibility(View.VISIBLE);
4497c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                            mNotificationPanel.show(false, true);
450b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
451b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekIndex = peekIndex;
452a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekKey = entry.key;
453b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
454b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
455b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
456b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_CLOSE_NOTIFICATION_PEEK:
457b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notification peek window");
458b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekWindow.setVisibility(View.GONE);
459b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekRow.removeAllViews();
460b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    final int N = mNotns.size();
461a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
462b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
463b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        entry.icon.setBackgroundColor(0);
464b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
465a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler
466a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    mNotificationPeekIndex = -1;
467a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    mNotificationPeekKey = null;
468b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
4699120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_OPEN_NOTIFICATION_PANEL:
4709120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notifications panel");
4717c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    if (!mNotificationPanel.isShowing()) {
472b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mNotificationPeekWindow.setVisibility(View.GONE);
4737c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                        mNotificationPanel.show(true, true);
4740ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mNotificationArea.setVisibility(View.GONE);
47550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mTicker.halt();
476091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
4779120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
4789120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_CLOSE_NOTIFICATION_PANEL:
4799120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
4807c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    if (mNotificationPanel.isShowing()) {
4817c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                        mNotificationPanel.show(false, true);
4820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mNotificationArea.setVisibility(View.VISIBLE);
483091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
4849120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
48544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_OPEN_RECENTS_PANEL:
48644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "opening recents panel");
48744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE);
48844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    break;
48944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_CLOSE_RECENTS_PANEL:
49044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "closing recents panel");
49144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE);
4929120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
4930ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                case MSG_SHOW_CHROME:
494e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
4950ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mBarContents.setVisibility(View.VISIBLE);
4960ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mShadow.setVisibility(View.GONE);
49706e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
4980ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                case MSG_HIDE_CHROME:
499e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
50006e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    animateCollapse();
5010ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mBarContents.setVisibility(View.GONE);
5020ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mShadow.setVisibility(View.VISIBLE);
503e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    break;
5049120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            }
5059120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        }
5069120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
507271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
508271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler    public void refreshNotificationTrigger() {
509fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        /*
510cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler        if (mNotificationTrigger == null) return;
511cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler
512271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        int resId;
5137c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        boolean panel = (mNotificationPanel != null && mNotificationPanel.isShowing();
514271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        if (!mNotificationsOn) {
515271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = R.drawable.ic_sysbar_noti_dnd;
516271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else if (mNotns.size() > 0) {
517271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_avail_open : R.drawable.ic_sysbar_noti_avail;
518271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        } else {
519271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            resId = panel ? R.drawable.ic_sysbar_noti_none_open : R.drawable.ic_sysbar_noti_none;
520271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        }
521fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        //mNotificationTrigger.setImageResource(resId);
522fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        */
5231e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler    }
5249120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
525808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
5261e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
527808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
528808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
529808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
530808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
5311e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
532808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
533808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
534808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
5351e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
536808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
537808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
538808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
5393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
5403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        addNotificationViews(key, notification);
541fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler
54250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
543cf2b199e98de71dcac042484800c07366363a734Joe Onorato        if (false && immersive) {
544fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // TODO: immersive mode popups for tablet
545fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else if (notification.notification.fullScreenIntent != null) {
546fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // not immersive & a full-screen alert should be shown
547fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
548fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                    + " sending fullScreenIntent");
549fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            try {
550fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                notification.notification.fullScreenIntent.send();
551fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            } catch (PendingIntent.CanceledException e) {
552fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            }
553fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else {
55450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            tick(key, notification);
555fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        }
5565dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
5575dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
558808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
559808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
560808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
5613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
56244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
5630f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        final NotificationData.Entry oldEntry = mNotns.findByKey(key);
564379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (oldEntry == null) {
5653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
5663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return;
5673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarNotification oldNotification = oldEntry.notification;
5703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews oldContentView = oldNotification.notification.contentView;
5713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews contentView = notification.notification.contentView;
5733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
574373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        if (DEBUG) {
5753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
5763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " expanded=" + oldEntry.expanded
5783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + oldContentView);
5793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "new notification: when=" + notification.notification.when
5803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + contentView);
5823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
5853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // didn't change.
586373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        boolean orderUnchanged = (notification.notification.when == oldNotification.notification.when
5873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && notification.isOngoing() == oldNotification.isOngoing()
5883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldEntry.expanded != null
5893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView != null
5903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView != null
5913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView.getPackage() != null
5923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage() != null
5933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage().equals(contentView.getPackage())
594373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId());
595373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
596373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount() - 1;
597373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        if (orderUnchanged || isLastAnyway) {
5983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
5993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            oldEntry.notification = notification;
6003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
6013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Reapply the RemoteViews
602f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
6033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // update the contentIntent
6043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final PendingIntent contentIntent = notification.notification.contentIntent;
6053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (contentIntent != null) {
6063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
6073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                                notification.pkg, notification.tag, notification.id));
608184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
609184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
6103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
6113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Update the icon.
6123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
6133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.icon, notification.notification.iconLevel,
6143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.number);
6153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (!oldEntry.icon.set(ic)) {
6163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
6173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    return;
6183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
6193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
6203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            catch (RuntimeException e) {
6213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // It failed to add cleanly.  Log, and remove the view from the panel.
6223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
6233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                removeNotificationViews(key);
6243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                addNotificationViews(key, notification);
6253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
6263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
6273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
6283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            removeNotificationViews(key);
6293eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            addNotificationViews(key, notification);
6303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
63150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // fullScreenIntent doesn't happen on updates.  You need to clear & repost a new
63250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // notification.
63350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
63450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (false && immersive) {
63550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // TODO: immersive mode
63650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } else {
63750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            tick(key, notification);
63850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
6395dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6405dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
641808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
6443eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO");
6453eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        removeNotificationViews(key);
64650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mTicker.remove(key);
6475dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
648808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
649808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
6503e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler    public void showClock(boolean show) {
6513e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        View clock = mBarContents.findViewById(R.id.clock);
6523e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        View network_text = mBarContents.findViewById(R.id.network_text);
6533e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if (clock != null) {
6543e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            clock.setVisibility(show ? View.VISIBLE : View.GONE);
6553e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
6563e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if (network_text != null) {
6573e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            network_text.setVisibility((!show) ? View.VISIBLE : View.GONE);
6583e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
6593e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler    }
6603e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler
661808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
662091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int old = mDisabled;
663091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int diff = state ^ old;
664dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mDisabled = state;
665dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
666091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // act accordingly
6673e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
6683e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
6693e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            Slog.d(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
6703e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            showClock(show);
6713e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
672dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
673dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
674dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_EXPAND: yes");
675dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                animateCollapse();
676dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
677dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
678dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
679dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
680dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
681b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
6820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mNotificationIconArea.setVisibility(View.GONE);
683091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                mTicker.halt();
684dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
685dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
686b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
6870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mNotificationIconArea.setVisibility(View.VISIBLE);
688dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
689dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
690091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
691ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                mTicker.halt();
692dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
693dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
694091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
695091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
696091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: yes");
697fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.GONE);
698dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
699091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: no");
700fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.VISIBLE);
701dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
702dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
703dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
704dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
705ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private boolean hasTicker(Notification n) {
70646439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
707ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
708ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
70950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private void tick(IBinder key, StatusBarNotification n) {
71055d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // Don't show the ticker when the windowshade is open.
7117c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        if (mNotificationPanel.isShowing()) {
71255d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato            return;
71355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        }
714dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Show the ticker if one is requested. Also don't do this
715dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // until status bar window is attached to the window manager,
716dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // because...  well, what's the point otherwise?  And trying to
717dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // run a ticker without being attached will crash!
718ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
719dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
720dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
72150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                mTicker.add(key, n);
722dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
723dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
724dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
725dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
726808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
727b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
728b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
729808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
730808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
731808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
732b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
733b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
73444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
73544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
7369120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
7379120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
738fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    // called by StatusBar
73906e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler    @Override
7409305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
74159485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
74259485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // that can't handle lights-out mode.
7430ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mMenuButton.getVisibility() == View.VISIBLE) {
74459485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler            on = true;
74559485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        }
7460ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.removeMessages(MSG_HIDE_CHROME);
7470ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.removeMessages(MSG_SHOW_CHROME);
7480ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.sendEmptyMessage(on ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
7499305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
7509305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
751e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    public void setMenuKeyVisible(boolean visible) {
752e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        if (DEBUG) {
753e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
754e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        }
755b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
75659485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler
75759485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // See above re: lights-out policy for legacy apps.
75859485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        if (visible) setLightsOn(true);
759e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    }
760e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
761cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    public void setIMEButtonVisible(IBinder token, boolean visible) {
76206487a58be22b100daf3f950b9a1d25c3ea42aa2satok        if (DEBUG) {
76306487a58be22b100daf3f950b9a1d25c3ea42aa2satok            Slog.d(TAG, (visible?"showing":"hiding") + " the IME button");
76406487a58be22b100daf3f950b9a1d25c3ea42aa2satok        }
765cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton.setIMEButtonVisible(token, visible);
766536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton.setImageResource(
767536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato                visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back);
76810163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        if (FAKE_SPACE_BAR) {
76910163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            mFakeSpaceBar.setVisibility(visible ? View.VISIBLE : View.GONE);
77010163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        }
77106487a58be22b100daf3f950b9a1d25c3ea42aa2satok    }
77206487a58be22b100daf3f950b9a1d25c3ea42aa2satok
77350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private boolean isImmersive() {
77450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        try {
77550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return ActivityManagerNative.getDefault().isTopActivityImmersive();
77650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
77750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } catch (RemoteException ex) {
77850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // the end is nigh
77950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return false;
78050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
78150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    }
78250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
7835dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    private void setAreThereNotifications() {
7845dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        final boolean hasClearable = mNotns.hasClearableItems();
7855dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    }
7865dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
787f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    /**
788f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     * Cancel this notification and tell the status bar service about the failure. Hold no locks.
789f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     */
790f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
791f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        removeNotification(key);
792f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        try {
793f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
794f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        } catch (RemoteException ex) {
795f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            // The end is nigh.
796f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
797f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
798f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
79910163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    private void sendKey(KeyEvent key) {
80010163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        try {
80110163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            if (DEBUG) Slog.d(TAG, "injecting key event: " + key);
80210163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            mWindowManager.injectInputEventNoWait(key);
80310163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        } catch (RemoteException ex) {
80410163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        }
80510163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    }
80610163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
807f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
808f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        public void onClick(View v) {
809fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            if (v == mNotificationTrigger) {
810f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickNotificationTrigger();
811f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            } else if (v == mRecentButton) {
812f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickRecentButton();
813f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            }
814f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
815f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    };
816f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
817f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickNotificationTrigger() {
818b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
819091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
820271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            if (!mNotificationsOn) {
821271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mNotificationsOn = true;
822cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler                mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
823271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                refreshNotificationTrigger();
824271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            } else {
8257c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                int msg = !mNotificationPanel.isShowing()
826271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    ? MSG_OPEN_NOTIFICATION_PANEL
827271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    : MSG_CLOSE_NOTIFICATION_PANEL;
828271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.removeMessages(msg);
829271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.sendEmptyMessage(msg);
830271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            }
831091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
8329120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
8339120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
834f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickRecentButton() {
835b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
83644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (mRecentsPanel == null) {
83744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            Intent intent = new Intent();
83844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setClass(mContext, RecentApplicationsActivity.class);
83944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
84044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
84144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mContext.startActivity(intent);
84244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        } else {
84344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
84444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mRecentsPanel.getVisibility() == View.GONE)
84544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ? MSG_OPEN_RECENTS_PANEL
84644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    : MSG_CLOSE_RECENTS_PANEL;
84744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.removeMessages(msg);
84844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.sendEmptyMessage(msg);
84944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            }
85044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
8513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
8523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private class NotificationClicker implements View.OnClickListener {
8543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private PendingIntent mIntent;
8553eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mPkg;
8563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mTag;
8573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private int mId;
8583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
8603eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mIntent = intent;
8613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mPkg = pkg;
8623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mTag = tag;
8633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mId = id;
8643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
8653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public void onClick(View v) {
8673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
8683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // The intent we are sending is for the application, which
8693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // won't have permission to immediately start an activity after
8703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // the user switches to home.  We know it is safe to do at this
8713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // point, so make sure new activity switches are now allowed.
8723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                ActivityManagerNative.getDefault().resumeAppSwitches();
8733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException e) {
8743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
8753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (mIntent != null) {
8773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                int[] pos = new int[2];
8783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                v.getLocationOnScreen(pos);
8793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Intent overlay = new Intent();
8803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                overlay.setSourceBounds(
8813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
8823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                try {
883f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
8843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                } catch (PendingIntent.CanceledException e) {
8853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    // the stack trace isn't very helpful here.  Just log the exception message.
8863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    Slog.w(TAG, "Sending contentIntent failed: " + e);
8873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
8883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
8893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
8913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                mBarService.onNotificationClick(mPkg, mTag, mId);
8923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException ex) {
8933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // system process is dead if we're here.
8943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
8953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // close the shade if it was open
8973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            animateCollapse();
8983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // If this click was on the intruder alert, hide that instead
9003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
9013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
9023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
9033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
9050f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        NotificationData.Entry entry = mNotns.remove(key);
9063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (entry == null) {
9073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
9083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
9093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
9103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the expanded view.
9113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
9123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
913a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler
914a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler        if (key == mNotificationPeekKey) {
915a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler            // must close the peek as well, since it's gone
916a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
917a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler        }
9183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the icon.
9190f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        ViewGroup iconParent = (ViewGroup)entry.icon.getParent();
9200f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        if (iconParent != null) iconParent.removeView(entry.icon);
9210ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
9223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return entry.notification;
9243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
9253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
926b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private class NotificationIconTouchListener implements View.OnTouchListener {
927b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        VelocityTracker mVT;
928b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
929b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public NotificationIconTouchListener() {
930b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
931b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
932b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public boolean onTouch(View v, MotionEvent event) {
933b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
9347c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato            boolean panelShowing = mNotificationPanel.isShowing();
935b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (panelShowing) return false;
936b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
937b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            switch (event.getAction()) {
938b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_DOWN:
939b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = VelocityTracker.obtain();
940b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
941b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // fall through
942b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_OUTSIDE:
943b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_MOVE:
944b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // peek and switch icons if necessary
945b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    int numIcons = mIconLayout.getChildCount();
9465e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                    int peekIndex = (int)((float)event.getX() * numIcons / mIconLayout.getWidth());
947b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peekIndex > numIcons - 1) peekIndex = numIcons - 1;
948b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    else if (peekIndex < 0) peekIndex = 0;
949b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
950b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (!peeking || mNotificationPeekIndex != peekIndex) {
951b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + peekIndex);
952b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
953b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        peekMsg.arg1 = peekIndex;
954b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
955b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
956b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
957b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // no delay if we're scrubbing left-right
9585e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendMessage(peekMsg);
959b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
960b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
961b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // check for fling
962b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mVT != null) {
963b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.addMovement(event);
964b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.computeCurrentVelocity(1000);
965b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // require a little more oomph once we're already in peekaboo mode
966b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (!panelShowing && (
967b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                               (peeking && mVT.getYVelocity() < -mNotificationFlingVelocity*3)
968b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            || (mVT.getYVelocity() < -mNotificationFlingVelocity))) {
969b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
970b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
971b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
972b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
973b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
974b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
975b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
976b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_UP:
977b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_CANCEL:
978b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
979b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peeking) {
9805e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK, 5000);
981b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
982b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT.recycle();
983b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = null;
984b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
985b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
986b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            return false;
987b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
988b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
989b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
9903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
991dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
992dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
993dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
9943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the icon.
995f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
9963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                notification.pkg + "/0x" + Integer.toHexString(notification.id));
9973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
9983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
10003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.icon,
10013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.iconLevel,
10023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.number);
10033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (!iconView.set(ic)) {
10043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
10053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
10063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the expanded view.
10083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
1009dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (!inflateViews(entry, mPile)) {
10103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
10113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + notification);
10123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
10133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
1014b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Add the icon.
1016dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mNotns.add(entry);
10170ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
10180f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
10193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return iconView;
10203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
10213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10220ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    private void reloadAllNotificationIcons() {
10230ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mIconLayout == null) return;
10240ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mIconLayout.removeAllViews();
10250ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
10260ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
10270ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
10280ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    private void updateNotificationIcons() {
10290f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // XXX: need to implement a new limited linear layout class
10300f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // to avoid removing & readding everything
1031dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
10320ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mIconLayout == null) return;
10330ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
1034b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final LinearLayout.LayoutParams params
10350ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mBarHeight);
1036b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10370f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        int N = mNotns.size();
1038dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1039dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
1040b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
1041dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
1042dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1043b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
1044b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10450ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        for (int i=0; i<MAX_NOTIFICATION_ICONS; i++) {
10460f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler            if (i>=N) break;
1047b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(mNotns.get(N-i-1).icon);
10480f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        }
1049dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1050b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
1051b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mIconLayout.getChildCount(); i++) {
1052b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mIconLayout.getChildAt(i);
1053b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
1054b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
1055b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1056b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1057b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1058b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
1059b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mIconLayout.removeView(remove);
1060dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
1061271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
1062b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
1063b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
10640ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            v.setPadding(mIconHPadding, 0, mIconHPadding, 0);
1065b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
10660ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mIconLayout.addView(v, i, params);
1067b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1068b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1069b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1070b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        loadNotificationPanel();
1071271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler        refreshNotificationTrigger();
10720f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    }
10730f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
1074b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private void loadNotificationPanel() {
1075b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        int N = mNotns.size();
1076b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1077b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
1078b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1079b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<N; i++) {
1080b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View row = mNotns.get(N-i-1).row;
1081b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(row);
1082b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1083b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1084b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
1085b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
1086b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mPile.getChildAt(i);
1087b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
1088b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
1089b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1090b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1091b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1092b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
1093b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mPile.removeView(remove);
1094b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1095b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1096b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
1097b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
1098b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
1099b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mPile.addView(toShow.get(i));
1100b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1101b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1102b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
1103b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
11044daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    void workAroundBadLayerDrawableOpacity(View v) {
11054daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        LayerDrawable d = (LayerDrawable)v.getBackground();
11064daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(null);
11074daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        d.setOpacity(PixelFormat.TRANSLUCENT);
11084daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(d);
11094daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    }
11104daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato
11113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
11123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        StatusBarNotification sbn = entry.notification;
11133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        RemoteViews remoteViews = sbn.notification.contentView;
11143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (remoteViews == null) {
11153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
11163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // create the row view
1119f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
1120f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
1121755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
11224daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        workAroundBadLayerDrawableOpacity(row);
11230f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        View vetoButton = row.findViewById(R.id.veto);
1124a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        if (entry.notification.isClearable()) {
1125a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _pkg = sbn.pkg;
1126a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _tag = sbn.tag;
1127a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final int _id = sbn.id;
112844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            vetoButton.setOnClickListener(new View.OnClickListener() {
1129a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                    public void onClick(View v) {
1130a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        try {
1131a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            mBarService.onNotificationClear(_pkg, _tag, _id);
1132a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        } catch (RemoteException ex) {
1133a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            // system process is dead if we're here.
1134a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        }
11350f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler                    }
1136a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                });
1137a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        } else {
1138a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            vetoButton.setVisibility(View.INVISIBLE);
1139a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        }
11403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1141561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        // the large icon
1142561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
1143561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        if (sbn.notification.largeIcon != null) {
1144561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setImageBitmap(sbn.notification.largeIcon);
1145561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        } else {
1146561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.getLayoutParams().width = 0;
1147561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setVisibility(View.INVISIBLE);
1148561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        }
1149561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato
11503eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // bind the click event to the content area
11513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
11523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // XXX: update to allow controls within notification views
11533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
11543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//        content.setOnFocusChangeListener(mFocusChangeListener);
11553eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        PendingIntent contentIntent = sbn.notification.contentIntent;
11563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (contentIntent != null) {
11573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent,
11583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        sbn.pkg, sbn.tag, sbn.id));
1159184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
1160184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
11613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        View expanded = null;
11643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        Exception exception = null;
11653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        try {
1166f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
11673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        catch (RuntimeException e) {
11693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            exception = e;
11703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (expanded == null) {
117246439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
11733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
11743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
11753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
11763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.addView(expanded);
11773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            row.setDrawingCacheEnabled(true);
11783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.row = row;
11813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.content = content;
11823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.expanded = expanded;
11833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return true;
11853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
1186ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
11870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler/*
1188b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public class ShadowController {
1189b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        boolean mShowShadows;
1190b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mShadowsForElements = new IdentityHashMap<View, View>(7);
1191b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mElementsForShadows = new IdentityHashMap<View, View>(7);
1192b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        LayoutTransition mElementTransition, mShadowTransition;
1193b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1194b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        View mTouchTarget;
1195f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1196b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        ShadowController(boolean showShadows) {
1197b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = showShadows;
1198b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mTouchTarget = null;
1199b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1200b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition = new LayoutTransition();
1201b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            AnimatorSet s = new AnimatorSet();
1202b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 48, 0))
1203b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 0.5f, 1f))
1204b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f))
1205b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1206b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.APPEARING, //s);
1207b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                   ObjectAnimator.ofInt(null, "top", 48, 0));
1208b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.APPEARING, 100);
1209b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setStartDelay(LayoutTransition.APPEARING, 0);
1210b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1211b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s = new AnimatorSet();
1212b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 0, 48))
1213b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 1f, 0.5f))
1214b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 1f, 0.5f))
1215b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1216b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.DISAPPEARING, //s);
1217b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofInt(null, "top", 0, 48));
1218b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.DISAPPEARING, 400);
1219b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1220b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition = new LayoutTransition();
1221b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.APPEARING,
1222b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
1223b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.APPEARING, 200);
1224b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setStartDelay(LayoutTransition.APPEARING, 100);
1225b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.DISAPPEARING,
1226b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
1227b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.DISAPPEARING, 100);
1228b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1229b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup bar = (ViewGroup) TabletStatusBar.this.mBarContents;
1230b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            bar.setLayoutTransition(mElementTransition);
1231b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup nav = (ViewGroup) TabletStatusBar.this.mNavigationArea;
1232b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            nav.setLayoutTransition(mElementTransition);
1233b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup shadowGroup = (ViewGroup) bar.findViewById(R.id.shadows);
1234b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadowGroup.setLayoutTransition(mShadowTransition);
1235b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1236b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1237b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void add(View element, View shadow) {
1238b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadow.setOnTouchListener(makeTouchListener());
1239b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowsForElements.put(element, shadow);
1240b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementsForShadows.put(shadow, element);
1241f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1242f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1243b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public boolean getShadowState() {
1244b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return mShowShadows;
1245f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1246f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1247b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public View.OnTouchListener makeTouchListener() {
1248b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return new View.OnTouchListener() {
1249b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
1250b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    final int action = ev.getAction();
1251b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1252b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);
1253b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1254b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    // currently redirecting events?
1255b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget == null) {
1256b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        mTouchTarget = mElementsForShadows.get(v);
1257b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1258b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1259b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
1260b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        boolean last = false;
1261b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        switch (action) {
1262b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_CANCEL:
1263b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_UP:
1264e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1265b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                if (mShowShadows) {
1266e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                    mHandler.sendEmptyMessageDelayed(MSG_RESTORE_SHADOWS,
1267b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                            v == mNotificationShadow ? 5000 : 500);
1268b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                }
1269b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                last = true;
1270b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1271b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_DOWN:
1272e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1273b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                                setElementShadow(mTouchTarget, false);
1274b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1275b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        }
1276b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        mTouchTarget.dispatchTouchEvent(ev);
1277b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        if (last) mTouchTarget = null;
1278b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        return true;
1279b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1280b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1281b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    return false;
1282b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1283b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            };
1284b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1285b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1286e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        public void refresh() {
1287b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            for (View element : mShadowsForElements.keySet()) {
1288b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                setElementShadow(element, mShowShadows);
1289b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1290e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        }
1291e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler
1292b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void showAllShadows() {
1293b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = true;
1294e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1295ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        }
1296ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1297b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void hideAllShadows() {
1298b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = false;
1299e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1300b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1301b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1302b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
1303b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // disabled (and should not be shadowed or re-shown)
1304b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void setElementShadow(View button, boolean shade) {
1305b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1306b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            if (shadow != null) {
1307b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                if (button.getVisibility() != View.GONE) {
1308b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
1309b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
1310b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1311b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            }
1312b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1313b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1314b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Hide both element and shadow, using default layout animations.
1315b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void hideElement(View button) {
1316b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "hiding: " + button);
1317b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1318b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1319b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(View.GONE);
1320b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1321b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(View.GONE);
1322b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1323b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1324b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Honoring the current shadow state.
1325b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void showElement(View button) {
1326b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "showing: " + button);
1327b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1328b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1329b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(mShowShadows ? View.VISIBLE : View.INVISIBLE);
1330b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1331b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(mShowShadows ? View.INVISIBLE : View.VISIBLE);
1332b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1333ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    }
13340ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    */
1335b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1336b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public class TouchOutsideListener implements View.OnTouchListener {
1337b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        private int mMsg;
1338ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        private StatusBarPanel mPanel;
1339b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1340ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        public TouchOutsideListener(int msg, StatusBarPanel panel) {
1341b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            mMsg = msg;
1342ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            mPanel = panel;
1343b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1344b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1345b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        public boolean onTouch(View v, MotionEvent ev) {
1346ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            final int action = ev.getAction();
1347ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            if (action == MotionEvent.ACTION_OUTSIDE
1348ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                    || (action == MotionEvent.ACTION_DOWN
1349ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                        && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
1350b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.removeMessages(mMsg);
1351b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.sendEmptyMessage(mMsg);
1352b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                return true;
1353b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            }
1354b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            return false;
1355b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1356b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    }
1357091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
1358f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1359f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.print("mDisabled=0x");
1360f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.println(Integer.toHexString(mDisabled));
1361f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
1362808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
1363d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1364d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1365