PhoneStatusBar.java revision 5050813f15a1d39d49cb8eca5a3aa6df43c4d450
146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/* 246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Copyright (C) 2010 The Android Open Source Project 346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * you may not use this file except in compliance with the License. 646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * You may obtain a copy of the License at 746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 1046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 1146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 1246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * See the License for the specific language governing permissions and 1446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * limitations under the License. 1546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 1646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)package com.android.systemui.statusbar.phone; 1846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.animation.Animator; 2046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.animation.AnimatorListenerAdapter; 2146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.animation.AnimatorSet; 221e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdochimport android.animation.ObjectAnimator; 2346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.ActivityManager; 2462c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurunimport android.app.ActivityManagerNative; 2546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.Dialog; 2646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.KeyguardManager; 27251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liuimport android.app.Notification; 2846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.PendingIntent; 2946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.StatusBarManager; 3046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.BroadcastReceiver; 31e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liuimport android.content.Context; 3246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Intent; 334320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liuimport android.content.IntentFilter; 34885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsenimport android.content.res.Configuration; 3546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.res.Resources; 3646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.Canvas; 3762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurunimport android.graphics.ColorFilter; 38809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liuimport android.graphics.PixelFormat; 3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.PorterDuff; 40e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liuimport android.graphics.Rect; 4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.drawable.Drawable; 4246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.drawable.NinePatchDrawable; 4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.inputmethodservice.InputMethodService; 4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.IBinder; 4546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Message; 4646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.RemoteException; 4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.ServiceManager; 4846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.SystemClock; 4946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.UserHandle; 5046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.provider.Settings; 5146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.service.dreams.IDreamManager; 5246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.DisplayMetrics; 5346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.Log; 5446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.Slog; 5546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.Display; 5646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.Gravity; 5746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.IWindowManager; 5846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.KeyEvent; 5946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.MotionEvent; 6046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.VelocityTracker; 6146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.View; 6246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.ViewGroup; 6346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.ViewGroup.LayoutParams; 6446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.WindowManager; 6546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.WindowManagerImpl; 6646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.animation.AccelerateInterpolator; 6746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.animation.Animation; 6846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.animation.AnimationUtils; 6946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.animation.DecelerateInterpolator; 7046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.widget.FrameLayout; 7146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.widget.ImageView; 7246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.widget.LinearLayout; 7346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.widget.ScrollView; 7446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.widget.TextView; 7546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 7646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.internal.statusbar.StatusBarIcon; 7746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.internal.statusbar.StatusBarNotification; 7846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.R; 7946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.recent.RecentTasksLoader; 8046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.BaseStatusBar; 8146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.CommandQueue; 8246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.GestureRecorder; 8346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.NotificationData; 8446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.NotificationData.Entry; 854320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liuimport com.android.systemui.statusbar.RotationToggle; 864320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liuimport com.android.systemui.statusbar.SignalClusterView; 879b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdochimport com.android.systemui.statusbar.StatusBarIconView; 889b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdochimport com.android.systemui.statusbar.policy.BatteryController; 899b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdochimport com.android.systemui.statusbar.policy.DateView; 909b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdochimport com.android.systemui.statusbar.policy.IntruderAlertView; 9146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.policy.LocationController; 9246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.policy.NetworkController; 9346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.policy.NotificationRowLayout; 9446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import com.android.systemui.statusbar.policy.OnSizeChangedListener; 9546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 9646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.io.FileDescriptor; 9746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.io.PrintWriter; 9846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.util.ArrayList; 9946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 10046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class PhoneStatusBar extends BaseStatusBar { 10146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) static final String TAG = "PhoneStatusBar"; 10246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final boolean DEBUG = false; 10346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final boolean SPEW = DEBUG; 1049b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch public static final boolean DUMPTRUCK = true; // extra dumpsys info 1059b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch 1069b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch // additional instrumentation for testing purposes; intended to be left on during development 1079b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch public static final boolean CHATTY = DEBUG; 1089b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch 1099b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch public static final String ACTION_STATUSBAR_START 1109b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch = "com.android.internal.policy.statusbar.START"; 1111ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1121ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final boolean SHOW_CARRIER_LABEL = false; // XXX: doesn't work with rubberband panels right now 1131ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1141ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; 1151ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001; 1161ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch // 1020-1030 reserved for BaseStatusBar 1171ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1181ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch // will likely move to a resource or other tunable param at some point 1191ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000; 1201ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1211ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true; 1221ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1231ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService 1241ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER; 1251ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch 1261ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch // fling gesture tuning parameters, scaled to display density 1271ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private float mSelfExpandVelocityPx; // classic value: 2000px/s 1281ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up") 1291ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch private float mFlingExpandMinVelocityPx; // classic value: 200px/s 1309b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mFlingCollapseMinVelocityPx; // classic value: 200px/s 1319b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1) 1329b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand) 1339b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s 1349b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch 1359b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mExpandAccelPx; // classic value: 2000px/s/s 1369b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up") 13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little 13946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // faster than mSelfCollapseVelocityPx) 14046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) PhoneStatusBarPolicy mIconPolicy; 14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 14346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // These are no longer handled by the policy, because we need custom strategies for them 14446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) BatteryController mBatteryController; 14546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LocationController mLocationController; 14646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) NetworkController mNetworkController; 14746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 14846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mNaturalBarHeight = -1; 14946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mIconSize = -1; 15046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mIconHPadding = -1; 15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Display mDisplay; 15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) IWindowManager mWindowManager; 15446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) IDreamManager mDreamManager; 15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) StatusBarWindowView mStatusBarWindow; 15746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) PhoneStatusBarView mStatusBarView; 15846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mPixelFormat; 16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Object mQueueLock = new Object(); 16146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 16246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // icons 16346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LinearLayout mIcons; 16446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) IconMerger mNotificationIcons; 16546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) View mMoreIcon; 16646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LinearLayout mStatusIcons; 16746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 16846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // expanded notifications 16946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) PanelView mNotificationPanel; // the sliding/resizing panel within the notification window 17046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ScrollView mScrollView; 17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) View mExpandedContents; 17246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) final Rect mNotificationPanelBackgroundPadding = new Rect(); 17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mNotificationPanelGravity; 17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mNotificationPanelMarginBottomPx, mNotificationPanelMarginPx; 17546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mNotificationPanelMinHeight; 17646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean mNotificationPanelIsFullScreenWidth; 17746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) TextView mNotificationPanelDebugText; 17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 17946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // settings 18046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) PanelView mSettingsPanel; 18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mSettingsPanelGravity; 18246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 18346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // top bar 18446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) View mClearButton; 185fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu View mSettingsButton; 186fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu RotationToggle mRotationButton; 18746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 188fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu // carrier/wifi label 18946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private TextView mCarrierLabel; 19046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private boolean mCarrierLabelVisible = false; 19146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private int mCarrierLabelHeight; 19246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private TextView mEmergencyCallLabel; 19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // position 19546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int[] mPositionTmp = new int[2]; 19646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean mExpandedVisible; 19746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 19846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // the date view 19946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) DateView mDateView; 20046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 201fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu // for immersive activities 20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private IntruderAlertView mIntruderAlertView; 20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 20446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // on-screen navigation buttons 20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private NavigationBarView mNavigationBarView = null; 20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 20746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // the tracker view 20846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mTrackingPosition; // the position of the top of the tracking view. 20946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 21046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // ticker 21146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private Ticker mTicker; 21246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private View mTickerView; 21346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private boolean mTicking; 2144320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu 2154320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu // Tracking finger for opening/closing. 2164320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore 2174320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu boolean mTracking; 21846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) VelocityTracker mVelocityTracker; 21946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 22046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean mAnimating; 22146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean mClosing; // only valid when mAnimating; indicates the initial acceleration 22246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) float mAnimY; 22346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) float mAnimVel; 22446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) float mAnimAccel; 22546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) long mAnimLastTimeNanos; 22646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean mAnimatingReveal = false; 22746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mViewDelta; 22846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) float mFlingVelocity; 22946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int mFlingY; 23046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int[] mAbsPos = new int[2]; 231809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu Runnable mPostCollapseCleanup = null; 232809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu 233809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu private AnimatorSet mLightsOutAnimation; 234809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu private AnimatorSet mLightsOnAnimation; 235809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu 236809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu // for disabling the status bar 237809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu int mDisabled = 0; 238809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu 2395e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu // tracking calls to View.setSystemUiVisibility() 2405e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE; 2415e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu 2425e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu DisplayMetrics mDisplayMetrics = new DisplayMetrics(); 2435e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu 2445e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu // XXX: gesture research 2455e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu private GestureRecorder mGestureRec = new GestureRecorder("/sdcard/statusbar_gestures.dat"); 2465e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu 24746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private int mNavigationIconHints = 0; 24846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() { 24946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 25046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void onAnimationEnd(Animator animation) { 25146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // double-check to avoid races 25246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mIcons.getAlpha() == 0) { 25346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.d(TAG, "makeIconsInvisible"); 25446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mIcons.setVisibility(View.INVISIBLE); 25546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 25646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 25746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) }; 25846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 25946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 26046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void start() { 26146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) 26246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) .getDefaultDisplay(); 26346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 26446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mWindowManager = IWindowManager.Stub.asInterface( 26546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ServiceManager.getService(Context.WINDOW_SERVICE)); 26646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 26746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mDreamManager = IDreamManager.Stub.asInterface( 26846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ServiceManager.checkService("dreams")); 26946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 27046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) super.start(); // calls createAndAddWindows() 27146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 27246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) addNavigationBar(); 27346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 27446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (ENABLE_INTRUDERS) addIntruderView(); 27546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 27646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Lastly, call to the icon policy to install/update all the icons. 27746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mIconPolicy = new PhoneStatusBarPolicy(mContext); 27846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 27946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 28046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // ================================================================================ 28146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Constructing the view 28246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // ================================================================================ 28346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) protected PhoneStatusBarView makeStatusBarView() { 28446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) final Context context = mContext; 28546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 28646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Resources res = context.getResources(); 28746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 28846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateDisplaySize(); // populates mDisplayMetrics 28946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) loadDimens(); 29046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 29146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); 29246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 29346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarWindow = (StatusBarWindowView) View.inflate(context, 29446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) R.layout.super_status_bar, null); 29546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (DEBUG) { 29646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarWindow.setBackgroundColor(0x6000FF80); 29746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 29846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarWindow.mService = this; 29946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() { 30046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 3015ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil public boolean onTouch(View v, MotionEvent event) { 3025ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil if (event.getAction() == MotionEvent.ACTION_DOWN) { 3035ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil if (mExpandedVisible && !mAnimating) { 3049c5a40623b62737244deb2d04a98830d7ffa8404Leandro Gracia Gil animateCollapse(); 3055ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil } 3065ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil } 3075ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil return mStatusBarWindow.onTouchEvent(event); 3085ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil }}); 3095ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil 31046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar); 31146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarView.setBar(this); 31246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 31346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder); 31446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStatusBarView.setPanelHolder(holder); 3159b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch 3169b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel); 3179b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch // don't allow clicks on the panel to pass through to the background where they will cause the panel to close 3189b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch View.OnTouchListener clickStopper = new View.OnTouchListener() { 3191ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch @Override 3209b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch public boolean onTouch(View v, MotionEvent event) { 3219b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch return true; 322d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch } 323d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch }; 324d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch mNotificationPanel.setOnTouchListener(clickStopper); 325d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch mNotificationPanelIsFullScreenWidth = 326d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT); 327d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch mNotificationPanel.setSystemUiVisibility( 328d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER 329d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch | (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO)); 330d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch 331d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch // quick settings (WIP) 332d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel); 333d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch mSettingsPanel.setOnTouchListener(clickStopper); 334d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch 335d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch if (!ActivityManager.isHighEndGfx(mDisplay)) { 336d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch mStatusBarWindow.setBackground(null); 337d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor( 3381e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch R.color.notification_panel_solid_background))); 3391e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( 3401e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch R.color.notification_panel_solid_background))); 3411e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch } 3421e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch if (ENABLE_INTRUDERS) { 3431e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null); 3441e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch mIntruderAlertView.setVisibility(View.GONE); 3451e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch mIntruderAlertView.setBar(this); 34646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 34746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (MULTIUSER_DEBUG) { 34846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info); 34946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNotificationPanelDebugText.setVisibility(View.VISIBLE); 35046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 35146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 35246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateShowSearchHoldoff(); 35346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 35446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 35546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean showNav = mWindowManager.hasNavigationBar(); 35646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav); 35746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (showNav) { 35846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView = 35946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); 36046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 36146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.setDisabledFlags(mDisabled); 36246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.setBar(this); 36346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 36446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (RemoteException ex) { 365e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch // no window manager? good luck with that 366e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch } 367e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch 368e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch // figure out which pixel-format to use for the status bar. 369e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mPixelFormat = PixelFormat.OPAQUE; 370e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons); 371e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons); 372e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mNotificationIcons.setOverflowIndicator(mMoreIcon); 373e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mIcons = (LinearLayout)mStatusBarView.findViewById(R.id.icons); 374e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mTickerView = mStatusBarView.findViewById(R.id.ticker); 375e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch 376e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems); 377e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mPile.setLayoutTransitionsEnabled(false); 378e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mPile.setLongPressListener(getNotificationLongClicker()); 379e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout); 380e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch 381e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button); 382e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mClearButton.setOnClickListener(mClearButtonListener); 383e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mClearButton.setAlpha(0f); 384e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mClearButton.setVisibility(View.INVISIBLE); 385e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mClearButton.setEnabled(false); 386e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date); 387e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button); 388e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mSettingsButton.setOnClickListener(mSettingsButtonListener); 389e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch mRotationButton = (RotationToggle) mStatusBarWindow.findViewById(R.id.rotation_lock_button); 39046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 39146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll); 39246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns 39346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 39446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mTicker = new MyTicker(context, mStatusBarView); 39546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 39646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) TickerView tickerView = (TickerView)mStatusBarView.findViewById(R.id.tickerText); 39746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) tickerView.mTicker = mTicker; 39846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 39946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); 40046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 40146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // set the inital view visibility 40246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) setAreThereNotifications(); 40346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 40446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Other icons 40546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mLocationController = new LocationController(mContext); // will post a notification 40646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mBatteryController = new BatteryController(mContext); 40746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery)); 40846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNetworkController = new NetworkController(mContext); 40946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) final SignalClusterView signalCluster = 41046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster); 41146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 41246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNetworkController.addSignalCluster(signalCluster); 41346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) signalCluster.setNetworkController(mNetworkController); 414b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon 415b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon mEmergencyCallLabel = (TextView)mStatusBarWindow.findViewById(R.id.emergency_calls_only); 416b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon if (mEmergencyCallLabel != null) { 417b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon mNetworkController.addEmergencyLabelView(mEmergencyCallLabel); 418b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon mEmergencyCallLabel.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 419b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon @Override 420b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon public void onLayoutChange(View v, int left, int top, int right, int bottom, 42146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int oldLeft, int oldTop, int oldRight, int oldBottom) { 42246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateCarrierLabelVisibility(false); 42346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) }}); 42446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 42546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 42646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (SHOW_CARRIER_LABEL) { 42746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label); 42846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE); 42946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 43046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // for mobile devices, we always show mobile connection info here (SPN/PLMN) 43146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // for other devices, we show whatever network is connected 43246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mNetworkController.hasMobileDataFeature()) { 43346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNetworkController.addMobileLabelView(mCarrierLabel); 43446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 43546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNetworkController.addCombinedLabelView(mCarrierLabel); 43646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 43746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 43846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // set up the dynamic hide/show of the label 43946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mPile.setOnSizeChangedListener(new OnSizeChangedListener() { 44046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 44146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void onSizeChanged(View view, int w, int h, int oldw, int oldh) { 44246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateCarrierLabelVisibility(false); 44346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 44446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) }); 44546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 44646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 44746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)// final ImageView wimaxRSSI = 44846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)// (ImageView)sb.findViewById(R.id.wimax_signal); 44946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)// if (wimaxRSSI != null) { 45046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)// mNetworkController.addWimaxIconView(wimaxRSSI); 45146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)// } 45246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Recents Panel 45346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mRecentTasksLoader = new RecentTasksLoader(context); 45446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateRecentsPanel(); 4553e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu 45646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // receive broadcasts 45746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) IntentFilter filter = new IntentFilter(); 45846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); 4593e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 46046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) filter.addAction(Intent.ACTION_SCREEN_OFF); 46146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) context.registerReceiver(mBroadcastReceiver, filter); 46246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 46346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mStatusBarView; 46446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 46546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 46646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 46746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) { 46846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean opaque = false; 46946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 47046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) layoutParams.width, 47146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) layoutParams.height, 47246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, 47346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 47446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 47546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 47646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); 47746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (ActivityManager.isHighEndGfx(mDisplay)) { 47846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 47946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 48046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; 48146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.dimAmount = 0.75f; 48246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 48346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 48446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.setTitle("RecentsPanel"); 48546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; 48646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED 48746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; 48846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return lp; 48946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 49046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 49146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 49246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) { 49346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) boolean opaque = false; 49446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 49546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LayoutParams.MATCH_PARENT, 49646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LayoutParams.MATCH_PARENT, 49746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, 49846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 49946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 50046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 50146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT)); 50246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (ActivityManager.isHighEndGfx(mDisplay)) { 50346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 50446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 50546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 506885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen lp.setTitle("SearchPanel"); 507885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen // TODO: Define custom animation for Search panel 508885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications; 509885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED 510885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; 511885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen return lp; 512885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen } 513885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen 514885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen protected void updateRecentsPanel() { 515885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen super.updateRecentsPanel(R.layout.status_bar_recent_panel); 516885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen // Make .03 alpha the minimum so you always see the item a bit-- slightly below 51746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks 51846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // a bit jarring 51946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mRecentsPanel.setMinSwipeAlpha(0.03f); 52046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mNavigationBarView != null) { 52146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel); 52246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 52346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 52446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 52546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 52646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) protected void updateSearchPanel() { 52746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) super.updateSearchPanel(); 52846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mSearchPanelView.setStatusBarView(mNavigationBarView); 52946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.setDelegateView(mSearchPanelView); 53046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 53146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 53246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 53346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void showSearchPanel() { 53446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) super.showSearchPanel(); 53546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams lp = 53646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams(); 53746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 53846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp); 53946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 54046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 54146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 54246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void hideSearchPanel() { 54346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) super.hideSearchPanel(); 54446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams lp = 54546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams(); 54646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; 54746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp); 54846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 54946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 55046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) protected int getStatusBarGravity() { 551251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu return Gravity.TOP | Gravity.FILL_HORIZONTAL; 55262c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun } 55362c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun 55462c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun public int getStatusBarHeight() { 55562c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun if (mNaturalBarHeight < 0) { 55662c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun final Resources res = mContext.getResources(); 55762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun mNaturalBarHeight = 55862c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); 55962c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun } 56062c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun return mNaturalBarHeight; 56162c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun } 56262c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun 56362c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun private View.OnClickListener mRecentsClickListener = new View.OnClickListener() { 56462c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun public void onClick(View v) { 56562c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun toggleRecentApps(); 56662c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun } 56762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun }; 56862c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun 56962c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun private int mShowSearchHoldoff = 0; 57062c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun private Runnable mShowSearchPanel = new Runnable() { 57162c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun public void run() { 57262c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun showSearchPanel(); 57362c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun awakenDreams(); 57462c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun } 57597a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu }; 57697a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu 57797a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() { 57897a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu public boolean onTouch(View v, MotionEvent event) { 57997a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu switch(event.getAction()) { 580251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu case MotionEvent.ACTION_DOWN: 581251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) { 582251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu mHandler.removeCallbacks(mShowSearchPanel); 583251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff); 5844320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu } 5854320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu break; 5864320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu 5874320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu case MotionEvent.ACTION_UP: 5884320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu case MotionEvent.ACTION_CANCEL: 5894320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu mHandler.removeCallbacks(mShowSearchPanel); 5904320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu awakenDreams(); 5914320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu break; 5924320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu } 5934320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu return false; 5944320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu } 5954320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu }; 5964320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu 5974320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu private void awakenDreams() { 5984320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu if (mDreamManager != null) { 5993c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung try { 6003520eb778d668dc76ca4541c69abd568b9d02691Mikhail Naganov mDreamManager.awaken(); 6013c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung } catch (RemoteException e) { 6023c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung // fine, stay asleep then 6034320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu } 604e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu } 605e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu } 606e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu 607e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu private void prepareNavigationBarView() { 608e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu mNavigationBarView.reorient(); 609e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu 61046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener); 61146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel); 61246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener); 61346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) updateSearchPanel(); 61446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 61546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 61646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // For small-screen devices (read: phones) that lack hardware navigation buttons 61746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private void addNavigationBar() { 61846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView); 61946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mNavigationBarView == null) return; 62046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 62146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) prepareNavigationBarView(); 62246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 62346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManagerImpl.getDefault().addView( 62446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView, getNavigationBarLayoutParams()); 62546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 62646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 62746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private void repositionNavigationBar() { 62846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mNavigationBarView == null) return; 62946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 63046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) prepareNavigationBarView(); 63146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 63246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManagerImpl.getDefault().updateViewLayout( 63346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mNavigationBarView, getNavigationBarLayoutParams()); 63446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 63546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 636d32343c77868461af07738ac7abd802000490d3dBen Murdoch private WindowManager.LayoutParams getNavigationBarLayoutParams() { 63746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 63846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 63946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, 640 0 641 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING 642 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 643 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 644 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 645 PixelFormat.OPAQUE); 646 // this will allow the navbar to run in an overlay on devices that support this 647 if (ActivityManager.isHighEndGfx(mDisplay)) { 648 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 649 } 650 651 lp.setTitle("NavigationBar"); 652 lp.windowAnimations = 0; 653 return lp; 654 } 655 656 private void addIntruderView() { 657 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 658 ViewGroup.LayoutParams.MATCH_PARENT, 659 ViewGroup.LayoutParams.WRAP_CONTENT, 660 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar! 661 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 662 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 663 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 664 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 665 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 666 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 667 PixelFormat.TRANSLUCENT); 668 lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; 669 //lp.y += height * 1.5; // FIXME 670 lp.setTitle("IntruderAlert"); 671 lp.packageName = mContext.getPackageName(); 672 lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert; 673 674 WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp); 675 } 676 677 public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { 678 if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex 679 + " icon=" + icon); 680 StatusBarIconView view = new StatusBarIconView(mContext, slot, null); 681 view.set(icon); 682 mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize)); 683 } 684 685 public void updateIcon(String slot, int index, int viewIndex, 686 StatusBarIcon old, StatusBarIcon icon) { 687 if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex 688 + " old=" + old + " icon=" + icon); 689 StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex); 690 view.set(icon); 691 } 692 693 public void removeIcon(String slot, int index, int viewIndex) { 694 if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex); 695 mStatusIcons.removeViewAt(viewIndex); 696 } 697 698 public void addNotification(IBinder key, StatusBarNotification notification) { 699 /* if (DEBUG) */ Slog.d(TAG, "addNotification score=" + notification.score); 700 StatusBarIconView iconView = addNotificationViews(key, notification); 701 if (iconView == null) return; 702 703 boolean immersive = false; 704 try { 705 immersive = ActivityManagerNative.getDefault().isTopActivityImmersive(); 706 if (DEBUG) { 707 Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive")); 708 } 709 } catch (RemoteException ex) { 710 } 711 712 /* 713 * DISABLED due to missing API 714 if (ENABLE_INTRUDERS && ( 715 // TODO(dsandler): Only if the screen is on 716 notification.notification.intruderView != null)) { 717 Slog.d(TAG, "Presenting high-priority notification"); 718 // special new transient ticker mode 719 // 1. Populate mIntruderAlertView 720 721 if (notification.notification.intruderView == null) { 722 Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null"); 723 return; 724 } 725 726 // bind the click event to the content area 727 PendingIntent contentIntent = notification.notification.contentIntent; 728 final View.OnClickListener listener = (contentIntent != null) 729 ? new NotificationClicker(contentIntent, 730 notification.pkg, notification.tag, notification.id) 731 : null; 732 733 mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener); 734 735 mCurrentlyIntrudingNotification = notification; 736 737 // 2. Animate mIntruderAlertView in 738 mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER); 739 740 // 3. Set alarm to age the notification off (TODO) 741 mHandler.removeMessages(MSG_HIDE_INTRUDER); 742 if (INTRUDER_ALERT_DECAY_MS > 0) { 743 mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS); 744 } 745 } else 746 */ 747 748 if (notification.notification.fullScreenIntent != null) { 749 // not immersive & a full-screen alert should be shown 750 Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent"); 751 try { 752 notification.notification.fullScreenIntent.send(); 753 } catch (PendingIntent.CanceledException e) { 754 } 755 } else { 756 // usual case: status bar visible & not immersive 757 758 // show the ticker if there isn't an intruder too 759 if (mCurrentlyIntrudingNotification == null) { 760 tick(null, notification, true); 761 } 762 } 763 764 // Recalculate the position of the sliding windows and the titles. 765 setAreThereNotifications(); 766 updateExpandedViewPos(EXPANDED_LEAVE_ALONE); 767 } 768 769 public void removeNotification(IBinder key) { 770 StatusBarNotification old = removeNotificationViews(key); 771 if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old); 772 773 if (old != null) { 774 // Cancel the ticker if it's still running 775 mTicker.removeEntry(old); 776 777 // Recalculate the position of the sliding windows and the titles. 778 updateExpandedViewPos(EXPANDED_LEAVE_ALONE); 779 780 if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) { 781 mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); 782 } 783 784 if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0 && !mAnimating) { 785 animateCollapse(); 786 } 787 } 788 789 setAreThereNotifications(); 790 } 791 792 @Override 793 protected void onConfigurationChanged(Configuration newConfig) { 794 updateRecentsPanel(); 795 updateShowSearchHoldoff(); 796 } 797 798 private void updateShowSearchHoldoff() { 799 mShowSearchHoldoff = mContext.getResources().getInteger( 800 R.integer.config_show_search_delay); 801 } 802 803 private void loadNotificationShade() { 804 if (mPile == null) return; 805 806 int N = mNotificationData.size(); 807 808 ArrayList<View> toShow = new ArrayList<View>(); 809 810 final boolean provisioned = isDeviceProvisioned(); 811 // If the device hasn't been through Setup, we only show system notifications 812 for (int i=0; i<N; i++) { 813 Entry ent = mNotificationData.get(N-i-1); 814 if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue; 815 if (!notificationIsForCurrentUser(ent.notification)) continue; 816 toShow.add(ent.row); 817 } 818 819 ArrayList<View> toRemove = new ArrayList<View>(); 820 for (int i=0; i<mPile.getChildCount(); i++) { 821 View child = mPile.getChildAt(i); 822 if (!toShow.contains(child)) { 823 toRemove.add(child); 824 } 825 } 826 827 for (View remove : toRemove) { 828 mPile.removeView(remove); 829 } 830 831 for (int i=0; i<toShow.size(); i++) { 832 View v = toShow.get(i); 833 if (v.getParent() == null) { 834 mPile.addView(v, i); 835 } 836 } 837 838 mSettingsButton.setEnabled(isDeviceProvisioned()); 839 } 840 841 @Override 842 protected void updateNotificationIcons() { 843 if (mNotificationIcons == null) return; 844 845 loadNotificationShade(); 846 847 final LinearLayout.LayoutParams params 848 = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight); 849 850 int N = mNotificationData.size(); 851 852 if (DEBUG) { 853 Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons); 854 } 855 856 ArrayList<View> toShow = new ArrayList<View>(); 857 858 final boolean provisioned = isDeviceProvisioned(); 859 // If the device hasn't been through Setup, we only show system notifications 860 for (int i=0; i<N; i++) { 861 Entry ent = mNotificationData.get(N-i-1); 862 if (!((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE) 863 || showNotificationEvenIfUnprovisioned(ent.notification))) continue; 864 if (!notificationIsForCurrentUser(ent.notification)) continue; 865 toShow.add(ent.icon); 866 } 867 868 ArrayList<View> toRemove = new ArrayList<View>(); 869 for (int i=0; i<mNotificationIcons.getChildCount(); i++) { 870 View child = mNotificationIcons.getChildAt(i); 871 if (!toShow.contains(child)) { 872 toRemove.add(child); 873 } 874 } 875 876 for (View remove : toRemove) { 877 mNotificationIcons.removeView(remove); 878 } 879 880 for (int i=0; i<toShow.size(); i++) { 881 View v = toShow.get(i); 882 if (v.getParent() == null) { 883 mNotificationIcons.addView(v, i, params); 884 } 885 } 886 } 887 888 protected void updateCarrierLabelVisibility(boolean force) { 889 if (!SHOW_CARRIER_LABEL) return; 890 // The idea here is to only show the carrier label when there is enough room to see it, 891 // i.e. when there aren't enough notifications to fill the panel. 892 if (DEBUG) { 893 Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d", 894 mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight)); 895 } 896 897 final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null; 898 final boolean makeVisible = 899 !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly()) 900 && mPile.getHeight() < (mScrollView.getHeight() - mCarrierLabelHeight); 901 902 if (force || mCarrierLabelVisible != makeVisible) { 903 mCarrierLabelVisible = makeVisible; 904 if (DEBUG) { 905 Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible")); 906 } 907 mCarrierLabel.animate().cancel(); 908 if (makeVisible) { 909 mCarrierLabel.setVisibility(View.VISIBLE); 910 } 911 mCarrierLabel.animate() 912 .alpha(makeVisible ? 1f : 0f) 913 //.setStartDelay(makeVisible ? 500 : 0) 914 //.setDuration(makeVisible ? 750 : 100) 915 .setDuration(150) 916 .setListener(makeVisible ? null : new AnimatorListenerAdapter() { 917 @Override 918 public void onAnimationEnd(Animator animation) { 919 if (!mCarrierLabelVisible) { // race 920 mCarrierLabel.setVisibility(View.INVISIBLE); 921 mCarrierLabel.setAlpha(0f); 922 } 923 } 924 }) 925 .start(); 926 } 927 } 928 929 @Override 930 protected void setAreThereNotifications() { 931 final boolean any = mNotificationData.size() > 0; 932 933 final boolean clearable = any && mNotificationData.hasClearableItems(); 934 935 if (DEBUG) { 936 Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size() 937 + " any=" + any + " clearable=" + clearable); 938 } 939 940 if (mClearButton.isShown()) { 941 if (clearable != (mClearButton.getAlpha() == 1.0f)) { 942 ObjectAnimator clearAnimation = ObjectAnimator.ofFloat( 943 mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250); 944 clearAnimation.addListener(new AnimatorListenerAdapter() { 945 @Override 946 public void onAnimationEnd(Animator animation) { 947 if (mClearButton.getAlpha() <= 0.0f) { 948 mClearButton.setVisibility(View.INVISIBLE); 949 } 950 } 951 952 @Override 953 public void onAnimationStart(Animator animation) { 954 if (mClearButton.getAlpha() <= 0.0f) { 955 mClearButton.setVisibility(View.VISIBLE); 956 } 957 } 958 }); 959 clearAnimation.start(); 960 } 961 } else { 962 mClearButton.setAlpha(clearable ? 1.0f : 0.0f); 963 mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE); 964 } 965 mClearButton.setEnabled(clearable); 966 967 final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out); 968 final boolean showDot = (any&&!areLightsOn()); 969 if (showDot != (nlo.getAlpha() == 1.0f)) { 970 if (showDot) { 971 nlo.setAlpha(0f); 972 nlo.setVisibility(View.VISIBLE); 973 } 974 nlo.animate() 975 .alpha(showDot?1:0) 976 .setDuration(showDot?750:250) 977 .setInterpolator(new AccelerateInterpolator(2.0f)) 978 .setListener(showDot ? null : new AnimatorListenerAdapter() { 979 @Override 980 public void onAnimationEnd(Animator _a) { 981 nlo.setVisibility(View.GONE); 982 } 983 }) 984 .start(); 985 } 986 987 updateCarrierLabelVisibility(false); 988 } 989 990 public void showClock(boolean show) { 991 if (mStatusBarView == null) return; 992 View clock = mStatusBarView.findViewById(R.id.clock); 993 if (clock != null) { 994 clock.setVisibility(show ? View.VISIBLE : View.GONE); 995 } 996 } 997 998 /** 999 * State is one or more of the DISABLE constants from StatusBarManager. 1000 */ 1001 public void disable(int state) { 1002 final int old = mDisabled; 1003 final int diff = state ^ old; 1004 mDisabled = state; 1005 1006 if (DEBUG) { 1007 Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)", 1008 old, state, diff)); 1009 } 1010 1011 StringBuilder flagdbg = new StringBuilder(); 1012 flagdbg.append("disable: < "); 1013 flagdbg.append(((state & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand"); 1014 flagdbg.append(((diff & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " "); 1015 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons"); 1016 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " "); 1017 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts"); 1018 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " "); 1019 flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker"); 1020 flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " "); 1021 flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info"); 1022 flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " "); 1023 flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back"); 1024 flagdbg.append(((diff & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " "); 1025 flagdbg.append(((state & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home"); 1026 flagdbg.append(((diff & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " "); 1027 flagdbg.append(((state & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent"); 1028 flagdbg.append(((diff & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " "); 1029 flagdbg.append(((state & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock"); 1030 flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " "); 1031 flagdbg.append(">"); 1032 Slog.d(TAG, flagdbg.toString()); 1033 1034 if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { 1035 mIcons.animate().cancel(); 1036 if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { 1037 if (mTicking) { 1038 mTicker.halt(); 1039 } 1040 mIcons.animate() 1041 .alpha(0f) 1042 .translationY(mNaturalBarHeight*0.5f) 1043 //.setStartDelay(100) 1044 .setDuration(175) 1045 .setInterpolator(new DecelerateInterpolator(1.5f)) 1046 .setListener(mMakeIconsInvisible) 1047 .start(); 1048 } else { 1049 mIcons.setVisibility(View.VISIBLE); 1050 mIcons.animate() 1051 .alpha(1f) 1052 .translationY(0) 1053 .setStartDelay(0) 1054 .setInterpolator(new DecelerateInterpolator(1.5f)) 1055 .setDuration(175) 1056 .start(); 1057 } 1058 } 1059 1060 if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) { 1061 boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0; 1062 showClock(show); 1063 } 1064 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { 1065 if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { 1066 animateCollapse(); 1067 } 1068 } 1069 1070 if ((diff & (StatusBarManager.DISABLE_HOME 1071 | StatusBarManager.DISABLE_RECENT 1072 | StatusBarManager.DISABLE_BACK)) != 0) { 1073 // the nav bar will take care of these 1074 if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state); 1075 1076 if ((state & StatusBarManager.DISABLE_RECENT) != 0) { 1077 // close recents if it's visible 1078 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); 1079 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); 1080 } 1081 } 1082 1083 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 1084 if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 1085 if (mTicking) { 1086 mTicker.halt(); 1087 } else { 1088 setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); 1089 } 1090 } else { 1091 if (!mExpandedVisible) { 1092 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); 1093 } 1094 } 1095 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { 1096 if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { 1097 mTicker.halt(); 1098 } 1099 } 1100 } 1101 1102 @Override 1103 protected BaseStatusBar.H createHandler() { 1104 return new PhoneStatusBar.H(); 1105 } 1106 1107 /** 1108 * All changes to the status bar and notifications funnel through here and are batched. 1109 */ 1110 private class H extends BaseStatusBar.H { 1111 public void handleMessage(Message m) { 1112 super.handleMessage(m); 1113 switch (m.what) { 1114 case MSG_OPEN_NOTIFICATION_PANEL: 1115 animateExpand(); 1116 break; 1117 case MSG_CLOSE_NOTIFICATION_PANEL: 1118 animateCollapse(); 1119 break; 1120 case MSG_SHOW_INTRUDER: 1121 setIntruderAlertVisibility(true); 1122 break; 1123 case MSG_HIDE_INTRUDER: 1124 setIntruderAlertVisibility(false); 1125 mCurrentlyIntrudingNotification = null; 1126 break; 1127 } 1128 } 1129 } 1130 1131 View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() { 1132 public void onFocusChange(View v, boolean hasFocus) { 1133 // Because 'v' is a ViewGroup, all its children will be (un)selected 1134 // too, which allows marqueeing to work. 1135 v.setSelected(hasFocus); 1136 } 1137 }; 1138 1139 void makeExpandedVisible(boolean revealAfterDraw) { 1140 if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible); 1141 if (mExpandedVisible) { 1142 return; 1143 } 1144 1145 mExpandedVisible = true; 1146 mPile.setLayoutTransitionsEnabled(true); 1147 if (mNavigationBarView != null) 1148 mNavigationBarView.setSlippery(true); 1149 1150 updateCarrierLabelVisibility(true); 1151 1152 updateExpandedViewPos(EXPANDED_LEAVE_ALONE); 1153 1154 // Expand the window to encompass the full screen in anticipation of the drag. 1155 // This is only possible to do atomically because the status bar is at the top of the screen! 1156 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams(); 1157 lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 1158 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 1159 lp.height = ViewGroup.LayoutParams.MATCH_PARENT; 1160 final WindowManager wm = WindowManagerImpl.getDefault(); 1161 wm.updateViewLayout(mStatusBarWindow, lp); 1162 1163 // Updating the window layout will force an expensive traversal/redraw. 1164 // Kick off the reveal animation after this is complete to avoid animation latency. 1165 if (revealAfterDraw) { 1166// mHandler.post(mStartRevealAnimation); 1167 } 1168 1169 visibilityChanged(true); 1170 } 1171 1172 public void animateCollapse() { 1173 animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE); 1174 } 1175 1176 public void animateCollapse(int flags) { 1177 if (SPEW) { 1178 Slog.d(TAG, "animateCollapse(): " 1179 + " mExpandedVisible=" + mExpandedVisible 1180 + " mAnimating=" + mAnimating 1181 + " mAnimatingReveal=" + mAnimatingReveal 1182 + " mAnimY=" + mAnimY 1183 + " mAnimVel=" + mAnimVel 1184 + " flags=" + flags); 1185 } 1186 1187 if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) { 1188 mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); 1189 mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); 1190 } 1191 1192 if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) { 1193 mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL); 1194 mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL); 1195 } 1196 1197 mStatusBarView.collapseAllPanels(true); 1198 } 1199 1200 @Override 1201 public void animateExpand() { 1202 if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible); 1203 if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { 1204 return ; 1205 } 1206 1207 mNotificationPanel.expand(); 1208 1209 if (false) postStartTracing(); 1210 } 1211 1212 void makeExpandedInvisible() { 1213 if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible 1214 + " mExpandedVisible=" + mExpandedVisible); 1215 1216 if (!mExpandedVisible) { 1217 return; 1218 } 1219 1220 // Ensure the panel is fully collapsed (just in case; bug 6765842) 1221 mStatusBarView.collapseAllPanels(/*animate=*/ false); 1222 1223 mExpandedVisible = false; 1224 mPile.setLayoutTransitionsEnabled(false); 1225 if (mNavigationBarView != null) 1226 mNavigationBarView.setSlippery(false); 1227 visibilityChanged(false); 1228 1229 // Shrink the window to the size of the status bar only 1230 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams(); 1231 lp.height = getStatusBarHeight(); 1232 lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 1233 lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 1234 final WindowManager wm = WindowManagerImpl.getDefault(); 1235 wm.updateViewLayout(mStatusBarWindow, lp); 1236 1237 if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) { 1238 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); 1239 } 1240 1241 // Close any "App info" popups that might have snuck on-screen 1242 dismissPopups(); 1243 1244 if (mPostCollapseCleanup != null) { 1245 mPostCollapseCleanup.run(); 1246 mPostCollapseCleanup = null; 1247 } 1248 } 1249 1250 /** 1251 * Enables or disables layers on the children of the notifications pile. 1252 * 1253 * When layers are enabled, this method attempts to enable layers for the minimal 1254 * number of children. Only children visible when the notification area is fully 1255 * expanded will receive a layer. The technique used in this method might cause 1256 * more children than necessary to get a layer (at most one extra child with the 1257 * current UI.) 1258 * 1259 * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE} 1260 */ 1261 private void setPileLayers(int layerType) { 1262 final int count = mPile.getChildCount(); 1263 1264 switch (layerType) { 1265 case View.LAYER_TYPE_NONE: 1266 for (int i = 0; i < count; i++) { 1267 mPile.getChildAt(i).setLayerType(layerType, null); 1268 } 1269 break; 1270 case View.LAYER_TYPE_HARDWARE: 1271 final int[] location = new int[2]; 1272 mNotificationPanel.getLocationInWindow(location); 1273 1274 final int left = location[0]; 1275 final int top = location[1]; 1276 final int right = left + mNotificationPanel.getWidth(); 1277 final int bottom = top + getExpandedViewMaxHeight(); 1278 1279 final Rect childBounds = new Rect(); 1280 1281 for (int i = 0; i < count; i++) { 1282 final View view = mPile.getChildAt(i); 1283 view.getLocationInWindow(location); 1284 1285 childBounds.set(location[0], location[1], 1286 location[0] + view.getWidth(), location[1] + view.getHeight()); 1287 1288 if (childBounds.intersects(left, top, right, bottom)) { 1289 view.setLayerType(layerType, null); 1290 } 1291 } 1292 1293 break; 1294 } 1295 } 1296 1297 boolean interceptTouchEvent(MotionEvent event) { 1298 if (SPEW) { 1299 Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled=" 1300 + mDisabled + " mTracking=" + mTracking); 1301 } else if (CHATTY) { 1302 if (event.getAction() != MotionEvent.ACTION_MOVE) { 1303 Slog.d(TAG, String.format( 1304 "panel: %s at (%f, %f) mDisabled=0x%08x", 1305 MotionEvent.actionToString(event.getAction()), 1306 event.getRawX(), event.getRawY(), mDisabled)); 1307 } 1308 } 1309 1310 mGestureRec.add(event); 1311 1312 return false; 1313 } 1314 1315 public GestureRecorder getGestureRecorder() { 1316 return mGestureRec; 1317 } 1318 1319 @Override // CommandQueue 1320 public void setNavigationIconHints(int hints) { 1321 if (hints == mNavigationIconHints) return; 1322 1323 mNavigationIconHints = hints; 1324 1325 if (mNavigationBarView != null) { 1326 mNavigationBarView.setNavigationIconHints(hints); 1327 } 1328 } 1329 1330 @Override // CommandQueue 1331 public void setSystemUiVisibility(int vis, int mask) { 1332 final int oldVal = mSystemUiVisibility; 1333 final int newVal = (oldVal&~mask) | (vis&mask); 1334 final int diff = newVal ^ oldVal; 1335 1336 if (diff != 0) { 1337 mSystemUiVisibility = newVal; 1338 1339 if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) { 1340 final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)); 1341 if (lightsOut) { 1342 animateCollapse(); 1343 if (mTicking) { 1344 mTicker.halt(); 1345 } 1346 } 1347 1348 if (mNavigationBarView != null) { 1349 mNavigationBarView.setLowProfile(lightsOut); 1350 } 1351 1352 setStatusBarLowProfile(lightsOut); 1353 } 1354 1355 notifyUiVisibilityChanged(); 1356 } 1357 } 1358 1359 private void setStatusBarLowProfile(boolean lightsOut) { 1360 if (mLightsOutAnimation == null) { 1361 final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area); 1362 final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons); 1363 final View signal = mStatusBarView.findViewById(R.id.signal_cluster); 1364 final View battery = mStatusBarView.findViewById(R.id.battery); 1365 final View clock = mStatusBarView.findViewById(R.id.clock); 1366 1367 mLightsOutAnimation = new AnimatorSet(); 1368 mLightsOutAnimation.playTogether( 1369 ObjectAnimator.ofFloat(notifications, View.ALPHA, 0), 1370 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0), 1371 ObjectAnimator.ofFloat(signal, View.ALPHA, 0), 1372 ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f), 1373 ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f) 1374 ); 1375 mLightsOutAnimation.setDuration(750); 1376 1377 mLightsOnAnimation = new AnimatorSet(); 1378 mLightsOnAnimation.playTogether( 1379 ObjectAnimator.ofFloat(notifications, View.ALPHA, 1), 1380 ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1), 1381 ObjectAnimator.ofFloat(signal, View.ALPHA, 1), 1382 ObjectAnimator.ofFloat(battery, View.ALPHA, 1), 1383 ObjectAnimator.ofFloat(clock, View.ALPHA, 1) 1384 ); 1385 mLightsOnAnimation.setDuration(250); 1386 } 1387 1388 mLightsOutAnimation.cancel(); 1389 mLightsOnAnimation.cancel(); 1390 1391 final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation; 1392 a.start(); 1393 1394 setAreThereNotifications(); 1395 } 1396 1397 private boolean areLightsOn() { 1398 return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE); 1399 } 1400 1401 public void setLightsOn(boolean on) { 1402 Log.v(TAG, "setLightsOn(" + on + ")"); 1403 if (on) { 1404 setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE); 1405 } else { 1406 setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE); 1407 } 1408 } 1409 1410 private void notifyUiVisibilityChanged() { 1411 try { 1412 mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility); 1413 } catch (RemoteException ex) { 1414 } 1415 } 1416 1417 public void topAppWindowChanged(boolean showMenu) { 1418 if (DEBUG) { 1419 Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button"); 1420 } 1421 if (mNavigationBarView != null) { 1422 mNavigationBarView.setMenuVisibility(showMenu); 1423 } 1424 1425 // See above re: lights-out policy for legacy apps. 1426 if (showMenu) setLightsOn(true); 1427 } 1428 1429 @Override 1430 public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { 1431 boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS) 1432 || ((vis & InputMethodService.IME_VISIBLE) != 0); 1433 1434 mCommandQueue.setNavigationIconHints( 1435 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT) 1436 : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT)); 1437 } 1438 1439 @Override 1440 public void setHardKeyboardStatus(boolean available, boolean enabled) { } 1441 1442 @Override 1443 protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) { 1444 // no ticking in lights-out mode 1445 if (!areLightsOn()) return; 1446 1447 // no ticking in Setup 1448 if (!isDeviceProvisioned()) return; 1449 1450 // Show the ticker if one is requested. Also don't do this 1451 // until status bar window is attached to the window manager, 1452 // because... well, what's the point otherwise? And trying to 1453 // run a ticker without being attached will crash! 1454 if (n.notification.tickerText != null && mStatusBarWindow.getWindowToken() != null) { 1455 if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS 1456 | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { 1457 mTicker.addEntry(n); 1458 } 1459 } 1460 } 1461 1462 private class MyTicker extends Ticker { 1463 MyTicker(Context context, View sb) { 1464 super(context, sb); 1465 } 1466 1467 @Override 1468 public void tickerStarting() { 1469 mTicking = true; 1470 mIcons.setVisibility(View.GONE); 1471 mTickerView.setVisibility(View.VISIBLE); 1472 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null)); 1473 mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null)); 1474 } 1475 1476 @Override 1477 public void tickerDone() { 1478 mIcons.setVisibility(View.VISIBLE); 1479 mTickerView.setVisibility(View.GONE); 1480 mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null)); 1481 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out, 1482 mTickingDoneListener)); 1483 } 1484 1485 public void tickerHalting() { 1486 mIcons.setVisibility(View.VISIBLE); 1487 mTickerView.setVisibility(View.GONE); 1488 mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null)); 1489 mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out, 1490 mTickingDoneListener)); 1491 } 1492 } 1493 1494 Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {; 1495 public void onAnimationEnd(Animation animation) { 1496 mTicking = false; 1497 } 1498 public void onAnimationRepeat(Animation animation) { 1499 } 1500 public void onAnimationStart(Animation animation) { 1501 } 1502 }; 1503 1504 private Animation loadAnim(int id, Animation.AnimationListener listener) { 1505 Animation anim = AnimationUtils.loadAnimation(mContext, id); 1506 if (listener != null) { 1507 anim.setAnimationListener(listener); 1508 } 1509 return anim; 1510 } 1511 1512 public static String viewInfo(View v) { 1513 return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom() 1514 + ") " + v.getWidth() + "x" + v.getHeight() + "]"; 1515 } 1516 1517 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1518 synchronized (mQueueLock) { 1519 pw.println("Current Status Bar state:"); 1520 pw.println(" mExpandedVisible=" + mExpandedVisible 1521 + ", mTrackingPosition=" + mTrackingPosition); 1522 pw.println(" mTicking=" + mTicking); 1523 pw.println(" mTracking=" + mTracking); 1524 pw.println(" mNotificationPanel=" + 1525 ((mNotificationPanel == null) 1526 ? "null" 1527 : (mNotificationPanel + " params=" + mNotificationPanel.getLayoutParams().debug("")))); 1528 pw.println(" mAnimating=" + mAnimating 1529 + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel 1530 + ", mAnimAccel=" + mAnimAccel); 1531 pw.println(" mAnimLastTimeNanos=" + mAnimLastTimeNanos); 1532 pw.println(" mAnimatingReveal=" + mAnimatingReveal 1533 + " mViewDelta=" + mViewDelta); 1534 pw.println(" mDisplayMetrics=" + mDisplayMetrics); 1535 pw.println(" mPile: " + viewInfo(mPile)); 1536 pw.println(" mTickerView: " + viewInfo(mTickerView)); 1537 pw.println(" mScrollView: " + viewInfo(mScrollView) 1538 + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY()); 1539 } 1540 1541 pw.print(" mNavigationBarView="); 1542 if (mNavigationBarView == null) { 1543 pw.println("null"); 1544 } else { 1545 mNavigationBarView.dump(fd, pw, args); 1546 } 1547 1548 if (DUMPTRUCK) { 1549 synchronized (mNotificationData) { 1550 int N = mNotificationData.size(); 1551 pw.println(" notification icons: " + N); 1552 for (int i=0; i<N; i++) { 1553 NotificationData.Entry e = mNotificationData.get(i); 1554 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon); 1555 StatusBarNotification n = e.notification; 1556 pw.println(" pkg=" + n.pkg + " id=" + n.id + " score=" + n.score); 1557 pw.println(" notification=" + n.notification); 1558 pw.println(" tickerText=\"" + n.notification.tickerText + "\""); 1559 } 1560 } 1561 1562 int N = mStatusIcons.getChildCount(); 1563 pw.println(" system icons: " + N); 1564 for (int i=0; i<N; i++) { 1565 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i); 1566 pw.println(" [" + i + "] icon=" + ic); 1567 } 1568 1569 if (false) { 1570 pw.println("see the logcat for a dump of the views we have created."); 1571 // must happen on ui thread 1572 mHandler.post(new Runnable() { 1573 public void run() { 1574 mStatusBarView.getLocationOnScreen(mAbsPos); 1575 Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1] 1576 + ") " + mStatusBarView.getWidth() + "x" 1577 + getStatusBarHeight()); 1578 mStatusBarView.debug(); 1579 } 1580 }); 1581 } 1582 } 1583 1584 pw.print(" status bar gestures: "); 1585 mGestureRec.dump(fd, pw, args); 1586 1587 mNetworkController.dump(fd, pw, args); 1588 } 1589 1590 @Override 1591 public void createAndAddWindows() { 1592 addStatusBarWindow(); 1593 } 1594 1595 private void addStatusBarWindow() { 1596 // Put up the view 1597 final int height = getStatusBarHeight(); 1598 1599 // Now that the status bar window encompasses the sliding panel and its 1600 // translucent backdrop, the entire thing is made TRANSLUCENT and is 1601 // hardware-accelerated. 1602 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 1603 ViewGroup.LayoutParams.MATCH_PARENT, 1604 height, 1605 WindowManager.LayoutParams.TYPE_STATUS_BAR, 1606 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 1607 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING 1608 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 1609 PixelFormat.TRANSLUCENT); 1610 1611 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 1612 1613 lp.gravity = getStatusBarGravity(); 1614 lp.setTitle("StatusBar"); 1615 lp.packageName = mContext.getPackageName(); 1616 1617 makeStatusBarView(); 1618 WindowManagerImpl.getDefault().addView(mStatusBarWindow, lp); 1619 } 1620 1621 void setNotificationIconVisibility(boolean visible, int anim) { 1622 int old = mNotificationIcons.getVisibility(); 1623 int v = visible ? View.VISIBLE : View.INVISIBLE; 1624 if (old != v) { 1625 mNotificationIcons.setVisibility(v); 1626 mNotificationIcons.startAnimation(loadAnim(anim, null)); 1627 } 1628 } 1629 1630 void updateExpandedInvisiblePosition() { 1631 mTrackingPosition = -mDisplayMetrics.heightPixels; 1632 } 1633 1634 static final float saturate(float a) { 1635 return a < 0f ? 0f : (a > 1f ? 1f : a); 1636 } 1637 1638 @Override 1639 protected int getExpandedViewMaxHeight() { 1640 return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx; 1641 } 1642 1643 @Override 1644 public void updateExpandedViewPos(int thingy) { 1645 // TODO 1646 if (DEBUG) Slog.v(TAG, "updateExpandedViewPos"); 1647 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams(); 1648 lp.gravity = mNotificationPanelGravity; 1649 lp.leftMargin = mNotificationPanelMarginPx; 1650 mNotificationPanel.setLayoutParams(lp); 1651 lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams(); 1652 lp.gravity = mSettingsPanelGravity; 1653 lp.rightMargin = mNotificationPanelMarginPx; 1654 mSettingsPanel.setLayoutParams(lp); 1655 } 1656 1657 // called by makeStatusbar and also by PhoneStatusBarView 1658 void updateDisplaySize() { 1659 mDisplay.getMetrics(mDisplayMetrics); 1660 mGestureRec.tag("display", 1661 String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); 1662 } 1663 1664 void performDisableActions(int net) { 1665 int old = mDisabled; 1666 int diff = net ^ old; 1667 mDisabled = net; 1668 1669 // act accordingly 1670 if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { 1671 if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { 1672 Slog.d(TAG, "DISABLE_EXPAND: yes"); 1673 animateCollapse(); 1674 } 1675 } 1676 if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 1677 if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { 1678 Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); 1679 if (mTicking) { 1680 mNotificationIcons.setVisibility(View.INVISIBLE); 1681 mTicker.halt(); 1682 } else { 1683 setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); 1684 } 1685 } else { 1686 Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); 1687 if (!mExpandedVisible) { 1688 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); 1689 } 1690 } 1691 } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { 1692 if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { 1693 mTicker.halt(); 1694 } 1695 } 1696 } 1697 1698 private View.OnClickListener mClearButtonListener = new View.OnClickListener() { 1699 public void onClick(View v) { 1700 synchronized (mNotificationData) { 1701 // animate-swipe all dismissable notifications, then animate the shade closed 1702 int numChildren = mPile.getChildCount(); 1703 1704 int scrollTop = mScrollView.getScrollY(); 1705 int scrollBottom = scrollTop + mScrollView.getHeight(); 1706 final ArrayList<View> snapshot = new ArrayList<View>(numChildren); 1707 for (int i=0; i<numChildren; i++) { 1708 final View child = mPile.getChildAt(i); 1709 if (mPile.canChildBeDismissed(child) && child.getBottom() > scrollTop && 1710 child.getTop() < scrollBottom) { 1711 snapshot.add(child); 1712 } 1713 } 1714 if (snapshot.isEmpty()) { 1715 animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE); 1716 return; 1717 } 1718 new Thread(new Runnable() { 1719 @Override 1720 public void run() { 1721 // Decrease the delay for every row we animate to give the sense of 1722 // accelerating the swipes 1723 final int ROW_DELAY_DECREMENT = 10; 1724 int currentDelay = 140; 1725 int totalDelay = 0; 1726 1727 // Set the shade-animating state to avoid doing other work during 1728 // all of these animations. In particular, avoid layout and 1729 // redrawing when collapsing the shade. 1730 mPile.setViewRemoval(false); 1731 1732 mPostCollapseCleanup = new Runnable() { 1733 @Override 1734 public void run() { 1735 if (DEBUG) { 1736 Slog.v(TAG, "running post-collapse cleanup"); 1737 } 1738 try { 1739 mPile.setViewRemoval(true); 1740 mBarService.onClearAllNotifications(); 1741 } catch (Exception ex) { } 1742 } 1743 }; 1744 1745 View sampleView = snapshot.get(0); 1746 int width = sampleView.getWidth(); 1747 final int velocity = width * 8; // 1000/8 = 125 ms duration 1748 for (final View _v : snapshot) { 1749 mHandler.postDelayed(new Runnable() { 1750 @Override 1751 public void run() { 1752 mPile.dismissRowAnimated(_v, velocity); 1753 } 1754 }, totalDelay); 1755 currentDelay = Math.max(50, currentDelay - ROW_DELAY_DECREMENT); 1756 totalDelay += currentDelay; 1757 } 1758 // Delay the collapse animation until after all swipe animations have 1759 // finished. Provide some buffer because there may be some extra delay 1760 // before actually starting each swipe animation. Ideally, we'd 1761 // synchronize the end of those animations with the start of the collaps 1762 // exactly. 1763 mHandler.postDelayed(new Runnable() { 1764 @Override 1765 public void run() { 1766 animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE); 1767 } 1768 }, totalDelay + 225); 1769 } 1770 }).start(); 1771 } 1772 } 1773 }; 1774 1775 private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() { 1776 public void onClick(View v) { 1777 // We take this as a good indicator that Setup is running and we shouldn't 1778 // allow you to go somewhere else 1779 if (!isDeviceProvisioned()) return; 1780 try { 1781 // Dismiss the lock screen when Settings starts. 1782 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); 1783 } catch (RemoteException e) { 1784 } 1785 v.getContext().startActivityAsUser(new Intent(Settings.ACTION_SETTINGS) 1786 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), UserHandle.USER_CURRENT); 1787 animateCollapse(); 1788 } 1789 }; 1790 1791 private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1792 public void onReceive(Context context, Intent intent) { 1793 Slog.v(TAG, "onReceive: " + intent); 1794 String action = intent.getAction(); 1795 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { 1796 int flags = CommandQueue.FLAG_EXCLUDE_NONE; 1797 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { 1798 String reason = intent.getStringExtra("reason"); 1799 if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { 1800 flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL; 1801 } 1802 } 1803 animateCollapse(flags); 1804 } 1805 else if (Intent.ACTION_SCREEN_OFF.equals(action)) { 1806 // no waiting! 1807 makeExpandedInvisible(); 1808 } 1809 else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 1810 updateResources(); 1811 repositionNavigationBar(); 1812 updateExpandedViewPos(EXPANDED_LEAVE_ALONE); 1813 } 1814 } 1815 }; 1816 1817 @Override 1818 public void userSwitched(int newUserId) { 1819 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); 1820 animateCollapse(); 1821 updateNotificationIcons(); 1822 } 1823 1824 private void setIntruderAlertVisibility(boolean vis) { 1825 if (!ENABLE_INTRUDERS) return; 1826 if (DEBUG) { 1827 Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window"); 1828 } 1829 mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE); 1830 } 1831 1832 public void dismissIntruder() { 1833 if (mCurrentlyIntrudingNotification == null) return; 1834 1835 try { 1836 mBarService.onNotificationClear( 1837 mCurrentlyIntrudingNotification.pkg, 1838 mCurrentlyIntrudingNotification.tag, 1839 mCurrentlyIntrudingNotification.id); 1840 } catch (android.os.RemoteException ex) { 1841 // oh well 1842 } 1843 } 1844 1845 /** 1846 * Reload some of our resources when the configuration changes. 1847 * 1848 * We don't reload everything when the configuration changes -- we probably 1849 * should, but getting that smooth is tough. Someday we'll fix that. In the 1850 * meantime, just update the things that we know change. 1851 */ 1852 void updateResources() { 1853 final Context context = mContext; 1854 final Resources res = context.getResources(); 1855 1856 if (mClearButton instanceof TextView) { 1857 ((TextView)mClearButton).setText(context.getText(R.string.status_bar_clear_all_button)); 1858 } 1859 loadDimens(); 1860 } 1861 1862 protected void loadDimens() { 1863 final Resources res = mContext.getResources(); 1864 1865 mNaturalBarHeight = res.getDimensionPixelSize( 1866 com.android.internal.R.dimen.status_bar_height); 1867 1868 int newIconSize = res.getDimensionPixelSize( 1869 com.android.internal.R.dimen.status_bar_icon_size); 1870 int newIconHPadding = res.getDimensionPixelSize( 1871 R.dimen.status_bar_icon_padding); 1872 1873 if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) { 1874// Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding); 1875 mIconHPadding = newIconHPadding; 1876 mIconSize = newIconSize; 1877 //reloadAllNotificationIcons(); // reload the tray 1878 } 1879 1880 mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); 1881 1882 mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity); 1883 mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity); 1884 mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity); 1885 mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity); 1886 1887 mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1); 1888 mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1); 1889 1890 mExpandAccelPx = res.getDimension(R.dimen.expand_accel); 1891 mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel); 1892 1893 mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity); 1894 1895 mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity); 1896 1897 mNotificationPanelMarginBottomPx 1898 = (int) res.getDimension(R.dimen.notification_panel_margin_bottom); 1899 mNotificationPanelMarginPx 1900 = (int) res.getDimension(R.dimen.notification_panel_margin_left); 1901 mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity); 1902 if (mNotificationPanelGravity <= 0) { 1903 mNotificationPanelGravity = Gravity.LEFT | Gravity.TOP; 1904 } 1905 mSettingsPanelGravity = res.getInteger(R.integer.settings_panel_layout_gravity); 1906 if (mSettingsPanelGravity <= 0) { 1907 mSettingsPanelGravity = Gravity.RIGHT | Gravity.TOP; 1908 } 1909 getNinePatchPadding(res.getDrawable(R.drawable.notification_panel_bg), mNotificationPanelBackgroundPadding); 1910 final int notificationPanelDecorationHeight = 1911 res.getDimensionPixelSize(R.dimen.notification_panel_padding_top) 1912 + res.getDimensionPixelSize(R.dimen.notification_panel_header_height) 1913 + mNotificationPanelBackgroundPadding.top 1914 + mNotificationPanelBackgroundPadding.bottom; 1915 mNotificationPanelMinHeight = 1916 notificationPanelDecorationHeight 1917 + res.getDimensionPixelSize(R.dimen.close_handle_underlap); 1918 1919 mCarrierLabelHeight = res.getDimensionPixelSize(R.dimen.carrier_label_height); 1920 1921 if (false) Slog.v(TAG, "updateResources"); 1922 } 1923 1924 private static void getNinePatchPadding(Drawable d, Rect outPadding) { 1925 if (d instanceof NinePatchDrawable) { 1926 NinePatchDrawable ninePatch = (NinePatchDrawable) d; 1927 ninePatch.getPadding(outPadding); 1928 } 1929 } 1930 1931 // 1932 // tracing 1933 // 1934 1935 void postStartTracing() { 1936 mHandler.postDelayed(mStartTracing, 3000); 1937 } 1938 1939 void vibrate() { 1940 android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService( 1941 Context.VIBRATOR_SERVICE); 1942 vib.vibrate(250); 1943 } 1944 1945 Runnable mStartTracing = new Runnable() { 1946 public void run() { 1947 vibrate(); 1948 SystemClock.sleep(250); 1949 Slog.d(TAG, "startTracing"); 1950 android.os.Debug.startMethodTracing("/data/statusbar-traces/trace"); 1951 mHandler.postDelayed(mStopTracing, 10000); 1952 } 1953 }; 1954 1955 Runnable mStopTracing = new Runnable() { 1956 public void run() { 1957 android.os.Debug.stopMethodTracing(); 1958 Slog.d(TAG, "stopTracing"); 1959 vibrate(); 1960 } 1961 }; 1962 1963 @Override 1964 protected void haltTicker() { 1965 mTicker.halt(); 1966 } 1967 1968 @Override 1969 protected boolean shouldDisableNavbarGestures() { 1970 return mExpandedVisible || (mDisabled & StatusBarManager.DISABLE_HOME) != 0; 1971 } 1972 1973 private static class FastColorDrawable extends Drawable { 1974 private final int mColor; 1975 1976 public FastColorDrawable(int color) { 1977 mColor = 0xff000000 | color; 1978 } 1979 1980 @Override 1981 public void draw(Canvas canvas) { 1982 canvas.drawColor(mColor, PorterDuff.Mode.SRC); 1983 } 1984 1985 @Override 1986 public void setAlpha(int alpha) { 1987 } 1988 1989 @Override 1990 public void setColorFilter(ColorFilter cf) { 1991 } 1992 1993 @Override 1994 public int getOpacity() { 1995 return PixelFormat.OPAQUE; 1996 } 1997 1998 @Override 1999 public void setBounds(int left, int top, int right, int bottom) { 2000 } 2001 2002 @Override 2003 public void setBounds(Rect bounds) { 2004 } 2005 } 2006} 2007