diff options
7 files changed, 112 insertions, 131 deletions
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 8905268..9499d82 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -87,7 +87,7 @@ public class StatusBarManager { */ public void expand() { try { - mService.activate(); + mService.expand(); } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); @@ -99,7 +99,7 @@ public class StatusBarManager { */ public void collapse() { try { - mService.deactivate(); + mService.collapse(); } catch (RemoteException ex) { // system process is dead anyway. throw new RuntimeException(ex); diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 2a5ae15..65628b0 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -23,5 +23,6 @@ oneway interface IStatusBar { void setIcon(int index, in StatusBarIcon icon); void removeIcon(int index); + void disable(int state); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 0a9c8da..ba63eaf 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -23,8 +23,8 @@ import com.android.internal.statusbar.StatusBarIconList; /** @hide */ interface IStatusBarService { - void activate(); - void deactivate(); + void expand(); + void collapse(); void toggle(); void disable(int what, IBinder token, String pkg); void setIcon(String slot, String iconPackage, int iconId, int iconLevel); diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java index 3357e10..90f17d5 100644 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/CommandQueue.java @@ -24,6 +24,12 @@ import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; +/** + * This class takes the functions from IStatusBar that come in on + * binder pool threads and posts messages to get them onto the main + * thread, and calls onto Callbacks. It also takes care of + * coalescing these calls so they don't stack up. + */ class CommandQueue extends IStatusBar.Stub { private static final String TAG = "StatusBar.CommandQueue"; @@ -34,6 +40,8 @@ class CommandQueue extends IStatusBar.Stub { private static final int OP_SET_ICON = 1; private static final int OP_REMOVE_ICON = 2; + private static final int MSG_DISABLE = 0x00020000; + private StatusBarIconList mList; private Callbacks mCallbacks; private Handler mHandler = new H(); @@ -46,6 +54,7 @@ class CommandQueue extends IStatusBar.Stub { public void updateIcon(String slot, int index, int viewIndex, StatusBarIcon old, StatusBarIcon icon); public void removeIcon(String slot, int index, int viewIndex); + public void disable(int state); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -69,13 +78,20 @@ class CommandQueue extends IStatusBar.Stub { } } + public void disable(int state) { + synchronized (mList) { + mHandler.removeMessages(MSG_DISABLE); + mHandler.obtainMessage(MSG_DISABLE, state, 0, null).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { - int what = msg.what & MSG_MASK; + final int what = msg.what & MSG_MASK; switch (what) { case MSG_ICON: { - int index = msg.what & INDEX_MASK; - int viewIndex = mList.getViewIndex(index); + final int index = msg.what & INDEX_MASK; + final int viewIndex = mList.getViewIndex(index); switch (msg.arg1) { case OP_SET_ICON: { StatusBarIcon icon = (StatusBarIcon)msg.obj; @@ -96,7 +112,10 @@ class CommandQueue extends IStatusBar.Stub { break; } break; - } + } + case MSG_DISABLE: + mCallbacks.disable(msg.arg1); + break; } } } diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java index 8291d70..6ae632b 100644 --- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java +++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java @@ -101,7 +101,7 @@ public class PhoneStatusBarService extends StatusBarService { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_BACK: if (!down) { - //TODO PhoneStatusBarService.this.deactivate(); + //TODO PhoneStatusBarService.this.collapse(); } return true; } @@ -329,6 +329,42 @@ public class PhoneStatusBarService extends StatusBarService { Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex); mStatusIcons.removeViewAt(viewIndex); } + + /** + * State is one or more of the DISABLE constants from StatusBarManager. + */ + public void disable(int state) { + final int old = mDisabled; + final int diff = state ^ old; + mDisabled = state; + + if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { + if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { + Slog.d(TAG, "DISABLE_EXPAND: yes"); + animateCollapse(); + } + } + if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + if (mTicking) { + mTicker.halt(); + } else { + setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); + } + } else { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + if (!mExpandedVisible) { + setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); + } + } + } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes"); + mTicker.halt(); + } + } + } /** * All changes to the status bar and notifications funnel through here and are batched. @@ -854,7 +890,7 @@ public class PhoneStatusBarService extends StatusBarService { // the stack trace isn't very helpful here. Just log the exception message. Slog.w(TAG, "Sending contentIntent failed: " + e); } - //deactivate(); + //collapse(); } } @@ -1224,7 +1260,7 @@ public class PhoneStatusBarService extends StatusBarService { if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { Slog.d(TAG, "DISABLE_EXPAND: yes"); - animateCollapse(); + //animateCollapse(); } } if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { @@ -1261,7 +1297,7 @@ public class PhoneStatusBarService extends StatusBarService { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action)) { - //deactivate(); + //collapse(); } else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java index 11ebd0f..3169fe0 100755 --- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java @@ -1541,7 +1541,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (sbs != null) { try { // Make sure the window shade is hidden. - sbs.deactivate(); + sbs.collapse(); } catch (RemoteException e) { } } diff --git a/services/java/com/android/server/status/StatusBarManagerService.java b/services/java/com/android/server/status/StatusBarManagerService.java index 0f5f2ac..1752f26 100644 --- a/services/java/com/android/server/status/StatusBarManagerService.java +++ b/services/java/com/android/server/status/StatusBarManagerService.java @@ -28,6 +28,7 @@ import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; import android.os.Binder; +import android.os.Handler; import android.os.SystemClock; import android.util.Slog; @@ -43,49 +44,30 @@ import java.util.HashMap; /** - * The public (ok, semi-public) service for the status bar. - * <p> - * This interesting thing to note about this class is that most of the methods that - * are called from other classes just post a message, and everything else is batched - * and coalesced into a series of calls to methods that all start with "perform." - * There are two reasons for this. The first is that some of the methods (activate/deactivate) - * are on IStatusBarService, so they're called from the thread pool and they need to make their - * way onto the UI thread. The second is that the message queue is stopped while animations - * are happening in order to make for smoother transitions. - * <p> - * Each icon is either an icon or an icon and a notification. They're treated mostly - * separately throughout the code, although they both use the same key, which is assigned - * when they are created. + * A note on locking: We rely on the fact that calls onto mBar are oneway or + * if they are local, that they just enqueue messages to not deadlock. */ public class StatusBarManagerService extends IStatusBarService.Stub { static final String TAG = "StatusBar"; - static final boolean SPEW = false; + static final boolean SPEW = true; public static final String ACTION_STATUSBAR_START = "com.android.internal.policy.statusbar.START"; - static final int EXPANDED_LEAVE_ALONE = -10000; - static final int EXPANDED_FULL_OPEN = -10001; - - private static final int MSG_ANIMATE = 1000; - private static final int MSG_ANIMATE_REVEAL = 1001; - - private static final int OP_ADD_ICON = 1; - private static final int OP_UPDATE_ICON = 2; - private static final int OP_REMOVE_ICON = 3; - private static final int OP_SET_VISIBLE = 4; - private static final int OP_EXPAND = 5; - private static final int OP_TOGGLE = 6; - private static final int OP_DISABLE = 7; - private class PendingOp { - IBinder key; - int code; - IconData iconData; - NotificationData notificationData; - boolean visible; - int integer; - } + final Context mContext; + Handler mHandler = new Handler(); + NotificationCallbacks mNotificationCallbacks; + IStatusBar mBar; + StatusBarIconList mIcons = new StatusBarIconList(); + private UninstallReceiver mUninstallReceiver; + + // expanded notifications + NotificationViewList mNotificationData = new NotificationViewList(); + + // for disabling the status bar + ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); + int mDisabled = 0; private class DisableRecord implements IBinder.DeathRecipient { String pkg; @@ -106,23 +88,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub void onPanelRevealed(); } - final Context mContext; - Object mQueueLock = new Object(); - ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>(); - NotificationCallbacks mNotificationCallbacks; - IStatusBar mBar; - - // icons - StatusBarIconList mIcons = new StatusBarIconList(); - private UninstallReceiver mUninstallReceiver; - - // expanded notifications - NotificationViewList mNotificationData = new NotificationViewList(); - - // for disabling the status bar - ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); - int mDisabled = 0; - /** * Construct the service, add the status bar view to the window manager */ @@ -154,11 +119,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub // ================================================================================ // From IStatusBarService // ================================================================================ - public void activate() { + public void expand() { enforceExpandStatusBar(); } - public void deactivate() { + public void collapse() { enforceExpandStatusBar(); } @@ -168,18 +133,29 @@ public class StatusBarManagerService extends IStatusBarService.Stub public void disable(int what, IBinder token, String pkg) { enforceStatusBar(); - synchronized (mNotificationCallbacks) { - // This is a little gross, but I think it's safe as long as nobody else - // synchronizes on mNotificationCallbacks. It's important that the the callback - // and the pending op get done in the correct order and not interleaved with - // other calls, otherwise they'll get out of sync. - int net; - synchronized (mDisableRecords) { - manageDisableListLocked(what, token, pkg); - net = gatherDisableActionsLocked(); - mNotificationCallbacks.onSetDisabled(net); + + // It's important that the the callback and the call to mBar get done + // in the same order when multiple threads are calling this function + // so they are paired correctly. The messages on the handler will be + // handled in the order they were enqueued, but will be outside the lock. + synchronized (mDisableRecords) { + manageDisableListLocked(what, token, pkg); + final int net = gatherDisableActionsLocked(); + Slog.d(TAG, "disable... net=0x" + Integer.toHexString(net)); + if (net != mDisabled) { + mDisabled = net; + mHandler.post(new Runnable() { + public void run() { + mNotificationCallbacks.onSetDisabled(net); + } + }); + if (mBar != null) { + try { + mBar.disable(net); + } catch (RemoteException ex) { + } + } } - //addPendingOp(OP_DISABLE, net); } } @@ -196,7 +172,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon); mIcons.setIcon(index, icon); - // Tell the client. If it fails, it'll restart soon and we'll sync up. if (mBar != null) { try { mBar.setIcon(index, icon); @@ -223,7 +198,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub if (icon.visible != visible) { icon.visible = visible; - // Tell the client. If it fails, it'll restart soon and we'll sync up. if (mBar != null) { try { mBar.setIcon(index, icon); @@ -245,7 +219,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub mIcons.removeIcon(index); - // Tell the client. If it fails, it'll restart soon and we'll sync up. if (mBar != null) { try { mBar.removeIcon(index); @@ -289,8 +262,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub // lock on mDisableRecords void manageDisableListLocked(int what, IBinder token, String pkg) { if (SPEW) { - Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) - + " pkg=" + pkg); + Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg); } // update the list synchronized (mDisableRecords) { @@ -361,18 +333,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub mIcons.dump(pw); } - synchronized (mQueueLock) { - pw.println("Current Status Bar state:"); - final int N = mQueue.size(); - pw.println(" mQueue.size=" + N); - for (int i=0; i<N; i++) { - PendingOp op = mQueue.get(i); - pw.println(" [" + i + "] key=" + op.key + " code=" + op.code + " visible=" - + op.visible); - pw.println(" iconData=" + op.iconData); - pw.println(" notificationData=" + op.notificationData); - } - } synchronized (mNotificationData) { int N = mNotificationData.ongoingCount(); pw.println(" ongoingCount.size=" + N); @@ -419,47 +379,12 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } - void performDisableActions(int net) { - /* - int old = mDisabled; - int diff = net ^ old; - mDisabled = net; - - // act accordingly - if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { - if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { - Slog.d(TAG, "DISABLE_EXPAND: yes"); - //animateCollapse(); - } - } - if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); - if (mTicking) { - //mTicker.halt(); - } else { - setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); - } - } else { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); - if (!mExpandedVisible) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } - } - } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - //mTicker.halt(); - } - } - */ - } - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) || Intent.ACTION_SCREEN_OFF.equals(action)) { - deactivate(); + collapse(); } /* else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { |