Make disable() work.

Change-Id: I93fea37e777b3e04fe7f9171d5b84821587c24f5
This commit is contained in:
Joe Onorato
2010-05-14 18:49:29 -07:00
parent 5368017294
commit f3f0e053f0
7 changed files with 110 additions and 129 deletions

View File

@@ -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);

View File

@@ -23,5 +23,6 @@ oneway interface IStatusBar
{
void setIcon(int index, in StatusBarIcon icon);
void removeIcon(int index);
void disable(int state);
}

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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),

View File

@@ -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) {
}
}

View File

@@ -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;
final Context mContext;
Handler mHandler = new Handler();
NotificationCallbacks mNotificationCallbacks;
IStatusBar mBar;
StatusBarIconList mIcons = new StatusBarIconList();
private UninstallReceiver mUninstallReceiver;
private static final int MSG_ANIMATE = 1000;
private static final int MSG_ANIMATE_REVEAL = 1001;
// expanded notifications
NotificationViewList mNotificationData = new NotificationViewList();
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;
}
// 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)) {