TabletStatusBar.java revision 933464dd02e9aeaff7944a2c8e3e44942971e1e8
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
122ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato    ViewGroup mNotificationAndImeArea;
123cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    InputMethodButton mInputMethodSwitchButton;
12406487a58be22b100daf3f950b9a1d25c3ea42aa2satok
125ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato    NotificationPanel mNotificationPanel;
1268a576713e255eb822558cef840d170d4477f47f0Joe Onorato    NotificationPeekPanel mNotificationPeekWindow;
127b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    ViewGroup mNotificationPeekRow;
128b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekIndex;
129a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler    IBinder mNotificationPeekKey;
130b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
131b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
132b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationPeekTapDuration;
133b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    int mNotificationFlingVelocity;
1343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1350f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    ViewGroup mPile;
1363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
137fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    BatteryController mBatteryController;
138fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    NetworkController mNetworkController;
1391e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
140ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    View mBarContents;
141b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1420ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    // hide system chrome ("lights out") support
1430ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    View mShadow;
144ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1450f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    NotificationIconArea.IconLayout mIconLayout;
1460f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
147ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    TabletTicker mTicker;
148dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
14910163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    View mFakeSpaceBar;
15010163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    KeyEvent mSpaceBarKeyEvent = null;
15110163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
152dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    // for disabling the status bar
153dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    int mDisabled = 0;
154dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
15555d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato    boolean mNotificationsOn = true;
15644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller    private RecentAppsPanel mRecentsPanel;
15755d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
158c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    public Context getContext() { return mContext; }
159c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
1609120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    protected void addPanelWindows() {
161f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
162f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
16344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Notification Panel
164f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationPanel = (NotificationPanel)View.inflate(context,
165755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_panel, null);
1667c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        mNotificationPanel.show(false, false);
167b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mNotificationPanel.setOnTouchListener(
168ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
169b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
170fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the battery and network icons
171fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
172fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addLabelView(
173fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.battery_text));
174ddbba42b812ab397a75db78aba6b48fecf0e31f6Joe Onorato        mNetworkController.addCombinedSignalIconView(
17542f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network_signal));
17642f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addDataTypeIconView(
17742f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)mNotificationPanel.findViewById(R.id.network_type));
178fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController.addLabelView(
179fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                (TextView)mNotificationPanel.findViewById(R.id.network_text));
1803e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        mNetworkController.addLabelView(
1813e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler                (TextView)mBarContents.findViewById(R.id.network_text));
182fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
18355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
184d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1859120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
1864cddc98a4b63961e3528c5a70cd5c55a67a0c60aJoe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
187cf2b199e98de71dcac042484800c07366363a734Joe Onorato                ViewGroup.LayoutParams.MATCH_PARENT,
1889120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
1899120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
19046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
1917c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
1927c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
1939120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                PixelFormat.TRANSLUCENT);
194ea70e63c0dcd09ec5790f4dca6ddd76284a6a23dJoe Onorato        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
1959120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        lp.setTitle("NotificationPanel");
1967c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
1977c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
1987c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
1999120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
2009120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
2019120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
202b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // Notification preview window
2038a576713e255eb822558cef840d170d4477f47f0Joe Onorato        mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context,
204755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                R.layout.status_bar_notification_peek, null);
205b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content);
206b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setVisibility(View.GONE);
207b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekWindow.setOnTouchListener(
2085e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow));
209b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight = new LayoutTransition();
210b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING,
211b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
212b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING,
213b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", -512, 0));
214b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubRight.setDuration(500);
215b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
216b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft = new LayoutTransition();
217b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING,
218b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
219b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING,
220b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ObjectAnimator.ofInt(null, "left", 512, 0));
221b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekScrubLeft.setDuration(500);
222b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
223b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        // XXX: setIgnoreChildren?
224b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp = new WindowManager.LayoutParams(
225b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                512, // ViewGroup.LayoutParams.WRAP_CONTENT,
226b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                ViewGroup.LayoutParams.WRAP_CONTENT,
227b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
228b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
22946e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
23046e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
231b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                PixelFormat.TRANSLUCENT);
232b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
233b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.setTitle("NotificationPeekWindow");
234b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
235b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
236b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp);
237b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
23844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        // Recents Panel
23944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (USE_2D_RECENTS) {
240755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato            mRecentsPanel = (RecentAppsPanel) View.inflate(context,
241755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato                    R.layout.status_bar_recent_panel, null);
24244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setVisibility(View.GONE);
24344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
24444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    mRecentsPanel));
24544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
24644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
24744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp = new WindowManager.LayoutParams(
24844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
24944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ViewGroup.LayoutParams.WRAP_CONTENT,
25044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
25144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
25246e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
253169a211f6be5fc842dce6281aad16697c6cecfa9Jim Miller                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
254169a211f6be5fc842dce6281aad16697c6cecfa9Jim Miller                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
25544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    PixelFormat.TRANSLUCENT);
25644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
25744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            lp.setTitle("RecentsPanel");
258fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            lp.windowAnimations = R.style.Animation_RecentPanel;
25944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
26044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
26144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mRecentsPanel.setBar(this);
26244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
2639120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
264808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
265808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    @Override
266f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void start() {
267f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        super.start(); // will add the main bar view
268808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
269808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
2700ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    @Override
2710ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    protected void onConfigurationChanged (Configuration newConfig) {
2720ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        loadDimens();
2730ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
2740ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2750ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    protected void loadDimens() {
2760ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final Resources res = mContext.getResources();
2770ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2780ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mBarHeight = res.getDimensionPixelSize(
2790ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            com.android.internal.R.dimen.status_bar_height);
2800ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        int newIconSize = res.getDimensionPixelSize(
2820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            com.android.internal.R.dimen.status_bar_icon_size);
2830ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        int newIconHPadding = res.getDimensionPixelSize(
2840ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            R.dimen.status_bar_icon_padding);
2850ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
2860ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
2870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
2880ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            mIconHPadding = newIconHPadding;
2890ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            mIconSize = newIconSize;
2900ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            reloadAllNotificationIcons(); // reload the tray
2910ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        }
2920ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
2930ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
294808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected View makeStatusBarView() {
295f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final Context context = mContext;
29610163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
29710163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        mWindowManager = IWindowManager.Stub.asInterface(
29810163c689a713a35f69aad420c35372946b8b32aDaniel Sandler                ServiceManager.getService(Context.WINDOW_SERVICE));
299808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3000ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        loadDimens();
301808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
302b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
303f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                context, R.layout.status_bar, null);
304808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mStatusBarView = sb;
305808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
306b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        sb.setHandler(mHandler);
307b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
308ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        mBarContents = sb.findViewById(R.id.bar_contents);
309f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
310fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // the whole right-hand side of the bar
311fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationArea = sb.findViewById(R.id.notificationArea);
312fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato
31355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // the button to open the notification area
314fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
315f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        mNotificationTrigger.setOnClickListener(mOnClickListener);
31655d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato
317808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        // the more notifications icon
318808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
319808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
3203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // where the icons go
3213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
322b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mIconLayout.setOnTouchListener(new NotificationIconTouchListener());
323b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
324b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ViewConfiguration vc = ViewConfiguration.get(context);
325b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationPeekTapDuration = vc.getTapTimeout();
326b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        mNotificationFlingVelocity = 300; // px/s
3273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
328c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        mTicker = new TabletTicker(this);
329dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
330fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        // The icons
331fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController = new BatteryController(mContext);
332fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
333fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato        mNetworkController = new NetworkController(mContext);
33442f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addCombinedSignalIconView(
33542f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)sb.findViewById(R.id.network_signal));
33642f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato        mNetworkController.addDataTypeIconView(
33742f8e130244cf216701bd03a34935c0fa1c3efc5Joe Onorato                (ImageView)sb.findViewById(R.id.network_type));
3381e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler
339091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // The navigation buttons
340091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        mNavigationArea = sb.findViewById(R.id.navigationArea);
341536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton = (ImageView)mNavigationArea.findViewById(R.id.back);
342b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mHomeButton = mNavigationArea.findViewById(R.id.home);
343e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        mMenuButton = mNavigationArea.findViewById(R.id.menu);
344b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
345b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mRecentButton.setOnClickListener(mOnClickListener);
346091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
34706487a58be22b100daf3f950b9a1d25c3ea42aa2satok        // The bar contents buttons
348ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        mNotificationAndImeArea = (ViewGroup)sb.findViewById(R.id.notificationAndImeArea);
349cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton = (InputMethodButton) sb.findViewById(R.id.imeSwitchButton);
35006487a58be22b100daf3f950b9a1d25c3ea42aa2satok
35110163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        // for redirecting errant bar taps to the IME
35210163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
35310163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
354b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // "shadows" of the status bar features, for lights-out mode
3550ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mShadow = sb.findViewById(R.id.bar_shadow);
3560ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mShadow.setOnTouchListener(
3570ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            new View.OnTouchListener() {
3580ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
3590ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
3600ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mShadow.setVisibility(View.GONE);
3610ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mBarContents.setVisibility(View.VISIBLE);
3620ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    }
3630ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    return false;
3640ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                }
3650ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            });
3660ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3670ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        // tuning parameters
3680ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SYSBAR_DURATION = 600;
3690ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SHADOW_DURATION = 1000;
3700ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_GOING_OUT_SHADOW_DELAY    = 500;
3710ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3720ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_COMING_UP_SYSBAR_DURATION = 200;
3730ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler//        final int LIGHTS_COMING_UP_SYSBAR_DELAY    = 50;
3740ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        final int LIGHTS_COMING_UP_SHADOW_DURATION = 0;
3750ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3760ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        LayoutTransition xition = new LayoutTransition();
3770ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.APPEARING,
3780ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f));
3790ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_COMING_UP_SYSBAR_DURATION);
3800ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.APPEARING, 0);
3810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.DISAPPEARING,
3820ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
3830ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_GOING_OUT_SYSBAR_DURATION);
3840ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
3850ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        ((ViewGroup)sb.findViewById(R.id.bar_contents_holder)).setLayoutTransition(xition);
3860ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
3870ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition = new LayoutTransition();
3880ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.APPEARING,
3890ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
3900ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DURATION);
3910ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DELAY);
3920ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setAnimator(LayoutTransition.DISAPPEARING,
3930ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
3940ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_COMING_UP_SHADOW_DURATION);
3950ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
3960ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        ((ViewGroup)sb.findViewById(R.id.bar_shadow_holder)).setLayoutTransition(xition);
397b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
3985dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        // set the initial view visibility
3995dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
4005dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
401dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Add the windows
402dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        addPanelWindows();
403dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
404dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content);
405dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mPile.removeAllViews();
40644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
407dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        ScrollView scroller = (ScrollView)mPile.getParent();
408dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        scroller.setFillViewport(true);
409dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
410808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return sb;
411808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
412808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
413808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    protected int getStatusBarGravity() {
414808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato        return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
415808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
416808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
4179120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    private class H extends Handler {
4189120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        public void handleMessage(Message m) {
4199120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            switch (m.what) {
420b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_OPEN_NOTIFICATION_PEEK:
421b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
422b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (m.arg1 >= 0) {
423b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int N = mNotns.size();
424a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                        if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
425b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
426b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0);
427a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekIndex = -1;
428a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekKey = null;
429b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
430b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
431b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        final int peekIndex = m.arg1;
432b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (peekIndex < N) {
4330ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                            //Slog.d(TAG, "loading peek: " + peekIndex);
434b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
435b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            NotificationData.Entry copy = new NotificationData.Entry(
436b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.key,
437b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.notification,
438b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                                    entry.icon);
439b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            inflateViews(copy, mNotificationPeekRow);
440b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
441b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            entry.icon.setBackgroundColor(0x20FFFFFF);
442b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
443b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                          mNotificationPeekRow.setLayoutTransition(
444b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                              peekIndex < mNotificationPeekIndex
445b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  ? mNotificationPeekScrubLeft
446b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler//                                  : mNotificationPeekScrubRight);
447b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
448b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.removeAllViews();
449b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekRow.addView(copy.row);
450b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
451b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekWindow.setVisibility(View.VISIBLE);
4527c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                            mNotificationPanel.show(false, true);
453b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
454b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mNotificationPeekIndex = peekIndex;
455a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                            mNotificationPeekKey = entry.key;
456b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
457b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
458b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
459b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MSG_CLOSE_NOTIFICATION_PEEK:
460b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notification peek window");
461b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekWindow.setVisibility(View.GONE);
462b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mNotificationPeekRow.removeAllViews();
463b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    final int N = mNotns.size();
464a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
465b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
466b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        entry.icon.setBackgroundColor(0);
467b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
468a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler
469a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    mNotificationPeekIndex = -1;
470a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler                    mNotificationPeekKey = null;
471b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    break;
4729120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_OPEN_NOTIFICATION_PANEL:
4739120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "opening notifications panel");
4747c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    if (!mNotificationPanel.isShowing()) {
475b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mNotificationPeekWindow.setVisibility(View.GONE);
4767c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                        mNotificationPanel.show(true, true);
4770ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mNotificationArea.setVisibility(View.GONE);
47850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                        mTicker.halt();
479091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
4809120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
4819120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                case MSG_CLOSE_NOTIFICATION_PANEL:
4829120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
4837c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                    if (mNotificationPanel.isShowing()) {
4847c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                        mNotificationPanel.show(false, true);
4850ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                        mNotificationArea.setVisibility(View.VISIBLE);
486091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                    }
4879120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
48844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_OPEN_RECENTS_PANEL:
48944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "opening recents panel");
49044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE);
49144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    break;
49244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                case MSG_CLOSE_RECENTS_PANEL:
49344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (DEBUG) Slog.d(TAG, "closing recents panel");
49444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE);
4959120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler                    break;
4960ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                case MSG_SHOW_CHROME:
497e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
4980ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mBarContents.setVisibility(View.VISIBLE);
4990ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mShadow.setVisibility(View.GONE);
50006e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    break;
5010ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                case MSG_HIDE_CHROME:
502e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
50306e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler                    animateCollapse();
5040ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mBarContents.setVisibility(View.GONE);
5050ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                    mShadow.setVisibility(View.VISIBLE);
506e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                    break;
5079120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler            }
5089120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler        }
5099120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
510271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
511808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
5121e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
513808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
514808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
515808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateIcon(String slot, int index, int viewIndex,
516808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato            StatusBarIcon old, StatusBarIcon icon) {
5171e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
518808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
519808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
520808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeIcon(String slot, int index, int viewIndex) {
5211e3ed8fc9537209920eea6adf5e576058f81d587Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
522808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
523808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
524808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void addNotification(IBinder key, StatusBarNotification notification) {
5253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
5263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        addNotificationViews(key, notification);
527fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler
52850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
529cf2b199e98de71dcac042484800c07366363a734Joe Onorato        if (false && immersive) {
530fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // TODO: immersive mode popups for tablet
531fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else if (notification.notification.fullScreenIntent != null) {
532fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            // not immersive & a full-screen alert should be shown
533fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;"
534fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                    + " sending fullScreenIntent");
535fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            try {
536fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler                notification.notification.fullScreenIntent.send();
537fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            } catch (PendingIntent.CanceledException e) {
538fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler            }
539fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        } else {
540eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato            tick(key, notification, true);
541fb970e920413e7f3a6159056fa698bb9c6b04056Daniel Sandler        }
5425dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
5435dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
544808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
545808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
546808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void updateNotification(IBinder key, StatusBarNotification notification) {
5473eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
54844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller
5490f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        final NotificationData.Entry oldEntry = mNotns.findByKey(key);
550379020aec619c66d3e040de01f0726687fd2ad85Daniel Sandler        if (oldEntry == null) {
5513eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "updateNotification for unknown key: " + key);
5523eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return;
5533eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5553eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarNotification oldNotification = oldEntry.notification;
5563eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews oldContentView = oldNotification.notification.contentView;
5573eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5583eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final RemoteViews contentView = notification.notification.contentView;
5593eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
560373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        if (DEBUG) {
5613eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
5623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " expanded=" + oldEntry.expanded
5643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + oldContentView);
5653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.d(TAG, "new notification: when=" + notification.notification.when
5663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " ongoing=" + oldNotification.isOngoing()
5673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + " contentView=" + contentView);
5683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
5693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
5703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Can we just reapply the RemoteViews in place?  If when didn't change, the order
5713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // didn't change.
572373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        boolean orderUnchanged = (notification.notification.when == oldNotification.notification.when
5733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && notification.isOngoing() == oldNotification.isOngoing()
5743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldEntry.expanded != null
5753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView != null
5763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView != null
5773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && contentView.getPackage() != null
5783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage() != null
5793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                && oldContentView.getPackage().equals(contentView.getPackage())
580373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler                && oldContentView.getLayoutId() == contentView.getLayoutId());
581373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
582373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        boolean isLastAnyway = rowParent.indexOfChild(oldEntry.row) == rowParent.getChildCount() - 1;
583373a9983742b3d2370c36183aca3cde4614e6185Daniel Sandler        if (orderUnchanged || isLastAnyway) {
5843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
5853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            oldEntry.notification = notification;
5863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
5873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Reapply the RemoteViews
588f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                contentView.reapply(mContext, oldEntry.content);
5893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // update the contentIntent
5903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final PendingIntent contentIntent = notification.notification.contentIntent;
5913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (contentIntent != null) {
5923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
5933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                                notification.pkg, notification.tag, notification.id));
594184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                } else {
595184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato                    oldEntry.content.setOnClickListener(null);
5963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
5973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // Update the icon.
5983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
5993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.icon, notification.notification.iconLevel,
6003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        notification.notification.number);
6013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                if (!oldEntry.icon.set(ic)) {
6023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    handleNotificationError(key, notification, "Couldn't update icon: " + ic);
6033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    return;
6043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
6057ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler
6067ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                if (key == mNotificationPeekKey) {
6077ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                    // must update the peek window
6087ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                    Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
6097ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                    peekMsg.arg1 = mNotificationPeekIndex;
6107ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
6117ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                    mHandler.sendMessage(peekMsg);
6127ef29b5a066e87ac890cf198c58e2ffe8549bea1Daniel Sandler                }
6133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
6143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            catch (RuntimeException e) {
6153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // It failed to add cleanly.  Log, and remove the view from the panel.
6163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
6173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                removeNotificationViews(key);
6183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                addNotificationViews(key, notification);
6193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
6203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
6213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
6223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            removeNotificationViews(key);
6233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            addNotificationViews(key, notification);
6243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
62550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // fullScreenIntent doesn't happen on updates.  You need to clear & repost a new
62650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        // notification.
62750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        final boolean immersive = isImmersive();
62850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        if (false && immersive) {
62950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // TODO: immersive mode
63050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } else {
631eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato            tick(key, notification, false);
63250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
6335dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
6345dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
635808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
636808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
637808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void removeNotification(IBinder key) {
6383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO");
6393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        removeNotificationViews(key);
64050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        mTicker.remove(key);
6415dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        setAreThereNotifications();
642808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
643808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
6443e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler    public void showClock(boolean show) {
6453e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        View clock = mBarContents.findViewById(R.id.clock);
6463e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        View network_text = mBarContents.findViewById(R.id.network_text);
6473e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if (clock != null) {
6483e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            clock.setVisibility(show ? View.VISIBLE : View.GONE);
6493e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
6503e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if (network_text != null) {
6513e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            network_text.setVisibility((!show) ? View.VISIBLE : View.GONE);
6523e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
6533e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler    }
6543e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler
655808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void disable(int state) {
656091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int old = mDisabled;
657091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        int diff = state ^ old;
658dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mDisabled = state;
659dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
660091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        // act accordingly
6613e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
6623e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
6633e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            Slog.d(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
6643e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler            showClock(show);
6653e8f5a2c1beb4b918856063880e05125946e4347Daniel Sandler        }
6666f6cf3c5e577aa62cfd959fa5ef046531090ce31Daniel Sandler        if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
6676f6cf3c5e577aa62cfd959fa5ef046531090ce31Daniel Sandler            boolean show = (state & StatusBarManager.DISABLE_SYSTEM_INFO) == 0;
6686f6cf3c5e577aa62cfd959fa5ef046531090ce31Daniel Sandler            Slog.d(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes"));
6696f6cf3c5e577aa62cfd959fa5ef046531090ce31Daniel Sandler            mNotificationTrigger.setVisibility(show ? View.VISIBLE : View.GONE);
6706f6cf3c5e577aa62cfd959fa5ef046531090ce31Daniel Sandler        }
671dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
672dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
673dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_EXPAND: yes");
674dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                animateCollapse();
675dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
676dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
677dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
678dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
679dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
680b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
6810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mNotificationIconArea.setVisibility(View.GONE);
682091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                mTicker.halt();
683dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
684dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
685b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                // synchronize with current shadow state
6860ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mNotificationIconArea.setVisibility(View.VISIBLE);
687dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
688dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
689091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
690ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato                mTicker.halt();
691dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
692dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
693091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) {
694091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato            if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) {
695091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: yes");
696fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.GONE);
697b70c82dc45f62a1c257a80e7aa9e0ecfe063c1besatok                mInputMethodSwitchButton.setScreenLocked(true);
698dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            } else {
699091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato                Slog.d(TAG, "DISABLE_NAVIGATION: no");
700fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato                mNavigationArea.setVisibility(View.VISIBLE);
701b70c82dc45f62a1c257a80e7aa9e0ecfe063c1besatok                mInputMethodSwitchButton.setScreenLocked(false);
702dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
703dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
704dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
705dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
706ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    private boolean hasTicker(Notification n) {
70746439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato        return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
708ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato    }
709ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato
710eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato    private void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
71155d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        // Don't show the ticker when the windowshade is open.
7127c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato        if (mNotificationPanel.isShowing()) {
71355d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato            return;
71455d2d7646bf13bb5406bf01fd1bb96e58588570cJoe Onorato        }
715eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato        // If they asked for FLAG_ONLY_ALERT_ONCE, then only show this notification
716eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato        // if it's a new notification.
717eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato        if (!firstTime && (n.notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
718eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato            return;
719eeed9949835ae4d516a751f3254967e9ad7398a5Joe Onorato        }
720dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // Show the ticker if one is requested. Also don't do this
721dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // until status bar window is attached to the window manager,
722dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // because...  well, what's the point otherwise?  And trying to
723dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        // run a ticker without being attached will crash!
724ef1e7763c2dc5b9bac69cc747efe05c81d9fd9fcJoe Onorato        if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
725dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
726dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
72750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato                mTicker.add(key, n);
728ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato                mNotificationAndImeArea.setVisibility(View.GONE);
729dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            }
730dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
731dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler    }
732dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
733b8027d87d87fbf24a6091ef183e519157876df41Daniel Sandler    // called by TabletTicker when it's done with all queued ticks
734b8027d87d87fbf24a6091ef183e519157876df41Daniel Sandler    public void doneTicking() {
735ec51a82bd6e7a33fe6ed84ba252b82625629eaacJoe Onorato        mNotificationAndImeArea.setVisibility(View.VISIBLE);
736b8027d87d87fbf24a6091ef183e519157876df41Daniel Sandler    }
737b8027d87d87fbf24a6091ef183e519157876df41Daniel Sandler
738808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateExpand() {
739b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
740b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
741808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    }
742808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato
743808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato    public void animateCollapse() {
744b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
745b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
74644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
74744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
7489120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
7499120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
750fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato    // called by StatusBar
75106e6630a462b6a5c04c319d781d64896778d351fDaniel Sandler    @Override
7529305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    public void setLightsOn(boolean on) {
75359485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
75459485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // that can't handle lights-out mode.
7550ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mMenuButton.getVisibility() == View.VISIBLE) {
75659485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler            on = true;
75759485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        }
7580ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.removeMessages(MSG_HIDE_CHROME);
7590ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.removeMessages(MSG_SHOW_CHROME);
7600ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mHandler.sendEmptyMessage(on ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
7619305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato    }
7629305647eb61bb60a1f42481a0c0d208dc9bbe965Joe Onorato
763e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    public void setMenuKeyVisible(boolean visible) {
764e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        if (DEBUG) {
765e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
766e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler        }
767b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
76859485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler
76959485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        // See above re: lights-out policy for legacy apps.
77059485d7442a175551fcb5eeee71820432df4ea7bDaniel Sandler        if (visible) setLightsOn(true);
771e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler    }
772e02d808abf370965c3c4e4d38af11bc69110fde2Daniel Sandler
773cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok    public void setIMEButtonVisible(IBinder token, boolean visible) {
77406487a58be22b100daf3f950b9a1d25c3ea42aa2satok        if (DEBUG) {
77506487a58be22b100daf3f950b9a1d25c3ea42aa2satok            Slog.d(TAG, (visible?"showing":"hiding") + " the IME button");
77606487a58be22b100daf3f950b9a1d25c3ea42aa2satok        }
777cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok        mInputMethodSwitchButton.setIMEButtonVisible(token, visible);
778536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato        mBackButton.setImageResource(
779536c58fbe51a53d0e6e78c360c9f6069ae0fd465Joe Onorato                visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back);
78010163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        if (FAKE_SPACE_BAR) {
78110163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            mFakeSpaceBar.setVisibility(visible ? View.VISIBLE : View.GONE);
78210163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        }
78306487a58be22b100daf3f950b9a1d25c3ea42aa2satok    }
78406487a58be22b100daf3f950b9a1d25c3ea42aa2satok
78550ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    private boolean isImmersive() {
78650ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        try {
78750ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return ActivityManagerNative.getDefault().isTopActivityImmersive();
78850ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
78950ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        } catch (RemoteException ex) {
79050ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            // the end is nigh
79150ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato            return false;
79250ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato        }
79350ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato    }
79450ec5ec0b8b3ab9cf697c8e3925e3fdd837f5e7dJoe Onorato
7955dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    private void setAreThereNotifications() {
7965dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato        final boolean hasClearable = mNotns.hasClearableItems();
7975dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato    }
7985dd1169ae95162383acf00d1e9a1886e0ac99a70Joe Onorato
799f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    /**
800f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     * Cancel this notification and tell the status bar service about the failure. Hold no locks.
801f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato     */
802f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
803f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        removeNotification(key);
804f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        try {
805f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
806f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        } catch (RemoteException ex) {
807f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            // The end is nigh.
808f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
809f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
810f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
81110163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    private void sendKey(KeyEvent key) {
81210163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        try {
81310163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            if (DEBUG) Slog.d(TAG, "injecting key event: " + key);
81410163c689a713a35f69aad420c35372946b8b32aDaniel Sandler            mWindowManager.injectInputEventNoWait(key);
81510163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        } catch (RemoteException ex) {
81610163c689a713a35f69aad420c35372946b8b32aDaniel Sandler        }
81710163c689a713a35f69aad420c35372946b8b32aDaniel Sandler    }
81810163c689a713a35f69aad420c35372946b8b32aDaniel Sandler
819f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
820f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        public void onClick(View v) {
821fd52b18d9bf3cd62c7a07058536e9f97db65beeaJoe Onorato            if (v == mNotificationTrigger) {
822f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickNotificationTrigger();
823f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            } else if (v == mRecentButton) {
824f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                onClickRecentButton();
825f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            }
826f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        }
827f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    };
828f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato
829f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickNotificationTrigger() {
830b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked notification icons; disabled=" + mDisabled);
831091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
832271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            if (!mNotificationsOn) {
833271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mNotificationsOn = true;
834cf3c7cf3c986526398e2bc79a39227d751202822Daniel Sandler                mIconLayout.setVisibility(View.VISIBLE); // TODO: animation
835271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            } else {
8367c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato                int msg = !mNotificationPanel.isShowing()
837271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    ? MSG_OPEN_NOTIFICATION_PANEL
838271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                    : MSG_CLOSE_NOTIFICATION_PANEL;
839271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.removeMessages(msg);
840271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler                mHandler.sendEmptyMessage(msg);
841271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler            }
842091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato        }
8439120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler    }
8449120d55b806aec981ce7c1af20b7aa3d303ccca5Daniel Sandler
845f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void onClickRecentButton() {
846b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
84744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        if (mRecentsPanel == null) {
84844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            Intent intent = new Intent();
84944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setClass(mContext, RecentApplicationsActivity.class);
85044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
85144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
85244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            mContext.startActivity(intent);
85344c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        } else {
85444c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
85544c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                int msg = (mRecentsPanel.getVisibility() == View.GONE)
85644c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    ? MSG_OPEN_RECENTS_PANEL
85744c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                    : MSG_CLOSE_RECENTS_PANEL;
85844c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.removeMessages(msg);
85944c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller                mHandler.sendEmptyMessage(msg);
86044c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            }
86144c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller        }
8623eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
8633eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
864c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
865c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler        return new NotificationClicker(intent, pkg, tag, id);
866c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler    }
867c51451a318af8e7076e7789bc1fcd91454f1e5a9Daniel Sandler
8683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private class NotificationClicker implements View.OnClickListener {
8693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private PendingIntent mIntent;
8703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mPkg;
8713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private String mTag;
8723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        private int mId;
8733eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8743eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
8753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mIntent = intent;
8763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mPkg = pkg;
8773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mTag = tag;
8783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            mId = id;
8793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
8803eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        public void onClick(View v) {
8823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
8833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // The intent we are sending is for the application, which
8843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // won't have permission to immediately start an activity after
8853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // the user switches to home.  We know it is safe to do at this
8863eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // point, so make sure new activity switches are now allowed.
8873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                ActivityManagerNative.getDefault().resumeAppSwitches();
8883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException e) {
8893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
8903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
8913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            if (mIntent != null) {
8923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                int[] pos = new int[2];
8933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                v.getLocationOnScreen(pos);
8943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                Intent overlay = new Intent();
8953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                overlay.setSourceBounds(
8963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
8973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                try {
898f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                    mIntent.send(mContext, 0, overlay);
8993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                } catch (PendingIntent.CanceledException e) {
9003eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    // the stack trace isn't very helpful here.  Just log the exception message.
9013eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    Slog.w(TAG, "Sending contentIntent failed: " + e);
9023eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                }
9033eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
9043eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            try {
9063eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                mBarService.onNotificationClick(mPkg, mTag, mId);
9073eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            } catch (RemoteException ex) {
9083eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                // system process is dead if we're here.
9093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            }
9103eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // close the shade if it was open
9123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            animateCollapse();
9133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            // If this click was on the intruder alert, hide that instead
9153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
9163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
9173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
9183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarNotification removeNotificationViews(IBinder key) {
9200f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        NotificationData.Entry entry = mNotns.remove(key);
9213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (entry == null) {
9223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.w(TAG, "removeNotification for unknown key: " + key);
9233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
9243eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
9253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the expanded view.
9263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup rowParent = (ViewGroup)entry.row.getParent();
9273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (rowParent != null) rowParent.removeView(entry.row);
928a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler
929a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler        if (key == mNotificationPeekKey) {
930a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler            // must close the peek as well, since it's gone
931a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
932a8e5b060a6ec5a5807f2858eccec835c7b083067Daniel Sandler        }
9333eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Remove the icon.
9340f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        ViewGroup iconParent = (ViewGroup)entry.icon.getParent();
9350f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler//        if (iconParent != null) iconParent.removeView(entry.icon);
9360ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
9373eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
9383eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return entry.notification;
9393eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
9403eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
941b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private class NotificationIconTouchListener implements View.OnTouchListener {
942b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        VelocityTracker mVT;
943b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
944b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public NotificationIconTouchListener() {
945b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
946b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
947b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        public boolean onTouch(View v, MotionEvent event) {
948b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            boolean peeking = mNotificationPeekWindow.getVisibility() != View.GONE;
9497c270fab75c2f4529e45ea80b31d4017ab516482Joe Onorato            boolean panelShowing = mNotificationPanel.isShowing();
950b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (panelShowing) return false;
951b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
952b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            switch (event.getAction()) {
953b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_DOWN:
954b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = VelocityTracker.obtain();
955b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
956b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // fall through
957b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_OUTSIDE:
958b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_MOVE:
959b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // peek and switch icons if necessary
960b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    int numIcons = mIconLayout.getChildCount();
9615e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                    int peekIndex = (int)((float)event.getX() * numIcons / mIconLayout.getWidth());
962b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peekIndex > numIcons - 1) peekIndex = numIcons - 1;
963b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    else if (peekIndex < 0) peekIndex = 0;
964b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
965b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (!peeking || mNotificationPeekIndex != peekIndex) {
966b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (DEBUG) Slog.d(TAG, "will peek at notification #" + peekIndex);
967b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK);
968b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        peekMsg.arg1 = peekIndex;
969b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
970b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
971b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
972b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // no delay if we're scrubbing left-right
9735e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendMessage(peekMsg);
974b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
975b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
976b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    // check for fling
977b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (mVT != null) {
978b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.addMovement(event);
979b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        mVT.computeCurrentVelocity(1000);
980b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        // require a little more oomph once we're already in peekaboo mode
981b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        if (!panelShowing && (
982b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                               (peeking && mVT.getYVelocity() < -mNotificationFlingVelocity*3)
983b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            || (mVT.getYVelocity() < -mNotificationFlingVelocity))) {
984b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
985b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
986b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
987b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                            mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
988b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                        }
989b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
990b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
991b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_UP:
992b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                case MotionEvent.ACTION_CANCEL:
993b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK);
994b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    if (peeking) {
9955e759460dcb91ba96758c2ac6d354ff8563b78a4Joe Onorato                        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK, 5000);
996b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    }
997b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT.recycle();
998b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    mVT = null;
999b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                    return true;
1000b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1001b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            return false;
1002b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1003b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
1004b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10053eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
1006dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
1007dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
1008dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
10093eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the icon.
1010f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        final StatusBarIconView iconView = new StatusBarIconView(mContext,
10113eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                notification.pkg + "/0x" + Integer.toHexString(notification.id));
10123eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
10133eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10143eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
10153eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.icon,
10163eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.iconLevel,
10173eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    notification.notification.number);
10183eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (!iconView.set(ic)) {
10193eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
10203eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
10213eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
10223eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Construct the expanded view.
10233eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
1024dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (!inflateViews(entry, mPile)) {
10253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
10263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                    + notification);
10273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return null;
10283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
1029b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // Add the icon.
1031dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        mNotns.add(entry);
10320ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
10330f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
10343eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return iconView;
10353eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
10363eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
10370ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    private void reloadAllNotificationIcons() {
10380ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mIconLayout == null) return;
10390ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        mIconLayout.removeAllViews();
10400ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        updateNotificationIcons();
10410ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    }
10420ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
10430ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    private void updateNotificationIcons() {
10440f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // XXX: need to implement a new limited linear layout class
10450f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        // to avoid removing & readding everything
1046dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
10470ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        if (mIconLayout == null) return;
10480ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler
1049b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        final LinearLayout.LayoutParams params
10500ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mBarHeight);
1051b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10520f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        int N = mNotns.size();
1053dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1054dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        if (DEBUG) {
1055b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
1056dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
1057dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1058b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
1059b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
10600ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler        for (int i=0; i<MAX_NOTIFICATION_ICONS; i++) {
10610f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler            if (i>=N) break;
1062b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(mNotns.get(N-i-1).icon);
10630f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        }
1064dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler
1065b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
1066b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mIconLayout.getChildCount(); i++) {
1067b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mIconLayout.getChildAt(i);
1068b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
1069b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
1070b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1071b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1072b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1073b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
1074b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mIconLayout.removeView(remove);
1075dfa08db1652585a8cf27f929371c7ca6bf18ca60Daniel Sandler        }
1076271ea12dc29ad30009df785f21f6782ec29844c8Daniel Sandler
1077b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
1078b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
10790ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler            v.setPadding(mIconHPadding, 0, mIconHPadding, 0);
1080b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
10810ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler                mIconLayout.addView(v, i, params);
1082b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1083b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1084b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1085b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        loadNotificationPanel();
10860f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler    }
10870f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler
1088b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    private void loadNotificationPanel() {
1089b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        int N = mNotns.size();
1090b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1091b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toShow = new ArrayList<View>();
1092b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1093b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<N; i++) {
1094b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View row = mNotns.get(N-i-1).row;
1095b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            toShow.add(row);
1096b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1097b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1098b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        ArrayList<View> toRemove = new ArrayList<View>();
1099b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<mPile.getChildCount(); i++) {
1100b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View child = mPile.getChildAt(i);
1101b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (!toShow.contains(child)) {
1102b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                toRemove.add(child);
1103b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1104b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1105b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1106b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (View remove : toRemove) {
1107b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            mPile.removeView(remove);
1108b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1109b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
1110b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        for (int i=0; i<toShow.size(); i++) {
1111b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            View v = toShow.get(i);
1112b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            if (v.getParent() == null) {
1113b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler                mPile.addView(toShow.get(i));
1114b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler            }
1115b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler        }
1116b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler    }
1117b0cc50de14dc9e2d0d224803bb523aa7f48904acDaniel Sandler
11184daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    void workAroundBadLayerDrawableOpacity(View v) {
11194daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        LayerDrawable d = (LayerDrawable)v.getBackground();
11204daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(null);
11214daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        d.setOpacity(PixelFormat.TRANSLUCENT);
11224daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        v.setBackgroundDrawable(d);
11234daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato    }
11244daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato
11253eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
11263eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        StatusBarNotification sbn = entry.notification;
11273eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        RemoteViews remoteViews = sbn.notification.contentView;
11283eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (remoteViews == null) {
11293eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
11303eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11313eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11323eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // create the row view
1133f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
1134f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato                Context.LAYOUT_INFLATER_SERVICE);
1135755cc74e4cebdf67d21a2477512a4ac9b01e8323Joe Onorato        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
11364daaeafd278d22ec9013d1cdaade562044ee907eJoe Onorato        workAroundBadLayerDrawableOpacity(row);
11370f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler        View vetoButton = row.findViewById(R.id.veto);
1138a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        if (entry.notification.isClearable()) {
1139a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _pkg = sbn.pkg;
1140a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final String _tag = sbn.tag;
1141a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            final int _id = sbn.id;
114244c66fe2cd912fcea2e9824eb421d5c8d9ffadbdJim Miller            vetoButton.setOnClickListener(new View.OnClickListener() {
1143a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                    public void onClick(View v) {
1144a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        try {
1145a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            mBarService.onNotificationClear(_pkg, _tag, _id);
1146a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        } catch (RemoteException ex) {
1147a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                            // system process is dead if we're here.
1148a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                        }
11490f0b11c8719495ce559b93366fe9cd79782d791cDaniel Sandler                    }
1150a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato                });
1151a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        } else {
1152a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato            vetoButton.setVisibility(View.INVISIBLE);
1153a4a6503d30ed21402847dbd25849ba2dc68a1369Joe Onorato        }
11543eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
1155561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        // the large icon
1156561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
1157561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        if (sbn.notification.largeIcon != null) {
1158561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setImageBitmap(sbn.notification.largeIcon);
1159561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        } else {
1160561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.getLayoutParams().width = 0;
1161561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato            largeIcon.setVisibility(View.INVISIBLE);
1162561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato        }
1163561d3858bb9409b999a19f7ba93f0b12e1db835fJoe Onorato
11643eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // bind the click event to the content area
11653eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
11663eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        // XXX: update to allow controls within notification views
11673eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
11683eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler//        content.setOnFocusChangeListener(mFocusChangeListener);
11693eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        PendingIntent contentIntent = sbn.notification.contentIntent;
11703eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (contentIntent != null) {
11713eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.setOnClickListener(new NotificationClicker(contentIntent,
11723eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler                        sbn.pkg, sbn.tag, sbn.id));
1173184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato        } else {
1174184498ce5a8d77e1d9c45693363829daaeef9611Joe Onorato            content.setOnClickListener(null);
11753eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11763eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11773eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        View expanded = null;
11783eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        Exception exception = null;
11793eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        try {
1180f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato            expanded = remoteViews.apply(mContext, content);
11813eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11823eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        catch (RuntimeException e) {
11833eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            exception = e;
11843eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11853eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        if (expanded == null) {
118646439cec0eb0da4d0f853f2d8712d0c00c98475bJoe Onorato            final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
11873eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
11883eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            return false;
11893eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        } else {
11903eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            content.addView(expanded);
11913eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler            row.setDrawingCacheEnabled(true);
11923eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        }
11933eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11943eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.row = row;
11953eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.content = content;
11963eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        entry.expanded = expanded;
11973eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler
11983eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler        return true;
11993eebd1ffbf4583270e6926e9c74ff088a2113e07Daniel Sandler    }
1200ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
12010ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler/*
1202b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler    public class ShadowController {
1203b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        boolean mShowShadows;
1204b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mShadowsForElements = new IdentityHashMap<View, View>(7);
1205b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        Map<View, View> mElementsForShadows = new IdentityHashMap<View, View>(7);
1206b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        LayoutTransition mElementTransition, mShadowTransition;
1207b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1208b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        View mTouchTarget;
1209f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1210b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        ShadowController(boolean showShadows) {
1211b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = showShadows;
1212b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mTouchTarget = null;
1213b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1214b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition = new LayoutTransition();
1215b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            AnimatorSet s = new AnimatorSet();
1216b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 48, 0))
1217b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 0.5f, 1f))
1218b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f))
1219b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1220b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.APPEARING, //s);
1221b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                   ObjectAnimator.ofInt(null, "top", 48, 0));
1222b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.APPEARING, 100);
1223b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setStartDelay(LayoutTransition.APPEARING, 0);
1224b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1225b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s = new AnimatorSet();
1226b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//            s.play(ObjectAnimator.ofInt(null, "top", 0, 48))
1227b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "scaleY", 1f, 0.5f))
1228b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                .with(ObjectAnimator.ofFloat(null, "alpha", 1f, 0.5f))
1229b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler//                ;
1230b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setAnimator(LayoutTransition.DISAPPEARING, //s);
1231b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofInt(null, "top", 0, 48));
1232b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementTransition.setDuration(LayoutTransition.DISAPPEARING, 400);
1233b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1234b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition = new LayoutTransition();
1235b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.APPEARING,
1236b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
1237b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.APPEARING, 200);
1238b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setStartDelay(LayoutTransition.APPEARING, 100);
1239b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setAnimator(LayoutTransition.DISAPPEARING,
1240b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                    ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
1241b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowTransition.setDuration(LayoutTransition.DISAPPEARING, 100);
1242b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1243b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup bar = (ViewGroup) TabletStatusBar.this.mBarContents;
1244b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            bar.setLayoutTransition(mElementTransition);
1245b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup nav = (ViewGroup) TabletStatusBar.this.mNavigationArea;
1246b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            nav.setLayoutTransition(mElementTransition);
1247b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            ViewGroup shadowGroup = (ViewGroup) bar.findViewById(R.id.shadows);
1248b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadowGroup.setLayoutTransition(mShadowTransition);
1249b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1250b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1251b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void add(View element, View shadow) {
1252b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            shadow.setOnTouchListener(makeTouchListener());
1253b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mShadowsForElements.put(element, shadow);
1254b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            mElementsForShadows.put(shadow, element);
1255f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1256f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1257b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public boolean getShadowState() {
1258b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return mShowShadows;
1259f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato        }
1260f63b0f44eb53f535a65bd83dbc1d8b95abc501daJoe Onorato
1261b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public View.OnTouchListener makeTouchListener() {
1262b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            return new View.OnTouchListener() {
1263b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                public boolean onTouch(View v, MotionEvent ev) {
1264b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    final int action = ev.getAction();
1265b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1266b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (DEBUG) Slog.d(TAG, "ShadowController: v=" + v + ", ev=" + ev);
1267b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1268b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    // currently redirecting events?
1269b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget == null) {
1270b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                        mTouchTarget = mElementsForShadows.get(v);
1271b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1272b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1273b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) {
1274b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        boolean last = false;
1275b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        switch (action) {
1276b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_CANCEL:
1277b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_UP:
1278e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1279b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                if (mShowShadows) {
1280e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                    mHandler.sendEmptyMessageDelayed(MSG_RESTORE_SHADOWS,
1281b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                            v == mNotificationShadow ? 5000 : 500);
1282b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                }
1283b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                last = true;
1284b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1285b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                            case MotionEvent.ACTION_DOWN:
1286e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler                                mHandler.removeMessages(MSG_RESTORE_SHADOWS);
1287b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                                setElementShadow(mTouchTarget, false);
1288b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                                break;
1289b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        }
1290b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        mTouchTarget.dispatchTouchEvent(ev);
1291b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        if (last) mTouchTarget = null;
1292b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                        return true;
1293b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    }
1294b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1295b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    return false;
1296b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1297b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            };
1298b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1299b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1300e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        public void refresh() {
1301b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            for (View element : mShadowsForElements.keySet()) {
1302b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                setElementShadow(element, mShowShadows);
1303b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1304e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler        }
1305e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler
1306b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void showAllShadows() {
1307b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = true;
1308e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1309ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler        }
1310ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler
1311b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        public void hideAllShadows() {
1312b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            mShowShadows = false;
1313e03d1bcfc42188e574a8e401154c77d5714eea41Daniel Sandler            refresh();
1314b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1315b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler
1316b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are
1317b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        // disabled (and should not be shadowed or re-shown)
1318b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void setElementShadow(View button, boolean shade) {
1319b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1320b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            if (shadow != null) {
1321b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                if (button.getVisibility() != View.GONE) {
1322b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE);
1323b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                    button.setVisibility(shade ? View.INVISIBLE : View.VISIBLE);
1324b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler                }
1325b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler            }
1326b6d3dc68977eada24515a825c43eb01df9a4edb5Daniel Sandler        }
1327b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1328b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Hide both element and shadow, using default layout animations.
1329b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void hideElement(View button) {
1330b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "hiding: " + button);
1331b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1332b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1333b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(View.GONE);
1334b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1335b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(View.GONE);
1336b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1337b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler
1338b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        // Honoring the current shadow state.
1339b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        public void showElement(View button) {
1340b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            Slog.d(TAG, "showing: " + button);
1341b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            View shadow = mShadowsForElements.get(button);
1342b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            if (shadow != null) {
1343b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler                shadow.setVisibility(mShowShadows ? View.VISIBLE : View.INVISIBLE);
1344b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            }
1345b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler            button.setVisibility(mShowShadows ? View.INVISIBLE : View.VISIBLE);
1346b96069936c4e6d10c119efa9943fba818b09373eDaniel Sandler        }
1347ce70d91844d2e4fb987617d2924ae5b73096e5c3Daniel Sandler    }
13480ad460b087abbd4b523a2e61ff27b0bf6fb5be92Daniel Sandler    */
1349b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1350b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    public class TouchOutsideListener implements View.OnTouchListener {
1351b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        private int mMsg;
1352ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        private StatusBarPanel mPanel;
1353b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1354ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato        public TouchOutsideListener(int msg, StatusBarPanel panel) {
1355b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            mMsg = msg;
1356ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            mPanel = panel;
1357b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1358b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato
1359b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        public boolean onTouch(View v, MotionEvent ev) {
1360ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            final int action = ev.getAction();
1361ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato            if (action == MotionEvent.ACTION_OUTSIDE
1362ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                    || (action == MotionEvent.ACTION_DOWN
1363ddf680bff5bb9bc04ef04667644db8ade0b38c46Joe Onorato                        && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) {
1364b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.removeMessages(mMsg);
1365b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                mHandler.sendEmptyMessage(mMsg);
1366b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato                return true;
1367b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            }
1368b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato            return false;
1369b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato        }
1370b62ac127824e9723534a197189eca58d30f15d3dJoe Onorato    }
1371091e1b8a86d34d2d51d2a5f7ae3cd903925fa5bfJoe Onorato
1372f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1373f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.print("mDisabled=0x");
1374f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato        pw.println(Integer.toHexString(mDisabled));
1375933464dd02e9aeaff7944a2c8e3e44942971e1e8Joe Onorato        pw.println("mNetworkController:");
1376933464dd02e9aeaff7944a2c8e3e44942971e1e8Joe Onorato        mNetworkController.dump(fd, pw, args);
1377f3c3c4fd14cb4185ec6df5a4355aab8b9f4039dcJoe Onorato    }
1378808182dc874e93582da38d013a4a790d6bc08fc9Joe Onorato}
1379d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1380d39e388e6d7f19d6e8d620e449af4124efab1d0dDaniel Sandler
1381