android 怎么把状态栏移到底部

首先还是感觉网友的分享,网上一个例子是关于状态栏移到底部的。

不过不知道是版本不一样还是怎么回事,我根据网上的做(有的函数名对不上),状态栏显示在了底部,但下拉的通知栏不见了(拉不出)。

我根据网上的内容,然后加了修改通知栏的部份,经测试算是实现这个功能了。

 

源版版本:2.3.4

 

实现:

1。frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\StatusBarService.java

修改:addStatusBarView() 中的TOP改为BOTTOM,修改后代码:

[java] view plaincopy
  1. lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;  
  2. lp.setTitle("StatusBar");  
  3. lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar;  

表示状态栏显示在底部。

2。frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java

修改:

把mDockTop = mContentTop = mCurTop = mStatusBar.getFrameLw().bottom; 更改为:

mDockTop = mContentTop = mCurTop = 0

即以屏幕的左上角坐标(0,0)为参考点

修改mDockBottom ,mCurBottom, mContentBottom 的值,让它最终的值与下移后的状态栏的TOP位置一样。
修改成:mDockBottom = mContentBottom = mCurBottom = ( displayHeight - mStatusBar.getFrameLw().height());
也可以修改成:mDockBottom = mContentBottom = mCurBottom = mStatusBar.getFrameLw().top;

 

3。frameworks\base\packages\SystemUI\res\layout\status_bar_tracking.xml

修改:把Close按钮,就是可以拉动通知框的那个手柄移到内容的前面,修改后:

[html] view plain copy
  1. <com.android.systemui.statusbar.TrackingView  
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:visibility="gone"  
  5.     android:focusable="true"  
  6.     android:descendantFocusability="afterDescendants"  
  7.     android:paddingBottom="0px"  
  8.     android:paddingLeft="0px"  
  9.     android:paddingRight="0px"  
  10.     >  
  11.   
  12.     <com.android.systemui.statusbar.CloseDragHandle android:id="@+id/close"  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:orientation="vertical"  
  16.         >  
  17.         <ImageView  
  18.             android:layout_width="match_parent"  
  19.             android:layout_height="wrap_content"  
  20.             android:layout_gravity="bottom"  
  21.             android:scaleType="fitXY"  
  22.             android:src="@drawable/status_bar_close_on"  
  23.             />  
  24.   
  25.     com.android.systemui.statusbar.CloseDragHandle>  
  26.       
  27.     <View  
  28.          android:layout_width="match_parent"  
  29.          android:layout_height="wrap_content"  
  30.          android:layout_weight="1"  
  31.          android:background="#ff212121"  
  32.          />  
  33.   
  34. com.android.systemui.statusbar.TrackingView>  


4,最后就是要修改1中StatusBarService中,处理通知栏点击,拖动,抬起的逻辑了,由于改的地方有点多,所以把修改后的文件全部复制在这里了。

修改后:

 

[java] view plain copy
  1. /* 
  2.  * Copyright (C) 2010 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.android.systemui.statusbar;  
  18.   
  19. import android.app.Service;  
  20. import android.util.Log;  
  21. import com.android.internal.statusbar.IStatusBar;  
  22. import com.android.internal.statusbar.IStatusBarService;  
  23. import com.android.internal.statusbar.StatusBarIcon;  
  24. import com.android.internal.statusbar.StatusBarIconList;  
  25. import com.android.internal.statusbar.StatusBarNotification;  
  26.   
  27. import android.app.ActivityManagerNative;  
  28. import android.app.Dialog;  
  29. import android.app.Notification;  
  30. import android.app.NotificationManager;  
  31. import android.app.PendingIntent;  
  32. import android.app.Service;  
  33. import android.app.StatusBarManager;  
  34. import android.content.BroadcastReceiver;  
  35. import android.content.Context;  
  36. import android.content.Intent;  
  37. import android.content.IntentFilter;  
  38. import android.content.pm.PackageManager;  
  39. import android.content.res.Resources;  
  40. import android.graphics.PixelFormat;  
  41. import android.graphics.Rect;  
  42. import android.graphics.drawable.Drawable;  
  43. import android.net.Uri;  
  44. import android.os.IBinder;  
  45. import android.os.RemoteException;  
  46. import android.os.Binder;  
  47. import android.os.Handler;  
  48. import android.os.Message;  
  49. import android.os.ServiceManager;  
  50. import android.os.SystemClock;  
  51. import android.text.TextUtils;  
  52. import android.util.Slog;  
  53. import android.util.Log;  
  54. import android.view.Display;  
  55. import android.view.Gravity;  
  56. import android.view.KeyEvent;  
  57. import android.view.LayoutInflater;  
  58. import android.view.MotionEvent;  
  59. import android.view.VelocityTracker;  
  60. import android.view.View;  
  61. import android.view.ViewGroup;  
  62. import android.view.Window;  
  63. import android.view.WindowManager;  
  64. import android.view.WindowManagerImpl;  
  65. import android.view.animation.Animation;  
  66. import android.view.animation.AnimationUtils;  
  67. import android.widget.Button;  
  68. import android.widget.ImageView;  
  69. import android.widget.LinearLayout;  
  70. import android.widget.RemoteViews;  
  71. import android.widget.ScrollView;  
  72. import android.widget.TextView;  
  73. import android.widget.FrameLayout;  
  74.   
  75. import java.io.FileDescriptor;  
  76. import java.io.PrintWriter;  
  77. import java.util.ArrayList;  
  78. import java.util.HashMap;  
  79. import java.util.Set;  
  80.   
  81. import com.android.systemui.R;  
  82. import com.android.systemui.statusbar.policy.StatusBarPolicy;  
  83.   
  84. import android.content.IntentFilter;  
  85. import android.content.BroadcastReceiver;  
  86. import android.widget.Toast;  
  87.   
  88. import android.app.Notification;  
  89. import android.app.NotificationManager;  
  90. import android.app.PendingIntent;  
  91.   
  92. public class StatusBarService extends Service implements CommandQueue.Callbacks {  
  93.     NotificationManager mNotificationManage;  
  94.     Notification notification;  
  95.     PendingIntent contentIntent;  
  96.     private static final int ID_NOTIFICATION = 1;  
  97.       
  98.     BroadcastReceiver    mUsbReceiver;  
  99.     Context              mContext;  
  100.       
  101.     static final String TAG = "StatusBarService";  
  102.     static final boolean SPEW_ICONS = false;  
  103.     static final boolean SPEW = false;  
  104.   
  105.     public static final String ACTION_STATUSBAR_START  
  106.             = "com.android.internal.policy.statusbar.START";  
  107.   
  108.     static final int EXPANDED_LEAVE_ALONE = -10000;  
  109.     static final int EXPANDED_FULL_OPEN = -10001;  
  110.   
  111.     private static final int MSG_ANIMATE = 1000;  
  112.     private static final int MSG_ANIMATE_REVEAL = 1001;  
  113.   
  114.     StatusBarPolicy mIconPolicy;  
  115.   
  116.     CommandQueue mCommandQueue;  
  117.     IStatusBarService mBarService;  
  118.   
  119.     int mIconSize;  
  120.     Display mDisplay;  
  121.     StatusBarView mStatusBarView;  
  122.     int mPixelFormat;  
  123.     H mHandler = new H();  
  124.     Object mQueueLock = new Object();  
  125.   
  126.     // icons  
  127.     LinearLayout mIcons;  
  128.     IconMerger mNotificationIcons;  
  129.     LinearLayout mStatusIcons;  
  130.   
  131.     // expanded notifications  
  132.     Dialog mExpandedDialog;  
  133.     ExpandedView mExpandedView;  
  134.     WindowManager.LayoutParams mExpandedParams;  
  135.     ScrollView mScrollView;  
  136.     View mNotificationLinearLayout;  
  137.     View mExpandedContents;  
  138.     // top bar  
  139.     TextView mNoNotificationsTitle;  
  140.     TextView mClearButton;  
  141.     // drag bar  
  142.     CloseDragHandle mCloseView;  
  143.     // ongoing  
  144.     NotificationData mOngoing = new NotificationData();  
  145.     TextView mOngoingTitle;  
  146.     LinearLayout mOngoingItems;  
  147.     // latest  
  148.     NotificationData mLatest = new NotificationData();  
  149.     TextView mLatestTitle;  
  150.     LinearLayout mLatestItems;  
  151.     // position  
  152.     int[] mPositionTmp = new int[2];  
  153.     boolean mExpanded;  
  154.     boolean mExpandedVisible;  
  155.   
  156.     // the date view  
  157.     DateView mDateView;  
  158.   
  159.     // the tracker view  
  160.     TrackingView mTrackingView;  
  161.     WindowManager.LayoutParams mTrackingParams;  
  162.     int mTrackingPosition; // the position of the top of the tracking view.  
  163.     private boolean mPanelSlightlyVisible;  
  164.   
  165.     // ticker  
  166.     private Ticker mTicker;  
  167.     private View mTickerView;  
  168.     private boolean mTicking;  
  169.   
  170.     // Tracking finger for opening/closing.  
  171.     int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore  
  172.     boolean mTracking;  
  173.     VelocityTracker mVelocityTracker;  
  174.   
  175.     static final int ANIM_FRAME_DURATION = (1000/60);  
  176.   
  177.     boolean mAnimating;  
  178.     long mCurAnimationTime;  
  179.     float mDisplayHeight;  
  180.     float mAnimY;  
  181.     float mAnimVel;  
  182.     float mAnimAccel;  
  183.     long mAnimLastTime;  
  184.     boolean mAnimatingReveal = false;  
  185.     int mViewDelta;  
  186.     int[] mAbsPos = new int[2];  
  187.   
  188.     // for disabling the status bar  
  189.     int mDisabled = 0;  
  190.   
  191.     private class ExpandedDialog extends Dialog {  
  192.         ExpandedDialog(Context context) {  
  193.             super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);  
  194.         }  
  195.   
  196.         @Override  
  197.         public boolean dispatchKeyEvent(KeyEvent event) {  
  198.             boolean down = event.getAction() == KeyEvent.ACTION_DOWN;  
  199.             switch (event.getKeyCode()) {  
  200.             case KeyEvent.KEYCODE_BACK:  
  201.                 if (!down) {  
  202.                     animateCollapse();  
  203.                 }  
  204.                 return true;  
  205.             }  
  206.             return super.dispatchKeyEvent(event);  
  207.         }  
  208.     }  
  209.   
  210.   
  211.     @Override  
  212.     public void onCreate() {  
  213.         mContext = this;  
  214.         // First set up our views and stuff.  
  215.         mDisplay = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();  
  216.         makeStatusBarView(this);  
  217.   
  218.         // Connect in to the status bar manager service  
  219.         StatusBarIconList iconList = new StatusBarIconList();  
  220.         ArrayList notificationKeys = new ArrayList();  
  221.         ArrayList notifications = new ArrayList();  
  222.         mCommandQueue = new CommandQueue(this, iconList);  
  223.         mBarService = IStatusBarService.Stub.asInterface(  
  224.                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));  
  225.         try {  
  226.             mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications);  
  227.         } catch (RemoteException ex) {  
  228.             // If the system process isn't there we're doomed anyway.  
  229.         }  
  230.   
  231.         // Set up the initial icon state  
  232.         int N = iconList.size();  
  233.         int viewIndex = 0;  
  234.         for (int i=0; i
  235.             StatusBarIcon icon = iconList.getIcon(i);  
  236.             if (icon != null) {  
  237.                 addIcon(iconList.getSlot(i), i, viewIndex, icon);  
  238.                 viewIndex++;  
  239.             }  
  240.         }  
  241.   
  242.         // Set up the initial notification state  
  243.         N = notificationKeys.size();  
  244.         if (N == notifications.size()) {  
  245.             for (int i=0; i
  246.                 addNotification(notificationKeys.get(i), notifications.get(i));  
  247.             }  
  248.         } else {  
  249.             Log.wtf(TAG, "Notification list length mismatch: keys=" + N  
  250.                     + " notifications=" + notifications.size());  
  251.         }  
  252.   
  253.         // Put up the view  
  254.         addStatusBarView();  
  255.   
  256.         // Lastly, call to the icon policy to install/update all the icons.  
  257.         mIconPolicy = new StatusBarPolicy(this);  
  258.           
  259.       /*  mUsbReceiver = new BroadcastReceiver() { 
  260.  
  261.             @Override 
  262.             public void onReceive(Context context, Intent intent) { 
  263.                 // TODO Auto-generated method stub 
  264.                 if (intent.getDataString().contains("/sdcard/sd")) {  
  265.                 if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED) || 
  266.                         intent.getAction().equals(Intent.ACTION_MEDIA_CHECKING)) { 
  267.  
  268.                     String ns = Context.NOTIFICATION_SERVICE; 
  269.  
  270.                     mNotificationManage = (NotificationManager) mContext.getSystemService(ns); 
  271.                     int icon = R.drawable.u_normal; //notification icon 
  272.                     String tickerText = mContext.getString(R.string.u_disk); 
  273.                     long when = System.currentTimeMillis(); //happened time  
  274.                     notification = new Notification(icon, tickerText, when); 
  275.                      
  276.                     Context acontext = getApplicationContext(); 
  277.                     String contentTitle = mContext.getString(R.string.u_unmount); 
  278.                     String contentText = mContext.getString(R.string.u_unmount_summary); 
  279.                     Intent notificationIntent = new Intent(mContext, UsbUmountActivity.class); 
  280.  
  281.                     PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0); 
  282.                     notification.setLatestEventInfo(acontext, 
  283.                             contentTitle, contentText, contentIntent); 
  284.                     mNotificationManage.notify(ID_NOTIFICATION, notification); 
  285.                 } 
  286.                 else if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 
  287.                     mNotificationManage.cancel(ID_NOTIFICATION); 
  288.                 } 
  289.                 } 
  290.             } 
  291.         }; 
  292.          
  293.         IntentFilter filter=new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 
  294.           filter.addAction(Intent.ACTION_MEDIA_CHECKING); 
  295.           filter.addAction(Intent.ACTION_MEDIA_EJECT); 
  296.           filter.addAction(Intent.ACTION_MEDIA_REMOVED); 
  297.           filter.addAction(Intent.ACTION_MEDIA_SHARED); 
  298.           filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 
  299.           filter.addDataScheme("file"); 
  300.           mContext.registerReceiver(mUsbReceiver,filter); */  
  301.     }  
  302.   
  303.     @Override  
  304.     public void onDestroy() {  
  305.         // we're never destroyed  
  306.     }  
  307.   
  308.     /** 
  309.      * Nobody binds to us. 
  310.      */  
  311.     @Override  
  312.     public IBinder onBind(Intent intent) {  
  313.         return null;  
  314.     }  
  315.   
  316.     // ================================================================================  
  317.     // Constructing the view  
  318.     // ================================================================================  
  319.     private void makeStatusBarView(Context context) {  
  320.         Resources res = context.getResources();  
  321.   
  322.         mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);  
  323.   
  324.         ExpandedView expanded = (ExpandedView)View.inflate(context,  
  325.                 R.layout.status_bar_expanded, null);  
  326.         expanded.mService = this;  
  327.   
  328.         StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null);  
  329.         sb.mService = this;  
  330.   
  331.         // figure out which pixel-format to use for the status bar.  
  332.         mPixelFormat = PixelFormat.TRANSLUCENT;  
  333.         Drawable bg = sb.getBackground();  
  334.         if (bg != null) {  
  335.             mPixelFormat = bg.getOpacity();  
  336.         }  
  337.   
  338.         mStatusBarView = sb;  
  339.         mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);  
  340.         mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);  
  341.         mIcons = (LinearLayout)sb.findViewById(R.id.icons);  
  342.         mTickerView = sb.findViewById(R.id.ticker);  
  343.         mDateView = (DateView)sb.findViewById(R.id.date);  
  344.   
  345.         mExpandedDialog = new ExpandedDialog(context);  
  346.         mExpandedView = expanded;  
  347.         mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout);  
  348.         mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle);  
  349.         mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems);  
  350.         mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle);  
  351.         mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems);  
  352.         mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);  
  353.         mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button);  
  354.         mClearButton.setOnClickListener(mClearButtonListener);  
  355.         mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);  
  356.         mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);  
  357.   
  358.         mExpandedView.setVisibility(View.GONE);  
  359.         mOngoingTitle.setVisibility(View.GONE);  
  360.         mLatestTitle.setVisibility(View.GONE);  
  361.   
  362.         mTicker = new MyTicker(context, sb);  
  363.   
  364.         TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText);  
  365.         tickerView.mTicker = mTicker;  
  366.   
  367.         mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null);  
  368.         mTrackingView.mService = this;  
  369.         mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close);  
  370.         mCloseView.mService = this;  
  371.   
  372.         mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);  
  373.   
  374.         // set the inital view visibility  
  375.         setAreThereNotifications();  
  376.         mDateView.setVisibility(View.INVISIBLE);  
  377.   
  378.         // receive broadcasts  
  379.         IntentFilter filter = new IntentFilter();  
  380.         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);  
  381.         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);  
  382.         filter.addAction(Intent.ACTION_SCREEN_OFF);  
  383.         context.registerReceiver(mBroadcastReceiver, filter);  
  384.     }  
  385.   
  386.     protected void addStatusBarView() {  
  387.         Resources res = getResources();  
  388.         final int height= res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);  
  389.   
  390.         final StatusBarView view = mStatusBarView;  
  391.         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(  
  392.                 ViewGroup.LayoutParams.MATCH_PARENT,  
  393.                 height,  
  394.                 WindowManager.LayoutParams.TYPE_STATUS_BAR,  
  395.                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  
  396.                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,  
  397.                 PixelFormat.RGBX_8888);  
  398.         lp.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;  
  399.         lp.setTitle("StatusBar");  
  400.         lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar;  
  401.   
  402.         WindowManagerImpl.getDefault().addView(view, lp);  
  403.     }  
  404.   
  405.     public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {  
  406.         if (SPEW_ICONS) {  
  407.             Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex  
  408.                     + " icon=" + icon);  
  409.         }  
  410.         StatusBarIconView view = new StatusBarIconView(this, slot);  
  411.         view.set(icon);  
  412.         mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));  
  413.     }  
  414.   
  415.     public void updateIcon(String slot, int index, int viewIndex,  
  416.             StatusBarIcon old, StatusBarIcon icon) {  
  417.         if (SPEW_ICONS) {  
  418.             Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex  
  419.                     + " old=" + old + " icon=" + icon);  
  420.         }  
  421.         StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);  
  422.         view.set(icon);  
  423.     }  
  424.   
  425.     public void removeIcon(String slot, int index, int viewIndex) {  
  426.         if (SPEW_ICONS) {  
  427.             Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);  
  428.         }  
  429.         mStatusIcons.removeViewAt(viewIndex);  
  430.     }  
  431.   
  432.     public void addNotification(IBinder key, StatusBarNotification notification) {  
  433.         boolean shouldTick = true;  
  434.         if (notification.notification.fullScreenIntent != null) {  
  435.             shouldTick = false;  
  436.             Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");  
  437.             try {  
  438.                 notification.notification.fullScreenIntent.send();  
  439.             } catch (PendingIntent.CanceledException e) {  
  440.             }  
  441.         }   
  442.   
  443.         StatusBarIconView iconView = addNotificationViews(key, notification);  
  444.         if (iconView == nullreturn;  
  445.   
  446.         if (shouldTick) {  
  447.             tick(notification);  
  448.         }  
  449.           
  450.         // Recalculate the position of the sliding windows and the titles.  
  451.         setAreThereNotifications();  
  452.         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);  
  453.     }  
  454.   
  455.     public void updateNotification(IBinder key, StatusBarNotification notification) {  
  456.         NotificationData oldList;  
  457.         int oldIndex = mOngoing.findEntry(key);  
  458.         if (oldIndex >= 0) {  
  459.             oldList = mOngoing;  
  460.         } else {  
  461.             oldIndex = mLatest.findEntry(key);  
  462.             if (oldIndex < 0) {  
  463.                 Slog.w(TAG, "updateNotification for unknown key: " + key);  
  464.                 return;  
  465.             }  
  466.             oldList = mLatest;  
  467.         }  
  468.         final NotificationData.Entry oldEntry = oldList.getEntryAt(oldIndex);  
  469.         final StatusBarNotification oldNotification = oldEntry.notification;  
  470.         final RemoteViews oldContentView = oldNotification.notification.contentView;  
  471.   
  472.         final RemoteViews contentView = notification.notification.contentView;  
  473.   
  474.         if (false) {  
  475.             Slog.d(TAG, "old notification: when=" + oldNotification.notification.when  
  476.                     + " ongoing=" + oldNotification.isOngoing()  
  477.                     + " expanded=" + oldEntry.expanded  
  478.                     + " contentView=" + oldContentView);  
  479.             Slog.d(TAG, "new notification: when=" + notification.notification.when  
  480.                     + " ongoing=" + oldNotification.isOngoing()  
  481.                     + " contentView=" + contentView);  
  482.         }  
  483.   
  484.         // Can we just reapply the RemoteViews in place?  If when didn't change, the order  
  485.         // didn't change.  
  486.         if (notification.notification.when == oldNotification.notification.when  
  487.                 && notification.isOngoing() == oldNotification.isOngoing()  
  488.                 && oldEntry.expanded != null  
  489.                 && contentView != null && oldContentView != null  
  490.                 && contentView.getPackage() != null  
  491.                 && oldContentView.getPackage() != null  
  492.                 && oldContentView.getPackage().equals(contentView.getPackage())  
  493.                 && oldContentView.getLayoutId() == contentView.getLayoutId()) {  
  494.             if (SPEW) Slog.d(TAG, "reusing notification");  
  495.             oldEntry.notification = notification;  
  496.             try {  
  497.                 // Reapply the RemoteViews  
  498.                 contentView.reapply(this, oldEntry.content);  
  499.                 // update the contentIntent  
  500.                 final PendingIntent contentIntent = notification.notification.contentIntent;  
  501.                 if (contentIntent != null) {  
  502.                     oldEntry.content.setOnClickListener(new Launcher(contentIntent,  
  503.                                 notification.pkg, notification.tag, notification.id));  
  504.                 }  
  505.                 // Update the icon.  
  506.                 final StatusBarIcon ic = new StatusBarIcon(notification.pkg,  
  507.                         notification.notification.icon, notification.notification.iconLevel,  
  508.                         notification.notification.number);  
  509.                 if (!oldEntry.icon.set(ic)) {  
  510.                     handleNotificationError(key, notification, "Couldn't update icon: " + ic);  
  511.                     return;  
  512.                 }  
  513.             }  
  514.             catch (RuntimeException e) {  
  515.                 // It failed to add cleanly.  Log, and remove the view from the panel.  
  516.                 Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);  
  517.                 removeNotificationViews(key);  
  518.                 addNotificationViews(key, notification);  
  519.             }  
  520.         } else {  
  521.             if (SPEW) Slog.d(TAG, "not reusing notification");  
  522.             removeNotificationViews(key);  
  523.             addNotificationViews(key, notification);  
  524.         }  
  525.   
  526.         // Restart the ticker if it's still running  
  527.         if (notification.notification.tickerText != null  
  528.                 && !TextUtils.equals(notification.notification.tickerText,  
  529.                     oldEntry.notification.notification.tickerText)) {  
  530.             tick(notification);  
  531.         }  
  532.   
  533.         // Recalculate the position of the sliding windows and the titles.  
  534.         setAreThereNotifications();  
  535.         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);  
  536.     }  
  537.   
  538.     public void removeNotification(IBinder key) {  
  539.         if (SPEW) Slog.d(TAG, "removeNotification key=" + key);  
  540.         StatusBarNotification old = removeNotificationViews(key);  
  541.   
  542.         if (old != null) {  
  543.             // Cancel the ticker if it's still running  
  544.             mTicker.removeEntry(old);  
  545.   
  546.             // Recalculate the position of the sliding windows and the titles.  
  547.             setAreThereNotifications();  
  548.             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);  
  549.         }  
  550.     }  
  551.   
  552.     private int chooseIconIndex(boolean isOngoing, int viewIndex) {  
  553.         final int latestSize = mLatest.size();  
  554.         if (isOngoing) {  
  555.             return latestSize + (mOngoing.size() - viewIndex);  
  556.         } else {  
  557.             return latestSize - viewIndex;  
  558.         }  
  559.     }  
  560.   
  561.     View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {  
  562.         Notification n = notification.notification;  
  563.         RemoteViews remoteViews = n.contentView;  
  564.         if (remoteViews == null) {  
  565.             return null;  
  566.         }  
  567.   
  568.         // create the row view  
  569.         LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  570.         View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false);  
  571.   
  572.         // bind the click event to the content area  
  573.         ViewGroup content = (ViewGroup)row.findViewById(R.id.content);  
  574.         content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);  
  575.         content.setOnFocusChangeListener(mFocusChangeListener);  
  576.         PendingIntent contentIntent = n.contentIntent;  
  577.         if (contentIntent != null) {  
  578.             content.setOnClickListener(new Launcher(contentIntent, notification.pkg,  
  579.                         notification.tag, notification.id));  
  580.         }  
  581.   
  582.         View expanded = null;  
  583.         Exception exception = null;  
  584.         try {  
  585.             expanded = remoteViews.apply(this, content);  
  586.         }  
  587.         catch (RuntimeException e) {  
  588.             exception = e;  
  589.         }  
  590.         if (expanded == null) {  
  591.             String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);  
  592.             Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);  
  593.             return null;  
  594.         } else {  
  595.             content.addView(expanded);  
  596.             row.setDrawingCacheEnabled(true);  
  597.         }  
  598.   
  599.         return new View[] { row, content, expanded };  
  600.     }  
  601.   
  602.     StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {  
  603.         NotificationData list;  
  604.         ViewGroup parent;  
  605.         final boolean isOngoing = notification.isOngoing();  
  606.         if (isOngoing) {  
  607.             list = mOngoing;  
  608.             parent = mOngoingItems;  
  609.         } else {  
  610.             list = mLatest;  
  611.             parent = mLatestItems;  
  612.         }  
  613.         // Construct the expanded view.  
  614.         final View[] views = makeNotificationView(notification, parent);  
  615.         if (views == null) {  
  616.             handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "  
  617.                     + notification);  
  618.             return null;  
  619.         }  
  620.         final View row = views[0];  
  621.         final View content = views[1];  
  622.         final View expanded = views[2];  
  623.         // Construct the icon.  
  624.         final StatusBarIconView iconView = new StatusBarIconView(this,  
  625.                 notification.pkg + "/0x" + Integer.toHexString(notification.id));  
  626.         final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,  
  627.                     notification.notification.iconLevel, notification.notification.number);  
  628.         if (!iconView.set(ic)) {  
  629.             handleNotificationError(key, notification, "Coulding create icon: " + ic);  
  630.             return null;  
  631.         }  
  632.         // Add the expanded view.  
  633.         final int viewIndex = list.add(key, notification, row, content, expanded, iconView);  
  634.         parent.addView(row, viewIndex);  
  635.         // Add the icon.  
  636.         final int iconIndex = chooseIconIndex(isOngoing, viewIndex);  
  637.         mNotificationIcons.addView(iconView, iconIndex);  
  638.         return iconView;  
  639.     }  
  640.   
  641.     StatusBarNotification removeNotificationViews(IBinder key) {  
  642.         NotificationData.Entry entry = mOngoing.remove(key);  
  643.         if (entry == null) {  
  644.             entry = mLatest.remove(key);  
  645.             if (entry == null) {  
  646.                 Slog.w(TAG, "removeNotification for unknown key: " + key);  
  647.                 return null;  
  648.             }  
  649.         }  
  650.         // Remove the expanded view.  
  651.         ((ViewGroup)entry.row.getParent()).removeView(entry.row);  
  652.         // Remove the icon.  
  653.         ((ViewGroup)entry.icon.getParent()).removeView(entry.icon);  
  654.   
  655.         return entry.notification;  
  656.     }  
  657.   
  658.     private void setAreThereNotifications() {  
  659.         boolean ongoing = mOngoing.hasVisibleItems();  
  660.         boolean latest = mLatest.hasVisibleItems();  
  661.   
  662.         // (no ongoing notifications are clearable)  
  663.         if (mLatest.hasClearableItems()) {  
  664.             mClearButton.setVisibility(View.VISIBLE);  
  665.         } else {  
  666.             mClearButton.setVisibility(View.INVISIBLE);  
  667.         }  
  668.   
  669.         mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);  
  670.         mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);  
  671.   
  672.         if (ongoing || latest) {  
  673.             mNoNotificationsTitle.setVisibility(View.GONE);  
  674.         } else {  
  675.             mNoNotificationsTitle.setVisibility(View.VISIBLE);  
  676.         }  
  677.     }  
  678.   
  679.   
  680.     /** 
  681.      * State is one or more of the DISABLE constants from StatusBarManager. 
  682.      */  
  683.     public void disable(int state) {  
  684.         final int old = mDisabled;  
  685.         final int diff = state ^ old;  
  686.         mDisabled = state;  
  687.   
  688.         if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {  
  689.             if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {  
  690.                 if (SPEW) Slog.d(TAG, "DISABLE_EXPAND: yes");  
  691.                 animateCollapse();  
  692.             }  
  693.         }  
  694.         if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {  
  695.             if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {  
  696.                 if (SPEW) Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");  
  697.                 if (mTicking) {  
  698.                     mTicker.halt();  
  699.                 } else {  
  700.                     setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);  
  701.                 }  
  702.             } else {  
  703.                 if (SPEW) Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");  
  704.                 if (!mExpandedVisible) {  
  705.                     setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);  
  706.                 }  
  707.             }  
  708.         } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {  
  709.             if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {  
  710.                 if (SPEW) Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes");  
  711.                 mTicker.halt();  
  712.             }  
  713.         }  
  714.     }  
  715.   
  716.     /** 
  717.      * All changes to the status bar and notifications funnel through here and are batched. 
  718.      */  
  719.     private class H extends Handler {  
  720.         public void handleMessage(Message m) {  
  721.             switch (m.what) {  
  722.                 case MSG_ANIMATE:  
  723.                     doAnimation();  
  724.                     break;  
  725.                 case MSG_ANIMATE_REVEAL:  
  726.                     doRevealAnimation();  
  727.                     break;  
  728.             }  
  729.         }  
  730.     }  
  731.   
  732.     View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() {  
  733.         public void onFocusChange(View v, boolean hasFocus) {  
  734.             // Because 'v' is a ViewGroup, all its children will be (un)selected  
  735.             // too, which allows marqueeing to work.  
  736.             v.setSelected(hasFocus);  
  737.         }  
  738.     };  
  739.   
  740.     private void makeExpandedVisible() {  
  741.         if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);  
  742.         if (mExpandedVisible) {  
  743.             return;  
  744.         }  
  745.         mExpandedVisible = true;  
  746.         visibilityChanged(true);  
  747.   
  748.         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);  
  749.         mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  750.         mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;  
  751.         mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  752.         mExpandedView.requestFocus(View.FOCUS_FORWARD);  
  753.         mTrackingView.setVisibility(View.VISIBLE);  
  754.         mExpandedView.setVisibility(View.VISIBLE);  
  755.   
  756.         if (!mTicking) {  
  757.             setDateViewVisibility(true, com.android.internal.R.anim.fade_in);  
  758.         }  
  759.     }  
  760.   
  761.     public void animateExpand() {  
  762.         if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded);  
  763.         if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {  
  764.             return ;  
  765.         }  
  766.         if (mExpanded) {  
  767.             return;  
  768.         }  
  769.   
  770.         prepareTracking(0true);  
  771.         performFling(02000.0f, true);  
  772.     }  
  773.   
  774.     public void animateCollapse() {  
  775.         if (SPEW) {  
  776.             Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded  
  777.                     + " mExpandedVisible=" + mExpandedVisible  
  778.                     + " mExpanded=" + mExpanded  
  779.                     + " mAnimating=" + mAnimating  
  780.                     + " mAnimY=" + mAnimY  
  781.                     + " mAnimVel=" + mAnimVel);  
  782.         }  
  783.   
  784.         if (!mExpandedVisible) {  
  785.             return;  
  786.         }  
  787.   
  788.         int y;  
  789.         if (mAnimating) {  
  790.             y = (int)mAnimY;  
  791.         } else {  
  792.             y = mDisplay.getHeight()-1;  
  793.         }  
  794.         // Let the fling think that we're open so it goes in the right direction  
  795.         // and doesn't try to re-open the windowshade.  
  796.         mExpanded = true;  
  797.         prepareTracking(y, false);  
  798.         performFling(y, -2000.0f, true);  
  799.     }  
  800.   
  801.     void performExpand() {  
  802.         if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);  
  803.         if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {  
  804.             return ;  
  805.         }  
  806.         if (mExpanded) {  
  807.             return;  
  808.         }  
  809.   
  810.         mExpanded = true;  
  811.         makeExpandedVisible();  
  812.         //mStatusBarView.hiddenHotIcons();  
  813.         updateExpandedViewPos(EXPANDED_FULL_OPEN);  
  814.   
  815.         if (false) postStartTracing();  
  816.     }  
  817.   
  818.     void performCollapse() {  
  819.         if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded  
  820.                 + " mExpandedVisible=" + mExpandedVisible  
  821.                 + " mTicking=" + mTicking);  
  822.   
  823.         if (!mExpandedVisible) {  
  824.             return;  
  825.         }  
  826.         mExpandedVisible = false;  
  827.         visibilityChanged(false);  
  828.         mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  829.         mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;  
  830.         mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  831.         mTrackingView.setVisibility(View.GONE);  
  832.         mExpandedView.setVisibility(View.GONE);  
  833.   
  834.         //mStatusBarView.showHotIcons();  
  835.           
  836.         if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {  
  837.             setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);  
  838.         }  
  839.         if (mDateView.getVisibility() == View.VISIBLE) {  
  840.             setDateViewVisibility(false, com.android.internal.R.anim.fade_out);  
  841.         }  
  842.   
  843.         if (!mExpanded) {  
  844.             return;  
  845.         }  
  846.         mExpanded = false;  
  847.     }  
  848.   
  849.     void doAnimation() {  
  850.         if (mAnimating) {  
  851.             if (SPEW) Slog.d(TAG, "doAnimation");  
  852.             if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);  
  853.             incrementAnim();  
  854.             if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);  
  855.             if (mAnimY >= mDisplay.getHeight() - mStatusBarView.getHeight()) {  
  856.                 if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");  
  857.                 mAnimating = false;  
  858.                 updateExpandedViewPos(mDisplay.getHeight() - mStatusBarView.getHeight()  
  859.                         + mCloseView.getHeight());  
  860.                 performCollapse();  
  861.             }  
  862.             else if (mAnimY < mStatusBarView.getHeight()) {  
  863.                 if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");  
  864.                 mAnimating = false;  
  865.                 updateExpandedViewPos(0);  
  866.                 performExpand();  
  867.             }  
  868.             else {  
  869.                 updateExpandedViewPos((int)mAnimY);  
  870.                 mCurAnimationTime += ANIM_FRAME_DURATION;  
  871.                 mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);  
  872.             }  
  873.         }  
  874.     }  
  875.   
  876.     void stopTracking() {  
  877.         mTracking = false;  
  878.         mVelocityTracker.recycle();  
  879.         mVelocityTracker = null;  
  880.     }  
  881.   
  882.     void incrementAnim() {  
  883.         long now = SystemClock.uptimeMillis();  
  884.         float t = ((float)(now - mAnimLastTime)) / 1000;            // ms -> s  
  885.         final float y = mAnimY;  
  886.         final float v = mAnimVel;                                   // px/s  
  887.         final float a = mAnimAccel;                                 // px/s/s  
  888.         mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px  
  889.         mAnimVel = v + (a*t);                                       // px/s  
  890.         mAnimLastTime = now;                                        // ms  
  891.         //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY  
  892.         //        + " mAnimAccel=" + mAnimAccel);  
  893.     }  
  894.   
  895.     void doRevealAnimation() {  
  896.         final int h = mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();  
  897.         if (mAnimatingReveal && mAnimating && mAnimY > h) {  
  898.             incrementAnim();  
  899.             if (mAnimY <= h) {  
  900.                 mAnimY = h;  
  901.                 updateExpandedViewPos((int)mAnimY);  
  902.             } else {  
  903.                 updateExpandedViewPos((int)mAnimY);  
  904.                 mCurAnimationTime += ANIM_FRAME_DURATION;  
  905.                 mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),  
  906.                         mCurAnimationTime);  
  907.             }  
  908.         }  
  909.     }  
  910.   
  911.     void prepareTracking(int y, boolean opening) {  
  912.         mTracking = true;  
  913.         mVelocityTracker = VelocityTracker.obtain();  
  914.         if (opening) {  
  915.             mAnimAccel = -2000.0f;  
  916.             mAnimVel = -200;  
  917.             mAnimY = mDisplay.getHeight() - mStatusBarView.getHeight();  
  918.             updateExpandedViewPos((int)mAnimY);  
  919.             mAnimating = true;  
  920.             mAnimatingReveal = true;  
  921.             mHandler.removeMessages(MSG_ANIMATE);  
  922.             mHandler.removeMessages(MSG_ANIMATE_REVEAL);  
  923.             long now = SystemClock.uptimeMillis();  
  924.             mAnimLastTime = now;  
  925.             mCurAnimationTime = now + ANIM_FRAME_DURATION;  
  926.             mAnimating = true;  
  927.             mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL),  
  928.                     mCurAnimationTime);  
  929.             makeExpandedVisible();  
  930.         } else {  
  931.             // it's open, close it?  
  932.             if (mAnimating) {  
  933.                 mAnimating = false;  
  934.                 mHandler.removeMessages(MSG_ANIMATE);  
  935.             }  
  936.             updateExpandedViewPos(y + mViewDelta);  
  937.         }  
  938.     }  
  939.   
  940.     void performFling(int y, float vel, boolean always) {  
  941.         mAnimatingReveal = false;  
  942.         mDisplayHeight = mDisplay.getHeight();  
  943.   
  944.         mAnimY = y;  
  945.         mAnimVel = vel;  
  946.   
  947.         //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);  
  948.   
  949.         if (mExpanded) {  
  950.             if (!always && (  
  951.                     vel < -200.0f  
  952.                     || ((y > 25) && (vel < 200.0f)))) {  
  953.                 // We are expanded, but they didn't move sufficiently to cause  
  954.                 // us to retract.  Animate back to the expanded position.  
  955.                 mAnimAccel = 2000.0f;  
  956.                 if (vel > 0) {  
  957.                     mAnimVel = 0;  
  958.                 }  
  959.             }  
  960.             else {  
  961.                 // We are expanded and are now going to animate away.  
  962.                 mAnimAccel = -2000.0f;  
  963.                 if (vel < 0) {  
  964.                     mAnimVel = 0;  
  965.                 }  
  966.             }  
  967.         } else {  
  968.             if (always || (  
  969.                     vel < -200.0f  
  970.                     || ((y < mDisplayHeight/2) && (vel < 200.0f)))) {  
  971.                 // We are collapsed, and they moved enough to allow us to  
  972.                 // expand.  Animate in the notifications.  
  973.                 mAnimAccel = -2000.0f;  
  974.                 if (vel > 0) {  
  975.                     mAnimVel = 0;  
  976.                 }  
  977.             }  
  978.             else {  
  979.                 // We are collapsed, but they didn't move sufficiently to cause  
  980.                 // us to retract.  Animate back to the collapsed position.  
  981.                 mAnimAccel = 2000.0f;  
  982.                 if (vel < 0) {  
  983.                     mAnimVel = 0;  
  984.                 }  
  985.             }  
  986.         }  
  987.         //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel  
  988.         //        + " mAnimAccel=" + mAnimAccel);  
  989.   
  990.         long now = SystemClock.uptimeMillis();  
  991.         mAnimLastTime = now;  
  992.         mCurAnimationTime = now + ANIM_FRAME_DURATION;  
  993.         mAnimating = true;  
  994.         mHandler.removeMessages(MSG_ANIMATE);  
  995.         mHandler.removeMessages(MSG_ANIMATE_REVEAL);  
  996.         mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime);  
  997.         stopTracking();  
  998.     }  
  999.   
  1000.     boolean interceptTouchEvent(MotionEvent event) {  
  1001.         if (SPEW) {  
  1002.             Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="  
  1003.                 + mDisabled);  
  1004.         }  
  1005.   
  1006.         if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {  
  1007.             return false;  
  1008.         }  
  1009.   
  1010.         final int statusBarSize = mStatusBarView.getHeight();  
  1011.         final int disph = mDisplay.getHeight();  
  1012.         final int hitSize = statusBarSize*2;  
  1013.         if (event.getAction() == MotionEvent.ACTION_DOWN) {  
  1014.             final int y = (int)event.getRawY();  
  1015.   
  1016.             if (!mExpanded) {  
  1017.                 mStatusBarView.getLocationOnScreen(mAbsPos);  
  1018.                 mViewDelta = y - mAbsPos[1];  
  1019.             } else {  
  1020.                 mTrackingView.getLocationOnScreen(mAbsPos);  
  1021.                 mViewDelta = y - mAbsPos[1];  
  1022.             }  
  1023.             if ((!mExpanded && y > hitSize && y < disph) ||  
  1024.                     (mExpanded && y < hitSize)) {  
  1025.   
  1026.                 // We drop events at the edge of the screen to make the windowshade come  
  1027.                 // down by accident less, especially when pushing open a device with a keyboard  
  1028.                 // that rotates (like g1 and droid)  
  1029.                 int x = (int)event.getRawX();  
  1030.                 final int edgeBorder = mEdgeBorder;  
  1031.                 if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) {  
  1032.                     prepareTracking(y, !mExpanded);// opening if we're not already fully visible  
  1033.                     mVelocityTracker.addMovement(event);  
  1034.   
  1035.                /*     Log.i("interceptTouchEvent " +  
  1036.                     "if (event.getAction() == MotionEvent.ACTION_DOWN)" + 
  1037.                             "if ((!mExpanded && y > hitSize && y < disph) " + 
  1038.                     "||(mExpanded && y > (mDisplay.getHeight()-hitSize)))" + 
  1039.                     "if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder)", 
  1040.                     "   mExpanded is " + mExpanded + 
  1041.                     "   mExpandedVisible " + mExpandedVisible + 
  1042.                     "   mPanelSlightlyVisible " + mPanelSlightlyVisible + 
  1043.                     "   mTracking " + mTracking + 
  1044.                     "   mAnimating " + mAnimating + 
  1045.                     "   mAnimatingReveal " + mAnimatingReveal); */  
  1046.                 }  
  1047.             }  
  1048.         } else if (mTracking) {  
  1049.             mVelocityTracker.addMovement(event);  
  1050.             final int maxY = disph - statusBarSize - mCloseView.getHeight();  
  1051.             if (event.getAction() == MotionEvent.ACTION_MOVE) {  
  1052.                 int y = (int)event.getRawY();  
  1053.                 if (mAnimatingReveal && y > maxY) {  
  1054.                     // nothing  
  1055.                 } else  {  
  1056.                     mAnimatingReveal = false;  
  1057.                     updateExpandedViewPos(y - mViewDelta);  
  1058.                 }  
  1059.             } else if (event.getAction() == MotionEvent.ACTION_UP) {  
  1060.                 mVelocityTracker.computeCurrentVelocity(1000);  
  1061.   
  1062.                 float yVel = mVelocityTracker.getYVelocity();  
  1063.   
  1064.                 boolean negative = yVel < 0;  
  1065.   
  1066.                 float xVel = mVelocityTracker.getXVelocity();  
  1067.                 if (xVel < 0) {  
  1068.                     xVel = -xVel;  
  1069.                 }  
  1070.                 if (xVel > 150.0f) {  
  1071.                     xVel = 150.0f; // limit how much we care about the x axis  
  1072.                 }  
  1073.   
  1074.                 float vel = (float)Math.hypot(yVel, xVel);  
  1075.                 if (negative) {  
  1076.                     vel = -vel;  
  1077.                 }  
  1078.   
  1079.                 performFling((int)event.getRawY(), vel, false);  
  1080.             }  
  1081.   
  1082.         }  
  1083.         return false;  
  1084.     }  
  1085.   
  1086.     private class Launcher implements View.OnClickListener {  
  1087.         private PendingIntent mIntent;  
  1088.         private String mPkg;  
  1089.         private String mTag;  
  1090.         private int mId;  
  1091.   
  1092.         Launcher(PendingIntent intent, String pkg, String tag, int id) {  
  1093.             mIntent = intent;  
  1094.             mPkg = pkg;  
  1095.             mTag = tag;  
  1096.             mId = id;  
  1097.         }  
  1098.   
  1099.         public void onClick(View v) {  
  1100.             try {  
  1101.                 // The intent we are sending is for the application, which  
  1102.                 // won't have permission to immediately start an activity after  
  1103.                 // the user switches to home.  We know it is safe to do at this  
  1104.                 // point, so make sure new activity switches are now allowed.  
  1105.                 ActivityManagerNative.getDefault().resumeAppSwitches();  
  1106.             } catch (RemoteException e) {  
  1107.             }  
  1108.   
  1109.             if (mIntent != null) {  
  1110.                 int[] pos = new int[2];  
  1111.                 v.getLocationOnScreen(pos);  
  1112.                 Intent overlay = new Intent();  
  1113.                 overlay.setSourceBounds(  
  1114.                         new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));  
  1115.                 try {  
  1116.                     mIntent.send(StatusBarService.this0, overlay);  
  1117.                 } catch (PendingIntent.CanceledException e) {  
  1118.                     // the stack trace isn't very helpful here.  Just log the exception message.  
  1119.                     Slog.w(TAG, "Sending contentIntent failed: " + e);  
  1120.                 }  
  1121.             }  
  1122.   
  1123.             try {  
  1124.                 mBarService.onNotificationClick(mPkg, mTag, mId);  
  1125.             } catch (RemoteException ex) {  
  1126.                 // system process is dead if we're here.  
  1127.             }  
  1128.   
  1129.             // close the shade if it was open  
  1130.             animateCollapse();  
  1131.         }  
  1132.     }  
  1133.   
  1134.     private void tick(StatusBarNotification n) {  
  1135.         // Show the ticker if one is requested. Also don't do this  
  1136.         // until status bar window is attached to the window manager,  
  1137.         // because...  well, what's the point otherwise?  And trying to  
  1138.         // run a ticker without being attached will crash!  
  1139.         if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) {  
  1140.             if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS  
  1141.                             | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {  
  1142.                 mTicker.addEntry(n);  
  1143.             }  
  1144.         }  
  1145.     }  
  1146.   
  1147.     /** 
  1148.      * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService 
  1149.      * about the failure. 
  1150.      * 
  1151.      * WARNING: this will call back into us.  Don't hold any locks. 
  1152.      */  
  1153.     void handleNotificationError(IBinder key, StatusBarNotification n, String message) {  
  1154.         removeNotification(key);  
  1155.         try {  
  1156.             mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);  
  1157.         } catch (RemoteException ex) {  
  1158.             // The end is nigh.  
  1159.         }  
  1160.     }  
  1161.   
  1162.     private class MyTicker extends Ticker {  
  1163.         MyTicker(Context context, StatusBarView sb) {  
  1164.             super(context, sb);  
  1165.         }  
  1166.   
  1167.         @Override  
  1168.         void tickerStarting() {  
  1169.             if (SPEW) Slog.d(TAG, "tickerStarting");  
  1170.             mTicking = true;  
  1171.             mIcons.setVisibility(View.GONE);  
  1172.             mTickerView.setVisibility(View.VISIBLE);  
  1173.             mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));  
  1174.             mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));  
  1175.             if (mExpandedVisible) {  
  1176.                 setDateViewVisibility(false, com.android.internal.R.anim.push_up_out);  
  1177.             }  
  1178.         }  
  1179.   
  1180.         @Override  
  1181.         void tickerDone() {  
  1182.             if (SPEW) Slog.d(TAG, "tickerDone");  
  1183.             mTicking = false;  
  1184.             mIcons.setVisibility(View.VISIBLE);  
  1185.             mTickerView.setVisibility(View.GONE);  
  1186.             mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));  
  1187.             mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out, null));  
  1188.             if (mExpandedVisible) {  
  1189.                 setDateViewVisibility(true, com.android.internal.R.anim.push_down_in);  
  1190.             }  
  1191.         }  
  1192.   
  1193.         void tickerHalting() {  
  1194.             if (SPEW) Slog.d(TAG, "tickerHalting");  
  1195.             mTicking = false;  
  1196.             mIcons.setVisibility(View.VISIBLE);  
  1197.             mTickerView.setVisibility(View.GONE);  
  1198.             mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));  
  1199.             mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out, null));  
  1200.             if (mExpandedVisible) {  
  1201.                 setDateViewVisibility(true, com.android.internal.R.anim.fade_in);  
  1202.             }  
  1203.         }  
  1204.     }  
  1205.   
  1206.     private Animation loadAnim(int id, Animation.AnimationListener listener) {  
  1207.         Animation anim = AnimationUtils.loadAnimation(StatusBarService.this, id);  
  1208.         if (listener != null) {  
  1209.             anim.setAnimationListener(listener);  
  1210.         }  
  1211.         return anim;  
  1212.     }  
  1213.   
  1214.     public String viewInfo(View v) {  
  1215.         return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()  
  1216.                 + " " + v.getWidth() + "x" + v.getHeight() + ")";  
  1217.     }  
  1218.   
  1219.     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {  
  1220.         if (checkCallingOrSelfPermission(android.Manifest.permission.DUMP)  
  1221.                 != PackageManager.PERMISSION_GRANTED) {  
  1222.             pw.println("Permission Denial: can't dump StatusBar from from pid="  
  1223.                     + Binder.getCallingPid()  
  1224.                     + ", uid=" + Binder.getCallingUid());  
  1225.             return;  
  1226.         }  
  1227.   
  1228.         synchronized (mQueueLock) {  
  1229.             pw.println("Current Status Bar state:");  
  1230.             pw.println("  mExpanded=" + mExpanded  
  1231.                     + ", mExpandedVisible=" + mExpandedVisible);  
  1232.             pw.println("  mTicking=" + mTicking);  
  1233.             pw.println("  mTracking=" + mTracking);  
  1234.             pw.println("  mAnimating=" + mAnimating  
  1235.                     + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel  
  1236.                     + ", mAnimAccel=" + mAnimAccel);  
  1237.             pw.println("  mCurAnimationTime=" + mCurAnimationTime  
  1238.                     + " mAnimLastTime=" + mAnimLastTime);  
  1239.             pw.println("  mDisplayHeight=" + mDisplayHeight  
  1240.                     + " mAnimatingReveal=" + mAnimatingReveal  
  1241.                     + " mViewDelta=" + mViewDelta);  
  1242.             pw.println("  mDisplayHeight=" + mDisplayHeight);  
  1243.             pw.println("  mExpandedParams: " + mExpandedParams);  
  1244.             pw.println("  mExpandedView: " + viewInfo(mExpandedView));  
  1245.             pw.println("  mExpandedDialog: " + mExpandedDialog);  
  1246.             pw.println("  mTrackingParams: " + mTrackingParams);  
  1247.             pw.println("  mTrackingView: " + viewInfo(mTrackingView));  
  1248.             pw.println("  mOngoingTitle: " + viewInfo(mOngoingTitle));  
  1249.             pw.println("  mOngoingItems: " + viewInfo(mOngoingItems));  
  1250.             pw.println("  mLatestTitle: " + viewInfo(mLatestTitle));  
  1251.             pw.println("  mLatestItems: " + viewInfo(mLatestItems));  
  1252.             pw.println("  mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));  
  1253.             pw.println("  mCloseView: " + viewInfo(mCloseView));  
  1254.             pw.println("  mTickerView: " + viewInfo(mTickerView));  
  1255.             pw.println("  mScrollView: " + viewInfo(mScrollView)  
  1256.                     + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());  
  1257.             pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));  
  1258.         }  
  1259.   
  1260.         if (true) {  
  1261.             // must happen on ui thread  
  1262.             mHandler.post(new Runnable() {  
  1263.                     public void run() {  
  1264.                         Slog.d(TAG, "mStatusIcons:");  
  1265.                         mStatusIcons.debug();  
  1266.                     }  
  1267.                 });  
  1268.         }  
  1269.   
  1270.     }  
  1271.   
  1272.     void onBarViewAttached() {  
  1273.         WindowManager.LayoutParams lp;  
  1274.         int pixelFormat;  
  1275.         Drawable bg;  
  1276.   
  1277.         /// ---------- Tracking View --------------  
  1278.         pixelFormat = PixelFormat.RGBX_8888;  
  1279.         bg = mTrackingView.getBackground();  
  1280.         if (bg != null) {  
  1281.             pixelFormat = bg.getOpacity();  
  1282.         }  
  1283.   
  1284.         lp = new WindowManager.LayoutParams(  
  1285.                 ViewGroup.LayoutParams.MATCH_PARENT,  
  1286.                 ViewGroup.LayoutParams.MATCH_PARENT,  
  1287.                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,  
  1288.                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN  
  1289.                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS  
  1290.                 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,  
  1291.                 pixelFormat);  
  1292. //        lp.token = mStatusBarView.getWindowToken();  
  1293.         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;  
  1294.         lp.setTitle("TrackingView");  
  1295.         lp.y = mTrackingPosition;  
  1296.         mTrackingParams = lp;  
  1297.   
  1298.         WindowManagerImpl.getDefault().addView(mTrackingView, lp);  
  1299.     }  
  1300.   
  1301.     void onTrackingViewAttached() {  
  1302.         WindowManager.LayoutParams lp;  
  1303.         int pixelFormat;  
  1304.         Drawable bg;  
  1305.   
  1306.         /// ---------- Expanded View --------------  
  1307.         pixelFormat = PixelFormat.TRANSLUCENT;  
  1308.   
  1309.         final int disph = mDisplay.getHeight();  
  1310.         lp = mExpandedDialog.getWindow().getAttributes();  
  1311.         lp.width = ViewGroup.LayoutParams.MATCH_PARENT;  
  1312.         lp.height = getExpandedHeight();  
  1313.         lp.x = 0;  
  1314.         mTrackingPosition = disph - mStatusBarView.getHeight();  
  1315.         lp.y = mTrackingPosition + mCloseView.getHeight();  
  1316.         lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;  
  1317.         lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN  
  1318.                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS  
  1319.                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL  
  1320.                 | WindowManager.LayoutParams.FLAG_DITHER  
  1321.                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  1322.         lp.format = pixelFormat;  
  1323.         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;  
  1324.         lp.setTitle("StatusBarExpanded");  
  1325.         mExpandedDialog.getWindow().setAttributes(lp);  
  1326.         mExpandedDialog.getWindow().setFormat(pixelFormat);  
  1327.         mExpandedParams = lp;  
  1328.   
  1329.         mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);  
  1330.         mExpandedDialog.setContentView(mExpandedView,  
  1331.                 new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,  
  1332.                                            ViewGroup.LayoutParams.MATCH_PARENT));  
  1333.         mExpandedDialog.getWindow().setBackgroundDrawable(null);  
  1334.         mExpandedDialog.show();  
  1335.         FrameLayout hack = (FrameLayout)mExpandedView.getParent();  
  1336.     }  
  1337.   
  1338.     void setDateViewVisibility(boolean visible, int anim) {  
  1339.         mDateView.setUpdates(visible);  
  1340.         mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);  
  1341.         mDateView.startAnimation(loadAnim(anim, null));  
  1342.     }  
  1343.   
  1344.     void setNotificationIconVisibility(boolean visible, int anim) {  
  1345.         int old = mNotificationIcons.getVisibility();  
  1346.         int v = visible ? View.VISIBLE : View.INVISIBLE;  
  1347.         if (old != v) {  
  1348.             mNotificationIcons.setVisibility(v);  
  1349.             mNotificationIcons.startAnimation(loadAnim(anim, null));  
  1350.         }  
  1351.     }  
  1352.   
  1353.     void updateExpandedViewPos(int expandedPosition) {  
  1354.         if (SPEW) {  
  1355.             Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition  
  1356.                     + " mTrackingParams.y="   
  1357.                     + ((mTrackingParams == null) ? "???" : mTrackingParams.y)  
  1358.                     + " mTrackingPosition=" + mTrackingPosition);  
  1359.         }  
  1360.   
  1361.         int h = mStatusBarView.getHeight();  
  1362.         int disph = mDisplay.getHeight();  
  1363.         int closh = mCloseView.getHeight();  
  1364.   
  1365.         // If the expanded view is not visible, make sure they're still off screen.  
  1366.         // Maybe the view was resized.  
  1367.         if (!mExpandedVisible) {  
  1368.             if (mTrackingView != null) {  
  1369.                 mTrackingPosition = -disph;  
  1370.                 if (mTrackingParams != null) {  
  1371.                     mTrackingParams.y = mTrackingPosition;  
  1372.                     WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);  
  1373.                 }  
  1374.             }  
  1375.             if (mExpandedParams != null) {  
  1376.                 mExpandedParams.y = -disph;  
  1377.                 mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  1378.             }  
  1379.             return;  
  1380.         }  
  1381.   
  1382.         // tracking view...  
  1383.         int pos;  
  1384.         if (expandedPosition == EXPANDED_FULL_OPEN) {  
  1385.             pos = 0;  
  1386.         }  
  1387.         else if (expandedPosition == EXPANDED_LEAVE_ALONE) {  
  1388.             pos = mTrackingPosition;  
  1389.         }  
  1390.         else {  
  1391.             if (expandedPosition >= 0) {  
  1392.                 pos = expandedPosition;  
  1393.             }  
  1394.             else {  
  1395.                 pos = 0;  
  1396.             }  
  1397.         }  
  1398.         mTrackingPosition = mTrackingParams.y = pos;  
  1399.         mTrackingParams.height = disph-h;  
  1400.         WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams);  
  1401.   
  1402.         if (mExpandedParams != null) {  
  1403.             mCloseView.getLocationInWindow(mPositionTmp);  
  1404.             final int closePos = mPositionTmp[1];  
  1405.   
  1406.             if (expandedPosition != EXPANDED_LEAVE_ALONE) {  
  1407.                 mExpandedParams.y = mExpandedParams.y = pos + closePos + mCloseView.getHeight();  
  1408.                   
  1409.                 int max = disph - h;  
  1410.                 if (mExpandedParams.y > max) {  
  1411.                     mExpandedParams.y = max;  
  1412.                 }  
  1413.                 int min = mTrackingPosition + closePos + mCloseView.getHeight();  
  1414.                 if (mExpandedParams.y < min) {  
  1415.                     mExpandedParams.y = min;  
  1416.                 }  
  1417.   
  1418.                 boolean visible = pos < disph - h;  
  1419.                 if (!visible) {  
  1420.                     // if the contents aren't visible, move the expanded view way off screen  
  1421.                     // because the window itself extends below the content view.  
  1422.                     mExpandedParams.y = mDisplay.getHeight() - mStatusBarView.getHeight() + mCloseView.getHeight();  
  1423.                 }  
  1424.                 mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  1425.   
  1426.                 if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")");  
  1427.                 visibilityChanged(visible);  
  1428.             }  
  1429.         }  
  1430.   
  1431.         if (SPEW) {  
  1432.             Slog.d(TAG, "updateExpandedViewPos after  expandedPosition=" + expandedPosition  
  1433.                     + " mTrackingParams.y=" + mTrackingParams.y  
  1434.                     + " mTrackingPosition=" + mTrackingPosition  
  1435.                     + " mExpandedParams.y=" + mExpandedParams.y  
  1436.                     + " mExpandedParams.height=" + mExpandedParams.height);  
  1437.         }  
  1438.     }  
  1439.   
  1440.     int getExpandedHeight() {  
  1441.         return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight();  
  1442.     }  
  1443.   
  1444.     void updateExpandedHeight() {  
  1445.         if (mExpandedView != null) {  
  1446.             mExpandedParams.height = getExpandedHeight();  
  1447.             mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  1448.         }  
  1449.     }  
  1450.   
  1451.     /** 
  1452.      * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. 
  1453.      * This was added last-minute and is inconsistent with the way the rest of the notifications 
  1454.      * are handled, because the notification isn't really cancelled.  The lights are just 
  1455.      * turned off.  If any other notifications happen, the lights will turn back on.  Steve says 
  1456.      * this is what he wants. (see bug 1131461) 
  1457.      */  
  1458.     void visibilityChanged(boolean visible) {  
  1459.         if (mPanelSlightlyVisible != visible) {  
  1460.             mPanelSlightlyVisible = visible;  
  1461.             try {  
  1462.                 mBarService.onPanelRevealed();  
  1463.             } catch (RemoteException ex) {  
  1464.                 // Won't fail unless the world has ended.  
  1465.             }  
  1466.         }  
  1467.     }  
  1468.   
  1469.     void performDisableActions(int net) {  
  1470.         int old = mDisabled;  
  1471.         int diff = net ^ old;  
  1472.         mDisabled = net;  
  1473.   
  1474.         // act accordingly  
  1475.         if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {  
  1476.             if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {  
  1477.                 Slog.d(TAG, "DISABLE_EXPAND: yes");  
  1478.                 animateCollapse();  
  1479.             }  
  1480.         }  
  1481.         if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {  
  1482.             if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {  
  1483.                 Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");  
  1484.                 if (mTicking) {  
  1485.                     mNotificationIcons.setVisibility(View.INVISIBLE);  
  1486.                     mTicker.halt();  
  1487.                 } else {  
  1488.                     setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);  
  1489.                 }  
  1490.             } else {  
  1491.                 Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");  
  1492.                 if (!mExpandedVisible) {  
  1493.                     setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);  
  1494.                 }  
  1495.             }  
  1496.         } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {  
  1497.             Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: "  
  1498.                 + (((net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0)  
  1499.                     ? "yes" : "no"));  
  1500.             if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {  
  1501.                 mTicker.halt();  
  1502.             }  
  1503.         }  
  1504.     }  
  1505.   
  1506.     private View.OnClickListener mClearButtonListener = new View.OnClickListener() {  
  1507.         public void onClick(View v) {  
  1508.             try {  
  1509.                 mBarService.onClearAllNotifications();  
  1510.             } catch (RemoteException ex) {  
  1511.                 // system process is dead if we're here.  
  1512.             }  
  1513.             animateCollapse();  
  1514.         }  
  1515.     };  
  1516.   
  1517.     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {  
  1518.         public void onReceive(Context context, Intent intent) {  
  1519.             String action = intent.getAction();  
  1520.             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)  
  1521.                     || Intent.ACTION_SCREEN_OFF.equals(action)) {  
  1522.                 animateCollapse();  
  1523.             }  
  1524.             else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {  
  1525.                 updateResources();  
  1526.             }  
  1527.         }  
  1528.     };  
  1529.   
  1530.     /** 
  1531.      * Reload some of our resources when the configuration changes. 
  1532.      * 
  1533.      * We don't reload everything when the configuration changes -- we probably 
  1534.      * should, but getting that smooth is tough.  Someday we'll fix that.  In the 
  1535.      * meantime, just update the things that we know change. 
  1536.      */  
  1537.     void updateResources() {  
  1538.         Resources res = getResources();  
  1539.   
  1540.         mClearButton.setText(getText(R.string.status_bar_clear_all_button));  
  1541.         mOngoingTitle.setText(getText(R.string.status_bar_ongoing_events_title));  
  1542.         mLatestTitle.setText(getText(R.string.status_bar_latest_events_title));  
  1543.         mNoNotificationsTitle.setText(getText(R.string.status_bar_no_notifications_title));  
  1544.   
  1545.         mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);  
  1546.   
  1547.         if (false) Slog.v(TAG, "updateResources");  
  1548.     }  
  1549.   
  1550.     //  
  1551.     // tracing  
  1552.     //  
  1553.   
  1554.     void postStartTracing() {  
  1555.         mHandler.postDelayed(mStartTracing, 3000);  
  1556.     }  
  1557.   
  1558.     void vibrate() {  
  1559.         android.os.Vibrator vib = (android.os.Vibrator)getSystemService(Context.VIBRATOR_SERVICE);  
  1560.         vib.vibrate(250);  
  1561.     }  
  1562.   
  1563.     Runnable mStartTracing = new Runnable() {  
  1564.         public void run() {  
  1565.             vibrate();  
  1566.             SystemClock.sleep(250);  
  1567.             Slog.d(TAG, "startTracing");  
  1568.             android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");  
  1569.             mHandler.postDelayed(mStopTracing, 10000);  
  1570.         }  
  1571.     };  
  1572.   
  1573.     Runnable mStopTracing = new Runnable() {  
  1574.         public void run() {  
  1575.             android.os.Debug.stopMethodTracing();  
  1576.             Slog.d(TAG, "stopTracing");  
  1577.             vibrate();  
  1578.         }  
  1579.     };  
  1580. }

你可能感兴趣的:(android 怎么把状态栏移到底部)