[Nexus 5 Original Android Development] kufikugel:
so had some minutes time.....the code below should solve it. testing now locally. basically the activity stack checks if the app which the user is opening now has heads up enabled....if yes it notifies the supervisor stack....which notifies the statusbar service.... and in the status bar we check if the current heads up is from the package the user just opened. it this is the case we hide it.

we are a development thread so here some code :D

@@ -33,6 +33,7 @@ oneway interface IStatusBar
void animateCollapsePanels();
void setSystemUiVisibility(int vis, int mask);
void hideHeadsUp();
+ void hideHeadsUpCandidate(String packageName);
void updateHeadsUpPosition(boolean statusBarShows);
void topAppWindowChanged(boolean menuVisible);
void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index fa23ced..ec46f04 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -48,6 +48,7 @@ interface IStatusBarService
void onNotificationClear(String pkg, String tag, int id);
void setSystemUiVisibility(int vis, int mask);
void hideHeadsUp();
+ void hideHeadsUpCandidate(String packageName);
void updateHeadsUpPosition(boolean statusBarShows);
void setHardKeyboardEnabled(boolean enabled);
void toggleRecentApps();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index c402a84..23539aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -156,6 +156,7 @@ public abstract class BaseStatusBar extends SystemUI implements
private Locale mLocale;
private int mHeadsUpSnoozeTime = DEFAULT_TIME_HEADS_UP_SNOOZE;
private long mHeadsUpSnoozeStartTime;
+ protected String mHeadsUpPackageName;
protected boolean mShowHeadsUpUpdates;

protected IDreamManager mDreamManager;
@@ -1263,8 +1264,19 @@ public abstract class BaseStatusBar extends SystemUI implements
mHeadsUpSnoozeStartTime = 0;
}

+ @Override // CommandQueue
+ public void hideHeadsUpCandidate(String packageName) {
+ // Activity stack notifies us that probably the the current heads up
+ // is from the package which is opened now. If this is the case hide
+ // our heads up immediatelly to do not disturb the workflow.
+ if (mHeadsUpPackageName != null && mHeadsUpPackageName.equals(packageName)) {
+ hideHeadsUp();
+ }
+ }
+
protected boolean shouldInterrupt(StatusBarNotification sbn) {
Notification notification = sbn.getNotification();
+ mHeadsUpPackageName = sbn.getPackageName();
// some predicates to make the boolean logic legible
boolean isNoisy = (notification.defaults & Notification.DEFAULT_SOUND) != 0
|| (notification.defaults & Notification.DEFAULT_VIBRATE) != 0
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 9862089..a9a75f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -65,7 +65,8 @@ public class CommandQueue extends IStatusBar.Stub {
private static final int MSG_SET_PIE_TRIGGER_MASK = 23 << MSG_SHIFT;
private static final int MSG_SMART_PULLDOWN = 24 << MSG_SHIFT;
private static final int MSG_HIDE_HEADS_UP = 25 << MSG_SHIFT;
- private static final int MSG_UPDATE_HEADS_UP_POSITION = 26 << MSG_SHIFT;
+ private static final int MSG_HIDE_HEADS_UP_CANDIDATE = 26 << MSG_SHIFT;
+ private static final int MSG_UPDATE_HEADS_UP_POSITION = 27 << MSG_SHIFT;

public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -100,6 +101,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void animateExpandSettingsPanel(boolean flip);
public void setSystemUiVisibility(int vis, int mask);
public void hideHeadsUp();
+ public void hideHeadsUpCandidate(String packageName);
public void updateHeadsUpPosition(boolean statusBarShows);
public void topAppWindowChanged(boolean visible);
public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
@@ -207,6 +209,14 @@ public class CommandQueue extends IStatusBar.Stub {
}
}

+ public void hideHeadsUpCandidate(String packageName) {
+ synchronized (mList) {
+ mHandler.removeMessages(MSG_HIDE_HEADS_UP_CANDIDATE);
+ mHandler.obtainMessage(MMSG_HIDE_HEADS_UP_CANDIDATE,
+ 0, 0, packageName).sendToTarget();
+ }
+ }
+
public void updateHeadsUpPosition(boolean statusBarShows) {
synchronized (mList) {
mHandler.removeMessages(MSG_UPDATE_HEADS_UP_POSITION);
@@ -387,6 +397,9 @@ public class CommandQueue extends IStatusBar.Stub {
case MSG_HIDE_HEADS_UP:
mCallbacks.hideHeadsUp();
break;
+ case MSG_HIDE_HEADS_UP_CANDIDATE:
+ mCallbacks.hideHeadsUpCandidate((String) msg.obj);
+ break;
case MSG_UPDATE_HEADS_UP_POSITION:
mCallbacks.updateHeadsUpPosition(msg.arg1 != 0);
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 34e8337..705ecb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -4009,11 +4009,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}

private void setHeadsUpVisibility(boolean vis) {
+ if ((mInterruptingNotificationEntry == null && mHeadsUpPackageName == null && !vis)
+ || mInterruptingNotificationEntry != null && mHeadsUpPackageName != null && vis)) {
+ // Nothing to do here....opt out early.
+ return;
+ }
if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
if (!vis) {
if (DEBUG) Log.d(TAG, "setting heads up entry to null");
mInterruptingNotificationEntry = null;
+ mHeadsUpPackageName = null;
}
}

diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 3f2de9a..656f1b7 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -376,6 +376,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}

@Override
+ public void hideHeadsUpCandidate(String packageName) {
+ if (mBar != null) {
+ try {
+ mBar.hideHeadsUpCandidate(packageName);
+ } catch (RemoteException ex) {}
+ }
+ }
+
+ @Override
public void updateHeadsUpPosition(boolean statusBarShows) {
if (mBar != null) {
try {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 06d0ed8..45a0414 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -982,6 +982,7 @@ final class ActivityStack {
} else {
next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
}
+ updateHeadsUpState(next);
updatePrivacyGuardNotificationLocked(next);
}

@@ -1686,6 +1687,33 @@ final class ActivityStack {
mTaskHistory.add(stackNdx, task);
}

+ private final void updateHeadsUpState(ActivityRecord next) {
+ String headsUpPackageName = mStackSupervisor.mHeadsUpPackageName;
+ if (headsUpPackageName != null && headsUpPackageName.equals(next.packageName)) {
+ return;
+ }
+
+ boolean isHeadsUpCandidate = false;
+ try {
+ isHeadsUpCandidate = AppGlobals.getPackageManager().getHeadsUpSetting(
+ next.packageName, next.userId);
+ } catch (RemoteException e) {
+ // nothing
+ }
+ if (!isHeadsUpCandidate) {
+ // Next package has no heads up enabled. So we do not need to notify
+ // statusbar service that the package has changed. Why bother with it?
+ mStackSupervisor.mHeadsUpPackageName = null;
+ return;
+ } else {
+ // Next package has heads up enabled. Notify statusbar service,
+ // let it decide if the heads up which is currently shown is
+ // from this package and hide it if this is the case.
+ mStackSupervisor.hideHeadsUpCandidate(next.packageName);
+ mStackSupervisor.mHeadsUpPackageName = next.packageName;
+ }
+ }
+

diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index ae71071..b0cbae7 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -64,6 +64,7 @@ import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.EventLog;
@@ -72,6 +73,7 @@ import android.util.SparseIntArray;

import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.TransferPipe;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.StackBox;
@@ -113,6 +115,7 @@ public final class ActivityStackSupervisor {
static final boolean VALIDATE_WAKE_LOCK_CALLER = false;

final ActivityManagerService mService;
+ IStatusBarService mStatusBarService;
final Context mContext;
final Looper mLooper;

@@ -207,6 +210,11 @@ public final class ActivityStackSupervisor {
SparseIntArray mUserStackInFront = new SparseIntArray(2);

/**
+ * Is heads up currently enabled? Shared between ActivityStacks
+ */
+ String mHeadsUpPackageName = null;
+
+ /**
@@ -241,6 +249,26 @@ public final class ActivityStackSupervisor {
}
}

+ void hideHeadsUpCandidate(String packageName) {
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.hideHeadsUpCandidate(packageName);
+ }
+ } catch (RemoteException e) {
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ }
+
+ IStatusBarService getStatusBarService() {
+ if (mStatusBarService == null) {
+ mStatusBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService("statusbar"));
+ }
+ return mStatusBarService;
+ }