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.ActivityManager; 20 import android.app.Service; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.res.Resources; 24 import android.graphics.PixelFormat; 25 import android.os.IBinder; 26 import android.os.RemoteException; 27 import android.os.ServiceManager; 28 import android.util.Slog; 29 import android.util.Log; 30 import android.view.Display; 31 import android.view.Gravity; 32 import android.view.View; 33 import android.view.ViewGroup; 34 import android.view.WindowManager; 35 import android.view.WindowManagerImpl; 36 37 import java.util.ArrayList; 38 39 import com.android.internal.statusbar.IStatusBarService; 40 import com.android.internal.statusbar.StatusBarIcon; 41 import com.android.internal.statusbar.StatusBarIconList; 42 import com.android.internal.statusbar.StatusBarNotification; 43 44 import com.android.systemui.SystemUI; 45 import com.android.systemui.R; 46 47 public abstract class StatusBar extends SystemUI implements CommandQueue.Callbacks { 48 static final String TAG = "StatusBar"; 49 private static final boolean SPEW = false; 50 51 protected CommandQueue mCommandQueue; 52 protected IStatusBarService mBarService; 53 54 // Up-call methods 55 protected abstract View makeStatusBarView(); 56 protected abstract int getStatusBarGravity(); 57 public abstract int getStatusBarHeight(); 58 public abstract void animateCollapse(); 59 60 private DoNotDisturb mDoNotDisturb; 61 62 public void start() { 63 // First set up our views and stuff. 64 View sb = makeStatusBarView(); 65 66 // Connect in to the status bar manager service 67 StatusBarIconList iconList = new StatusBarIconList(); 68 ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>(); 69 ArrayList<StatusBarNotification> notifications = new ArrayList<StatusBarNotification>(); 70 mCommandQueue = new CommandQueue(this, iconList); 71 mBarService = IStatusBarService.Stub.asInterface( 72 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 73 int[] switches = new int[7]; 74 ArrayList<IBinder> binders = new ArrayList<IBinder>(); 75 try { 76 mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, 77 switches, binders); 78 } catch (RemoteException ex) { 79 // If the system process isn't there we're doomed anyway. 80 } 81 82 disable(switches[0]); 83 setSystemUiVisibility(switches[1]); 84 topAppWindowChanged(switches[2] != 0); 85 // StatusBarManagerService has a back up of IME token and it's restored here. 86 setImeWindowStatus(binders.get(0), switches[3], switches[4]); 87 setHardKeyboardStatus(switches[5] != 0, switches[6] != 0); 88 89 // Set up the initial icon state 90 int N = iconList.size(); 91 int viewIndex = 0; 92 for (int i=0; i<N; i++) { 93 StatusBarIcon icon = iconList.getIcon(i); 94 if (icon != null) { 95 addIcon(iconList.getSlot(i), i, viewIndex, icon); 96 viewIndex++; 97 } 98 } 99 100 // Set up the initial notification state 101 N = notificationKeys.size(); 102 if (N == notifications.size()) { 103 for (int i=0; i<N; i++) { 104 addNotification(notificationKeys.get(i), notifications.get(i)); 105 } 106 } else { 107 Log.wtf(TAG, "Notification list length mismatch: keys=" + N 108 + " notifications=" + notifications.size()); 109 } 110 111 // Put up the view 112 final int height = getStatusBarHeight(); 113 114 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 115 ViewGroup.LayoutParams.MATCH_PARENT, 116 height, 117 WindowManager.LayoutParams.TYPE_STATUS_BAR, 118 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 119 | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING 120 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 121 PixelFormat.OPAQUE); 122 123 // the status bar should be in an overlay if possible 124 final Display defaultDisplay 125 = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) 126 .getDefaultDisplay(); 127 if (ActivityManager.isHighEndGfx(defaultDisplay)) { 128 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 129 } 130 131 lp.gravity = getStatusBarGravity(); 132 lp.setTitle("StatusBar"); 133 lp.packageName = mContext.getPackageName(); 134 lp.windowAnimations = R.style.Animation_StatusBar; 135 WindowManagerImpl.getDefault().addView(sb, lp); 136 137 if (SPEW) { 138 Slog.d(TAG, "Added status bar view: gravity=0x" + Integer.toHexString(lp.gravity) 139 + " icons=" + iconList.size() 140 + " disabled=0x" + Integer.toHexString(switches[0]) 141 + " lights=" + switches[1] 142 + " menu=" + switches[2] 143 + " imeButton=" + switches[3] 144 ); 145 } 146 147 mDoNotDisturb = new DoNotDisturb(mContext); 148 } 149 150 protected View updateNotificationVetoButton(View row, StatusBarNotification n) { 151 View vetoButton = row.findViewById(R.id.veto); 152 if (n.isClearable()) { 153 final String _pkg = n.pkg; 154 final String _tag = n.tag; 155 final int _id = n.id; 156 vetoButton.setOnClickListener(new View.OnClickListener() { 157 public void onClick(View v) { 158 try { 159 mBarService.onNotificationClear(_pkg, _tag, _id); 160 } catch (RemoteException ex) { 161 // system process is dead if we're here. 162 } 163 } 164 }); 165 vetoButton.setVisibility(View.VISIBLE); 166 } else { 167 vetoButton.setVisibility(View.GONE); 168 } 169 return vetoButton; 170 } 171 } 172