am f3f0e053: Make disable() work.

This commit is contained in:
Joe Onorato
2010-06-02 16:24:55 -07:00
committed by Android Git Automerger
7 changed files with 110 additions and 129 deletions

View File

@@ -87,7 +87,7 @@ public class StatusBarManager {
*/ */
public void expand() { public void expand() {
try { try {
mService.activate(); mService.expand();
} catch (RemoteException ex) { } catch (RemoteException ex) {
// system process is dead anyway. // system process is dead anyway.
throw new RuntimeException(ex); throw new RuntimeException(ex);
@@ -99,7 +99,7 @@ public class StatusBarManager {
*/ */
public void collapse() { public void collapse() {
try { try {
mService.deactivate(); mService.collapse();
} catch (RemoteException ex) { } catch (RemoteException ex) {
// system process is dead anyway. // system process is dead anyway.
throw new RuntimeException(ex); throw new RuntimeException(ex);

View File

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

View File

@@ -23,8 +23,8 @@ import com.android.internal.statusbar.StatusBarIconList;
/** @hide */ /** @hide */
interface IStatusBarService interface IStatusBarService
{ {
void activate(); void expand();
void deactivate(); void collapse();
void toggle(); void toggle();
void disable(int what, IBinder token, String pkg); void disable(int what, IBinder token, String pkg);
void setIcon(String slot, String iconPackage, int iconId, int iconLevel); 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.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList; 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 { class CommandQueue extends IStatusBar.Stub {
private static final String TAG = "StatusBar.CommandQueue"; 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_SET_ICON = 1;
private static final int OP_REMOVE_ICON = 2; private static final int OP_REMOVE_ICON = 2;
private static final int MSG_DISABLE = 0x00020000;
private StatusBarIconList mList; private StatusBarIconList mList;
private Callbacks mCallbacks; private Callbacks mCallbacks;
private Handler mHandler = new H(); private Handler mHandler = new H();
@@ -46,6 +54,7 @@ class CommandQueue extends IStatusBar.Stub {
public void updateIcon(String slot, int index, int viewIndex, public void updateIcon(String slot, int index, int viewIndex,
StatusBarIcon old, StatusBarIcon icon); StatusBarIcon old, StatusBarIcon icon);
public void removeIcon(String slot, int index, int viewIndex); public void removeIcon(String slot, int index, int viewIndex);
public void disable(int state);
} }
public CommandQueue(Callbacks callbacks, StatusBarIconList list) { 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 { private final class H extends Handler {
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
int what = msg.what & MSG_MASK; final int what = msg.what & MSG_MASK;
switch (what) { switch (what) {
case MSG_ICON: { case MSG_ICON: {
int index = msg.what & INDEX_MASK; final int index = msg.what & INDEX_MASK;
int viewIndex = mList.getViewIndex(index); final int viewIndex = mList.getViewIndex(index);
switch (msg.arg1) { switch (msg.arg1) {
case OP_SET_ICON: { case OP_SET_ICON: {
StatusBarIcon icon = (StatusBarIcon)msg.obj; StatusBarIcon icon = (StatusBarIcon)msg.obj;
@@ -96,7 +112,10 @@ class CommandQueue extends IStatusBar.Stub {
break; break;
} }
break; break;
} }
case MSG_DISABLE:
mCallbacks.disable(msg.arg1);
break;
} }
} }
} }

View File

@@ -101,7 +101,7 @@ public class PhoneStatusBarService extends StatusBarService {
switch (event.getKeyCode()) { switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_BACK:
if (!down) { if (!down) {
//TODO PhoneStatusBarService.this.deactivate(); //TODO PhoneStatusBarService.this.collapse();
} }
return true; return true;
} }
@@ -330,6 +330,42 @@ public class PhoneStatusBarService extends StatusBarService {
mStatusIcons.removeViewAt(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. * 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. // the stack trace isn't very helpful here. Just log the exception message.
Slog.w(TAG, "Sending contentIntent failed: " + e); 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 ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
Slog.d(TAG, "DISABLE_EXPAND: yes"); Slog.d(TAG, "DISABLE_EXPAND: yes");
animateCollapse(); //animateCollapse();
} }
} }
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
@@ -1261,7 +1297,7 @@ public class PhoneStatusBarService extends StatusBarService {
String action = intent.getAction(); String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)) { || Intent.ACTION_SCREEN_OFF.equals(action)) {
//deactivate(); //collapse();
} }
else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),

View File

@@ -1541,7 +1541,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (sbs != null) { if (sbs != null) {
try { try {
// Make sure the window shade is hidden. // Make sure the window shade is hidden.
sbs.deactivate(); sbs.collapse();
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }

View File

@@ -28,6 +28,7 @@ import android.net.Uri;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.Binder; import android.os.Binder;
import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Slog; import android.util.Slog;
@@ -43,49 +44,30 @@ import java.util.HashMap;
/** /**
* The public (ok, semi-public) service for the status bar. * A note on locking: We rely on the fact that calls onto mBar are oneway or
* <p> * if they are local, that they just enqueue messages to not deadlock.
* 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.
*/ */
public class StatusBarManagerService extends IStatusBarService.Stub public class StatusBarManagerService extends IStatusBarService.Stub
{ {
static final String TAG = "StatusBar"; static final String TAG = "StatusBar";
static final boolean SPEW = false; static final boolean SPEW = true;
public static final String ACTION_STATUSBAR_START public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START"; = "com.android.internal.policy.statusbar.START";
static final int EXPANDED_LEAVE_ALONE = -10000; final Context mContext;
static final int EXPANDED_FULL_OPEN = -10001; Handler mHandler = new Handler();
NotificationCallbacks mNotificationCallbacks;
IStatusBar mBar;
StatusBarIconList mIcons = new StatusBarIconList();
private UninstallReceiver mUninstallReceiver;
private static final int MSG_ANIMATE = 1000; // expanded notifications
private static final int MSG_ANIMATE_REVEAL = 1001; NotificationViewList mNotificationData = new NotificationViewList();
private static final int OP_ADD_ICON = 1; // for disabling the status bar
private static final int OP_UPDATE_ICON = 2; ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
private static final int OP_REMOVE_ICON = 3; int mDisabled = 0;
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;
}
private class DisableRecord implements IBinder.DeathRecipient { private class DisableRecord implements IBinder.DeathRecipient {
String pkg; String pkg;
@@ -106,23 +88,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
void onPanelRevealed(); 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 * Construct the service, add the status bar view to the window manager
*/ */
@@ -154,11 +119,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// ================================================================================ // ================================================================================
// From IStatusBarService // From IStatusBarService
// ================================================================================ // ================================================================================
public void activate() { public void expand() {
enforceExpandStatusBar(); enforceExpandStatusBar();
} }
public void deactivate() { public void collapse() {
enforceExpandStatusBar(); enforceExpandStatusBar();
} }
@@ -168,18 +133,29 @@ public class StatusBarManagerService extends IStatusBarService.Stub
public void disable(int what, IBinder token, String pkg) { public void disable(int what, IBinder token, String pkg) {
enforceStatusBar(); enforceStatusBar();
synchronized (mNotificationCallbacks) {
// This is a little gross, but I think it's safe as long as nobody else // It's important that the the callback and the call to mBar get done
// synchronizes on mNotificationCallbacks. It's important that the the callback // in the same order when multiple threads are calling this function
// and the pending op get done in the correct order and not interleaved with // so they are paired correctly. The messages on the handler will be
// other calls, otherwise they'll get out of sync. // handled in the order they were enqueued, but will be outside the lock.
int net; synchronized (mDisableRecords) {
synchronized (mDisableRecords) { manageDisableListLocked(what, token, pkg);
manageDisableListLocked(what, token, pkg); final int net = gatherDisableActionsLocked();
net = gatherDisableActionsLocked(); Slog.d(TAG, "disable... net=0x" + Integer.toHexString(net));
mNotificationCallbacks.onSetDisabled(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); //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
mIcons.setIcon(index, icon); mIcons.setIcon(index, icon);
// Tell the client. If it fails, it'll restart soon and we'll sync up.
if (mBar != null) { if (mBar != null) {
try { try {
mBar.setIcon(index, icon); mBar.setIcon(index, icon);
@@ -223,7 +198,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
if (icon.visible != visible) { if (icon.visible != visible) {
icon.visible = visible; icon.visible = visible;
// Tell the client. If it fails, it'll restart soon and we'll sync up.
if (mBar != null) { if (mBar != null) {
try { try {
mBar.setIcon(index, icon); mBar.setIcon(index, icon);
@@ -245,7 +219,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
mIcons.removeIcon(index); mIcons.removeIcon(index);
// Tell the client. If it fails, it'll restart soon and we'll sync up.
if (mBar != null) { if (mBar != null) {
try { try {
mBar.removeIcon(index); mBar.removeIcon(index);
@@ -289,8 +262,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// lock on mDisableRecords // lock on mDisableRecords
void manageDisableListLocked(int what, IBinder token, String pkg) { void manageDisableListLocked(int what, IBinder token, String pkg) {
if (SPEW) { if (SPEW) {
Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
+ " pkg=" + pkg);
} }
// update the list // update the list
synchronized (mDisableRecords) { synchronized (mDisableRecords) {
@@ -361,18 +333,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
mIcons.dump(pw); 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) { synchronized (mNotificationData) {
int N = mNotificationData.ongoingCount(); int N = mNotificationData.ongoingCount();
pw.println(" ongoingCount.size=" + N); 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() { private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)) { || Intent.ACTION_SCREEN_OFF.equals(action)) {
deactivate(); collapse();
} }
/* /*
else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) { else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {