blob: cbd883102707a8fbf33b17b8006d7d3ae857ee1e [file] [log] [blame]
Joe Onorato808182d2010-07-09 18:52:06 -04001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.statusbar.tablet;
18
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -040019import android.animation.LayoutTransition;
20import android.animation.ObjectAnimator;
Jim Millere898ac52012-04-06 17:10:57 -070021import android.app.ActivityManager;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -040022import android.app.ActivityManagerNative;
Joe Onoratoef1e7762010-09-17 18:38:38 -040023import android.app.Notification;
Michael Jurkab7f43272011-10-27 15:06:38 -070024import android.app.PendingIntent;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -040025import android.app.StatusBarManager;
Michael Jurkab7f43272011-10-27 15:06:38 -070026import android.content.BroadcastReceiver;
Joe Onorato808182d2010-07-09 18:52:06 -040027import android.content.Context;
28import android.content.Intent;
Michael Jurkab7f43272011-10-27 15:06:38 -070029import android.content.IntentFilter;
Daniel Sandlerce6ff642011-02-18 12:51:08 -050030import android.content.SharedPreferences;
Daniel Sandler0ad460b2010-12-14 12:14:53 -050031import android.content.res.Configuration;
Joe Onorato808182d2010-07-09 18:52:06 -040032import android.content.res.Resources;
Daniel Sandler9120d552010-07-23 09:11:14 -040033import android.graphics.PixelFormat;
Jeff Brownbc68a592011-07-25 12:58:12 -070034import android.graphics.Point;
Adam Powell29ea5252011-11-15 18:59:36 -080035import android.graphics.drawable.Drawable;
Joe Onorato4daaeaf2010-11-17 20:43:12 -080036import android.graphics.drawable.LayerDrawable;
Michael Jurka7f2668c2012-03-27 07:49:52 -070037import android.inputmethodservice.InputMethodService;
Joe Onorato808182d2010-07-09 18:52:06 -040038import android.os.IBinder;
Daniel Sandler3eebd1f2010-07-27 08:39:33 -040039import android.os.Message;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -040040import android.os.RemoteException;
Daniel Sandler10163c62010-12-08 11:51:05 -050041import android.os.ServiceManager;
Joe Onoratoef1e7762010-09-17 18:38:38 -040042import android.text.TextUtils;
Daniel Sandler3eebd1f2010-07-27 08:39:33 -040043import android.util.Slog;
Joe Onorato07949e92011-05-25 17:35:35 -070044import android.view.Display;
Joe Onorato808182d2010-07-09 18:52:06 -040045import android.view.Gravity;
Daniel Sandler10163c62010-12-08 11:51:05 -050046import android.view.IWindowManager;
47import android.view.KeyEvent;
Joe Onoratob62ac122010-09-20 16:16:32 -040048import android.view.MotionEvent;
Daniel Sandleraa051d62011-03-01 16:23:57 -050049import android.view.SoundEffectConstants;
Daniel Sandler8304da42010-10-25 15:53:25 -040050import android.view.VelocityTracker;
Joe Onorato808182d2010-07-09 18:52:06 -040051import android.view.View;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -040052import android.view.ViewConfiguration;
Daniel Sandler9120d552010-07-23 09:11:14 -040053import android.view.ViewGroup;
Michael Jurka7f2668c2012-03-27 07:49:52 -070054import android.view.ViewGroup.LayoutParams;
Daniel Sandler9120d552010-07-23 09:11:14 -040055import android.view.WindowManager;
56import android.view.WindowManagerImpl;
Michael Jurka7f2668c2012-03-27 07:49:52 -070057import android.view.accessibility.AccessibilityEvent;
Daniel Sandler3eebd1f2010-07-27 08:39:33 -040058import android.widget.ImageView;
Joe Onorato808182d2010-07-09 18:52:06 -040059import android.widget.LinearLayout;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -040060import android.widget.ScrollView;
Daniel Sandler9120d552010-07-23 09:11:14 -040061import android.widget.TextView;
Joe Onorato808182d2010-07-09 18:52:06 -040062
63import com.android.internal.statusbar.StatusBarIcon;
Joe Onorato808182d2010-07-09 18:52:06 -040064import com.android.internal.statusbar.StatusBarNotification;
Joe Onorato808182d2010-07-09 18:52:06 -040065import com.android.systemui.R;
Michael Jurkab7f43272011-10-27 15:06:38 -070066import com.android.systemui.recent.RecentTasksLoader;
67import com.android.systemui.recent.RecentsPanelView;
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050068import com.android.systemui.statusbar.BaseStatusBar;
Jim Miller9a720f52012-05-30 03:19:43 -070069import com.android.systemui.statusbar.CommandQueue;
Daniel Sandlerd2217f02012-05-04 16:40:13 -040070import com.android.systemui.statusbar.DoNotDisturb;
Michael Jurkab7f43272011-10-27 15:06:38 -070071import com.android.systemui.statusbar.NotificationData;
Michael Jurkaa600fd92012-06-25 15:57:05 -070072import com.android.systemui.statusbar.NotificationData.Entry;
Michael Jurkab7f43272011-10-27 15:06:38 -070073import com.android.systemui.statusbar.SignalClusterView;
Michael Jurkab7f43272011-10-27 15:06:38 -070074import com.android.systemui.statusbar.StatusBarIconView;
Joe Onoratofd52b182010-11-10 18:00:52 -080075import com.android.systemui.statusbar.policy.BatteryController;
Joe Onoratofce2bf32011-02-01 17:00:29 -080076import com.android.systemui.statusbar.policy.BluetoothController;
Daniel Sandler45c04012011-06-07 15:29:07 -040077import com.android.systemui.statusbar.policy.CompatModeButton;
Daniel Sandlere40451a2011-02-03 14:51:35 -050078import com.android.systemui.statusbar.policy.LocationController;
Joe Onoratofd52b182010-11-10 18:00:52 -080079import com.android.systemui.statusbar.policy.NetworkController;
Daniel Sandlerf7a19562012-04-04 14:04:21 -040080import com.android.systemui.statusbar.policy.NotificationRowLayout;
Daniel Sandlerce6ff642011-02-18 12:51:08 -050081import com.android.systemui.statusbar.policy.Prefs;
Joe Onorato808182d2010-07-09 18:52:06 -040082
Daniel Sandler6a858c32012-03-12 14:38:58 -040083import java.io.FileDescriptor;
84import java.io.PrintWriter;
85import java.util.ArrayList;
86
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -050087public class TabletStatusBar extends BaseStatusBar implements
Daniel Sandler328310c2011-09-23 15:56:52 -040088 InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
89 RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
Daniel Sandlerfb970e92010-08-20 10:57:17 -040090 public static final boolean DEBUG = false;
Daniel Sandlere25f8332011-06-15 15:00:10 -040091 public static final boolean DEBUG_COMPAT_HELP = false;
Joe Onoratofd52b182010-11-10 18:00:52 -080092 public static final String TAG = "TabletStatusBar";
Joe Onorato808182d2010-07-09 18:52:06 -040093
Daniel Sandler0ad460b2010-12-14 12:14:53 -050094
Joe Onoratob62ac122010-09-20 16:16:32 -040095 public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
96 public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -040097 public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
98 public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
Michael Jurka7f2668c2012-03-27 07:49:52 -070099 // 1020-1029 reserved for BaseStatusBar
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500100 public static final int MSG_SHOW_CHROME = 1030;
101 public static final int MSG_HIDE_CHROME = 1031;
satok82beadf2010-12-27 19:03:06 +0900102 public static final int MSG_OPEN_INPUT_METHODS_PANEL = 1040;
103 public static final int MSG_CLOSE_INPUT_METHODS_PANEL = 1041;
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400104 public static final int MSG_OPEN_COMPAT_MODE_PANEL = 1050;
105 public static final int MSG_CLOSE_COMPAT_MODE_PANEL = 1051;
Daniel Sandler2ed08d22011-01-30 16:07:28 -0500106 public static final int MSG_STOP_TICKER = 2000;
Jim Miller44c66fe2010-10-20 18:32:52 -0700107
Daniel Sandler3a2fded2011-02-23 11:19:59 -0500108 // Fitts' Law assistance for LatinIME; see policy.EventHole
Daniel Sandler10163c62010-12-08 11:51:05 -0500109 private static final boolean FAKE_SPACE_BAR = true;
110
Daniel Sandler298a2a82011-08-11 16:13:22 -0400111 // Notification "peeking" (flyover preview of individual notifications)
Daniel Sandler298a2a82011-08-11 16:13:22 -0400112 final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
113 final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms
114
Daniel Sandler58b173b2012-05-03 11:25:29 -0400115 private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
116 private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
117
Joe Onoratodc100302011-01-11 17:07:41 -0800118 // The height of the bar, as definied by the build. It may be taller if we're plugged
119 // into hdmi.
120 int mNaturalBarHeight = -1;
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500121 int mIconSize = -1;
122 int mIconHPadding = -1;
Andrew Flynn1d9af302012-03-07 15:48:51 -0800123 int mNavIconWidth = -1;
124 int mMenuNavIconWidth = -1;
satok5485ff62011-05-27 19:15:01 +0900125 private int mMaxNotificationIcons = 5;
Daniel Sandler9120d552010-07-23 09:11:14 -0400126
Daniel Sandler10163c62010-12-08 11:51:05 -0500127 IWindowManager mWindowManager;
128
Joe Onoratob62ac122010-09-20 16:16:32 -0400129 TabletStatusBarView mStatusBarView;
Joe Onoratofd52b182010-11-10 18:00:52 -0800130 View mNotificationArea;
131 View mNotificationTrigger;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400132 NotificationIconArea mNotificationIconArea;
Daniel Sandler21eb86a2011-03-02 11:52:58 -0500133 ViewGroup mNavigationArea;
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500134
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500135 boolean mNotificationDNDMode;
136 NotificationData.Entry mNotificationDNDDummyEntry;
137
Joe Onorato536c58f2010-11-28 17:52:28 -0800138 ImageView mBackButton;
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500139 View mHomeButton;
Daniel Sandlere02d8082010-10-08 15:13:22 -0400140 View mMenuButton;
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400141 View mRecentButton;
Daniel Sandler328310c2011-09-23 15:56:52 -0400142 private boolean mAltBackButtonEnabledForIme;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400143
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400144 ViewGroup mFeedbackIconArea; // notification icons, IME icon, compat icon
satokcd7cd292010-11-20 15:46:23 +0900145 InputMethodButton mInputMethodSwitchButton;
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400146 CompatModeButton mCompatModeButton;
satok06487a52010-10-29 11:37:18 +0900147
Joe Onoratoddf680b2010-09-26 13:59:40 -0700148 NotificationPanel mNotificationPanel;
Joe Onorato07949e92011-05-25 17:35:35 -0700149 WindowManager.LayoutParams mNotificationPanelParams;
Joe Onorato8a576712010-11-15 16:50:34 -0800150 NotificationPeekPanel mNotificationPeekWindow;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400151 ViewGroup mNotificationPeekRow;
152 int mNotificationPeekIndex;
Daniel Sandlera8e5b062010-12-01 13:53:08 -0500153 IBinder mNotificationPeekKey;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400154 LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
155
156 int mNotificationPeekTapDuration;
157 int mNotificationFlingVelocity;
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400158
Joe Onoratofd52b182010-11-10 18:00:52 -0800159 BatteryController mBatteryController;
Joe Onoratofce2bf32011-02-01 17:00:29 -0800160 BluetoothController mBluetoothController;
Daniel Sandlere40451a2011-02-03 14:51:35 -0500161 LocationController mLocationController;
Joe Onoratofd52b182010-11-10 18:00:52 -0800162 NetworkController mNetworkController;
Daniel Sandlerd2217f02012-05-04 16:40:13 -0400163 DoNotDisturb mDoNotDisturb;
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400164
Daniel Sandler21eb86a2011-03-02 11:52:58 -0500165 ViewGroup mBarContents;
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500166
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500167 // hide system chrome ("lights out") support
168 View mShadow;
Daniel Sandlerce70d912010-09-02 11:59:41 -0400169
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400170 NotificationIconArea.IconLayout mIconLayout;
171
Joe Onoratoef1e7762010-09-17 18:38:38 -0400172 TabletTicker mTicker;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400173
Daniel Sandler10163c62010-12-08 11:51:05 -0500174 View mFakeSpaceBar;
175 KeyEvent mSpaceBarKeyEvent = null;
176
Dianne Hackborned31bbf2011-06-15 11:16:06 -0700177 View mCompatibilityHelpDialog = null;
Jim Millere898ac52012-04-06 17:10:57 -0700178
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400179 // for disabling the status bar
180 int mDisabled = 0;
181
satok82beadf2010-12-27 19:03:06 +0900182 private InputMethodsPanel mInputMethodsPanel;
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400183 private CompatModePanel mCompatModePanel;
Joe Onorato55d2d762010-09-26 13:02:01 -0700184
Mike Lockwood066c8912011-08-24 10:17:18 -0400185 private int mSystemUiVisibility = 0;
Daniel Sandler60ee2562011-07-22 12:34:33 -0400186
Daniel Sandler328310c2011-09-23 15:56:52 -0400187 private int mNavigationIconHints = 0;
188
Jim Miller9a720f52012-05-30 03:19:43 -0700189 private int mShowSearchHoldoff = 0;
190
Daniel Sandlerc51451a2010-12-16 19:06:46 -0500191 public Context getContext() { return mContext; }
192
Jim Miller9a720f52012-05-30 03:19:43 -0700193 private Runnable mShowSearchPanel = new Runnable() {
194 public void run() {
195 showSearchPanel();
196 }
197 };
198
Jim Miller998bb762012-05-21 13:37:27 -0700199 private View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
200 public boolean onTouch(View v, MotionEvent event) {
201 switch(event.getAction()) {
202 case MotionEvent.ACTION_DOWN:
John Spurlock67ad3682012-06-26 17:42:00 -0400203 if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) {
Jim Miller9a720f52012-05-30 03:19:43 -0700204 mHandler.removeCallbacks(mShowSearchPanel);
205 mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
Jim Millera073e572012-05-23 17:03:27 -0700206 }
Jim Miller998bb762012-05-21 13:37:27 -0700207 break;
Jim Miller9a720f52012-05-30 03:19:43 -0700208
209 case MotionEvent.ACTION_UP:
210 case MotionEvent.ACTION_CANCEL:
211 mHandler.removeCallbacks(mShowSearchPanel);
212 break;
Jim Miller998bb762012-05-21 13:37:27 -0700213 }
214 return false;
215 }
216 };
217
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500218 @Override
219 protected void createAndAddWindows() {
220 addStatusBarWindow();
221 addPanelWindows();
222 }
Jim Millere898ac52012-04-06 17:10:57 -0700223
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500224 private void addStatusBarWindow() {
Daniel Sandler079b33d2012-03-02 16:29:41 -0500225 final View sb = makeStatusBarView();
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500226
227 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
228 ViewGroup.LayoutParams.MATCH_PARENT,
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700229 ViewGroup.LayoutParams.MATCH_PARENT,
230 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500231 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
232 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
233 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Greg Hackmannbb033ea2012-07-10 14:39:29 -0700234 PixelFormat.OPAQUE);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500235
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500236 // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags. The status bar occupies
237 // very little screen real-estate and is updated fairly frequently. By using CPU rendering
238 // for the status bar, we prevent the GPU from having to wake up just to do these small
239 // updates, which should help keep power consumption down.
240
241 lp.gravity = getStatusBarGravity();
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700242 lp.setTitle("SystemBar");
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500243 lp.packageName = mContext.getPackageName();
Daniel Sandler079b33d2012-03-02 16:29:41 -0500244 WindowManagerImpl.getDefault().addView(sb, lp);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500245 }
246
Daniel Sandler9120d552010-07-23 09:11:14 -0400247 protected void addPanelWindows() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400248 final Context context = mContext;
Joe Onorato07949e92011-05-25 17:35:35 -0700249 final Resources res = mContext.getResources();
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400250
Jim Miller44c66fe2010-10-20 18:32:52 -0700251 // Notification Panel
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400252 mNotificationPanel = (NotificationPanel)View.inflate(context,
Daniel Sandler4a066c52012-04-20 14:49:13 -0400253 R.layout.system_bar_notification_panel, null);
Daniel Sandler1347c302011-08-01 16:47:53 -0400254 mNotificationPanel.setBar(this);
Joe Onorato7c270fa2010-12-08 17:31:42 -0800255 mNotificationPanel.show(false, false);
Joe Onoratob62ac122010-09-20 16:16:32 -0400256 mNotificationPanel.setOnTouchListener(
Joe Onoratoddf680b2010-09-26 13:59:40 -0700257 new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
Joe Onoratob62ac122010-09-20 16:16:32 -0400258
Daniel Sandler2b697352011-07-22 16:23:09 -0400259 // the battery icon
Joe Onoratofd52b182010-11-10 18:00:52 -0800260 mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
261 mBatteryController.addLabelView(
262 (TextView)mNotificationPanel.findViewById(R.id.battery_text));
Daniel Sandler2b697352011-07-22 16:23:09 -0400263
264 // Bt
Joe Onoratofce2bf32011-02-01 17:00:29 -0800265 mBluetoothController.addIconView(
266 (ImageView)mNotificationPanel.findViewById(R.id.bluetooth));
Daniel Sandler2b697352011-07-22 16:23:09 -0400267
268 // network icons: either a combo icon that switches between mobile and data, or distinct
269 // mobile and data icons
Jim Millera073e572012-05-23 17:03:27 -0700270 final ImageView mobileRSSI =
Daniel Sandler2b697352011-07-22 16:23:09 -0400271 (ImageView)mNotificationPanel.findViewById(R.id.mobile_signal);
272 if (mobileRSSI != null) {
273 mNetworkController.addPhoneSignalIconView(mobileRSSI);
274 }
Jim Millera073e572012-05-23 17:03:27 -0700275 final ImageView wifiRSSI =
Daniel Sandler2b697352011-07-22 16:23:09 -0400276 (ImageView)mNotificationPanel.findViewById(R.id.wifi_signal);
277 if (wifiRSSI != null) {
278 mNetworkController.addWifiIconView(wifiRSSI);
279 }
Daniel Sandler5962fd52012-01-11 14:57:04 -0500280 mNetworkController.addWifiLabelView(
281 (TextView)mNotificationPanel.findViewById(R.id.wifi_text));
Daniel Sandler2b697352011-07-22 16:23:09 -0400282
Joe Onorato42f8e132010-11-29 15:52:43 -0800283 mNetworkController.addDataTypeIconView(
Daniel Sandler5962fd52012-01-11 14:57:04 -0500284 (ImageView)mNotificationPanel.findViewById(R.id.mobile_type));
285 mNetworkController.addMobileLabelView(
286 (TextView)mNotificationPanel.findViewById(R.id.mobile_text));
287 mNetworkController.addCombinedLabelView(
Daniel Sandler3e8f5a22010-12-03 14:52:10 -0500288 (TextView)mBarContents.findViewById(R.id.network_text));
Joe Onoratofd52b182010-11-10 18:00:52 -0800289
Joe Onorato55d2d762010-09-26 13:02:01 -0700290 mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
Daniel Sandlerd39e3882010-08-31 14:16:13 -0400291
Joe Onorato07949e92011-05-25 17:35:35 -0700292 WindowManager.LayoutParams lp = mNotificationPanelParams = new WindowManager.LayoutParams(
293 res.getDimensionPixelSize(R.dimen.notification_panel_width),
294 getNotificationPanelHeight(),
Daniel Sandler4ce64fb2012-05-03 10:53:10 -0400295 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
Daniel Sandler9120d552010-07-23 09:11:14 -0400296 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
Joe Onorato07949e92011-05-25 17:35:35 -0700297 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
Jeff Brown46e75292010-11-10 16:53:45 -0800298 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
Joe Onorato7c270fa2010-12-08 17:31:42 -0800299 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
300 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
Daniel Sandler9120d552010-07-23 09:11:14 -0400301 PixelFormat.TRANSLUCENT);
Joe Onoratoea70e632010-09-27 17:59:37 -0700302 lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
Daniel Sandler9120d552010-07-23 09:11:14 -0400303 lp.setTitle("NotificationPanel");
Joe Onorato7c270fa2010-12-08 17:31:42 -0800304 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
305 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
306 lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
Daniel Sandler7d9ea8c2011-01-11 10:28:58 -0500307// lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
Daniel Sandler9120d552010-07-23 09:11:14 -0400308
309 WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
310
Jim Miller44c66fe2010-10-20 18:32:52 -0700311 // Recents Panel
Michael Jurkaab48b682011-09-12 15:39:45 -0700312 mRecentTasksLoader = new RecentTasksLoader(context);
Michael Jurka7f2668c2012-03-27 07:49:52 -0700313 updateRecentsPanel();
satok82beadf2010-12-27 19:03:06 +0900314
Jim Millere898ac52012-04-06 17:10:57 -0700315 // Search Panel
316 mStatusBarView.setBar(this);
Jim Miller998bb762012-05-21 13:37:27 -0700317 mHomeButton.setOnTouchListener(mHomeSearchActionListener);
Jim Millere898ac52012-04-06 17:10:57 -0700318 updateSearchPanel();
319
satok82beadf2010-12-27 19:03:06 +0900320 // Input methods Panel
321 mInputMethodsPanel = (InputMethodsPanel) View.inflate(context,
Daniel Sandler4a066c52012-04-20 14:49:13 -0400322 R.layout.system_bar_input_methods_panel, null);
Jeff Brown2992ea72011-01-28 22:04:14 -0800323 mInputMethodsPanel.setHardKeyboardEnabledChangeListener(this);
satok82beadf2010-12-27 19:03:06 +0900324 mInputMethodsPanel.setOnTouchListener(new TouchOutsideListener(
325 MSG_CLOSE_INPUT_METHODS_PANEL, mInputMethodsPanel));
satok913f42d2011-01-17 16:58:10 +0900326 mInputMethodsPanel.setImeSwitchButton(mInputMethodSwitchButton);
Daniel Sandler328310c2011-09-23 15:56:52 -0400327 mStatusBarView.setIgnoreChildren(2, mInputMethodSwitchButton, mInputMethodsPanel);
satok82beadf2010-12-27 19:03:06 +0900328 lp = new WindowManager.LayoutParams(
329 ViewGroup.LayoutParams.WRAP_CONTENT,
330 ViewGroup.LayoutParams.WRAP_CONTENT,
331 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
332 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
333 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
334 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
335 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
336 PixelFormat.TRANSLUCENT);
337 lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
338 lp.setTitle("InputMethodsPanel");
339 lp.windowAnimations = R.style.Animation_RecentPanel;
340
341 WindowManagerImpl.getDefault().addView(mInputMethodsPanel, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700342
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400343 // Compatibility mode selector panel
344 mCompatModePanel = (CompatModePanel) View.inflate(context,
Daniel Sandler4a066c52012-04-20 14:49:13 -0400345 R.layout.system_bar_compat_mode_panel, null);
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400346 mCompatModePanel.setOnTouchListener(new TouchOutsideListener(
347 MSG_CLOSE_COMPAT_MODE_PANEL, mCompatModePanel));
348 mCompatModePanel.setTrigger(mCompatModeButton);
349 mCompatModePanel.setVisibility(View.GONE);
Daniel Sandler328310c2011-09-23 15:56:52 -0400350 mStatusBarView.setIgnoreChildren(3, mCompatModeButton, mCompatModePanel);
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400351 lp = new WindowManager.LayoutParams(
352 250,
353 ViewGroup.LayoutParams.WRAP_CONTENT,
354 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
355 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
356 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
357 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
358 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
359 PixelFormat.TRANSLUCENT);
360 lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
361 lp.setTitle("CompatModePanel");
362 lp.windowAnimations = android.R.style.Animation_Dialog;
363
364 WindowManagerImpl.getDefault().addView(mCompatModePanel, lp);
Jim Millere898ac52012-04-06 17:10:57 -0700365
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500366 mRecentButton.setOnTouchListener(mRecentsPanel);
367
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400368 mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500369 mPile.removeAllViews();
Daniel Sandlerf7a19562012-04-04 14:04:21 -0400370 mPile.setLongPressListener(getNotificationLongClicker());
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -0500371
372 ScrollView scroller = (ScrollView)mPile.getParent();
373 scroller.setFillViewport(true);
Daniel Sandler9120d552010-07-23 09:11:14 -0400374 }
Joe Onorato808182d2010-07-09 18:52:06 -0400375
Chris Wren8fd12652012-05-09 21:25:57 -0400376 @Override
377 protected int getExpandedViewMaxHeight() {
378 return getNotificationPanelHeight();
379 }
380
Joe Onorato07949e92011-05-25 17:35:35 -0700381 private int getNotificationPanelHeight() {
382 final Resources res = mContext.getResources();
383 final Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
Jeff Brownbc68a592011-07-25 12:58:12 -0700384 final Point size = new Point();
385 d.getRealSize(size);
386 return Math.max(res.getDimensionPixelSize(R.dimen.notification_panel_min_height), size.y);
Joe Onorato07949e92011-05-25 17:35:35 -0700387 }
388
Joe Onorato808182d2010-07-09 18:52:06 -0400389 @Override
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400390 public void start() {
391 super.start(); // will add the main bar view
Joe Onorato808182d2010-07-09 18:52:06 -0400392 }
393
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500394 @Override
Joe Onoratodc100302011-01-11 17:07:41 -0800395 protected void onConfigurationChanged(Configuration newConfig) {
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500396 loadDimens();
Joe Onorato07949e92011-05-25 17:35:35 -0700397 mNotificationPanelParams.height = getNotificationPanelHeight();
398 WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
399 mNotificationPanelParams);
Michael Jurkaab48b682011-09-12 15:39:45 -0700400 mRecentsPanel.updateValuesFromResources();
Jim Miller9a720f52012-05-30 03:19:43 -0700401 mShowSearchHoldoff = mContext.getResources().getInteger(
402 R.integer.config_show_search_delay);
Jim Miller955a0162012-06-11 21:06:13 -0700403 updateSearchPanel();
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500404 }
405
406 protected void loadDimens() {
407 final Resources res = mContext.getResources();
408
Joe Onoratodc100302011-01-11 17:07:41 -0800409 mNaturalBarHeight = res.getDimensionPixelSize(
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700410 com.android.internal.R.dimen.navigation_bar_height);
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500411
412 int newIconSize = res.getDimensionPixelSize(
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700413 com.android.internal.R.dimen.system_bar_icon_size);
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500414 int newIconHPadding = res.getDimensionPixelSize(
415 R.dimen.status_bar_icon_padding);
Andrew Flynn1d9af302012-03-07 15:48:51 -0800416 int newNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_key_width);
417 int newMenuNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_menu_key_width);
418
419 if (mNavigationArea != null && newNavIconWidth != mNavIconWidth) {
420 mNavIconWidth = newNavIconWidth;
421
422 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
423 mNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
424 mBackButton.setLayoutParams(lp);
425 mHomeButton.setLayoutParams(lp);
426 mRecentButton.setLayoutParams(lp);
427 }
428
429 if (mNavigationArea != null && newMenuNavIconWidth != mMenuNavIconWidth) {
430 mMenuNavIconWidth = newMenuNavIconWidth;
431
432 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
433 mMenuNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
434 mMenuButton.setLayoutParams(lp);
435 }
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500436
437 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
438// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
439 mIconHPadding = newIconHPadding;
440 mIconSize = newIconSize;
441 reloadAllNotificationIcons(); // reload the tray
442 }
satok5485ff62011-05-27 19:15:01 +0900443
444 final int numIcons = res.getInteger(R.integer.config_maxNotificationIcons);
445 if (numIcons != mMaxNotificationIcons) {
446 mMaxNotificationIcons = numIcons;
447 if (DEBUG) Slog.d(TAG, "max notification icons: " + mMaxNotificationIcons);
448 reloadAllNotificationIcons();
449 }
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500450 }
451
Daniel Sandler328310c2011-09-23 15:56:52 -0400452 public View getStatusBarView() {
453 return mStatusBarView;
454 }
455
Joe Onorato808182d2010-07-09 18:52:06 -0400456 protected View makeStatusBarView() {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -0400457 final Context context = mContext;
Jim Miller85babff2011-01-11 14:26:03 -0800458
Daniel Sandler10163c62010-12-08 11:51:05 -0500459 mWindowManager = IWindowManager.Stub.asInterface(
460 ServiceManager.getService(Context.WINDOW_SERVICE));
Joe Onorato808182d2010-07-09 18:52:06 -0400461
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500462 loadDimens();
Joe Onorato808182d2010-07-09 18:52:06 -0400463
Joe Onoratob62ac122010-09-20 16:16:32 -0400464 final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
Daniel Sandler4a066c52012-04-20 14:49:13 -0400465 context, R.layout.system_bar, null);
Joe Onorato808182d2010-07-09 18:52:06 -0400466 mStatusBarView = sb;
467
Joe Onoratob62ac122010-09-20 16:16:32 -0400468 sb.setHandler(mHandler);
469
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400470 try {
471 // Sanity-check that someone hasn't set up the config wrong and asked for a navigation
472 // bar on a tablet that has only the system bar
473 if (mWindowManager.hasNavigationBar()) {
Mike Lockwoodc33d5762011-10-21 13:28:22 -0400474 Slog.e(TAG, "Tablet device cannot show navigation bar and system bar");
Daniel Sandler0c4ccff2011-10-19 16:39:14 -0400475 }
476 } catch (RemoteException ex) {
Chet Haasebc0009d2011-09-08 16:19:50 -0700477 }
478
Daniel Sandler21eb86a2011-03-02 11:52:58 -0500479 mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
Joe Onoratof63b0f42010-09-12 17:03:19 -0400480
Joe Onoratofd52b182010-11-10 18:00:52 -0800481 // the whole right-hand side of the bar
482 mNotificationArea = sb.findViewById(R.id.notificationArea);
Chris Wren0c8275b2012-05-08 13:36:48 -0400483 mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener());
Joe Onoratofd52b182010-11-10 18:00:52 -0800484
Joe Onorato55d2d762010-09-26 13:02:01 -0700485 // the button to open the notification area
Joe Onoratofd52b182010-11-10 18:00:52 -0800486 mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
Joe Onorato55d2d762010-09-26 13:02:01 -0700487
Joe Onorato808182d2010-07-09 18:52:06 -0400488 // the more notifications icon
489 mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
490
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400491 // where the icons go
492 mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400493
Michael Jurkaa600fd92012-06-25 15:57:05 -0700494 mNotificationPeekTapDuration = ViewConfiguration.getTapTimeout();
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400495 mNotificationFlingVelocity = 300; // px/s
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400496
Daniel Sandlerc51451a2010-12-16 19:06:46 -0500497 mTicker = new TabletTicker(this);
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400498
Joe Onoratofd52b182010-11-10 18:00:52 -0800499 // The icons
Daniel Sandlere40451a2011-02-03 14:51:35 -0500500 mLocationController = new LocationController(mContext); // will post a notification
501
Daniel Sandlerd2217f02012-05-04 16:40:13 -0400502 // watch the PREF_DO_NOT_DISTURB and convert to appropriate disable() calls
503 mDoNotDisturb = new DoNotDisturb(mContext);
504
Joe Onoratofd52b182010-11-10 18:00:52 -0800505 mBatteryController = new BatteryController(mContext);
506 mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
Joe Onoratofce2bf32011-02-01 17:00:29 -0800507 mBluetoothController = new BluetoothController(mContext);
508 mBluetoothController.addIconView((ImageView)sb.findViewById(R.id.bluetooth));
Daniel Sandler2b697352011-07-22 16:23:09 -0400509
Joe Onoratofd52b182010-11-10 18:00:52 -0800510 mNetworkController = new NetworkController(mContext);
Jim Millera073e572012-05-23 17:03:27 -0700511 final SignalClusterView signalCluster =
Christian Robertson2e347422011-08-11 14:01:04 -0700512 (SignalClusterView)sb.findViewById(R.id.signal_cluster);
513 mNetworkController.addSignalCluster(signalCluster);
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400514
Joe Onorato091e1b82010-09-26 18:04:44 -0700515 // The navigation buttons
Joe Onorato6478adc2011-01-27 21:15:01 -0800516 mBackButton = (ImageView)sb.findViewById(R.id.back);
Daniel Sandler21eb86a2011-03-02 11:52:58 -0500517 mNavigationArea = (ViewGroup) sb.findViewById(R.id.navigationArea);
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500518 mHomeButton = mNavigationArea.findViewById(R.id.home);
Daniel Sandlere02d8082010-10-08 15:13:22 -0400519 mMenuButton = mNavigationArea.findViewById(R.id.menu);
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500520 mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -0500521 mRecentButton.setOnClickListener(mOnClickListener);
Daniel Sandler4f9986e2011-12-02 16:10:37 -0500522
523 LayoutTransition lt = new LayoutTransition();
524 lt.setDuration(250);
525 // don't wait for these transitions; we just want icons to fade in/out, not move around
526 lt.setDuration(LayoutTransition.CHANGE_APPEARING, 0);
527 lt.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 0);
Daniel Sandler5a826602011-12-07 15:16:18 -0500528 lt.addTransitionListener(new LayoutTransition.TransitionListener() {
529 public void endTransition(LayoutTransition transition, ViewGroup container,
530 View view, int transitionType) {
531 // ensure the menu button doesn't stick around on the status bar after it's been
532 // removed
533 mBarContents.invalidate();
534 }
535 public void startTransition(LayoutTransition transition, ViewGroup container,
536 View view, int transitionType) {}
537 });
Daniel Sandler4f9986e2011-12-02 16:10:37 -0500538 mNavigationArea.setLayoutTransition(lt);
Daniel Sandler96f48182011-08-17 09:50:35 -0400539 // no multi-touch on the nav buttons
540 mNavigationArea.setMotionEventSplittingEnabled(false);
Joe Onorato091e1b82010-09-26 18:04:44 -0700541
satok06487a52010-10-29 11:37:18 +0900542 // The bar contents buttons
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400543 mFeedbackIconArea = (ViewGroup)sb.findViewById(R.id.feedbackIconArea);
satokcd7cd292010-11-20 15:46:23 +0900544 mInputMethodSwitchButton = (InputMethodButton) sb.findViewById(R.id.imeSwitchButton);
satok82beadf2010-12-27 19:03:06 +0900545 // Overwrite the lister
546 mInputMethodSwitchButton.setOnClickListener(mOnClickListener);
satok06487a52010-10-29 11:37:18 +0900547
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400548 mCompatModeButton = (CompatModeButton) sb.findViewById(R.id.compatModeButton);
549 mCompatModeButton.setOnClickListener(mOnClickListener);
Dianne Hackborne0f085d2011-11-30 18:41:15 -0800550 mCompatModeButton.setVisibility(View.GONE);
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400551
Daniel Sandler10163c62010-12-08 11:51:05 -0500552 // for redirecting errant bar taps to the IME
553 mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
554
Daniel Sandlerb9606992010-11-19 14:47:59 -0500555 // "shadows" of the status bar features, for lights-out mode
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500556 mShadow = sb.findViewById(R.id.bar_shadow);
557 mShadow.setOnTouchListener(
558 new View.OnTouchListener() {
559 public boolean onTouch(View v, MotionEvent ev) {
560 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
Daniel Sandlerd7201552011-01-28 09:58:02 -0500561 // even though setting the systemUI visibility below will turn these views
562 // on, we need them to come up faster so that they can catch this motion
563 // event
564 mShadow.setVisibility(View.GONE);
565 mBarContents.setVisibility(View.VISIBLE);
566
Joe Onorato55bf3802011-01-25 13:42:10 -0800567 try {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700568 mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Joe Onorato55bf3802011-01-25 13:42:10 -0800569 } catch (RemoteException ex) {
570 // system process dead
571 }
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500572 }
573 return false;
574 }
575 });
Daniel Sandlerb9606992010-11-19 14:47:59 -0500576
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500577 // tuning parameters
Daniel Sandler635fb492012-04-27 10:45:37 -0400578 final int LIGHTS_GOING_OUT_SYSBAR_DURATION = 750;
579 final int LIGHTS_GOING_OUT_SHADOW_DURATION = 750;
580 final int LIGHTS_GOING_OUT_SHADOW_DELAY = 0;
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500581
582 final int LIGHTS_COMING_UP_SYSBAR_DURATION = 200;
583// final int LIGHTS_COMING_UP_SYSBAR_DELAY = 50;
584 final int LIGHTS_COMING_UP_SHADOW_DURATION = 0;
585
586 LayoutTransition xition = new LayoutTransition();
587 xition.setAnimator(LayoutTransition.APPEARING,
588 ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f));
589 xition.setDuration(LayoutTransition.APPEARING, LIGHTS_COMING_UP_SYSBAR_DURATION);
590 xition.setStartDelay(LayoutTransition.APPEARING, 0);
591 xition.setAnimator(LayoutTransition.DISAPPEARING,
592 ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
593 xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_GOING_OUT_SYSBAR_DURATION);
594 xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
595 ((ViewGroup)sb.findViewById(R.id.bar_contents_holder)).setLayoutTransition(xition);
596
597 xition = new LayoutTransition();
598 xition.setAnimator(LayoutTransition.APPEARING,
599 ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
600 xition.setDuration(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DURATION);
601 xition.setStartDelay(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DELAY);
602 xition.setAnimator(LayoutTransition.DISAPPEARING,
603 ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
604 xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_COMING_UP_SHADOW_DURATION);
605 xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
606 ((ViewGroup)sb.findViewById(R.id.bar_shadow_holder)).setLayoutTransition(xition);
Daniel Sandlerb9606992010-11-19 14:47:59 -0500607
Joe Onorato5dd11692010-09-27 15:34:04 -0700608 // set the initial view visibility
609 setAreThereNotifications();
610
Michael Jurkab7f43272011-10-27 15:06:38 -0700611 // receive broadcasts
612 IntentFilter filter = new IntentFilter();
613 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
614 filter.addAction(Intent.ACTION_SCREEN_OFF);
615 context.registerReceiver(mBroadcastReceiver, filter);
616
Joe Onorato808182d2010-07-09 18:52:06 -0400617 return sb;
618 }
619
Michael Jurka7f2668c2012-03-27 07:49:52 -0700620 @Override
621 protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
622 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
623 (int) mContext.getResources().getDimension(R.dimen.status_bar_recents_width),
624 ViewGroup.LayoutParams.MATCH_PARENT,
Daniel Sandler4ce64fb2012-05-03 10:53:10 -0400625 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
Michael Jurka7f2668c2012-03-27 07:49:52 -0700626 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
627 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
628 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
629 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
630 PixelFormat.TRANSLUCENT);
631 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
632 lp.setTitle("RecentsPanel");
633 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
634 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
635 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
636
637 return lp;
638 }
639
Jim Millere898ac52012-04-06 17:10:57 -0700640 @Override
641 protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
642 boolean opaque = false;
643 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
644 LayoutParams.MATCH_PARENT,
645 LayoutParams.MATCH_PARENT,
646 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
647 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
648 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
649 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
650 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
651 if (ActivityManager.isHighEndGfx(mDisplay)) {
652 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
653 } else {
654 lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
655 lp.dimAmount = 0.7f;
656 }
657 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
658 lp.setTitle("SearchPanel");
659 // TODO: Define custom animation for Search panel
660 lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
661 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
662 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
663 return lp;
664 }
665
Michael Jurka7f2668c2012-03-27 07:49:52 -0700666 protected void updateRecentsPanel() {
Daniel Sandler4a066c52012-04-20 14:49:13 -0400667 super.updateRecentsPanel(R.layout.system_bar_recent_panel);
Michael Jurka7f2668c2012-03-27 07:49:52 -0700668 mRecentsPanel.setStatusBarView(mStatusBarView);
669 }
670
Jim Millere898ac52012-04-06 17:10:57 -0700671 @Override
672 protected void updateSearchPanel() {
673 super.updateSearchPanel();
674 mSearchPanelView.setStatusBarView(mStatusBarView);
675 mStatusBarView.setDelegateView(mSearchPanelView);
676 }
677
678 @Override
679 public void showSearchPanel() {
680 super.showSearchPanel();
681 WindowManager.LayoutParams lp =
682 (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
683 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jim Millere898ac52012-04-06 17:10:57 -0700684 WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
685 }
686
687 @Override
688 public void hideSearchPanel() {
689 super.hideSearchPanel();
690 WindowManager.LayoutParams lp =
691 (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
692 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Jim Millere898ac52012-04-06 17:10:57 -0700693 WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
694 }
695
Joe Onoratodc100302011-01-11 17:07:41 -0800696 public int getStatusBarHeight() {
Dianne Hackbornf87d1962012-04-04 12:48:24 -0700697 return mStatusBarView != null ? mStatusBarView.getHeight()
698 : mContext.getResources().getDimensionPixelSize(
699 com.android.internal.R.dimen.navigation_bar_height);
Joe Onoratodc100302011-01-11 17:07:41 -0800700 }
701
Joe Onorato808182d2010-07-09 18:52:06 -0400702 protected int getStatusBarGravity() {
703 return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
704 }
705
Joe Onoratodc100302011-01-11 17:07:41 -0800706 public void onBarHeightChanged(int height) {
707 final WindowManager.LayoutParams lp
708 = (WindowManager.LayoutParams)mStatusBarView.getLayoutParams();
709 if (lp == null) {
710 // haven't been added yet
711 return;
712 }
713 if (lp.height != height) {
714 lp.height = height;
715 final WindowManager wm = WindowManagerImpl.getDefault();
716 wm.updateViewLayout(mStatusBarView, lp);
717 }
718 }
719
Michael Jurka7f2668c2012-03-27 07:49:52 -0700720 @Override
Michael Jurkaecc395a2012-03-30 05:31:46 -0700721 protected BaseStatusBar.H createHandler() {
Michael Jurka7f2668c2012-03-27 07:49:52 -0700722 return new TabletStatusBar.H();
723 }
724
725 private class H extends BaseStatusBar.H {
Daniel Sandler9120d552010-07-23 09:11:14 -0400726 public void handleMessage(Message m) {
Michael Jurka7f2668c2012-03-27 07:49:52 -0700727 super.handleMessage(m);
Daniel Sandler9120d552010-07-23 09:11:14 -0400728 switch (m.what) {
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400729 case MSG_OPEN_NOTIFICATION_PEEK:
730 if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500731
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400732 if (m.arg1 >= 0) {
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500733 final int N = mNotificationData.size();
734
735 if (!mNotificationDNDMode) {
736 if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
737 NotificationData.Entry entry = mNotificationData.get(N-1-mNotificationPeekIndex);
738 entry.icon.setBackgroundColor(0);
739 mNotificationPeekIndex = -1;
740 mNotificationPeekKey = null;
741 }
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400742 }
743
744 final int peekIndex = m.arg1;
745 if (peekIndex < N) {
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500746 //Slog.d(TAG, "loading peek: " + peekIndex);
Jim Miller5fda69c2011-02-16 15:17:11 -0800747 NotificationData.Entry entry =
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500748 mNotificationDNDMode
749 ? mNotificationDNDDummyEntry
750 : mNotificationData.get(N-1-peekIndex);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400751 NotificationData.Entry copy = new NotificationData.Entry(
Jim Miller85babff2011-01-11 14:26:03 -0800752 entry.key,
753 entry.notification,
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400754 entry.icon);
755 inflateViews(copy, mNotificationPeekRow);
756
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500757 if (mNotificationDNDMode) {
758 copy.content.setOnClickListener(new View.OnClickListener() {
759 public void onClick(View v) {
760 SharedPreferences.Editor editor = Prefs.edit(mContext);
761 editor.putBoolean(Prefs.DO_NOT_DISTURB_PREF, false);
762 editor.apply();
763 animateCollapse();
Mike Lockwood066c8912011-08-24 10:17:18 -0400764 visibilityChanged(false);
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500765 }
766 });
767 }
768
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400769 entry.icon.setBackgroundColor(0x20FFFFFF);
770
771// mNotificationPeekRow.setLayoutTransition(
Jim Miller85babff2011-01-11 14:26:03 -0800772// peekIndex < mNotificationPeekIndex
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400773// ? mNotificationPeekScrubLeft
774// : mNotificationPeekScrubRight);
775
776 mNotificationPeekRow.removeAllViews();
777 mNotificationPeekRow.addView(copy.row);
778
779 mNotificationPeekWindow.setVisibility(View.VISIBLE);
Joe Onorato7c270fa2010-12-08 17:31:42 -0800780 mNotificationPanel.show(false, true);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400781
782 mNotificationPeekIndex = peekIndex;
Daniel Sandlera8e5b062010-12-01 13:53:08 -0500783 mNotificationPeekKey = entry.key;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400784 }
785 }
786 break;
787 case MSG_CLOSE_NOTIFICATION_PEEK:
788 if (DEBUG) Slog.d(TAG, "closing notification peek window");
789 mNotificationPeekWindow.setVisibility(View.GONE);
790 mNotificationPeekRow.removeAllViews();
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500791
792 final int N = mNotificationData.size();
Daniel Sandlera8e5b062010-12-01 13:53:08 -0500793 if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
Jim Miller5fda69c2011-02-16 15:17:11 -0800794 NotificationData.Entry entry =
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500795 mNotificationDNDMode
796 ? mNotificationDNDDummyEntry
797 : mNotificationData.get(N-1-mNotificationPeekIndex);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400798 entry.icon.setBackgroundColor(0);
799 }
Daniel Sandlera8e5b062010-12-01 13:53:08 -0500800
801 mNotificationPeekIndex = -1;
802 mNotificationPeekKey = null;
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -0400803 break;
Daniel Sandler9120d552010-07-23 09:11:14 -0400804 case MSG_OPEN_NOTIFICATION_PANEL:
805 if (DEBUG) Slog.d(TAG, "opening notifications panel");
Joe Onorato7c270fa2010-12-08 17:31:42 -0800806 if (!mNotificationPanel.isShowing()) {
Joe Onorato7c270fa2010-12-08 17:31:42 -0800807 mNotificationPanel.show(true, true);
Daniel Sandler21eb86a2011-03-02 11:52:58 -0500808 mNotificationArea.setVisibility(View.INVISIBLE);
Joe Onorato50ec5ec2010-11-28 17:15:26 -0800809 mTicker.halt();
Joe Onorato091e1b82010-09-26 18:04:44 -0700810 }
Daniel Sandler9120d552010-07-23 09:11:14 -0400811 break;
812 case MSG_CLOSE_NOTIFICATION_PANEL:
813 if (DEBUG) Slog.d(TAG, "closing notifications panel");
Joe Onorato7c270fa2010-12-08 17:31:42 -0800814 if (mNotificationPanel.isShowing()) {
815 mNotificationPanel.show(false, true);
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500816 mNotificationArea.setVisibility(View.VISIBLE);
Joe Onorato091e1b82010-09-26 18:04:44 -0700817 }
Daniel Sandler9120d552010-07-23 09:11:14 -0400818 break;
satok82beadf2010-12-27 19:03:06 +0900819 case MSG_OPEN_INPUT_METHODS_PANEL:
820 if (DEBUG) Slog.d(TAG, "opening input methods panel");
Tadashi G. Takaokae385f0c2011-02-01 02:57:44 +0900821 if (mInputMethodsPanel != null) mInputMethodsPanel.openPanel();
satok82beadf2010-12-27 19:03:06 +0900822 break;
823 case MSG_CLOSE_INPUT_METHODS_PANEL:
824 if (DEBUG) Slog.d(TAG, "closing input methods panel");
Tadashi G. Takaokae385f0c2011-02-01 02:57:44 +0900825 if (mInputMethodsPanel != null) mInputMethodsPanel.closePanel(false);
satok82beadf2010-12-27 19:03:06 +0900826 break;
Daniel Sandler3b0543a2011-06-14 11:30:28 -0400827 case MSG_OPEN_COMPAT_MODE_PANEL:
828 if (DEBUG) Slog.d(TAG, "opening compat panel");
829 if (mCompatModePanel != null) mCompatModePanel.openPanel();
830 break;
831 case MSG_CLOSE_COMPAT_MODE_PANEL:
832 if (DEBUG) Slog.d(TAG, "closing compat panel");
833 if (mCompatModePanel != null) mCompatModePanel.closePanel();
834 break;
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500835 case MSG_SHOW_CHROME:
Daniel Sandlere03d1bc2010-11-17 21:36:40 -0500836 if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500837 mBarContents.setVisibility(View.VISIBLE);
838 mShadow.setVisibility(View.GONE);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400839 mSystemUiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
840 notifyUiVisibilityChanged();
Daniel Sandler06e66302010-11-05 15:00:06 -0400841 break;
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500842 case MSG_HIDE_CHROME:
Daniel Sandlere03d1bc2010-11-17 21:36:40 -0500843 if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
Daniel Sandler06e66302010-11-05 15:00:06 -0400844 animateCollapse();
Mike Lockwood066c8912011-08-24 10:17:18 -0400845 visibilityChanged(false);
Daniel Sandler0ad460b2010-12-14 12:14:53 -0500846 mBarContents.setVisibility(View.GONE);
847 mShadow.setVisibility(View.VISIBLE);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400848 mSystemUiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
849 notifyUiVisibilityChanged();
Daniel Sandlere03d1bc2010-11-17 21:36:40 -0500850 break;
Daniel Sandler2ed08d22011-01-30 16:07:28 -0500851 case MSG_STOP_TICKER:
852 mTicker.halt();
853 break;
Daniel Sandler9120d552010-07-23 09:11:14 -0400854 }
855 }
856 }
Daniel Sandler271ea122010-10-22 14:06:10 -0400857
Joe Onorato808182d2010-07-09 18:52:06 -0400858 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400859 if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
Joe Onorato808182d2010-07-09 18:52:06 -0400860 }
861
862 public void updateIcon(String slot, int index, int viewIndex,
863 StatusBarIcon old, StatusBarIcon icon) {
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400864 if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
Joe Onorato808182d2010-07-09 18:52:06 -0400865 }
866
867 public void removeIcon(String slot, int index, int viewIndex) {
Daniel Sandler1e3ed8f2010-08-13 10:12:48 -0400868 if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
Joe Onorato808182d2010-07-09 18:52:06 -0400869 }
870
871 public void addNotification(IBinder key, StatusBarNotification notification) {
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400872 if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
873 addNotificationViews(key, notification);
Daniel Sandlerfb970e92010-08-20 10:57:17 -0400874
Joe Onorato50ec5ec2010-11-28 17:15:26 -0800875 final boolean immersive = isImmersive();
Joe Onoratocf2b1992010-11-16 21:36:42 -0800876 if (false && immersive) {
Daniel Sandlerfb970e92010-08-20 10:57:17 -0400877 // TODO: immersive mode popups for tablet
878 } else if (notification.notification.fullScreenIntent != null) {
879 // not immersive & a full-screen alert should be shown
Joe Onoratof68b5002011-01-16 17:00:34 -0800880 Slog.w(TAG, "Notification has fullScreenIntent and activity is not immersive;"
Daniel Sandlerfb970e92010-08-20 10:57:17 -0400881 + " sending fullScreenIntent");
882 try {
883 notification.notification.fullScreenIntent.send();
884 } catch (PendingIntent.CanceledException e) {
885 }
886 } else {
Joe Onoratoeeed9942011-01-04 17:13:53 -0800887 tick(key, notification, true);
Daniel Sandlerfb970e92010-08-20 10:57:17 -0400888 }
Joe Onorato5dd11692010-09-27 15:34:04 -0700889
890 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400891 }
892
Joe Onorato808182d2010-07-09 18:52:06 -0400893 public void removeNotification(IBinder key) {
Daniel Sandler3a2fded2011-02-23 11:19:59 -0500894 if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")");
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400895 removeNotificationViews(key);
Joe Onorato50ec5ec2010-11-28 17:15:26 -0800896 mTicker.remove(key);
Joe Onorato5dd11692010-09-27 15:34:04 -0700897 setAreThereNotifications();
Joe Onorato808182d2010-07-09 18:52:06 -0400898 }
899
Daniel Sandler3e8f5a22010-12-03 14:52:10 -0500900 public void showClock(boolean show) {
901 View clock = mBarContents.findViewById(R.id.clock);
902 View network_text = mBarContents.findViewById(R.id.network_text);
903 if (clock != null) {
904 clock.setVisibility(show ? View.VISIBLE : View.GONE);
905 }
906 if (network_text != null) {
907 network_text.setVisibility((!show) ? View.VISIBLE : View.GONE);
908 }
909 }
910
Joe Onorato808182d2010-07-09 18:52:06 -0400911 public void disable(int state) {
Joe Onorato091e1b82010-09-26 18:04:44 -0700912 int old = mDisabled;
913 int diff = state ^ old;
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400914 mDisabled = state;
915
Joe Onorato091e1b82010-09-26 18:04:44 -0700916 // act accordingly
Daniel Sandler3e8f5a22010-12-03 14:52:10 -0500917 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
918 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
Joe Onoratof68b5002011-01-16 17:00:34 -0800919 Slog.i(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
Daniel Sandler3e8f5a22010-12-03 14:52:10 -0500920 showClock(show);
921 }
Daniel Sandler6f6cf3c2010-12-16 12:54:03 -0500922 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
923 boolean show = (state & StatusBarManager.DISABLE_SYSTEM_INFO) == 0;
Joe Onoratof68b5002011-01-16 17:00:34 -0800924 Slog.i(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes"));
Daniel Sandler6f6cf3c2010-12-16 12:54:03 -0500925 mNotificationTrigger.setVisibility(show ? View.VISIBLE : View.GONE);
926 }
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400927 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
928 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
Joe Onoratof68b5002011-01-16 17:00:34 -0800929 Slog.i(TAG, "DISABLE_EXPAND: yes");
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400930 animateCollapse();
Mike Lockwood066c8912011-08-24 10:17:18 -0400931 visibilityChanged(false);
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400932 }
933 }
934 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500935 mNotificationDNDMode = Prefs.read(mContext)
936 .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
Daniel Sandler282ff9a2011-02-23 10:36:49 -0500937
938 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
939 Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes" + (mNotificationDNDMode?" (DND)":""));
940 mTicker.halt();
941 } else {
942 Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no" + (mNotificationDNDMode?" (DND)":""));
943 }
944
945 // refresh icons to show either notifications or the DND message
Daniel Sandlerce6ff642011-02-18 12:51:08 -0500946 reloadAllNotificationIcons();
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400947 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Joe Onorato091e1b82010-09-26 18:04:44 -0700948 if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
Joe Onoratoef1e7762010-09-17 18:38:38 -0400949 mTicker.halt();
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400950 }
951 }
Jim Miller354619c2012-04-27 17:33:44 -0700952 if ((diff & (StatusBarManager.DISABLE_RECENT
953 | StatusBarManager.DISABLE_BACK
Daniel Sandlerdba93562011-10-06 16:39:58 -0400954 | StatusBarManager.DISABLE_HOME)) != 0) {
955 setNavigationVisibility(state);
Michael Jurkab7f43272011-10-27 15:06:38 -0700956
957 if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
958 // close recents if it's visible
959 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
960 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
961 }
Joe Onorato091e1b82010-09-26 18:04:44 -0700962 }
Mike Lockwoode3646dd2011-09-01 12:46:28 -0400963 }
964
965 private void setNavigationVisibility(int visibility) {
Daniel Sandlerdba93562011-10-06 16:39:58 -0400966 boolean disableHome = ((visibility & StatusBarManager.DISABLE_HOME) != 0);
967 boolean disableRecent = ((visibility & StatusBarManager.DISABLE_RECENT) != 0);
Mike Lockwoode3646dd2011-09-01 12:46:28 -0400968 boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
969
Daniel Sandlerdba93562011-10-06 16:39:58 -0400970 mBackButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
971 mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
972 mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
Mike Lockwoode3646dd2011-09-01 12:46:28 -0400973
Daniel Sandlerdba93562011-10-06 16:39:58 -0400974 mInputMethodSwitchButton.setScreenLocked(
975 (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400976 }
977
Joe Onoratoef1e7762010-09-17 18:38:38 -0400978 private boolean hasTicker(Notification n) {
Joe Onorato46439ce2010-11-19 13:56:21 -0800979 return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
Joe Onoratoef1e7762010-09-17 18:38:38 -0400980 }
981
Chris Wren0c8275b2012-05-08 13:36:48 -0400982 @Override
983 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
Joe Onorato55d2d762010-09-26 13:02:01 -0700984 // Don't show the ticker when the windowshade is open.
Joe Onorato7c270fa2010-12-08 17:31:42 -0800985 if (mNotificationPanel.isShowing()) {
Joe Onorato55d2d762010-09-26 13:02:01 -0700986 return;
987 }
Joe Onoratoeeed9942011-01-04 17:13:53 -0800988 // If they asked for FLAG_ONLY_ALERT_ONCE, then only show this notification
989 // if it's a new notification.
990 if (!firstTime && (n.notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
991 return;
992 }
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400993 // Show the ticker if one is requested. Also don't do this
994 // until status bar window is attached to the window manager,
995 // because... well, what's the point otherwise? And trying to
996 // run a ticker without being attached will crash!
Joe Onoratoef1e7762010-09-17 18:38:38 -0400997 if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) {
Daniel Sandlerdfa08db2010-08-05 16:18:42 -0400998 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
999 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
Joe Onorato50ec5ec2010-11-28 17:15:26 -08001000 mTicker.add(key, n);
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001001 mFeedbackIconArea.setVisibility(View.GONE);
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001002 }
1003 }
1004 }
1005
Daniel Sandlerb8027d82010-12-16 19:35:54 -05001006 // called by TabletTicker when it's done with all queued ticks
1007 public void doneTicking() {
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001008 mFeedbackIconArea.setVisibility(View.VISIBLE);
Daniel Sandlerb8027d82010-12-16 19:35:54 -05001009 }
1010
Joe Onorato808182d2010-07-09 18:52:06 -04001011 public void animateExpand() {
Joe Onoratob62ac122010-09-20 16:16:32 -04001012 mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
1013 mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
Joe Onorato808182d2010-07-09 18:52:06 -04001014 }
1015
1016 public void animateCollapse() {
Jim Miller9a720f52012-05-30 03:19:43 -07001017 animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
Michael Jurkab7f43272011-10-27 15:06:38 -07001018 }
1019
Jim Miller9a720f52012-05-30 03:19:43 -07001020 public void animateCollapse(int flags) {
1021 if ((flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) {
1022 mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
1023 mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
1024 }
1025 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
Michael Jurkab7f43272011-10-27 15:06:38 -07001026 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
1027 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
1028 }
Jim Miller9a720f52012-05-30 03:19:43 -07001029 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
1030 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
1031 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
1032 }
1033 if ((flags & CommandQueue.FLAG_EXCLUDE_INPUT_METHODS_PANEL) == 0) {
1034 mHandler.removeMessages(MSG_CLOSE_INPUT_METHODS_PANEL);
1035 mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
1036 }
1037 if ((flags & CommandQueue.FLAG_EXCLUDE_COMPAT_MODE_PANEL) == 0) {
1038 mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL);
1039 mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL);
1040 }
1041
Daniel Sandler9120d552010-07-23 09:11:14 -04001042 }
1043
Daniel Sandler328310c2011-09-23 15:56:52 -04001044 @Override // CommandQueue
1045 public void setNavigationIconHints(int hints) {
1046 if (hints == mNavigationIconHints) return;
1047
1048 if (DEBUG) {
1049 android.widget.Toast.makeText(mContext,
1050 "Navigation icon hints = " + hints,
1051 500).show();
1052 }
1053
1054 mNavigationIconHints = hints;
1055
1056 mBackButton.setAlpha(
1057 (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
1058 mHomeButton.setAlpha(
1059 (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
1060 mRecentButton.setAlpha(
1061 (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
1062
1063 mBackButton.setImageResource(
1064 (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
1065 ? R.drawable.ic_sysbar_back_ime
1066 : R.drawable.ic_sysbar_back);
1067 }
1068
Daniel Sandler60ee2562011-07-22 12:34:33 -04001069 private void notifyUiVisibilityChanged() {
1070 try {
1071 mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
1072 } catch (RemoteException ex) {
1073 }
1074 }
1075
1076 @Override // CommandQueue
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001077 public void setSystemUiVisibility(int vis, int mask) {
1078 final int oldVal = mSystemUiVisibility;
1079 final int newVal = (oldVal&~mask) | (vis&mask);
1080 final int diff = newVal ^ oldVal;
Daniel Sandler60ee2562011-07-22 12:34:33 -04001081
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001082 if (diff != 0) {
1083 mSystemUiVisibility = newVal;
1084
1085 if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
1086 mHandler.removeMessages(MSG_HIDE_CHROME);
1087 mHandler.removeMessages(MSG_SHOW_CHROME);
Jim Millera073e572012-05-23 17:03:27 -07001088 mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001089 ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
1090 }
Daniel Sandler60ee2562011-07-22 12:34:33 -04001091
1092 notifyUiVisibilityChanged();
1093 }
1094 }
1095
Joe Onorato93056472010-09-10 10:30:46 -04001096 public void setLightsOn(boolean on) {
Daniel Sandler59485d742010-12-02 00:11:33 -05001097 // Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
1098 // that can't handle lights-out mode.
Daniel Sandler0ad460b2010-12-14 12:14:53 -05001099 if (mMenuButton.getVisibility() == View.VISIBLE) {
Daniel Sandler59485d742010-12-02 00:11:33 -05001100 on = true;
1101 }
Daniel Sandler60ee2562011-07-22 12:34:33 -04001102
1103 Slog.v(TAG, "setLightsOn(" + on + ")");
1104 if (on) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001105 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001106 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001107 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
Daniel Sandler60ee2562011-07-22 12:34:33 -04001108 }
Joe Onorato93056472010-09-10 10:30:46 -04001109 }
1110
Daniel Sandler5c8da942011-06-28 00:29:04 -04001111 public void topAppWindowChanged(boolean showMenu) {
Daniel Sandlere02d8082010-10-08 15:13:22 -04001112 if (DEBUG) {
Daniel Sandler5c8da942011-06-28 00:29:04 -04001113 Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
Daniel Sandlere02d8082010-10-08 15:13:22 -04001114 }
Daniel Sandler5c8da942011-06-28 00:29:04 -04001115 mMenuButton.setVisibility(showMenu ? View.VISIBLE : View.GONE);
Daniel Sandler59485d742010-12-02 00:11:33 -05001116
1117 // See above re: lights-out policy for legacy apps.
Daniel Sandler5c8da942011-06-28 00:29:04 -04001118 if (showMenu) setLightsOn(true);
Daniel Sandler45c04012011-06-07 15:29:07 -04001119
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001120 mCompatModeButton.refresh();
Daniel Sandler552b1f02011-06-15 01:03:02 -04001121 if (mCompatModeButton.getVisibility() == View.VISIBLE) {
Daniel Sandler319d1e32011-08-05 11:34:06 -04001122 if (DEBUG_COMPAT_HELP
1123 || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
Daniel Sandler552b1f02011-06-15 01:03:02 -04001124 showCompatibilityHelp();
Daniel Sandler319d1e32011-08-05 11:34:06 -04001125 }
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001126 } else {
1127 hideCompatibilityHelp();
1128 mCompatModePanel.closePanel();
Daniel Sandler552b1f02011-06-15 01:03:02 -04001129 }
1130 }
1131
1132 private void showCompatibilityHelp() {
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001133 if (mCompatibilityHelpDialog != null) {
1134 return;
1135 }
Jim Millere898ac52012-04-06 17:10:57 -07001136
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001137 mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null);
1138 View button = mCompatibilityHelpDialog.findViewById(R.id.button);
Daniel Sandler552b1f02011-06-15 01:03:02 -04001139
1140 button.setOnClickListener(new View.OnClickListener() {
1141 @Override
1142 public void onClick(View v) {
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001143 hideCompatibilityHelp();
1144 SharedPreferences.Editor editor = Prefs.edit(mContext);
1145 editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true);
1146 editor.apply();
Daniel Sandler552b1f02011-06-15 01:03:02 -04001147 }
1148 });
1149
Daniel Sandlerf1dd26b2011-06-20 14:44:35 -04001150 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Daniel Sandler552b1f02011-06-15 01:03:02 -04001151 ViewGroup.LayoutParams.MATCH_PARENT,
1152 ViewGroup.LayoutParams.MATCH_PARENT,
1153 WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
1154 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
1155 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
1156 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
1157 PixelFormat.TRANSLUCENT);
1158 lp.setTitle("CompatibilityModeDialog");
1159 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
1160 | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
1161 lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
1162
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001163 WindowManagerImpl.getDefault().addView(mCompatibilityHelpDialog, lp);
Daniel Sandlere02d8082010-10-08 15:13:22 -04001164 }
1165
Dianne Hackborned31bbf2011-06-15 11:16:06 -07001166 private void hideCompatibilityHelp() {
1167 if (mCompatibilityHelpDialog != null) {
1168 WindowManagerImpl.getDefault().removeView(mCompatibilityHelpDialog);
1169 mCompatibilityHelpDialog = null;
1170 }
1171 }
Jim Millere898ac52012-04-06 17:10:57 -07001172
Joe Onorato857fd9b2011-01-27 15:08:35 -08001173 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
1174 mInputMethodSwitchButton.setImeWindowStatus(token,
1175 (vis & InputMethodService.IME_ACTIVE) != 0);
satok51133822011-01-25 15:01:48 +09001176 updateNotificationIcons();
satok913f42d2011-01-17 16:58:10 +09001177 mInputMethodsPanel.setImeToken(token);
Daniel Sandler328310c2011-09-23 15:56:52 -04001178
1179 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
1180 || ((vis & InputMethodService.IME_VISIBLE) != 0);
1181 mAltBackButtonEnabledForIme = altBack;
1182
1183 mCommandQueue.setNavigationIconHints(
1184 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1185 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
1186
Daniel Sandler10163c62010-12-08 11:51:05 -05001187 if (FAKE_SPACE_BAR) {
Joe Onorato857fd9b2011-01-27 15:08:35 -08001188 mFakeSpaceBar.setVisibility(((vis & InputMethodService.IME_VISIBLE) != 0)
1189 ? View.VISIBLE : View.GONE);
Daniel Sandler10163c62010-12-08 11:51:05 -05001190 }
satok06487a52010-10-29 11:37:18 +09001191 }
1192
Jeff Brown2992ea72011-01-28 22:04:14 -08001193 @Override
Daniel Sandler328310c2011-09-23 15:56:52 -04001194 public void onRecentsPanelVisibilityChanged(boolean visible) {
1195 boolean altBack = visible || mAltBackButtonEnabledForIme;
1196 mCommandQueue.setNavigationIconHints(
1197 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
1198 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
1199 }
1200
1201 @Override
Jeff Brown2992ea72011-01-28 22:04:14 -08001202 public void setHardKeyboardStatus(boolean available, boolean enabled) {
1203 if (DEBUG) {
1204 Slog.d(TAG, "Set hard keyboard status: available=" + available
1205 + ", enabled=" + enabled);
1206 }
1207 mInputMethodSwitchButton.setHardKeyboardStatus(available);
1208 updateNotificationIcons();
1209 mInputMethodsPanel.setHardKeyboardStatus(available, enabled);
1210 }
1211
1212 @Override
1213 public void onHardKeyboardEnabledChange(boolean enabled) {
1214 try {
1215 mBarService.setHardKeyboardEnabled(enabled);
1216 } catch (RemoteException ex) {
1217 }
1218 }
1219
Joe Onorato50ec5ec2010-11-28 17:15:26 -08001220 private boolean isImmersive() {
1221 try {
1222 return ActivityManagerNative.getDefault().isTopActivityImmersive();
1223 //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
1224 } catch (RemoteException ex) {
1225 // the end is nigh
1226 return false;
1227 }
1228 }
Jim Miller85babff2011-01-11 14:26:03 -08001229
Chris Wren0c8275b2012-05-08 13:36:48 -04001230 @Override
1231 protected void setAreThereNotifications() {
Daniel Sandler06a0d4b2011-08-05 00:19:21 -04001232 if (mNotificationPanel != null) {
John Spurlock36231282012-06-23 17:11:27 -04001233 mNotificationPanel.setClearable(isDeviceProvisioned() && mNotificationData.hasClearableItems());
Daniel Sandler06a0d4b2011-08-05 00:19:21 -04001234 }
Joe Onorato5dd11692010-09-27 15:34:04 -07001235 }
1236
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001237 private View.OnClickListener mOnClickListener = new View.OnClickListener() {
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001238 public void onClick(View v) {
Daniel Sandler130453c2011-08-18 09:41:01 -04001239 if (v == mRecentButton) {
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001240 onClickRecentButton();
satok82beadf2010-12-27 19:03:06 +09001241 } else if (v == mInputMethodSwitchButton) {
1242 onClickInputMethodSwitchButton();
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001243 } else if (v == mCompatModeButton) {
1244 onClickCompatModeButton();
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001245 }
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001246 }
1247 };
1248
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001249 public void onClickRecentButton() {
Daniel Sandlerb6d3dc62010-11-17 16:51:26 -05001250 if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
Michael Jurka3b1fc472011-06-13 10:54:40 -07001251 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
Michael Jurka5571ab22011-10-27 12:54:39 -07001252 int msg = (mRecentsPanel.getVisibility() == View.VISIBLE)
1253 ? MSG_CLOSE_RECENTS_PANEL : MSG_OPEN_RECENTS_PANEL;
Michael Jurka3b1fc472011-06-13 10:54:40 -07001254 mHandler.removeMessages(msg);
1255 mHandler.sendEmptyMessage(msg);
Jim Miller44c66fe2010-10-20 18:32:52 -07001256 }
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001257 }
Joe Onorato55d2d762010-09-26 13:02:01 -07001258
satok82beadf2010-12-27 19:03:06 +09001259 public void onClickInputMethodSwitchButton() {
1260 if (DEBUG) Slog.d(TAG, "clicked input methods panel; disabled=" + mDisabled);
1261 int msg = (mInputMethodsPanel.getVisibility() == View.GONE) ?
1262 MSG_OPEN_INPUT_METHODS_PANEL : MSG_CLOSE_INPUT_METHODS_PANEL;
1263 mHandler.removeMessages(msg);
1264 mHandler.sendEmptyMessage(msg);
1265 }
1266
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001267 public void onClickCompatModeButton() {
1268 int msg = (mCompatModePanel.getVisibility() == View.GONE) ?
1269 MSG_OPEN_COMPAT_MODE_PANEL : MSG_CLOSE_COMPAT_MODE_PANEL;
1270 mHandler.removeMessages(msg);
1271 mHandler.sendEmptyMessage(msg);
1272 }
1273
Daniel Sandler56a6d882011-02-23 16:40:33 -05001274 private class NotificationTriggerTouchListener implements View.OnTouchListener {
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001275 VelocityTracker mVT;
Daniel Sandler56a6d882011-02-23 16:40:33 -05001276 float mInitialTouchX, mInitialTouchY;
1277 int mTouchSlop;
1278
1279 public NotificationTriggerTouchListener() {
1280 mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
1281 }
1282
Daniel Sandler298a2a82011-08-11 16:13:22 -04001283 private Runnable mHiliteOnR = new Runnable() { public void run() {
1284 mNotificationArea.setBackgroundResource(
1285 com.android.internal.R.drawable.list_selector_pressed_holo_dark);
1286 }};
1287 public void hilite(final boolean on) {
1288 if (on) {
1289 mNotificationArea.postDelayed(mHiliteOnR, 100);
1290 } else {
1291 mNotificationArea.removeCallbacks(mHiliteOnR);
Michael Jurkaa600fd92012-06-25 15:57:05 -07001292 mNotificationArea.setBackground(null);
Daniel Sandler298a2a82011-08-11 16:13:22 -04001293 }
1294 }
1295
Daniel Sandler56a6d882011-02-23 16:40:33 -05001296 public boolean onTouch(View v, MotionEvent event) {
1297// Slog.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)",
1298// event.getX(),
1299// event.getY(),
1300// mInitialTouchX,
1301// mInitialTouchY));
Daniel Sandler130453c2011-08-18 09:41:01 -04001302
1303 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
1304 return true;
1305 }
1306
Daniel Sandler56a6d882011-02-23 16:40:33 -05001307 final int action = event.getAction();
1308 switch (action) {
1309 case MotionEvent.ACTION_DOWN:
1310 mVT = VelocityTracker.obtain();
1311 mInitialTouchX = event.getX();
1312 mInitialTouchY = event.getY();
Daniel Sandler298a2a82011-08-11 16:13:22 -04001313 hilite(true);
Daniel Sandler56a6d882011-02-23 16:40:33 -05001314 // fall through
1315 case MotionEvent.ACTION_OUTSIDE:
1316 case MotionEvent.ACTION_MOVE:
1317 // check for fling
1318 if (mVT != null) {
1319 mVT.addMovement(event);
1320 mVT.computeCurrentVelocity(1000); // pixels per second
1321 // require a little more oomph once we're already in peekaboo mode
1322 if (mVT.getYVelocity() < -mNotificationFlingVelocity) {
1323 animateExpand();
Mike Lockwood066c8912011-08-24 10:17:18 -04001324 visibilityChanged(true);
Daniel Sandler298a2a82011-08-11 16:13:22 -04001325 hilite(false);
Daniel Sandler56a6d882011-02-23 16:40:33 -05001326 mVT.recycle();
1327 mVT = null;
1328 }
1329 }
1330 return true;
1331 case MotionEvent.ACTION_UP:
1332 case MotionEvent.ACTION_CANCEL:
Daniel Sandler298a2a82011-08-11 16:13:22 -04001333 hilite(false);
Daniel Sandler56a6d882011-02-23 16:40:33 -05001334 if (mVT != null) {
1335 if (action == MotionEvent.ACTION_UP
1336 // was this a sloppy tap?
Jim Miller9f0f0e02011-05-17 20:06:29 -07001337 && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop
Daniel Sandler56a6d882011-02-23 16:40:33 -05001338 && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
1339 // dragging off the bottom doesn't count
1340 && (int)event.getY() < v.getBottom()) {
1341 animateExpand();
Mike Lockwood066c8912011-08-24 10:17:18 -04001342 visibilityChanged(true);
Daniel Sandleraa051d62011-03-01 16:23:57 -05001343 v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
1344 v.playSoundEffect(SoundEffectConstants.CLICK);
Daniel Sandler56a6d882011-02-23 16:40:33 -05001345 }
1346
1347 mVT.recycle();
1348 mVT = null;
1349 return true;
1350 }
1351 }
1352 return false;
1353 }
1354 }
1355
Daniel Sandler663f0f22011-03-04 16:45:02 -05001356 public void resetNotificationPeekFadeTimer() {
1357 if (DEBUG) {
1358 Slog.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY
1359 + "ms from now");
1360 }
1361 mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
1362 mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK,
1363 NOTIFICATION_PEEK_FADE_DELAY);
1364 }
1365
Daniel Sandler0ad460b2010-12-14 12:14:53 -05001366 private void reloadAllNotificationIcons() {
1367 if (mIconLayout == null) return;
1368 mIconLayout.removeAllViews();
1369 updateNotificationIcons();
1370 }
1371
Chris Wren0c8275b2012-05-08 13:36:48 -04001372 @Override
1373 protected void updateNotificationIcons() {
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001374 // XXX: need to implement a new limited linear layout class
1375 // to avoid removing & readding everything
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001376
Daniel Sandler0ad460b2010-12-14 12:14:53 -05001377 if (mIconLayout == null) return;
1378
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001379 // first, populate the main notification panel
1380 loadNotificationPanel();
1381
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001382 final LinearLayout.LayoutParams params
Joe Onoratodc100302011-01-11 17:07:41 -08001383 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001384
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001385 // alternate behavior in DND mode
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001386 if (mNotificationDNDMode) {
1387 if (mIconLayout.getChildCount() == 0) {
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001388 final Notification dndNotification = new Notification.Builder(mContext)
1389 .setContentTitle(mContext.getText(R.string.notifications_off_title))
1390 .setContentText(mContext.getText(R.string.notifications_off_text))
1391 .setSmallIcon(R.drawable.ic_notification_dnd)
1392 .setOngoing(true)
1393 .getNotification();
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001394
Svetoslav Ganov6179ea32011-06-28 01:12:41 -07001395 final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd",
1396 dndNotification);
1397 iconView.setImageResource(R.drawable.ic_notification_dnd);
1398 iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
1399 iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0);
1400
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001401 mNotificationDNDDummyEntry = new NotificationData.Entry(
1402 null,
Daniel Sandler2561b0b2012-02-13 21:04:12 -05001403 new StatusBarNotification("", 0, "", 0, 0, Notification.PRIORITY_MAX, dndNotification),
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001404 iconView);
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001405
Daniel Sandler282ff9a2011-02-23 10:36:49 -05001406 mIconLayout.addView(iconView, params);
1407 }
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001408
1409 return;
Daniel Sandler8e41f312011-08-03 14:05:07 -04001410 } else if (0 != (mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS)) {
1411 // if icons are disabled but we're not in DND mode, this is probably Setup and we should
1412 // just leave the area totally empty
1413 return;
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001414 }
1415
1416 int N = mNotificationData.size();
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001417
1418 if (DEBUG) {
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001419 Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001420 }
1421
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001422 ArrayList<View> toShow = new ArrayList<View>();
1423
Daniel Sandler3b0543a2011-06-14 11:30:28 -04001424 // Extra Special Icons
1425 // The IME switcher and compatibility mode icons take the place of notifications. You didn't
1426 // need to see all those new emails, did you?
1427 int maxNotificationIconsCount = mMaxNotificationIcons;
1428 if (mInputMethodSwitchButton.getVisibility() != View.GONE) maxNotificationIconsCount --;
1429 if (mCompatModeButton.getVisibility() != View.GONE) maxNotificationIconsCount --;
1430
John Spurlock36231282012-06-23 17:11:27 -04001431 final boolean provisioned = isDeviceProvisioned();
1432 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandler58b173b2012-05-03 11:25:29 -04001433 for (int i=0; toShow.size()< maxNotificationIconsCount; i++) {
1434 if (i >= N) break;
1435 Entry ent = mNotificationData.get(N-i-1);
John Spurlock36231282012-06-23 17:11:27 -04001436 if ((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
1437 || showNotificationEvenIfUnprovisioned(ent.notification)) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001438 toShow.add(ent.icon);
1439 }
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001440 }
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001441
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001442 ArrayList<View> toRemove = new ArrayList<View>();
1443 for (int i=0; i<mIconLayout.getChildCount(); i++) {
1444 View child = mIconLayout.getChildAt(i);
1445 if (!toShow.contains(child)) {
1446 toRemove.add(child);
1447 }
Daniel Sandlerdfa08db2010-08-05 16:18:42 -04001448 }
Daniel Sandler271ea122010-10-22 14:06:10 -04001449
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001450 for (View remove : toRemove) {
1451 mIconLayout.removeView(remove);
1452 }
1453
1454 for (int i=0; i<toShow.size(); i++) {
1455 View v = toShow.get(i);
Daniel Sandler0ad460b2010-12-14 12:14:53 -05001456 v.setPadding(mIconHPadding, 0, mIconHPadding, 0);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001457 if (v.getParent() == null) {
Daniel Sandler0ad460b2010-12-14 12:14:53 -05001458 mIconLayout.addView(v, i, params);
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001459 }
1460 }
Daniel Sandler0f0b11c2010-08-04 15:54:58 -04001461 }
1462
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001463 private void loadNotificationPanel() {
Daniel Sandlerce6ff642011-02-18 12:51:08 -05001464 int N = mNotificationData.size();
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001465
1466 ArrayList<View> toShow = new ArrayList<View>();
1467
John Spurlock36231282012-06-23 17:11:27 -04001468 final boolean provisioned = isDeviceProvisioned();
1469 // If the device hasn't been through Setup, we only show system notifications
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001470 for (int i=0; i<N; i++) {
John Spurlock36231282012-06-23 17:11:27 -04001471 Entry ent = mNotificationData.get(N-i-1);
1472 if (provisioned || showNotificationEvenIfUnprovisioned(ent.notification)) {
1473 toShow.add(ent.row);
1474 }
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001475 }
1476
1477 ArrayList<View> toRemove = new ArrayList<View>();
1478 for (int i=0; i<mPile.getChildCount(); i++) {
1479 View child = mPile.getChildAt(i);
1480 if (!toShow.contains(child)) {
1481 toRemove.add(child);
1482 }
1483 }
1484
1485 for (View remove : toRemove) {
1486 mPile.removeView(remove);
1487 }
1488
1489 for (int i=0; i<toShow.size(); i++) {
1490 View v = toShow.get(i);
1491 if (v.getParent() == null) {
Daniel Sandler58b173b2012-05-03 11:25:29 -04001492 // the notification panel has the most important things at the bottom
John Spurlock36231282012-06-23 17:11:27 -04001493 mPile.addView(v, Math.min(toShow.size()-1-i, mPile.getChildCount()));
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001494 }
1495 }
Daniel Sandler40c15452011-01-22 01:26:22 -05001496
John Spurlock36231282012-06-23 17:11:27 -04001497 mNotificationPanel.setNotificationCount(toShow.size());
1498 mNotificationPanel.setSettingsEnabled(isDeviceProvisioned());
Daniel Sandlerb0cc50d2010-10-26 16:55:56 -04001499 }
1500
Daniel Sandler6a858c32012-03-12 14:38:58 -04001501 @Override
1502 protected void workAroundBadLayerDrawableOpacity(View v) {
Adam Powell29ea5252011-11-15 18:59:36 -08001503 Drawable bgd = v.getBackground();
1504 if (!(bgd instanceof LayerDrawable)) return;
1505
1506 LayerDrawable d = (LayerDrawable) bgd;
Michael Jurkaa600fd92012-06-25 15:57:05 -07001507 v.setBackground(null);
Joe Onorato4daaeaf2010-11-17 20:43:12 -08001508 d.setOpacity(PixelFormat.TRANSLUCENT);
Michael Jurkaa600fd92012-06-25 15:57:05 -07001509 v.setBackground(d);
Joe Onorato4daaeaf2010-11-17 20:43:12 -08001510 }
1511
Daniel Sandler06a0d4b2011-08-05 00:19:21 -04001512 public void clearAll() {
1513 try {
1514 mBarService.onClearAllNotifications();
1515 } catch (RemoteException ex) {
1516 // system process is dead if we're here.
1517 }
1518 animateCollapse();
Mike Lockwood066c8912011-08-24 10:17:18 -04001519 visibilityChanged(false);
Daniel Sandler06a0d4b2011-08-05 00:19:21 -04001520 }
1521
Michael Jurkab7f43272011-10-27 15:06:38 -07001522 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
1523 public void onReceive(Context context, Intent intent) {
1524 String action = intent.getAction();
1525 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
1526 || Intent.ACTION_SCREEN_OFF.equals(action)) {
Jim Miller9a720f52012-05-30 03:19:43 -07001527 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
Michael Jurkab7f43272011-10-27 15:06:38 -07001528 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
1529 String reason = intent.getStringExtra("reason");
Jim Miller9a720f52012-05-30 03:19:43 -07001530 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
1531 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurkab7f43272011-10-27 15:06:38 -07001532 }
1533 }
1534 if (Intent.ACTION_SCREEN_OFF.equals(action)) {
1535 // If we're turning the screen off, we want to hide the
1536 // recents panel with no animation
1537 // TODO: hide other things, like the notification tray,
1538 // with no animation as well
1539 mRecentsPanel.show(false, false);
Jim Miller9a720f52012-05-30 03:19:43 -07001540 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
Michael Jurkab7f43272011-10-27 15:06:38 -07001541 }
Jim Miller9a720f52012-05-30 03:19:43 -07001542 animateCollapse(flags);
Michael Jurkab7f43272011-10-27 15:06:38 -07001543 }
1544 }
1545 };
1546
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001547 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1548 pw.print("mDisabled=0x");
1549 pw.println(Integer.toHexString(mDisabled));
Joe Onorato933464d2011-01-05 15:53:36 -08001550 pw.println("mNetworkController:");
1551 mNetworkController.dump(fd, pw, args);
Joe Onoratof3c3c4f2010-10-21 11:09:02 -04001552 }
Daniel Sandlerc6d29fc2012-02-25 00:33:12 -05001553
Chris Wren0c8275b2012-05-08 13:36:48 -04001554 @Override
1555 protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
Daniel Sandler15986c62012-06-28 13:38:28 -04001556 if (parent == null || entry == null) return false;
Chris Wren0c8275b2012-05-08 13:36:48 -04001557 return parent.indexOfChild(entry.row) == parent.getChildCount()-1;
1558 }
1559
1560 @Override
1561 protected void haltTicker() {
1562 mTicker.halt();
1563 }
1564
1565 @Override
1566 protected void updateExpandedViewPos(int expandedPosition) {
1567 }
Jim Miller670d9dd2012-05-12 13:28:26 -07001568
1569 @Override
Jim Millerb4238e02012-05-14 15:26:20 -07001570 protected boolean shouldDisableNavbarGestures() {
1571 return mNotificationPanel.getVisibility() == View.VISIBLE
1572 || (mDisabled & StatusBarManager.DISABLE_HOME) != 0;
Jim Miller670d9dd2012-05-12 13:28:26 -07001573 }
Joe Onorato808182d2010-07-09 18:52:06 -04001574}
Daniel Sandlerd39e3882010-08-31 14:16:13 -04001575
1576